svn commit: r187756 - user/thompsa/usb/sys/dev/usb2/wlan

Andrew Thompson thompsa at FreeBSD.org
Mon Jan 26 17:32:13 PST 2009


Author: thompsa
Date: Tue Jan 27 01:32:13 2009
New Revision: 187756
URL: http://svn.freebsd.org/changeset/base/187756

Log:
  Convert over to the USB2 API.

Modified:
  user/thompsa/usb/sys/dev/usb2/wlan/if_rum2.c
  user/thompsa/usb/sys/dev/usb2/wlan/if_rumvar.h
  user/thompsa/usb/sys/dev/usb2/wlan/if_ural2.c
  user/thompsa/usb/sys/dev/usb2/wlan/if_uralreg.h
  user/thompsa/usb/sys/dev/usb2/wlan/if_uralvar.h
  user/thompsa/usb/sys/dev/usb2/wlan/if_zyd2.c
  user/thompsa/usb/sys/dev/usb2/wlan/if_zydreg.h

Modified: user/thompsa/usb/sys/dev/usb2/wlan/if_rum2.c
==============================================================================
--- user/thompsa/usb/sys/dev/usb2/wlan/if_rum2.c	Tue Jan 27 01:31:52 2009	(r187755)
+++ user/thompsa/usb/sys/dev/usb2/wlan/if_rum2.c	Tue Jan 27 01:32:13 2009	(r187756)
@@ -3,6 +3,7 @@
 /*-
  * Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini at free.fr>
  * Copyright (c) 2006 Niall O'Higgins <niallo at openbsd.org>
+ * Copyright (c) 2007-2008 Hans Petter Selasky <hselasky at freebsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -25,129 +26,113 @@ __FBSDID("$FreeBSD$");
  * http://www.ralinktech.com.tw/
  */
 
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/endian.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/rman.h>
-
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-
-#include <net80211/ieee80211_var.h>
-#include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_phy.h>
-#include <net80211/ieee80211_radiotap.h>
-#include <net80211/ieee80211_regdomain.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/if_rumreg.h>
-#include <dev/usb/if_rumvar.h>
-#include <dev/usb/rt2573_ucode.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x)	do { if (rumdebug > 0) printf x; } while (0)
-#define DPRINTFN(n, x)	do { if (rumdebug >= (n)) printf x; } while (0)
-int rumdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum");
-SYSCTL_INT(_hw_usb_rum, OID_AUTO, debug, CTLFLAG_RW, &rumdebug, 0,
-    "rum debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n, x)
+#include <dev/usb2/include/usb2_devid.h>
+#include <dev/usb2/include/usb2_standard.h>
+#include <dev/usb2/include/usb2_mfunc.h>
+#include <dev/usb2/include/usb2_error.h>
+
+#define	USB_DEBUG_VAR rum_debug
+
+#include <dev/usb2/core/usb2_core.h>
+#include <dev/usb2/core/usb2_lookup.h>
+#include <dev/usb2/core/usb2_process.h>
+#include <dev/usb2/core/usb2_debug.h>
+#include <dev/usb2/core/usb2_request.h>
+#include <dev/usb2/core/usb2_busdma.h>
+#include <dev/usb2/core/usb2_util.h>
+
+#include <dev/usb2/wlan/usb2_wlan.h>
+#include <dev/usb2/wlan/if_rumreg.h>
+#include <dev/usb2/wlan/if_rumvar.h>
+#include <dev/usb2/wlan/if_rumfw.h>
+
+#if USB_DEBUG
+static int rum_debug = 0;
+
+SYSCTL_NODE(_hw_usb2, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum");
+SYSCTL_INT(_hw_usb2_rum, OID_AUTO, debug, CTLFLAG_RW, &rum_debug, 0,
+    "Debug level");
 #endif
 
-/* various supported device vendors/products */
-static const struct usb_devno rum_devs[] = {
-	{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_HWU54DM },
-	{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_RT2573_2 },
-	{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_RT2573_3 },
-	{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_RT2573_4 },
-	{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_WUG2700 },
-	{ USB_VENDOR_AMIT,              USB_PRODUCT_AMIT_CGWLUSB2GO },
-	{ USB_VENDOR_ASUS,              USB_PRODUCT_ASUS_RT2573_1 },
-	{ USB_VENDOR_ASUS,              USB_PRODUCT_ASUS_RT2573_2 },
-	{ USB_VENDOR_BELKIN,            USB_PRODUCT_BELKIN_F5D7050A },
-	{ USB_VENDOR_BELKIN,            USB_PRODUCT_BELKIN_F5D9050V3 },
-	{ USB_VENDOR_CISCOLINKSYS,      USB_PRODUCT_CISCOLINKSYS_WUSB54GC },
-	{ USB_VENDOR_CISCOLINKSYS,      USB_PRODUCT_CISCOLINKSYS_WUSB54GR },
-	{ USB_VENDOR_CONCEPTRONIC2,     USB_PRODUCT_CONCEPTRONIC2_C54RU2 },
-	{ USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_CGWLUSB2GL },
-	{ USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_CGWLUSB2GPX },
-	{ USB_VENDOR_DICKSMITH,         USB_PRODUCT_DICKSMITH_CWD854F },
-	{ USB_VENDOR_DICKSMITH,         USB_PRODUCT_DICKSMITH_RT2573 },
-	{ USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWLG122C1 },
-	{ USB_VENDOR_DLINK2,            USB_PRODUCT_DLINK2_WUA1340 },
-	{ USB_VENDOR_DLINK2,            USB_PRODUCT_DLINK2_DWA111 },
-	{ USB_VENDOR_DLINK2,            USB_PRODUCT_DLINK2_DWA110 },
-	{ USB_VENDOR_GIGABYTE,          USB_PRODUCT_GIGABYTE_GNWB01GS },
-	{ USB_VENDOR_GIGABYTE,          USB_PRODUCT_GIGABYTE_GNWI05GS },
-	{ USB_VENDOR_GIGASET,           USB_PRODUCT_GIGASET_RT2573 },
-	{ USB_VENDOR_GOODWAY,           USB_PRODUCT_GOODWAY_RT2573 },
-	{ USB_VENDOR_GUILLEMOT,         USB_PRODUCT_GUILLEMOT_HWGUSB254LB },
-	{ USB_VENDOR_GUILLEMOT,         USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP },
-	{ USB_VENDOR_HUAWEI3COM,        USB_PRODUCT_HUAWEI3COM_WUB320G },
-	{ USB_VENDOR_MELCO,             USB_PRODUCT_MELCO_G54HP },
-	{ USB_VENDOR_MELCO,             USB_PRODUCT_MELCO_SG54HP },
-	{ USB_VENDOR_MSI,               USB_PRODUCT_MSI_RT2573_1 },
-	{ USB_VENDOR_MSI,               USB_PRODUCT_MSI_RT2573_2 },
-	{ USB_VENDOR_MSI,               USB_PRODUCT_MSI_RT2573_3 },
-	{ USB_VENDOR_MSI,               USB_PRODUCT_MSI_RT2573_4 },
-	{ USB_VENDOR_NOVATECH,          USB_PRODUCT_NOVATECH_RT2573 },
-	{ USB_VENDOR_PLANEX2,           USB_PRODUCT_PLANEX2_GWUS54HP },
-	{ USB_VENDOR_PLANEX2,           USB_PRODUCT_PLANEX2_GWUS54MINI2 },
-	{ USB_VENDOR_PLANEX2,           USB_PRODUCT_PLANEX2_GWUSMM },
-	{ USB_VENDOR_QCOM,              USB_PRODUCT_QCOM_RT2573 },
-	{ USB_VENDOR_QCOM,              USB_PRODUCT_QCOM_RT2573_2 },
-	{ USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2573 },
-	{ USB_VENDOR_RALINK,            USB_PRODUCT_RALINK_RT2573_2 },
-	{ USB_VENDOR_RALINK,            USB_PRODUCT_RALINK_RT2671 },
-	{ USB_VENDOR_SITECOMEU,         USB_PRODUCT_SITECOMEU_WL113R2 },
-	{ USB_VENDOR_SITECOMEU,         USB_PRODUCT_SITECOMEU_WL172 },
-	{ USB_VENDOR_SPARKLAN,		USB_PRODUCT_SPARKLAN_RT2573 },
-	{ USB_VENDOR_SURECOM,           USB_PRODUCT_SURECOM_RT2573 }
+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) },
+    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT2573_3) },
+    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT2573_4) },
+    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_WUG2700) },
+    { USB_VP(USB_VENDOR_AMIT,		USB_PRODUCT_AMIT_CGWLUSB2GO) },
+    { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT2573_1) },
+    { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT2573_2) },
+    { USB_VP(USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_F5D7050A) },
+    { USB_VP(USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_F5D9050V3) },
+    { USB_VP(USB_VENDOR_CISCOLINKSYS,	USB_PRODUCT_CISCOLINKSYS_WUSB54GC) },
+    { USB_VP(USB_VENDOR_CISCOLINKSYS,	USB_PRODUCT_CISCOLINKSYS_WUSB54GR) },
+    { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_C54RU2) },
+    { USB_VP(USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_CGWLUSB2GL) },
+    { USB_VP(USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_CGWLUSB2GPX) },
+    { USB_VP(USB_VENDOR_DICKSMITH,	USB_PRODUCT_DICKSMITH_CWD854F) },
+    { USB_VP(USB_VENDOR_DICKSMITH,	USB_PRODUCT_DICKSMITH_RT2573) },
+    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWLG122C1) },
+    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_WUA1340) },
+    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWA111) },
+    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWA110) },
+    { USB_VP(USB_VENDOR_GIGABYTE,	USB_PRODUCT_GIGABYTE_GNWB01GS) },
+    { USB_VP(USB_VENDOR_GIGABYTE,	USB_PRODUCT_GIGABYTE_GNWI05GS) },
+    { USB_VP(USB_VENDOR_GIGASET,	USB_PRODUCT_GIGASET_RT2573) },
+    { USB_VP(USB_VENDOR_GOODWAY,	USB_PRODUCT_GOODWAY_RT2573) },
+    { USB_VP(USB_VENDOR_GUILLEMOT,	USB_PRODUCT_GUILLEMOT_HWGUSB254LB) },
+    { USB_VP(USB_VENDOR_GUILLEMOT,	USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP) },
+    { USB_VP(USB_VENDOR_HUAWEI3COM,	USB_PRODUCT_HUAWEI3COM_WUB320G) },
+    { USB_VP(USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_G54HP) },
+    { USB_VP(USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_SG54HP) },
+    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_1) },
+    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_2) },
+    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_3) },
+    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_4) },
+    { USB_VP(USB_VENDOR_NOVATECH,	USB_PRODUCT_NOVATECH_RT2573) },
+    { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_GWUS54HP) },
+    { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_GWUS54MINI2) },
+    { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_GWUSMM) },
+    { USB_VP(USB_VENDOR_QCOM,		USB_PRODUCT_QCOM_RT2573) },
+    { USB_VP(USB_VENDOR_QCOM,		USB_PRODUCT_QCOM_RT2573_2) },
+    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2573) },
+    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2573_2) },
+    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2671) },
+    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_WL113R2) },
+    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_WL172) },
+    { USB_VP(USB_VENDOR_SPARKLAN,	USB_PRODUCT_SPARKLAN_RT2573) },
+    { USB_VP(USB_VENDOR_SURECOM,	USB_PRODUCT_SURECOM_RT2573) },
 };
 
 MODULE_DEPEND(rum, wlan, 1, 1, 1);
 MODULE_DEPEND(rum, wlan_amrr, 1, 1, 1);
