From 132990ecdcb072f2ce597b5d497ff3e5b1f09c20 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 25 Jan 2019 10:43:54 -0500 Subject: [PATCH] idualwifi7260: Fix logic errors in iwm_pcie_load_firmware_chunk. * There's no reason to have a while() loop here, because: - if msleep returns 0, that means we were woken up by the interrupt handler, and we are going to exit immediately as sc_fw_chunk_done will now be 1 (there is nothing else that sleeps on sc_fw.) - if msleep doesn't return 0 (i.e. it returned ETIMEDOUT) then we will exit immediately because of the if-test. So, just use a single msleep() and then check sc_fw_chunk_done as before. * The comment said we were sleeping for 5 seconds, but the msleep was only for 1. Before the "sync firmware loading" FreeBSD commit, this was 1 second and so was the comment, and in that commit the comment was changed and the function call wasn't. The bugs here were introduced in the same FreeBSD commit as the "sizeof" bug that I merged a fix for earlier. Possibly fixes failures to initialize uCode on certain devices. --- .../network/wlan/idualwifi7260/dev/iwm/if_iwm.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm.c index 6771e7dc21..e39e772001 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm.c @@ -2404,8 +2404,6 @@ static int iwm_pcie_load_firmware_chunk(struct iwm_softc *sc, uint32_t dst_addr, bus_addr_t phy_addr, uint32_t byte_cnt) { - int ret; - sc->sc_fw_chunk_done = 0; if (!iwm_nic_lock(sc)) @@ -2437,14 +2435,9 @@ iwm_pcie_load_firmware_chunk(struct iwm_softc *sc, uint32_t dst_addr, iwm_nic_unlock(sc); /* wait up to 5s for this segment to load */ - ret = 0; - while (!sc->sc_fw_chunk_done) { - ret = msleep(&sc->sc_fw, &sc->sc_mtx, 0, "iwmfw", hz); - if (ret) - break; - } + msleep(&sc->sc_fw, &sc->sc_mtx, 0, "iwmfw", hz * 5); - if (ret != 0) { + if (!sc->sc_fw_chunk_done) { device_printf(sc->sc_dev, "fw chunk addr 0x%x len %d failed to load\n", dst_addr, byte_cnt);