Date: Thu, 22 May 2014 06:28:09 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r266535 - head/sys/dev/usb/wlan Message-ID: <201405220628.s4M6S9TB061400@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: hselasky Date: Thu May 22 06:28:09 2014 New Revision: 266535 URL: http://svnweb.freebsd.org/changeset/base/266535 Log: - Stop transfers when RSU init fails. - Make sure TX/RX lists don't leak and are only allocated once. - Fix off-by one transfer index computation. - Give firmware loading more time. MFC after: 3 days Modified: head/sys/dev/usb/wlan/if_rsu.c Modified: head/sys/dev/usb/wlan/if_rsu.c ============================================================================== --- head/sys/dev/usb/wlan/if_rsu.c Thu May 22 05:33:50 2014 (r266534) +++ head/sys/dev/usb/wlan/if_rsu.c Thu May 22 06:28:09 2014 (r266535) @@ -319,6 +319,20 @@ rsu_attach(device_t self) TIMEOUT_TASK_INIT(taskqueue_thread, &sc->calib_task, 0, rsu_calib_task, sc); + /* Allocate Tx/Rx buffers. */ + error = rsu_alloc_rx_list(sc); + if (error != 0) { + device_printf(sc->sc_dev, "could not allocate Rx buffers\n"); + goto fail_usb; + } + + error = rsu_alloc_tx_list(sc); + if (error != 0) { + device_printf(sc->sc_dev, "could not allocate Tx buffers\n"); + rsu_free_rx_list(sc); + goto fail_usb; + } + iface_index = 0; error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, rsu_config, RSU_N_TRANSFER, sc, &sc->sc_mtx); @@ -615,12 +629,26 @@ rsu_alloc_tx_list(struct rsu_softc *sc) static void rsu_free_tx_list(struct rsu_softc *sc) { + int i; + + /* prevent further allocations from TX list(s) */ + STAILQ_INIT(&sc->sc_tx_inactive); + + for (i = 0; i != RSU_MAX_TX_EP; i++) { + STAILQ_INIT(&sc->sc_tx_active[i]); + STAILQ_INIT(&sc->sc_tx_pending[i]); + } + rsu_free_list(sc, sc->sc_tx, RSU_TX_LIST_COUNT); } static void rsu_free_rx_list(struct rsu_softc *sc) { + /* prevent further allocations from RX list(s) */ + STAILQ_INIT(&sc->sc_rx_inactive); + STAILQ_INIT(&sc->sc_rx_active); + rsu_free_list(sc, sc->sc_rx, RSU_RX_LIST_COUNT); } @@ -1695,9 +1723,9 @@ rsu_tx_start(struct rsu_softc *sc, struc which = RSU_BULK_TX_VO - RSU_BULK_TX_BE; break; default: - KASSERT(M_WME_GETAC(m0) < 4, - ("unsupported WME pipe %d", M_WME_GETAC(m0))); - which = M_WME_GETAC(m0) + RSU_BULK_TX_BE; + which = M_WME_GETAC(m0); + KASSERT(which < RSU_MAX_TX_EP, + ("unsupported WME pipe %d", which)); break; } hasqos = 0; @@ -2172,15 +2200,14 @@ rsu_load_firmware(struct rsu_softc *sc) goto fail; } /* Wait for load to complete. */ - for (ntries = 0; ntries < 10; ntries++) { + for (ntries = 0; ntries != 50; ntries++) { usb_pause_mtx(&sc->sc_mtx, hz / 100); reg = rsu_read_2(sc, R92S_TCR); if (reg & R92S_TCR_IMEM_CODE_DONE) break; } - if (ntries == 10 || !(reg & R92S_TCR_IMEM_CHK_RPT)) { - device_printf(sc->sc_dev, "timeout waiting for %s transfer\n", - "IMEM"); + if (ntries == 50) { + device_printf(sc->sc_dev, "timeout waiting for IMEM transfer\n"); error = ETIMEDOUT; goto fail; } @@ -2193,15 +2220,14 @@ rsu_load_firmware(struct rsu_softc *sc) goto fail; } /* Wait for load to complete. */ - for (ntries = 0; ntries < 10; ntries++) { + for (ntries = 0; ntries != 10; ntries++) { usb_pause_mtx(&sc->sc_mtx, hz / 100); reg = rsu_read_2(sc, R92S_TCR); if (reg & R92S_TCR_EMEM_CODE_DONE) break; } - if (ntries == 10 || !(reg & R92S_TCR_EMEM_CHK_RPT)) { - device_printf(sc->sc_dev, "timeout waiting for %s transfer\n", - "EMEM"); + if (ntries == 10) { + device_printf(sc->sc_dev, "timeout waiting for EMEM transfer\n"); error = ETIMEDOUT; goto fail; } @@ -2336,22 +2362,11 @@ rsu_init_locked(struct rsu_softc *sc) struct ifnet *ifp = sc->sc_ifp; struct r92s_set_pwr_mode cmd; int error; + int i; /* Init host async commands ring. */ sc->cmdq.cur = sc->cmdq.next = sc->cmdq.queued = 0; - /* Allocate Tx/Rx buffers. */ - error = rsu_alloc_rx_list(sc); - if (error != 0) { - device_printf(sc->sc_dev, "could not allocate Rx buffers\n"); - return; - } - error = rsu_alloc_tx_list(sc); - if (error != 0) { - device_printf(sc->sc_dev, "could not allocate Tx buffers\n"); - rsu_free_rx_list(sc); - return; - } /* Power on adapter. */ if (sc->cut == 1) rsu_power_on_acut(sc); @@ -2438,9 +2453,9 @@ rsu_init_locked(struct rsu_softc *sc) ifp->if_drv_flags |= IFF_DRV_RUNNING; return; fail: - rsu_free_rx_list(sc); - rsu_free_tx_list(sc); - return; + /* Need to stop all failed transfers, if any */ + for (i = 0; i != RSU_N_TRANSFER; i++) + usbd_transfer_stop(sc->sc_xfer[i]); } static void
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405220628.s4M6S9TB061400>