-MODULE_DEPEND(rum, usb, 1, 1, 1);
+MODULE_DEPEND(rum, usb2_wlan, 1, 1, 1);
+MODULE_DEPEND(rum, usb2_core, 1, 1, 1);
+
+static device_probe_t rum_match;
+static device_attach_t rum_attach;
+static device_detach_t rum_detach;
+
+static usb2_callback_t rum_bulk_read_callback;
+static usb2_callback_t rum_bulk_read_clear_stall_callback;
+static usb2_callback_t rum_bulk_write_callback;
+static usb2_callback_t rum_bulk_write_clear_stall_callback;
+
+static usb2_task_fn_t rum_task;
+static usb2_task_fn_t rum_scantask;
+static usb2_task_fn_t rum_promisctask;
+static usb2_task_fn_t rum_amrr_task;
 
 static struct ieee80211vap *rum_vap_create(struct ieee80211com *,
 			    const char name[IFNAMSIZ], int unit, int opmode,
 			    int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
 			    const uint8_t mac[IEEE80211_ADDR_LEN]);
 static void		rum_vap_delete(struct ieee80211vap *);
+static void		rum_tx_free(struct rum_tx_data *, int);
 static int		rum_alloc_tx_list(struct rum_softc *);
 static void		rum_free_tx_list(struct rum_softc *);
