Let iwm(4) and iwx(4) sleep for 1 second while loading firmware.
authorstsp <stsp@openbsd.org>
Wed, 8 Sep 2021 11:35:08 +0000 (11:35 +0000)
committerstsp <stsp@openbsd.org>
Wed, 8 Sep 2021 11:35:08 +0000 (11:35 +0000)
Sleeping for 1 second matches what iwn(4) does. Fixes issues where loading
firmware failed for bogus reasons. I could trigger this failure on AX200
with suspend/resume but it was not inherently specific to suspend/resume.

The previous code was looping over tsleep(9) in steps of 100msec.
This could lead to a race where the firmware's alive interrupt fired between
the endtsleep() timeout handler, which marks the sleep timeout as expired,
and sleep_finish(), which reschedules the sleeping thread. The driver would
see EWOULDBLOCK and report an error even though loading firmware did succeed.

ok mpi@

sys/dev/pci/if_iwm.c
sys/dev/pci/if_iwx.c

index be92ca7..d105180 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwm.c,v 1.365 2021/09/03 11:55:31 stsp Exp $       */
+/*     $OpenBSD: if_iwm.c,v 1.366 2021/09/08 11:35:08 stsp Exp $       */
 
 /*
  * Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -4145,9 +4145,10 @@ iwm_load_firmware_8000(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
 int
 iwm_load_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
 {
-       int err, w;
+       int err;
 
        sc->sc_uc.uc_intr = 0;
+       sc->sc_uc.uc_ok = 0;
 
        if (sc->sc_device_family >= IWM_DEVICE_FAMILY_8000)
                err = iwm_load_firmware_8000(sc, ucode_type);
@@ -4158,9 +4159,7 @@ iwm_load_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
                return err;
 
        /* wait for the firmware to load */
-       for (w = 0; !sc->sc_uc.uc_intr && w < 10; w++) {
-               err = tsleep_nsec(&sc->sc_uc, 0, "iwmuc", MSEC_TO_NSEC(100));
-       }
+       err = tsleep_nsec(&sc->sc_uc, 0, "iwmuc", SEC_TO_NSEC(1));
        if (err || !sc->sc_uc.uc_ok)
                printf("%s: could not load firmware\n", DEVNAME(sc));
 
index 428a299..24fb611 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwx.c,v 1.103 2021/09/03 11:55:31 stsp Exp $       */
+/*     $OpenBSD: if_iwx.c,v 1.104 2021/09/08 11:35:08 stsp Exp $       */
 
 /*
  * Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -3348,9 +3348,10 @@ int
 iwx_load_firmware(struct iwx_softc *sc)
 {
        struct iwx_fw_sects *fws;
-       int err, w;
+       int err;
 
        sc->sc_uc.uc_intr = 0;
+       sc->sc_uc.uc_ok = 0;
 
        fws = &sc->sc_fw.fw_sects[IWX_UCODE_TYPE_REGULAR];
        err = iwx_ctxt_info_init(sc, fws);
@@ -3360,9 +3361,7 @@ iwx_load_firmware(struct iwx_softc *sc)
        }
 
        /* wait for the firmware to load */
-       for (w = 0; !sc->sc_uc.uc_intr && w < 10; w++) {
-               err = tsleep_nsec(&sc->sc_uc, 0, "iwxuc", MSEC_TO_NSEC(100));
-       }
+       err = tsleep_nsec(&sc->sc_uc, 0, "iwxuc", SEC_TO_NSEC(1));
        if (err || !sc->sc_uc.uc_ok)
                printf("%s: could not load firmware, %d\n", DEVNAME(sc), err);