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