-static int		rum_alloc_rx_list(struct rum_softc *);
-static void		rum_free_rx_list(struct rum_softc *);
-static void		rum_task(void *);
-static void		rum_scantask(void *);
 static int		rum_newstate(struct ieee80211vap *,
 			    enum ieee80211_state, int);
-static void		rum_txeof(usbd_xfer_handle, usbd_private_handle,
-			    usbd_status);
-static void		rum_rxeof(usbd_xfer_handle, usbd_private_handle,
-			    usbd_status);
 static void		rum_setup_tx_desc(struct rum_softc *,
 			    struct rum_tx_desc *, uint32_t, uint16_t, int,
 			    int);
@@ -159,7 +144,6 @@ static int		rum_tx_raw(struct rum_softc 
 static int		rum_tx_data(struct rum_softc *, struct mbuf *,
 			    struct ieee80211_node *);
 static void		rum_start(struct ifnet *);
-static void		rum_watchdog(void *);
 static int		rum_ioctl(struct ifnet *, u_long, caddr_t);
 static void		rum_eeprom_read(struct rum_softc *, uint16_t, void *,
 			    int);
@@ -184,7 +168,6 @@ static void		rum_enable_tsf_sync(struct 
 static void		rum_update_slot(struct ifnet *);
 static void		rum_set_bssid(struct rum_softc *, const uint8_t *);
 static void		rum_set_macaddr(struct rum_softc *, const uint8_t *);
-static void		rum_update_promisc(struct rum_softc *);
 static const char	*rum_get_rf(int);
 static void		rum_read_eeprom(struct rum_softc *);
 static int		rum_bbp_init(struct rum_softc *);
@@ -207,8 +190,6 @@ static int		rum_get_rssi(struct rum_soft
 static void		rum_amrr_start(struct rum_softc *,
 			    struct ieee80211_node *);
 static void		rum_amrr_timeout(void *);
-static void		rum_amrr_update(usbd_xfer_handle, usbd_private_handle,
-			    usbd_status);
 
 static const struct {
 	uint32_t	reg;
@@ -369,89 +350,110 @@ static const struct rfprog {
 	{ 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 }
 };
 
+static const struct usb2_config rum_config[RUM_N_TRANSFER] = {
+	[RUM_BULK_DT_WR] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_OUT,
+		.mh.bufsize = (MCLBYTES + RT2573_TX_DESC_SIZE + 8),
+		.mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
+		.mh.callback = rum_bulk_write_callback,
+		.mh.timeout = 5000,	/* ms */
+	},
+
+	[RUM_BULK_DT_RD] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_IN,
+		.mh.bufsize = (MCLBYTES + RT2573_RX_DESC_SIZE),
+		.mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
+		.mh.callback = rum_bulk_read_callback,
+	},
+
+	[RUM_BULK_CS_WR] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.mh.bufsize = sizeof(struct usb2_device_request),
+		.mh.callback = rum_bulk_write_clear_stall_callback,
+		.mh.timeout = 1000,	/* 1 second */
+		.mh.interval = 50,	/* 50ms */
+	},
+
+	[RUM_BULK_CS_RD] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.mh.bufsize = sizeof(struct usb2_device_request),
+		.mh.callback = rum_bulk_read_clear_stall_callback,
+		.mh.timeout = 1000,	/* 1 second */
+		.mh.interval = 50,	/* 50ms */
+	},
+};
+
 static int
 rum_match(device_t self)
 {
-	struct usb_attach_arg *uaa = device_get_ivars(self);
+	struct usb2_attach_arg *uaa = device_get_ivars(self);
 
-	if (uaa->iface != NULL)
-		return UMATCH_NONE;
+	if (uaa->usb2_mode != USB_MODE_HOST)
+		return (ENXIO);
+	if (uaa->info.bConfigIndex != 0)
+		return (ENXIO);
+	if (uaa->info.bIfaceIndex != RT2573_IFACE_INDEX)
+		return (ENXIO);
 
-	return (usb_lookup(rum_devs, uaa->vendor, uaa->product) != NULL) ?
-	    UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
+	return (usb2_lookup_id_by_uaa(rum_devs, sizeof(rum_devs), uaa));
 }
 
 static int
 rum_attach(device_t self)
 {
+	struct usb2_attach_arg *uaa = device_get_ivars(self);
 	struct rum_softc *sc = device_get_softc(self);
-	struct usb_attach_arg *uaa = device_get_ivars(self);
 	struct ieee80211com *ic;
 	struct ifnet *ifp;
 	const uint8_t *ucode = NULL;
-	usb_interface_descriptor_t *id;
-	usb_endpoint_descriptor_t *ed;
-	usbd_status error;
-	int i, ntries, size;
-	uint8_t bands;
+	uint8_t bands, iface_index;
 	uint32_t tmp;
+	int error, ntries, size;
 
+	if (sc == NULL)
+		return (ENOMEM);
+
+	device_set_usb2_desc(self);
 	sc->sc_udev = uaa->device;
 	sc->sc_dev = self;
 
-	if (usbd_set_config_no(sc->sc_udev, RT2573_CONFIG_NO, 0) != 0) {
-		device_printf(self, "could not set configuration no\n");
-		return ENXIO;
-	}
-
-	/* get the first interface handle */
-	error = usbd_device2interface_handle(sc->sc_udev, RT2573_IFACE_INDEX,
-	    &sc->sc_iface);
-	if (error != 0) {
-		device_printf(self, "could not get interface handle\n");
-		return ENXIO;
-	}
-
-	/*
-	 * Find endpoints.
-	 */
-	id = usbd_get_interface_descriptor(sc->sc_iface);
-
-	sc->sc_rx_no = sc->sc_tx_no = -1;
-	for (i = 0; i < id->bNumEndpoints; i++) {
-		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
-		if (ed == NULL) {
-			device_printf(self,
-			    "no endpoint descriptor for iface %d\n", i);
-			return ENXIO;
-		}
-
-		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
-		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
-			sc->sc_rx_no = ed->bEndpointAddress;
-		else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
-		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
-			sc->sc_tx_no = ed->bEndpointAddress;
-	}
-	if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) {
-		device_printf(self, "missing endpoint\n");
-		return ENXIO;
+	mtx_init(&sc->sc_mtx, device_get_nameunit(self),
+	    MTX_NETWORK_LOCK, MTX_DEF);
+	USB_TASK_INIT(&sc->sc_task, rum_task, sc, NULL);
+	USB_TASK_INIT(&sc->sc_promisctask, rum_promisctask, sc, &sc->sc_mtx);
+	USB_TASK_INIT(&sc->sc_scantask, rum_scantask, sc, &sc->sc_mtx);
+
+	iface_index = RT2573_IFACE_INDEX;
+	error = usb2_transfer_setup(uaa->device, &iface_index,
+	    sc->sc_xfer, rum_config, RUM_N_TRANSFER, sc, &sc->sc_mtx);
+	if (error) {
+		device_printf(self, "could not allocate USB transfers, "
+		    "err=%s\n", usb2_errstr(error));
+		goto detach;
+	}
+	error = usb2_proc_create(&sc->sc_tq, USB_PRI_MED,
+	    device_get_nameunit(self));
+	if (error) {
+		device_printf(self, "could not setup config thread!\n");
+		goto detach;
 	}
 
 	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
 	if (ifp == NULL) {
-		device_printf(self, "can not if_alloc()\n"); 
-		return ENXIO;
+		device_printf(sc->sc_dev, "can not if_alloc()\n");
+		goto detach;
 	}
 	ic = ifp->if_l2com;
 
-	mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
-	    MTX_DEF | MTX_RECURSE);
-
-	usb_init_task(&sc->sc_task, rum_task, sc);
-	usb_init_task(&sc->sc_scantask, rum_scantask, sc);
-	callout_init(&sc->watchdog_ch, 0);
-
+	RUM_LOCK(sc);
 	/* retrieve RT2573 rev. no */
 	for (ntries = 0; ntries < 1000; ntries++) {
 		if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0)
