From: stsp Date: Wed, 8 Sep 2021 11:35:08 +0000 (+0000) Subject: Let iwm(4) and iwx(4) sleep for 1 second while loading firmware. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=9e8160305739fc9dbb648c10ba3382911a7d3379;p=openbsd Let iwm(4) and iwx(4) sleep for 1 second while loading firmware. 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@ --- diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c index be92ca7dabb..d105180e390 100644 --- a/sys/dev/pci/if_iwm.c +++ b/sys/dev/pci/if_iwm.c @@ -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 @@ -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)); diff --git a/sys/dev/pci/if_iwx.c b/sys/dev/pci/if_iwx.c index 428a299e7a2..24fb611ab1d 100644 --- a/sys/dev/pci/if_iwx.c +++ b/sys/dev/pci/if_iwx.c @@ -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 @@ -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);