PERFORCE change 157429 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Feb 9 05:43:19 PST 2009
http://perforce.freebsd.org/chv.cgi?CH=157429
Change 157429 by hselasky at 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) <<<
More information about the p4-projects
mailing list