@@ -460,7 +462,8 @@ rum_attach(device_t self)
 	}
 	if (ntries == 1000) {
 		device_printf(self, "timeout waiting for chip to settle\n");
-		goto bad;
+		RUM_UNLOCK(sc);
+		goto detach;
 	}
 
 	/* retrieve MAC address and various other things from EEPROM */
@@ -474,13 +477,14 @@ rum_attach(device_t self)
 	error = rum_load_microcode(sc, ucode, size);
 	if (error != 0) {
 		device_printf(self, "could not load 8051 microcode\n");
-		goto bad;
+		RUM_UNLOCK(sc);
+		goto detach;
 	}
+	RUM_UNLOCK(sc);
 
 	ifp->if_softc = sc;
 	if_initname(ifp, "rum", device_get_unit(sc->sc_dev));
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
-	    IFF_NEEDSGIANT; /* USB stack is still under Giant lock */
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_init = rum_init;
 	ifp->if_ioctl = rum_ioctl;
 	ifp->if_start = rum_start;
@@ -539,10 +543,9 @@ rum_attach(device_t self)
 		ieee80211_announce(ic);
 
 	return 0;
-bad:
-	mtx_destroy(&sc->sc_mtx);
-	if_free(ifp);
-	return ENXIO;
+detach:
+	rum_detach(self);
+	return (ENXIO);			/* failure */
 }
 
 static int
