> 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 */
> 
> 

Reply via email to