> Date: Mon, 8 May 2017 15:36:11 +0200
> From: Stefan Sperling <[email protected]>
>
> In iwm_send_cmd(), look at the generation counter instead of the STOPPED flag
> to determine whether the interface was reset while we were sleeping. The flag
> will be set if the interface is still down when the task wakes up, but the
> interface could already be up again in which case the flag will be cleared.
> A stale task which sends an outdated command could confuse the firmware.
Makes sense. The comment isn't really accurate now though...
> Index: if_iwm.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
> retrieving revision 1.180
> diff -u -p -r1.180 if_iwm.c
> --- if_iwm.c 8 May 2017 12:41:23 -0000 1.180
> +++ if_iwm.c 8 May 2017 13:04:05 -0000
> @@ -3630,6 +3630,7 @@ iwm_send_cmd(struct iwm_softc *sc, struc
> int group_id;
> size_t hdrlen, datasz;
> uint8_t *data;
> + int generation = sc->sc_generation;
>
> code = hcmd->id;
> async = hcmd->flags & IWM_CMD_ASYNC;
> @@ -3651,7 +3652,7 @@ iwm_send_cmd(struct iwm_softc *sc, struc
> * Is the hardware still available? (after e.g. above wait).
> */
> s = splnet();
> - if (sc->sc_flags & IWM_FLAG_STOPPED) {
> + if (generation != sc->sc_generation) {
> err = ENXIO;
> goto out;
> }
> @@ -3764,7 +3765,6 @@ iwm_send_cmd(struct iwm_softc *sc, struc
> IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
>
> if (!async) {
> - int generation = sc->sc_generation;
> err = tsleep(desc, PCATCH, "iwmcmd", hz);
> if (err == 0) {
> /* if hardware is no longer up, return error */
>
>