@@ -552,35 +555,23 @@ rum_detach(device_t self)
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 
+	RUM_LOCK(sc);
+	sc->sc_flags |= RUM_FLAG_DETACH;
 	rum_stop(sc);
-	bpfdetach(ifp);
-	ieee80211_ifdetach(ic);
-
-	usb_rem_task(sc->sc_udev, &sc->sc_task);
-	usb_rem_task(sc->sc_udev, &sc->sc_scantask);
-	callout_stop(&sc->watchdog_ch);
-
-	if (sc->amrr_xfer != NULL) {
-		usbd_free_xfer(sc->amrr_xfer);
-		sc->amrr_xfer = NULL;
-	}
+	RUM_UNLOCK(sc);
 
-	if (sc->sc_rx_pipeh != NULL) {
-		usbd_abort_pipe(sc->sc_rx_pipeh);
-		usbd_close_pipe(sc->sc_rx_pipeh);
-	}
-	if (sc->sc_tx_pipeh != NULL) {
-		usbd_abort_pipe(sc->sc_tx_pipeh);
-		usbd_close_pipe(sc->sc_tx_pipeh);
+	/* stop all USB transfers first */
+	usb2_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER);
+	usb2_proc_free(&sc->sc_tq);
+
+	if (ifp) {
+		bpfdetach(ifp);
+		ieee80211_ifdetach(ic);
+		if_free(ifp);
 	}
-	
-	rum_free_rx_list(sc);
-	rum_free_tx_list(sc);
-
-	if_free(ifp);
 	mtx_destroy(&sc->sc_mtx);
 
-	return 0;
+	return (0);
 }
 
 static struct ieee80211vap *
