From owner-p4-projects@FreeBSD.ORG Mon Feb 9 13:43:18 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 031471065672; Mon, 9 Feb 2009 13:43:18 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B6A06106566C for ; Mon, 9 Feb 2009 13:43:17 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id A2AF08FC1A for ; Mon, 9 Feb 2009 13:43:17 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n19DhHjt089935 for ; Mon, 9 Feb 2009 13:43:17 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n19DhHQF089933 for perforce@freebsd.org; Mon, 9 Feb 2009 13:43:17 GMT (envelope-from hselasky@FreeBSD.org) Date: Mon, 9 Feb 2009 13:43:17 GMT Message-Id: <200902091343.n19DhHQF089933@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 157429 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Feb 2009 13:43:19 -0000 http://perforce.freebsd.org/chv.cgi?CH=157429 Change 157429 by hselasky@hselasky_laptop001 on 2009/02/09 13:43:03 Factor out USB ethernet and USB serial driver specific control request. Fix some minor issues in USB WLAN drivers, like ensuring that xxx_tx_free() is called in all USB callback error cases. Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_request.c#32 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_request.h#10 edit .. //depot/projects/usb/src/sys/dev/usb2/ethernet/usb2_ethernet.c#11 edit .. //depot/projects/usb/src/sys/dev/usb2/ethernet/usb2_ethernet.h#9 edit .. //depot/projects/usb/src/sys/dev/usb2/serial/usb2_serial.c#27 edit .. //depot/projects/usb/src/sys/dev/usb2/serial/usb2_serial.h#15 edit .. //depot/projects/usb/src/sys/dev/usb2/wlan/if_rum2.c#27 edit .. //depot/projects/usb/src/sys/dev/usb2/wlan/if_rumvar.h#4 edit .. //depot/projects/usb/src/sys/dev/usb2/wlan/if_ural2.c#27 edit .. //depot/projects/usb/src/sys/dev/usb2/wlan/if_uralvar.h#4 edit .. //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2.c#30 edit .. //depot/projects/usb/src/sys/dev/usb2/wlan/if_zydreg.h#4 edit .. //depot/projects/usb/src/sys/dev/usb2/wlan/usb2_wlan.c#6 edit .. //depot/projects/usb/src/sys/dev/usb2/wlan/usb2_wlan.h#8 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_request.c#32 (text+ko) ==== @@ -477,6 +477,49 @@ } /*------------------------------------------------------------------------* + * usb2_do_request_proc - factored out code + * + * This function is factored out code. It does basically the same like + * usb2_do_request_flags, except it will check the status of the + * passed process argument before doing the USB request. If the + * process is draining the USB_ERR_IOERROR code will be returned. It + * is assumed that the mutex associated with the process is locked + * when calling this function. + *------------------------------------------------------------------------*/ +usb2_error_t +usb2_do_request_proc(struct usb2_device *udev, struct usb2_process *pproc, + struct usb2_device_request *req, void *data, uint32_t flags, + uint16_t *actlen, uint32_t timeout) +{ + usb2_error_t err; + uint16_t len; + + /* get request data length */ + len = UGETW(req->wLength); + + /* check if the device is being detached */ + if (usb2_proc_is_gone(pproc)) { + err = USB_ERR_IOERROR; + goto done; + } + + /* forward the USB request */ + err = usb2_do_request_flags(udev, pproc->up_mtx, + req, data, flags, actlen, timeout); + +done: + /* on failure we zero the data */ + /* on short packet we zero the unused data */ + if ((len != 0) && (req->bmRequestType & UE_DIR_IN)) { + if (err) + memset(data, 0, len); + else if (actlen && *actlen != len) + memset(((uint8_t *)data) + *actlen, 0, len - *actlen); + } + return (err); +} + +/*------------------------------------------------------------------------* * usb2_req_reset_port * * This function will instruct an USB HUB to perform a reset sequence ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_request.h#10 (text+ko) ==== @@ -27,9 +27,14 @@ #ifndef _USB2_REQUEST_H_ #define _USB2_REQUEST_H_ +struct usb2_process; + usb2_error_t usb2_do_request_flags(struct usb2_device *udev, struct mtx *mtx, struct usb2_device_request *req, void *data, uint32_t flags, uint16_t *actlen, uint32_t timeout); +usb2_error_t usb2_do_request_proc(struct usb2_device *udev, struct usb2_process *pproc, + struct usb2_device_request *req, void *data, uint32_t flags, + uint16_t *actlen, uint32_t timeout); usb2_error_t usb2_req_clear_hub_feature(struct usb2_device *udev, struct mtx *mtx, uint16_t sel); usb2_error_t usb2_req_clear_port_feature(struct usb2_device *udev, ==== //depot/projects/usb/src/sys/dev/usb2/ethernet/usb2_ethernet.c#11 (text+ko) ==== @@ -155,8 +155,8 @@ /* fork rest of the attach code */ UE_LOCK(ue); ue_queue_command(ue, ue_attach_post_task, - &ue->ue_attach_task[0].hdr, - &ue->ue_attach_task[1].hdr); + &ue->ue_sync_task[0].hdr, + &ue->ue_sync_task[1].hdr); UE_UNLOCK(ue); error: @@ -293,8 +293,8 @@ UE_LOCK(ue); if (ifp->if_drv_flags & IFF_DRV_RUNNING) ue_queue_command(ue, ue_stop_task, - &ue->ue_start_stop_task[0].hdr, - &ue->ue_start_stop_task[1].hdr); + &ue->ue_sync_task[0].hdr, + &ue->ue_sync_task[1].hdr); UE_UNLOCK(ue); } @@ -304,36 +304,6 @@ return (usb2_proc_is_gone(&ue->ue_tq)); } -/* factored out code */ -usb2_error_t -usb2_ether_do_request(struct usb2_ether *ue, - struct usb2_device_request *req, void *data, - unsigned int timeout) -{ - uint16_t len; - usb2_error_t err; - - /* get request data length */ - len = UGETW(req->wLength); - - /* check if the device is being detached */ - if (usb2_proc_is_gone(&ue->ue_tq)) { - err = USB_ERR_IOERROR; - goto done; - } - - /* do the USB request */ - err = usb2_do_request_flags(ue->ue_udev, ue->ue_mtx, - req, data, 0, NULL, timeout); - -done: - /* on failure we zero the data */ - if (err && len && (req->bmRequestType & UE_DIR_IN)) - memset(data, 0, len); - - return (err); -} - static void ue_init(void *arg) { @@ -341,8 +311,8 @@ UE_LOCK(ue); ue_queue_command(ue, ue_start_task, - &ue->ue_start_stop_task[0].hdr, - &ue->ue_start_stop_task[1].hdr); + &ue->ue_sync_task[0].hdr, + &ue->ue_sync_task[1].hdr); UE_UNLOCK(ue); } @@ -486,12 +456,12 @@ &ue->ue_promisc_task[1].hdr); else ue_queue_command(ue, ue_start_task, - &ue->ue_start_stop_task[0].hdr, - &ue->ue_start_stop_task[1].hdr); + &ue->ue_sync_task[0].hdr, + &ue->ue_sync_task[1].hdr); } else { ue_queue_command(ue, ue_stop_task, - &ue->ue_start_stop_task[0].hdr, - &ue->ue_start_stop_task[1].hdr); + &ue->ue_sync_task[0].hdr, + &ue->ue_sync_task[1].hdr); } UE_UNLOCK(ue); break; ==== //depot/projects/usb/src/sys/dev/usb2/ethernet/usb2_ethernet.h#9 (text+ko) ==== @@ -89,12 +89,11 @@ struct sysctl_ctx_list ue_sysctl_ctx; struct ifqueue ue_rxq; struct usb2_callout ue_watchdog; - struct usb2_ether_cfg_task ue_attach_task[2]; + struct usb2_ether_cfg_task ue_sync_task[2]; struct usb2_ether_cfg_task ue_media_task[2]; struct usb2_ether_cfg_task ue_multi_task[2]; struct usb2_ether_cfg_task ue_promisc_task[2]; struct usb2_ether_cfg_task ue_tick_task[2]; - struct usb2_ether_cfg_task ue_start_stop_task[2]; int ue_unit; @@ -102,10 +101,10 @@ uint8_t ue_eaddr[ETHER_ADDR_LEN]; }; +#define usb2_ether_do_request(ue,req,data,timo) \ + usb2_do_request_proc((ue)->ue_udev,&(ue)->ue_tq,req,data,0,NULL,timo) + uint8_t usb2_ether_pause(struct usb2_ether *, unsigned int); -usb2_error_t usb2_ether_do_request(struct usb2_ether *, - struct usb2_device_request *, void *, - unsigned int timeout); struct ifnet *usb2_ether_getifp(struct usb2_ether *); struct mii_data *usb2_ether_getmii(struct usb2_ether *); void *usb2_ether_getsc(struct usb2_ether *); ==== //depot/projects/usb/src/sys/dev/usb2/serial/usb2_serial.c#27 (text+ko) ==== @@ -1125,39 +1125,3 @@ usb2_cv_signal(&sc->sc_cv); mtx_unlock(sc->sc_mtx); } - -/* factored out code */ -usb2_error_t -usb2_com_cfg_do_request(struct usb2_device *udev, - struct usb2_com_softc *sc, struct usb2_device_request *req, - void *data, unsigned int flags, unsigned int timeout) -{ - struct usb2_com_super_softc *ssc = sc->sc_super; - uint16_t len; - uint16_t actlen; - usb2_error_t err; - - /* get request data length */ - len = UGETW(req->wLength); - - /* check if the device is being detached */ - if (usb2_proc_is_gone(&ssc->sc_tq)) { - err = USB_ERR_IOERROR; - goto done; - } - - /* do the USB request */ - err = usb2_do_request_flags(udev, sc->sc_mtx, - req, data, flags, &actlen, timeout); - -done: - if ((req->bmRequestType & UE_DIR_IN) && (len != 0)) { - /* on failure we zero the data */ - /* on short packet we zero the rest of the buffer */ - if (err) - memset(data, 0, len); - else if (len != actlen) - memset(((uint8_t *)data) + actlen, 0, len - actlen); - } - return (err); -} ==== //depot/projects/usb/src/sys/dev/usb2/serial/usb2_serial.h#15 (text+ko) ==== @@ -181,6 +181,9 @@ #define UCOM_LS_BREAK 0x04 }; +#define usb2_com_cfg_do_request(udev,com,req,ptr,flags,timo) \ + usb2_do_request_proc(udev,&(com)->sc_super->sc_tq,req,ptr,flags,NULL,timo) + int usb2_com_attach(struct usb2_com_super_softc *, struct usb2_com_softc *, uint32_t, void *, const struct usb2_com_callback *callback, struct mtx *); @@ -192,7 +195,4 @@ void usb2_com_put_data(struct usb2_com_softc *, struct usb2_page_cache *, uint32_t, uint32_t); uint8_t usb2_com_cfg_is_gone(struct usb2_com_softc *); -usb2_error_t usb2_com_cfg_do_request(struct usb2_device *, - struct usb2_com_softc *, struct usb2_device_request *, void *, - unsigned int, unsigned int); #endif /* _USB2_SERIAL_H_ */ ==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_rum2.c#27 (text+ko) ==== @@ -54,6 +54,9 @@ "Debug level"); #endif +#define rum_do_request(sc,req,data) \ + usb2_do_request_proc((sc)->sc_udev, &(sc)->sc_tq, req, data, 0, NULL, 5000) + static const struct usb2_device_id rum_devs[] = { { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM) }, { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2) }, @@ -116,10 +119,13 @@ static usb2_callback_t rum_bulk_read_callback; static usb2_callback_t rum_bulk_write_callback; +static usb2_proc_callback_t rum_attach_post; static usb2_proc_callback_t rum_task; static usb2_proc_callback_t rum_scantask; static usb2_proc_callback_t rum_promisctask; static usb2_proc_callback_t rum_amrr_task; +static usb2_proc_callback_t rum_init_task; +static usb2_proc_callback_t rum_stop_task; static struct ieee80211vap *rum_vap_create(struct ieee80211com *, const char name[IFNAMSIZ], int unit, int opmode, @@ -169,9 +175,7 @@ static const char *rum_get_rf(int); static void rum_read_eeprom(struct rum_softc *); static int rum_bbp_init(struct rum_softc *); -static void rum_init_locked(struct rum_softc *); static void rum_init(void *); -static void rum_stop(void *); static int rum_load_microcode(struct rum_softc *, const u_char *, size_t); static int rum_prepare_beacon(struct rum_softc *, @@ -391,12 +395,8 @@ { struct usb2_attach_arg *uaa = device_get_ivars(self); struct rum_softc *sc = device_get_softc(self); - struct ieee80211com *ic; - struct ifnet *ifp; - const uint8_t *ucode = NULL; - uint8_t bands, iface_index; - uint32_t tmp; - int error, ntries, size; + uint8_t iface_index; + int error; device_set_usb2_desc(self); sc->sc_udev = uaa->device; @@ -420,42 +420,64 @@ goto detach; } - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - goto detach; - } - ic = ifp->if_l2com; + /* fork rest of the attach code */ + RUM_LOCK(sc); + rum_queue_command(sc, rum_attach_post, + &sc->sc_synctask[0].hdr, + &sc->sc_synctask[1].hdr); + RUM_UNLOCK(sc); + return (0); + +detach: + rum_detach(self); + return (ENXIO); /* failure */ +} + +static void +rum_attach_post(struct usb2_proc_msg *pm) +{ + struct rum_task *task = (struct rum_task *)pm; + struct rum_softc *sc = task->sc; + struct ifnet *ifp; + struct ieee80211com *ic; + unsigned int ntries; + int error; + uint32_t tmp; + uint8_t bands; - RUM_LOCK(sc); /* retrieve RT2573 rev. no */ - for (ntries = 0; ntries < 1000; ntries++) { + for (ntries = 0; ntries != 1000; ntries++) { if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0) break; - DELAY(1000); + usb2_pause_mtx(&sc->sc_mtx, hz / 1000); } if (ntries == 1000) { - device_printf(self, "timeout waiting for chip to settle\n"); - RUM_UNLOCK(sc); - goto detach; + device_printf(sc->sc_dev, "timeout waiting for chip to settle\n"); + return; } /* retrieve MAC address and various other things from EEPROM */ rum_read_eeprom(sc); - device_printf(self, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n", + device_printf(sc->sc_dev, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n", tmp, rum_get_rf(sc->rf_rev)); - ucode = rt2573_ucode; - size = sizeof rt2573_ucode; - error = rum_load_microcode(sc, ucode, size); + error = rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode)); if (error != 0) { - device_printf(self, "could not load 8051 microcode\n"); RUM_UNLOCK(sc); - goto detach; + device_printf(sc->sc_dev, "could not load 8051 microcode\n"); + return; } RUM_UNLOCK(sc); + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(sc->sc_dev, "can not if_alloc()\n"); + RUM_LOCK(sc); + return; + } + ic = ifp->if_l2com; + ifp->if_softc = sc; if_initname(ifp, "rum", device_get_unit(sc->sc_dev)); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; @@ -516,10 +538,7 @@ if (bootverbose) ieee80211_announce(ic); - return 0; -detach: - rum_detach(self); - return (ENXIO); /* failure */ + RUM_LOCK(sc); } static int @@ -529,10 +548,8 @@ struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; - RUM_LOCK(sc); - sc->sc_flags |= RUM_FLAG_DETACH; - rum_stop(sc); - RUM_UNLOCK(sc); + /* wait for any post attach or other command to complete */ + usb2_proc_drain(&sc->sc_tq); /* stop all USB transfers first */ usb2_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER); @@ -543,6 +560,10 @@ ieee80211_ifdetach(ic); if_free(ifp); } + + /* free TX list, if any */ + rum_free_tx_list(sc); + mtx_destroy(&sc->sc_mtx); return (0); @@ -683,9 +704,6 @@ struct ieee80211_node *ni; uint32_t tmp; - if (sc->sc_flags & RUM_FLAG_DETACH) - return; - ostate = vap->iv_state; switch (sc->sc_state) { @@ -773,7 +791,7 @@ struct ieee80211_channel *c = ic->ic_curchan; struct rum_tx_data *data; struct mbuf *m; - int len; + unsigned int len; switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: @@ -790,15 +808,6 @@ /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: -#if 0 - if (sc->sc_flags & RUM_FLAG_WAIT_COMMAND) { - /* - * don't send anything while a command is pending ! - */ - break; - } -#endif - data = STAILQ_FIRST(&sc->tx_q); if (data) { STAILQ_REMOVE_HEAD(&sc->tx_q, next); @@ -845,6 +854,13 @@ DPRINTFN(11, "transfer error, %s\n", usb2_errstr(xfer->error)); + ifp->if_oerrors++; + data = xfer->priv_fifo; + if (data != NULL) { + rum_tx_free(data, xfer->error); + xfer->priv_fifo = NULL; + } + if (xfer->error == USB_ERR_STALLED) { /* try to clear stall first */ xfer->flags.stall_pipe = 1; @@ -852,13 +868,6 @@ } if (xfer->error == USB_ERR_TIMEOUT) device_printf(sc->sc_dev, "device timeout\n"); - - ifp->if_oerrors++; - data = xfer->priv_fifo; - if (data != NULL) { - rum_tx_free(data, xfer->error); - xfer->priv_fifo = NULL; - } break; } } @@ -873,7 +882,7 @@ struct mbuf *m = NULL; uint32_t flags; uint8_t rssi = 0; - int len; + unsigned int len; switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: @@ -965,7 +974,6 @@ goto tr_setup; } return; - } } @@ -1333,15 +1341,20 @@ RUM_LOCK(sc); if (ifp->if_flags & IFF_UP) { if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - rum_init_locked(sc); + rum_queue_command(sc, rum_init_task, + &sc->sc_synctask[0].hdr, + &sc->sc_synctask[1].hdr); startall = 1; } else rum_queue_command(sc, rum_promisctask, &sc->sc_promisctask[0].hdr, &sc->sc_promisctask[1].hdr); } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rum_stop(sc); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + rum_queue_command(sc, rum_stop_task, + &sc->sc_synctask[0].hdr, + &sc->sc_synctask[1].hdr); + } } RUM_UNLOCK(sc); if (startall) @@ -1372,7 +1385,7 @@ USETW(req.wIndex, addr); USETW(req.wLength, len); - error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, buf); + error = rum_do_request(sc, &req, buf); if (error != 0) { device_printf(sc->sc_dev, "could not read EEPROM: %s\n", usb2_errstr(error)); @@ -1401,7 +1414,7 @@ USETW(req.wIndex, reg); USETW(req.wLength, len); - error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, buf); + error = rum_do_request(sc, &req, buf); if (error != 0) { device_printf(sc->sc_dev, "could not multi read MAC register: %s\n", @@ -1429,7 +1442,7 @@ USETW(req.wIndex, reg); USETW(req.wLength, len); - error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, buf); + error = rum_do_request(sc, &req, buf); if (error != 0) { device_printf(sc->sc_dev, "could not multi write MAC register: %s\n", @@ -1787,9 +1800,6 @@ struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; - if (sc->sc_flags & RUM_FLAG_DETACH) - return; - tmp = rum_read(sc, RT2573_TXRX_CSR0); tmp &= ~RT2573_DROP_NOT_TO_ME; @@ -1933,9 +1943,11 @@ } static void -rum_init_locked(struct rum_softc *sc) +rum_init_task(struct usb2_proc_msg *pm) { #define N(a) (sizeof (a) / sizeof ((a)[0])) + struct rum_task *task = (struct rum_task *)pm; + struct rum_softc *sc = task->sc; struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; @@ -1944,11 +1956,8 @@ RUM_LOCK_ASSERT(sc, MA_OWNED); - if (sc->sc_flags & RUM_FLAG_DETACH) - return; + rum_stop_task(pm); - rum_stop(sc); - /* initialize MAC registers to default values */ for (i = 0; i < N(rum_def_mac); i++) rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val); @@ -2015,7 +2024,7 @@ usb2_transfer_start(sc->sc_xfer[RUM_BULK_RD]); return; -fail: rum_stop(sc); +fail: rum_stop_task(pm); #undef N } @@ -2027,7 +2036,9 @@ struct ieee80211com *ic = ifp->if_l2com; RUM_LOCK(sc); - rum_init_locked(sc); + rum_queue_command(sc, rum_init_task, + &sc->sc_synctask[0].hdr, + &sc->sc_synctask[1].hdr); RUM_UNLOCK(sc); if (ifp->if_drv_flags & IFF_DRV_RUNNING) @@ -2035,9 +2046,10 @@ } static void -rum_stop(void *priv) +rum_stop_task(struct usb2_proc_msg *pm) { - struct rum_softc *sc = priv; + struct rum_task *task = (struct rum_task *)pm; + struct rum_softc *sc = task->sc; struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; @@ -2053,10 +2065,6 @@ rum_free_tx_list(sc); - /* Stop now if the device has vanished */ - if (sc->sc_flags & RUM_FLAG_DETACH) - return; - /* disable Rx */ tmp = rum_read(sc, RT2573_TXRX_CSR0); rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX); @@ -2083,7 +2091,7 @@ USETW(req.wIndex, 0); USETW(req.wLength, 0); - error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL); + error = rum_do_request(sc, &req, NULL); if (error != 0) { device_printf(sc->sc_dev, "could not run firmware: %s\n", usb2_errstr(error)); @@ -2296,9 +2304,6 @@ RUM_LOCK_ASSERT(sc, MA_OWNED); - if (sc->sc_flags & RUM_FLAG_DETACH) - return; - switch (sc->sc_scan_action) { case RUM_SCAN_START: /* abort TSF synchronization */ @@ -2395,6 +2400,11 @@ task->hdr.pm_callback = fn; task->sc = sc; + /* + * Init and stop must be synchronous! + */ + if ((fn == rum_init_task) || (fn == rum_stop_task)) + usb2_proc_mwait(&sc->sc_tq, t0, t1); } static device_method_t rum_methods[] = { ==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_rumvar.h#4 (text+ko) ==== @@ -100,14 +100,14 @@ struct usb2_process sc_tq; const struct ieee80211_rate_table *sc_rates; + struct usb2_xfer *sc_xfer[RUM_N_TRANSFER]; uint8_t rf_rev; uint8_t rffreq; - struct usb2_xfer *sc_xfer[RUM_N_TRANSFER]; - enum ieee80211_state sc_state; int sc_arg; + struct rum_task sc_synctask[2]; struct rum_task sc_task[2]; struct rum_task sc_promisctask[2]; struct rum_task sc_scantask[2]; @@ -124,9 +124,6 @@ struct mtx sc_mtx; - int sc_flags; -#define RUM_FLAG_DETACH 0x0001 - uint32_t sta[6]; uint32_t rf_regs[4]; uint8_t txpow[44]; ==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_ural2.c#27 (text+ko) ==== @@ -55,6 +55,9 @@ "Debug level"); #endif +#define ural_do_request(sc,req,data) \ + usb2_do_request_proc((sc)->sc_udev, &(sc)->sc_tq, req, data, 0, NULL, 5000) + #define URAL_RSSI(rssi) \ ((rssi) > (RAL_NOISE_FLOOR + RAL_RSSI_CORR) ? \ ((rssi) - (RAL_NOISE_FLOOR + RAL_RSSI_CORR)) : 0) @@ -95,10 +98,13 @@ static usb2_callback_t ural_bulk_read_callback; static usb2_callback_t ural_bulk_write_callback; +static usb2_proc_callback_t ural_attach_post; static usb2_proc_callback_t ural_task; static usb2_proc_callback_t ural_scantask; static usb2_proc_callback_t ural_promisctask; static usb2_proc_callback_t ural_amrr_task; +static usb2_proc_callback_t ural_init_task; +static usb2_proc_callback_t ural_stop_task; static struct ieee80211vap *ural_vap_create(struct ieee80211com *, const char name[IFNAMSIZ], int unit, int opmode, @@ -153,9 +159,7 @@ static int ural_bbp_init(struct ural_softc *); static void ural_set_txantenna(struct ural_softc *, int); static void ural_set_rxantenna(struct ural_softc *, int); -static void ural_init_locked(struct ural_softc *); static void ural_init(void *); -static void ural_stop(void *); static int ural_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static void ural_amrr_start(struct ural_softc *, @@ -394,10 +398,8 @@ { struct usb2_attach_arg *uaa = device_get_ivars(self); struct ural_softc *sc = device_get_softc(self); - struct ifnet *ifp; - struct ieee80211com *ic; int error; - uint8_t bands, iface_index; + uint8_t iface_index; device_set_usb2_desc(self); sc->sc_udev = uaa->device; @@ -422,14 +424,28 @@ goto detach; } - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - goto detach; - } - ic = ifp->if_l2com; + /* fork rest of the attach code */ + RAL_LOCK(sc); + ural_queue_command(sc, ural_attach_post, + &sc->sc_synctask[0].hdr, + &sc->sc_synctask[1].hdr); + RAL_UNLOCK(sc); + return (0); + +detach: + ural_detach(self); + return (ENXIO); /* failure */ +} + +static void +ural_attach_post(struct usb2_proc_msg *pm) +{ + struct ural_task *task = (struct ural_task *)pm; + struct ural_softc *sc = task->sc; + struct ifnet *ifp; + struct ieee80211com *ic; + uint8_t bands; - RAL_LOCK(sc); /* retrieve RT2570 rev. no */ sc->asic_rev = ural_read(sc, RAL_MAC_CSR0); @@ -440,6 +456,14 @@ device_printf(sc->sc_dev, "MAC/BBP RT2570 (rev 0x%02x), RF %s\n", sc->asic_rev, ural_get_rf(sc->rf_rev)); + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(sc->sc_dev, "can not if_alloc()\n"); + RAL_LOCK(sc); + return; + } + ic = ifp->if_l2com; + ifp->if_softc = sc; if_initname(ifp, "ural", device_get_unit(sc->sc_dev)); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; @@ -500,11 +524,7 @@ if (bootverbose) ieee80211_announce(ic); - return (0); /* success */ - -detach: - ural_detach(self); - return (ENXIO); /* failure */ + RAL_LOCK(sc); } static int @@ -514,10 +534,8 @@ struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; - RAL_LOCK(sc); - sc->sc_flags |= URAL_FLAG_DETACH; - ural_stop(sc); - RAL_UNLOCK(sc); + /* wait for any post attach or other command to complete */ + usb2_proc_drain(&sc->sc_tq); /* stop all USB transfers first */ usb2_transfer_unsetup(sc->sc_xfer, URAL_N_TRANSFER); @@ -528,6 +546,10 @@ ieee80211_ifdetach(ic); if_free(ifp); } + + /* free TX list, if any */ + ural_free_tx_list(sc); + mtx_destroy(&sc->sc_mtx); return (0); @@ -668,9 +690,6 @@ struct ieee80211_node *ni; struct mbuf *m; - if (sc->sc_flags & URAL_FLAG_DETACH) - return; - ostate = vap->iv_state; switch (sc->sc_state) { @@ -747,9 +766,6 @@ RAL_LOCK_ASSERT(sc, MA_OWNED); - if (sc->sc_flags & URAL_FLAG_DETACH) - return; - if (sc->sc_scan_action == URAL_SCAN_START) { /* abort TSF synchronization */ DPRINTF("starting scan\n"); @@ -806,7 +822,7 @@ struct ieee80211_channel *c = ic->ic_curchan; struct ural_tx_data *data; struct mbuf *m; - int len; + unsigned int len; switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: @@ -823,15 +839,6 @@ /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: -#if 0 - if (sc->sc_flags & URAL_FLAG_WAIT_COMMAND) { - /* - * don't send anything while a command is pending ! - */ - break; - } -#endif - data = STAILQ_FIRST(&sc->tx_q); if (data) { STAILQ_REMOVE_HEAD(&sc->tx_q, next); @@ -878,6 +885,13 @@ DPRINTFN(11, "transfer error, %s\n", usb2_errstr(xfer->error)); + ifp->if_oerrors++; + data = xfer->priv_fifo; + if (data != NULL) { + ural_tx_free(data, xfer->error); + xfer->priv_fifo = NULL; + } + if (xfer->error == USB_ERR_STALLED) { /* try to clear stall first */ xfer->flags.stall_pipe = 1; @@ -885,13 +899,6 @@ } if (xfer->error == USB_ERR_TIMEOUT) device_printf(sc->sc_dev, "device timeout\n"); - - ifp->if_oerrors++; - data = xfer->priv_fifo; - if (data != NULL) { - ural_tx_free(data, xfer->error); - xfer->priv_fifo = NULL; - } break; } } @@ -906,7 +913,7 @@ struct mbuf *m = NULL; uint32_t flags; uint8_t rssi = 0; - int len; + unsigned int len; switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: @@ -1001,7 +1008,6 @@ goto tr_setup; } return; - } } @@ -1406,15 +1412,20 @@ RAL_LOCK(sc); if (ifp->if_flags & IFF_UP) { if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - ural_init_locked(sc); + ural_queue_command(sc, ural_init_task, + &sc->sc_synctask[0].hdr, + &sc->sc_synctask[1].hdr); startall = 1; } else ural_queue_command(sc, ural_promisctask, &sc->sc_promisctask[0].hdr, &sc->sc_promisctask[1].hdr); } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ural_stop(sc); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + ural_queue_command(sc, ural_stop_task, + &sc->sc_synctask[0].hdr, + &sc->sc_synctask[1].hdr); + } } RAL_UNLOCK(sc); if (startall) @@ -1443,7 +1454,7 @@ USETW(req.wIndex, 1); USETW(req.wLength, 0); - error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL); + error = ural_do_request(sc, &req, NULL); if (error != 0) { device_printf(sc->sc_dev, "could not set test mode: %s\n", usb2_errstr(error)); @@ -1462,7 +1473,7 @@ USETW(req.wIndex, addr); USETW(req.wLength, len); - error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, buf); + error = ural_do_request(sc, &req, buf); if (error != 0) { device_printf(sc->sc_dev, "could not read EEPROM: %s\n", usb2_errstr(error)); @@ -1482,7 +1493,7 @@ USETW(req.wIndex, reg); USETW(req.wLength, sizeof (uint16_t)); - error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, &val); >>> TRUNCATED FOR MAIL (1000 lines) <<<