@@ -589,6 +580,7 @@ rum_vap_create(struct ieee80211com *ic,
 	const uint8_t bssid[IEEE80211_ADDR_LEN],
 	const uint8_t mac[IEEE80211_ADDR_LEN])
 {
+	struct rum_softc *sc = ic->ic_ifp->if_softc;
 	struct rum_vap *rvp;
 	struct ieee80211vap *vap;
 
@@ -607,7 +599,9 @@ rum_vap_create(struct ieee80211com *ic,
 	rvp->newstate = vap->iv_newstate;
 	vap->iv_newstate = rum_newstate;
 
-	callout_init(&rvp->amrr_ch, 0);
+	rvp->sc = sc;
+	usb2_callout_init_mtx(&rvp->amrr_ch, &sc->sc_mtx, 0);
+	USB_TASK_INIT(&rvp->amrr_task, rum_amrr_task, rvp, &sc->sc_mtx);
 	ieee80211_amrr_init(&rvp->amrr, vap,
 	    IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
 	    IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
@@ -623,49 +617,58 @@ static void
 rum_vap_delete(struct ieee80211vap *vap)
 {
 	struct rum_vap *rvp = RUM_VAP(vap);
+	struct rum_softc *sc = rvp->sc;
 
-	callout_stop(&rvp->amrr_ch);
+	RUM_LOCK(sc);
+	usb2_callout_stop(&rvp->amrr_ch);
+	RUM_UNLOCK(sc);
 	ieee80211_amrr_cleanup(&rvp->amrr);
 	ieee80211_vap_detach(vap);
 	free(rvp, M_80211_VAP);
 }
 
+static void
+rum_tx_free(struct rum_tx_data *data, int txerr)
+{
+	struct rum_softc *sc = data->sc;
+
+	if (data->m != NULL) {
+		if (data->m->m_flags & M_TXCB)
+			ieee80211_process_callback(data->ni, data->m,
+			    txerr ? ETIMEDOUT : 0);
+		m_freem(data->m);
+		data->m = NULL;
+
+		ieee80211_free_node(data->ni);
+		data->ni = NULL;
+	}
+	STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
+	sc->tx_nfree++;
+}
+
 static int
 rum_alloc_tx_list(struct rum_softc *sc)
 {
 	struct rum_tx_data *data;
-	int i, error;
+	int i;
 
-	sc->tx_queued = sc->tx_cur = 0;
+	sc->tx_data = malloc(sizeof(struct rum_tx_data) * RUM_TX_LIST_COUNT,
+	    M_USB, M_NOWAIT|M_ZERO);
+	if (sc->tx_data == NULL)
+		return (ENOMEM);
+
+	sc->tx_nfree = 0;
+	STAILQ_INIT(&sc->tx_q);
+	STAILQ_INIT(&sc->tx_free);
 
 	for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
 		data = &sc->tx_data[i];
 
 		data->sc = sc;
-
-		data->xfer = usbd_alloc_xfer(sc->sc_udev);
-		if (data->xfer == NULL) {
-			device_printf(sc->sc_dev,
-			    "could not allocate tx xfer\n");
-			error = ENOMEM;
-			goto fail;
-		}
-		data->buf = usbd_alloc_buffer(data->xfer,
-		    RT2573_TX_DESC_SIZE + MCLBYTES);
-		if (data->buf == NULL) {
-			device_printf(sc->sc_dev,
-			    "could not allocate tx buffer\n");
-			error = ENOMEM;
-			goto fail;
-		}
-		/* clean Tx descriptor */
-		bzero(data->buf, RT2573_TX_DESC_SIZE);
+		STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
+		sc->tx_nfree++;
 	}
-
 	return 0;
-
-fail:	rum_free_tx_list(sc);
-	return error;
 }
 
 static void
@@ -674,85 +677,27 @@ rum_free_tx_list(struct rum_softc *sc)
 	struct rum_tx_data *data;
 	int i;
 
+	if (sc->tx_data == NULL)
+		return;
+
 	for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
 		data = &sc->tx_data[i];
 
-		if (data->xfer != NULL) {
-			usbd_free_xfer(data->xfer);
-			data->xfer = NULL;
+		if (data->m != NULL) {
+			m_freem(data->m);
+			data->m = NULL;
 		}
-
 		if (data->ni != NULL) {
 			ieee80211_free_node(data->ni);
 			data->ni = NULL;
 		}
 	}
-}
-
-static int
-rum_alloc_rx_list(struct rum_softc *sc)
-{
-	struct rum_rx_data *data;
-	int i, error;
-
-	for (i = 0; i < RUM_RX_LIST_COUNT; i++) {
-		data = &sc->rx_data[i];
-
-		data->sc = sc;
-
-		data->xfer = usbd_alloc_xfer(sc->sc_udev);
-		if (data->xfer == NULL) {
-			device_printf(sc->sc_dev,
-			    "could not allocate rx xfer\n");
-			error = ENOMEM;
-			goto fail;
-		}
-		if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) {
-			device_printf(sc->sc_dev,
-			    "could not allocate rx buffer\n");
-			error = ENOMEM;
-			goto fail;
-		}
-
-		data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
-		if (data->m == NULL) {
-			device_printf(sc->sc_dev,
-			    "could not allocate rx mbuf\n");
-		    	error = ENOMEM;
-			goto fail;
-		}
-
-		data->buf = mtod(data->m, uint8_t *);
-	}
-
-	return 0;
-
-fail:	rum_free_rx_list(sc);
-	return error;
+	free(sc->tx_data, M_USB);
+	sc->tx_data = NULL;
 }
 
 static void
-rum_free_rx_list(struct rum_softc *sc)
-{
-	struct rum_rx_data *data;
-	int i;
-
-	for (i = 0; i < RUM_RX_LIST_COUNT; i++) {
-		data = &sc->rx_data[i];
-
-		if (data->xfer != NULL) {
-			usbd_free_xfer(data->xfer);
-			data->xfer = NULL;
-		}
-		if (data->m != NULL) {
-			m_freem(data->m);
-			data->m = NULL;
-		}
-	}
-}
-
-static void
-rum_task(void *arg)
+rum_task(void *arg, struct usb2_task *task)
 {
 	struct rum_softc *sc = arg;
 	struct ifnet *ifp = sc->sc_ifp;
@@ -764,10 +709,12 @@ rum_task(void *arg)
 	struct ieee80211_node *ni;
 	uint32_t tmp;
 
+	if (sc->sc_flags & RUM_FLAG_DETACH)
+		return;
+
 	ostate = vap->iv_state;
 
 	RUM_LOCK(sc);
-
 	switch (sc->sc_state) {
 	case IEEE80211_S_INIT:
 		if (ostate == IEEE80211_S_RUN) {
@@ -803,7 +750,6 @@ rum_task(void *arg)
 	default:
 		break;
 	}
-
 	RUM_UNLOCK(sc);
 
 	IEEE80211_LOCK(ic);
@@ -820,152 +766,264 @@ rum_newstate(struct ieee80211vap *vap, e
 	struct ieee80211com *ic = vap->iv_ic;
 	struct rum_softc *sc = ic->ic_ifp->if_softc;
 
-	usb_rem_task(sc->sc_udev, &sc->sc_task);
-	usb_rem_task(sc->sc_udev, &sc->sc_scantask);
-	callout_stop(&rvp->amrr_ch);
+	DPRINTF("%s -> %s\n",
+		ieee80211_state_name[vap->iv_state],
+		ieee80211_state_name[nstate]);
+
+	RUM_LOCK(sc);
+	usb2_callout_stop(&rvp->amrr_ch);
 
 	/* do it in a process context */
 	sc->sc_state = nstate;
 	sc->sc_arg = arg;
+	RUM_UNLOCK(sc);
 
 	if (nstate == IEEE80211_S_INIT) {
 		rvp->newstate(vap, nstate, arg);
 		return 0;
 	} else {
-		usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
+		usb2_proc_enqueue(&sc->sc_tq, &sc->sc_task);
 		return EINPROGRESS;
 	}
 }
 
 static void
-rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
+rum_bulk_write_callback(struct usb2_xfer *xfer)
 {
-	struct rum_tx_data *data = priv;
-	struct rum_softc *sc = data->sc;
+	struct rum_softc *sc = xfer->priv_sc;
 	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211_channel *c = ic->ic_curchan;
+	struct rum_tx_data *data;
+	struct mbuf *m;
+	int len;
 
-	if (data->m != NULL && data->m->m_flags & M_TXCB)
-		ieee80211_process_callback(data->ni, data->m, 0/*XXX*/);
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		DPRINTFN(11, "transfer complete, %d bytes\n", xfer->actlen);
+
+		/* free resources */
+		data = xfer->priv_fifo;
+		rum_tx_free(data, 0);
+		xfer->priv_fifo = NULL;
+
+		ifp->if_opackets++;
+		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+		/* FALLTHROUGH */
+	case USB_ST_SETUP:
+		if (sc->sc_flags & RUM_FLAG_WRITE_STALL) {
+			usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_WR]);
+			break;
+		}
+#if 0
+		if (sc->sc_flags & RUM_FLAG_WAIT_COMMAND) {
+			/*
+			 * don't send anything while a command is pending !
+			 */
+			break;
+		}
+#endif
 
-	if (status != USBD_NORMAL_COMPLETION) {
-		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
-			return;
+		data = STAILQ_FIRST(&sc->tx_q);
+		if (data) {
+			STAILQ_REMOVE_HEAD(&sc->tx_q, next);
+			m = data->m;
+
+			if (m->m_pkthdr.len > (MCLBYTES + RT2573_TX_DESC_SIZE)) {
+				DPRINTFN(0, "data overflow, %u bytes\n",
+				    m->m_pkthdr.len);
+				m->m_pkthdr.len = (MCLBYTES + RT2573_TX_DESC_SIZE);
+			}
+			usb2_copy_in(xfer->frbuffers, 0, &data->desc,
+			    RT2573_TX_DESC_SIZE);
+			usb2_m_copy_in(xfer->frbuffers, RT2573_TX_DESC_SIZE, m,
+			    0, m->m_pkthdr.len);
+
+			if (bpf_peers_present(ifp->if_bpf)) {
+				struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
+
+				tap->wt_flags = 0;
+				tap->wt_rate = data->rate;
+				tap->wt_chan_freq = htole16(c->ic_freq);
+				tap->wt_chan_flags = htole16(c->ic_flags);
+				tap->wt_antenna = sc->tx_ant;
 
-		device_printf(sc->sc_dev, "could not transmit buffer: %s\n",
-		    usbd_errstr(status));
+				bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
+			}
 
-		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall_async(sc->sc_tx_pipeh);
+			/* align end on a 4-bytes boundary */
+			len = (RT2573_TX_DESC_SIZE + m->m_pkthdr.len + 3) & ~3;
+			if ((len % 64) == 0)
+				len += 4;
 
-		ifp->if_oerrors++;
-		return;
-	}
+			DPRINTFN(11, "sending frame len=%u xferlen=%u\n",
+			    m->m_pkthdr.len, len);
 
-	m_freem(data->m);
-	data->m = NULL;
-	ieee80211_free_node(data->ni);
-	data->ni = NULL;
+			xfer->frlengths[0] = len;
+			xfer->priv_fifo = data;
 
-	sc->tx_queued--;
-	ifp->if_opackets++;
+			usb2_start_hardware(xfer);
+		}
+		break;
+
+	default:			/* Error */
+		DPRINTFN(11, "transfer error, %s\n",
+		    usb2_errstr(xfer->error));
+
+		if (xfer->error == USB_ERR_STALLED) {
+			/* try to clear stall first */
+			sc->sc_flags |= RUM_FLAG_WRITE_STALL;
+			usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_WR]);
+			return;
+		}
+		if (xfer->error == USB_ERR_TIMEOUT)
+			device_printf(sc->sc_dev, "device timeout\n");
 
-	DPRINTFN(10, ("tx done\n"));
+		ifp->if_oerrors++;
+		data = xfer->priv_fifo;
+		if (data != NULL) {
+			rum_tx_free(data, xfer->error);
+			xfer->priv_fifo = NULL;
+		}
+		break;
+	}
+}
 
-	sc->sc_tx_timer = 0;
-	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-	rum_start(ifp);
+static void
+rum_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
+{
+	struct rum_softc *sc = xfer->priv_sc;
+	struct usb2_xfer *xfer_other = sc->sc_xfer[RUM_BULK_DT_WR];
+
+	if (usb2_clear_stall_callback(xfer, xfer_other)) {
+		DPRINTF("stall cleared\n");
+		sc->sc_flags &= ~RUM_FLAG_WRITE_STALL;
+		usb2_transfer_start(xfer_other);
+	}
 }
 
 static void
-rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
+rum_bulk_read_callback(struct usb2_xfer *xfer)
 {
-	struct rum_rx_data *data = priv;
-	struct rum_softc *sc = data->sc;
+	struct rum_softc *sc = xfer->priv_sc;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
-	struct rum_rx_desc *desc;
 	struct ieee80211_node *ni;
-	struct mbuf *mnew, *m;
-	int len, rssi;
-
-	if (status != USBD_NORMAL_COMPLETION) {
-		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
-			return;
+	struct mbuf *m = NULL;
+	uint32_t flags;
+	uint8_t rssi = 0;
+	int len;
 
-		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
-		goto skip;
-	}
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
 
-	usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
+		DPRINTFN(15, "rx done, actlen=%d\n", xfer->actlen);
 
-	if (len < RT2573_RX_DESC_SIZE + sizeof (struct ieee80211_frame_min)) {
-		DPRINTF(("%s: xfer too short %d\n", 
-		    device_get_nameunit(sc->sc_dev), len));
-		ifp->if_ierrors++;
-		goto skip;
-	}
+		len = xfer->actlen;
+		if (len < RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN) {
+			DPRINTF("%s: xfer too short %d\n",
+			    device_get_nameunit(sc->sc_dev), len);
+			ifp->if_ierrors++;
+			goto tr_setup;
+		}
+
+		len -= RT2573_RX_DESC_SIZE;
+		usb2_copy_out(xfer->frbuffers, 0, &sc->sc_rx_desc,
+		    RT2573_RX_DESC_SIZE);
+
+		rssi = rum_get_rssi(sc, sc->sc_rx_desc.rssi);
+		flags = le32toh(sc->sc_rx_desc.flags);
+		if (flags & RT2573_RX_CRC_ERROR) {
+			/*
+		         * This should not happen since we did not
+		         * request to receive those frames when we
+		         * filled RUM_TXRX_CSR2:
+		         */
+			DPRINTFN(5, "PHY or CRC error\n");
+			ifp->if_ierrors++;
+			goto tr_setup;
+		}
 
-	desc = (struct rum_rx_desc *)data->buf;
+		m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+		if (m == NULL) {
+			DPRINTF("could not allocate mbuf\n");
+			ifp->if_ierrors++;
+			goto tr_setup;
+		}
+		usb2_copy_out(xfer->frbuffers, RT2573_RX_DESC_SIZE,
+		    mtod(m, uint8_t *), len);
+
+		/* finalize mbuf */
+		m->m_pkthdr.rcvif = ifp;
+		m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
+
+		if (bpf_peers_present(ifp->if_bpf)) {
+			struct rum_rx_radiotap_header *tap = &sc->sc_rxtap;
+
+			tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
+			tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
+			    (flags & RT2573_RX_OFDM) ?
+			    IEEE80211_T_OFDM : IEEE80211_T_CCK);
+			tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
+			tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
+			tap->wr_antenna = sc->rx_ant;
+			tap->wr_antsignal = rssi;
+
+			bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
+		}
+		/* FALLTHROUGH */
+	case USB_ST_SETUP:
+tr_setup:
+		if (sc->sc_flags & RUM_FLAG_READ_STALL) {
+			usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_RD]);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-user mailing list