Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Jan 2008 18:40:57 +0200
From:      Oleksandr Tymoshenko <gonzo@pbxpress.com>
To:        freebsd-usb@freebsd.org
Subject:   Re: Call for testers: AXE88x78 support for RELENG_6
Message-ID:  <4790D699.9000403@pbxpress.com>
In-Reply-To: <4790D5E3.40008@pbxpress.com>
References:  <4790D5E3.40008@pbxpress.com>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------010506070101090909000909
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Oleksandr Tymoshenko wrote:
> patch atached
Sorry, now it *is* attached.


-- 
Sincerely,

Oleksandr Tymoshenko
PBXpress Communications, Inc.
http://www.pbxpress.com
Tel./Fax.: +1 866 SIP PBX1  Ext. 7117

--------------010506070101090909000909
Content-Type: text/plain;
 name="if_axe.88x78.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="if_axe.88x78.diff"

--- dev/usb/if_axe.c.orig	2008-01-18 18:04:09.000000000 +0000
+++ dev/usb/if_axe.c	2008-01-18 18:04:36.000000000 +0000
@@ -31,11 +31,11 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/usb/if_axe.c,v 1.30.2.6 2007/05/21 18:13:11 brueffer Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/usb/if_axe.c,v 1.56 2007/11/10 16:23:38 sam Exp $");
 
 /*
- * ASIX Electronics AX88172 USB 2.0 ethernet driver. Used in the
- * LinkSys USB200M and various other adapters.
+ * ASIX Electronics AX88172/AX88178/AX88778 USB 2.0 ethernet driver.
+ * Used in the LinkSys USB200M and various other adapters.
  *
  * Manuals available from:
  * http://www.asix.com.tw/datasheet/mac/Ax88172.PDF
@@ -69,12 +69,15 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/endian.h>
 #include <sys/sockio.h>
 #include <sys/mbuf.h>
 #include <sys/malloc.h>
+#include <sys/lock.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/socket.h>
+#include <sys/sx.h>
 
 #include <net/if.h>
 #include <net/if_arp.h>
@@ -98,51 +101,83 @@
 #include <dev/mii/mii.h>
 #include <dev/mii/miivar.h>
 
-/* "controller miibus0" required.  See GENERIC if you get errors here. */
+/* "device miibus" required.  See GENERIC if you get errors here. */
 #include "miibus_if.h"
 
+/*
+ * AXE_178_MAX_FRAME_BURST
+ * max frame burst size for Ax88178 and Ax88772
+ *	0	2048 bytes
+ *	1	4096 bytes
+ *	2	8192 bytes
+ *	3	16384 bytes
+ * use the largest your system can handle without usb stalling.
+ *
+ * NB: 88772 parts appear to generate lots of input errors with
+ * a 2K rx buffer and 8K is only slightly faster than 4K on an
+ * EHCI port on a T42 so change at your own risk.
+ */
+#define AXE_178_MAX_FRAME_BURST	1
+
 #include <dev/usb/if_axereg.h>
 
 /*
  * Various supported device vendors/products.
  */
-Static struct axe_type axe_devs[] = {
-	{ USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172 },
-	{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100 },
-	{ USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1 },
-	{ USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M },
-	{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX },
-	{ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120 },
-	{ USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL },
-	{ USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029 },
-	{ 0, 0 }
+const struct axe_type axe_devs[] = {
+        { { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UF200}, 0 },
+        { { USB_VENDOR_ACERCM, USB_PRODUCT_ACERCM_EP1427X2}, 0 },
+        { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172}, 0 },
+        { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772}, AX772 },
+        { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178}, AX178 },
+        { { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T}, 0 },
+        { { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055 }, AX178 },
+        { { USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR}, 0},
+        { { USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_USB200MV2}, AX772 },
+        { { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB2_TX }, 0},
+        { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100}, 0 },
+        { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1 }, AX772 },
+        { { USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_GWUSB2E}, 0 },
+        { { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETGUS2 }, AX178 },
+        { { USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1}, 0 },
+        { { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M}, 0 },
+        { { USB_VENDOR_LINKSYS5, USB_PRODUCT_LINKSYS5_USB1000 }, AX178 },
+        { { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX}, 0 },
+        { { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120}, 0 },
+        { { USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01PLUS }, AX772 },
+        { { USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GU1000T }, AX178 },
+        { { USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL}, 0 },
+        { { USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029}, 0 },
+        { { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028 }, AX178 }
 };
 
-Static int axe_match(device_ptr_t);
-Static int axe_attach(device_ptr_t);
-Static int axe_detach(device_ptr_t);
-
-Static int axe_encap(struct axe_softc *, struct mbuf *, int);
-Static void axe_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-Static void axe_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-Static void axe_tick(void *);
-Static void axe_rxstart(struct ifnet *);
-Static void axe_start(struct ifnet *);
-Static int axe_ioctl(struct ifnet *, u_long, caddr_t);
-Static void axe_init(void *);
-Static void axe_stop(struct axe_softc *);
-Static void axe_watchdog(struct ifnet *);
-Static void axe_shutdown(device_ptr_t);
-Static int axe_miibus_readreg(device_ptr_t, int, int);
-Static int axe_miibus_writereg(device_ptr_t, int, int, int);
-Static void axe_miibus_statchg(device_ptr_t);
-Static int axe_cmd(struct axe_softc *, int, int, int, void *);
-Static int axe_ifmedia_upd(struct ifnet *);
-Static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+#define axe_lookup(v, p) ((const struct axe_type *)usb_lookup(axe_devs, v, p))
+
+static device_probe_t axe_match;
+static device_attach_t axe_attach;
+static device_detach_t axe_detach;
+static device_shutdown_t axe_shutdown;
+static miibus_readreg_t axe_miibus_readreg;
+static miibus_writereg_t axe_miibus_writereg;
+static miibus_statchg_t axe_miibus_statchg;
+
+static int axe_encap(struct axe_softc *, struct mbuf *, int);
+static void axe_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
+static void axe_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
+static void axe_tick(void *);
+static void axe_tick_task(void *);
+static void axe_start(struct ifnet *);
+static int axe_ioctl(struct ifnet *, u_long, caddr_t);
+static void axe_init(void *);
+static void axe_stop(struct axe_softc *);
+static void axe_watchdog(struct ifnet *);
+static int axe_cmd(struct axe_softc *, int, int, int, void *);
+static int axe_ifmedia_upd(struct ifnet *);
+static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 
-Static void axe_setmulti(struct axe_softc *);
+static void axe_setmulti(struct axe_softc *);
 
-Static device_method_t axe_methods[] = {
+static device_method_t axe_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		axe_match),
 	DEVMETHOD(device_attach,	axe_attach),
@@ -161,25 +196,26 @@
 	{ 0, 0 }
 };
 
-Static driver_t axe_driver = {
+static driver_t axe_driver = {
 	"axe",
 	axe_methods,
 	sizeof(struct axe_softc)
 };
 
-Static devclass_t axe_devclass;
+static devclass_t axe_devclass;
 
 DRIVER_MODULE(axe, uhub, axe_driver, axe_devclass, usbd_driver_load, 0);
 DRIVER_MODULE(miibus, axe, miibus_driver, miibus_devclass, 0, 0);
 MODULE_DEPEND(axe, usb, 1, 1, 1);
 MODULE_DEPEND(axe, miibus, 1, 1, 1);
 
-Static int
+static int
 axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf)
 {
 	usb_device_request_t	req;
 	usbd_status		err;
 
+	AXE_SLEEPLOCKASSERT(sc);
 	if (sc->axe_dying)
 		return(0);
 
@@ -200,16 +236,17 @@
 	return(0);
 }
 
-Static int
-axe_miibus_readreg(device_ptr_t dev, int phy, int reg)
+static int
+axe_miibus_readreg(device_t dev, int phy, int reg)
 {
-	struct axe_softc	*sc = USBGETSOFTC(dev);
+	struct axe_softc	*sc = device_get_softc(dev);
 	usbd_status		err;
 	u_int16_t		val;
 
 	if (sc->axe_dying)
 		return(0);
 
+	AXE_SLEEPLOCKASSERT(sc);
 #ifdef notdef
 	/*
 	 * The chip tells us the MII address of any supported
@@ -232,7 +269,7 @@
 	AXE_UNLOCK(sc);
 
 	if (err) {
-		printf("axe%d: read PHY failed\n", sc->axe_unit);
+		device_printf(sc->axe_dev, "read PHY failed\n");
 		return(-1);
 	}
 
@@ -242,15 +279,16 @@
 	return (val);
 }
 
-Static int
-axe_miibus_writereg(device_ptr_t dev, int phy, int reg, int val)
+static int
+axe_miibus_writereg(device_t dev, int phy, int reg, int val)
 {
-	struct axe_softc	*sc = USBGETSOFTC(dev);
+	struct axe_softc	*sc = device_get_softc(dev);
 	usbd_status		err;
 
 	if (sc->axe_dying)
 		return(0);
 
+	AXE_SLEEPLOCKASSERT(sc);
 	AXE_LOCK(sc);
 	axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
 	err = axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, (void *)&val);
@@ -258,29 +296,46 @@
 	AXE_UNLOCK(sc);
 
 	if (err) {
-		printf("axe%d: write PHY failed\n", sc->axe_unit);
+		device_printf(sc->axe_dev, "write PHY failed\n");
 		return(-1);
 	}
 
 	return (0);
 }
 
-Static void
-axe_miibus_statchg(device_ptr_t dev)
+static void
+axe_miibus_statchg(device_t dev)
 {
-#ifdef notdef
-	struct axe_softc	*sc = USBGETSOFTC(dev);
+	struct axe_softc	*sc = device_get_softc(dev);
 	struct mii_data		*mii = GET_MII(sc);
-#endif
-	/* doesn't seem to be necessary */
+	int			val, err;
 
-	return;
+	val = (mii->mii_media_active & IFM_GMASK) == IFM_FDX ?
+	    AXE_MEDIA_FULL_DUPLEX : 0;
+	if (sc->axe_flags & (AX178|AX772)) {
+		val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC;
+
+		switch (IFM_SUBTYPE(mii->mii_media_active)) {
+		case IFM_1000_T:
+			val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK;
+			break;
+		case IFM_100_TX:
+			val |= AXE_178_MEDIA_100TX;
+			break;
+		case IFM_10_T:
+			/* doesn't need to be handled */
+			break;
+		}
+	}
+	err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL);
+	if (err)
+		device_printf(dev, "media change failed, error %d\n", err);
 }
 
 /*
  * Set media options.
  */
-Static int
+static int
 axe_ifmedia_upd(struct ifnet *ifp)
 {
         struct axe_softc        *sc = ifp->if_softc;
@@ -300,7 +355,7 @@
 /*
  * Report current media status.
  */
-Static void
+static void
 axe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 {
         struct axe_softc        *sc = ifp->if_softc;
@@ -313,7 +368,7 @@
         return;
 }
 
-Static void
+static void
 axe_setmulti(struct axe_softc *sc)
 {
 	struct ifnet		*ifp;
@@ -353,7 +408,94 @@
 	return;
 }
 
-Static void
+static void
+axe_ax88178_init(struct axe_softc *sc)
+{
+	int gpio0 = 0, phymode = 0;
+	u_int16_t eeprom;
+
+	axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL);
+	/* XXX magic */
+	axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom);
+	axe_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL);
+
+	/* if EEPROM is invalid we have to use to GPIO0 */
+	if (eeprom == 0xffff) {
+		phymode = 0;
+		gpio0 = 1;
+	} else {
+		phymode = eeprom & 7;
+		gpio0 = (eeprom & 0x80) ? 0 : 1;
+	}
+
+	axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x008c, NULL);
+	usbd_delay_ms(sc->axe_udev, 40);
+	if ((eeprom >> 8) != 1) {
+		axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
+		usbd_delay_ms(sc->axe_udev, 30);
+
+		axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x001c, NULL);
+		usbd_delay_ms(sc->axe_udev, 300);
+
+		axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
+		usbd_delay_ms(sc->axe_udev, 30);
+	} else {
+		axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x0004, NULL);
+		usbd_delay_ms(sc->axe_udev, 30);
+		axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x000c, NULL);
+		usbd_delay_ms(sc->axe_udev, 30);
+	}
+
+	/* soft reset */
+	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 0, NULL);
+	usbd_delay_ms(sc->axe_udev, 150);
+	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
+	    AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL);
+	usbd_delay_ms(sc->axe_udev, 150);
+	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
+}
+
+static void
+axe_ax88772_init(struct axe_softc *sc)
+{
+	axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL);
+	usbd_delay_ms(sc->axe_udev, 40);
+
+	if (sc->axe_phyaddrs[1] == AXE_INTPHY) {
+		/* ask for embedded PHY */
+		axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x01, NULL);
+		usbd_delay_ms(sc->axe_udev, 10);
+
+		/* power down and reset state, pin reset state */
+		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
+		usbd_delay_ms(sc->axe_udev, 60);
+
+		/* power down/reset state, pin operating state */
+		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
+		    AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
+		usbd_delay_ms(sc->axe_udev, 150);
+
+		/* power up, reset */
+		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL, NULL);
+
+		/* power up, operating */
+		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
+		    AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL);
+	} else {
+		/* ask for external PHY */
+		axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x00, NULL);
+		usbd_delay_ms(sc->axe_udev, 10);
+
+		/* power down/reset state, pin operating state */
+		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
+		    AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
+	}
+
+	usbd_delay_ms(sc->axe_udev, 150);
+	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
+}
+
+static void
 axe_reset(struct axe_softc *sc)
 {
 	if (sc->axe_dying)
@@ -362,8 +504,7 @@
 	if (usbd_set_config_no(sc->axe_udev, AXE_CONFIG_NO, 1) ||
 	    usbd_device2interface_handle(sc->axe_udev, AXE_IFACE_IDX,
 	    &sc->axe_iface)) {
-		printf("axe%d: getting interface handle failed\n",
-		    sc->axe_unit);
+		device_printf(sc->axe_dev, "getting interface handle failed\n");
 	}
 
 	/* Wait a little while for the chip to get its brains in order. */
@@ -374,71 +515,76 @@
 /*
  * Probe for a AX88172 chip.
  */
-USB_MATCH(axe)
+static int
+axe_match(device_t self)
 {
-	USB_MATCH_START(axe, uaa);
-	struct axe_type			*t;
+	struct usb_attach_arg *uaa = device_get_ivars(self);
 
 	if (!uaa->iface)
 		return(UMATCH_NONE);
-
-	t = axe_devs;
-	while(t->axe_vid) {
-		if (uaa->vendor == t->axe_vid &&
-		    uaa->product == t->axe_did) {
-			return(UMATCH_VENDOR_PRODUCT);
-		}
-		t++;
-	}
-
-	return(UMATCH_NONE);
+	return (axe_lookup(uaa->vendor, uaa->product) != NULL ?
+		UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
 }
 
 /*
  * Attach the interface. Allocate softc structures, do ifmedia
  * setup and ethernet/BPF attach.
  */
-USB_ATTACH(axe)
+static int
+axe_attach(device_t self)
 {
-	USB_ATTACH_START(axe, sc, uaa);
-	char			devinfo[1024];
+	struct axe_softc *sc = device_get_softc(self);
+	struct usb_attach_arg *uaa = device_get_ivars(self);
+	const struct axe_type *type;
 	u_char			eaddr[ETHER_ADDR_LEN];
 	struct ifnet		*ifp;
 	usb_interface_descriptor_t	*id;
 	usb_endpoint_descriptor_t	*ed;
 	int			i;
 
-	bzero(sc, sizeof(struct axe_softc));
 	sc->axe_udev = uaa->device;
 	sc->axe_dev = self;
-	sc->axe_unit = device_get_unit(self);
+	type = axe_lookup(uaa->vendor, uaa->product);
+	if (type != NULL)
+		sc->axe_flags = type->axe_flags;
 
 	if (usbd_set_config_no(sc->axe_udev, AXE_CONFIG_NO, 1)) {
-		printf("axe%d: getting interface handle failed\n",
-		    sc->axe_unit);
-		USB_ATTACH_ERROR_RETURN;
+		device_printf(sc->axe_dev, "getting interface handle failed\n");
+		return ENXIO;
 	}
 
+	usb_init_task(&sc->axe_tick_task, axe_tick_task, sc);
+
 	if (usbd_device2interface_handle(uaa->device,
 	    AXE_IFACE_IDX, &sc->axe_iface)) {
-		printf("axe%d: getting interface handle failed\n",
-		    sc->axe_unit);
-		USB_ATTACH_ERROR_RETURN;
+		device_printf(sc->axe_dev, "getting interface handle failed\n");
+		return ENXIO;
 	}
 
-	id = usbd_get_interface_descriptor(sc->axe_iface);
+	sc->axe_boundary = 64;
+	if (sc->axe_flags & (AX178|AX772)) {
+		if (sc->axe_udev->speed == USB_SPEED_HIGH) {
+			sc->axe_bufsz = AXE_178_MAX_BUFSZ;
+			sc->axe_boundary = 512;
+		} else
+			sc->axe_bufsz = AXE_178_MIN_BUFSZ;
+	} else
+		sc->axe_bufsz = AXE_172_BUFSZ;
+{ /* XXX debug */
+device_printf(sc->axe_dev, "%s, bufsz %d, boundary %d\n",
+	sc->axe_flags & AX178 ? "AX88178" :
+	sc->axe_flags & AX772 ? "AX88772" : "AX88172",
+	sc->axe_bufsz, sc->axe_boundary);
+}
 
-	usbd_devinfo(uaa->device, 0, devinfo);
-	device_set_desc_copy(self, devinfo);
-	printf("%s: %s\n", USBDEVNAME(self), devinfo);
+	id = usbd_get_interface_descriptor(sc->axe_iface);
 
 	/* Find endpoints. */
 	for (i = 0; i < id->bNumEndpoints; i++) {
 		ed = usbd_interface2endpoint_descriptor(sc->axe_iface, i);
 		if (!ed) {
-			printf("axe%d: couldn't get ep %d\n",
-			    sc->axe_unit, i);
-			USB_ATTACH_ERROR_RETURN;
+			device_printf(sc->axe_dev, "couldn't get ep %d\n", i);
+			return ENXIO;
 		}
 		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
@@ -454,18 +600,30 @@
 
 	mtx_init(&sc->axe_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
 	    MTX_DEF | MTX_RECURSE);
+	sx_init(&sc->axe_sleeplock, device_get_nameunit(self));
+	AXE_SLEEPLOCK(sc);
 	AXE_LOCK(sc);
 
+	/* We need the PHYID for the init dance in some cases */
+	axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, (void *)&sc->axe_phyaddrs);
+
+	if (sc->axe_flags & AX178)
+		axe_ax88178_init(sc);
+	else if (sc->axe_flags & AX772)
+		axe_ax88772_init(sc);
+
 	/*
 	 * Get station address.
 	 */
-	axe_cmd(sc, AXE_CMD_READ_NODEID, 0, 0, &eaddr);
+	if (sc->axe_flags & (AX178|AX772))
+		axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, &eaddr);
+	else
+		axe_cmd(sc, AXE_172_CMD_READ_NODEID, 0, 0, &eaddr);
 
 	/*
-	 * Load IPG values and PHY indexes.
+	 * Fetch IPG values.
 	 */
 	axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, (void *)&sc->axe_ipgs);
-	axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, (void *)&sc->axe_phyaddrs);
 
 	/*
 	 * Work around broken adapters that appear to lie about
@@ -475,13 +633,15 @@
 
 	ifp = sc->axe_ifp = if_alloc(IFT_ETHER);
 	if (ifp == NULL) {
-		printf("axe%d: can not if_alloc()\n", sc->axe_unit);
+		device_printf(sc->axe_dev, "can not if_alloc()\n");
 		AXE_UNLOCK(sc);
+		AXE_SLEEPUNLOCK(sc);
+		sx_destroy(&sc->axe_sleeplock);
 		mtx_destroy(&sc->axe_mtx);
-		USB_ATTACH_ERROR_RETURN;
+		return ENXIO;
 	}
 	ifp->if_softc = sc;
-	if_initname(ifp, "axe", sc->axe_unit);
+	if_initname(ifp, "axe", device_get_unit(sc->axe_dev));
 	ifp->if_mtu = ETHERMTU;
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
 	    IFF_NEEDSGIANT;
@@ -493,16 +653,15 @@
 	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
 	IFQ_SET_READY(&ifp->if_snd);
 
-	sc->axe_qdat.ifp = ifp;
-	sc->axe_qdat.if_rxstart = axe_rxstart;
-
 	if (mii_phy_probe(self, &sc->axe_miibus,
 	    axe_ifmedia_upd, axe_ifmedia_sts)) {
-		printf("axe%d: MII without any PHY!\n", sc->axe_unit);
+		device_printf(sc->axe_dev, "MII without any PHY!\n");
 		if_free(ifp);
 		AXE_UNLOCK(sc);
+		AXE_SLEEPUNLOCK(sc);
+		sx_destroy(&sc->axe_sleeplock);
 		mtx_destroy(&sc->axe_mtx);
-		USB_ATTACH_ERROR_RETURN;
+		return ENXIO;
 	}
 
 	/*
@@ -516,12 +675,13 @@
 	sc->axe_dying = 0;
 
 	AXE_UNLOCK(sc);
+	AXE_SLEEPUNLOCK(sc);
 
-	USB_ATTACH_SUCCESS_RETURN;
+	return 0;
 }
 
-Static int
-axe_detach(device_ptr_t dev)
+static int
+axe_detach(device_t dev)
 {
 	struct axe_softc	*sc;
 	struct ifnet		*ifp;
@@ -532,6 +692,8 @@
 
 	sc->axe_dying = 1;
 	untimeout(axe_tick, sc, sc->axe_stat_ch);
+	usb_rem_task(sc->axe_udev, &sc->axe_tick_task);
+
 	ether_ifdetach(ifp);
 	if_free(ifp);
 
@@ -543,55 +705,122 @@
 		usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
 
 	AXE_UNLOCK(sc);
+	sx_destroy(&sc->axe_sleeplock);
 	mtx_destroy(&sc->axe_mtx);
 
 	return(0);
 }
 
-Static void
-axe_rxstart(struct ifnet *ifp)
+static int
+axe_rx_list_init(struct axe_softc *sc)
 {
-	struct axe_softc	*sc;
-	struct ue_chain	*c;
+	struct axe_cdata	*cd;
+	struct axe_chain	*c;
+	int			i;
 
-	sc = ifp->if_softc;
-	AXE_LOCK(sc);
-	c = &sc->axe_cdata.ue_rx_chain[sc->axe_cdata.ue_rx_prod];
+	cd = &sc->axe_cdata;
+	for (i = 0; i < AXE_RX_LIST_CNT; i++) {
+		c = &cd->axe_rx_chain[i];
+		c->axe_sc = sc;
+		c->axe_idx = i;
+		c->axe_mbuf = NULL;
+		if (c->axe_xfer == NULL) {
+			c->axe_xfer = usbd_alloc_xfer(sc->axe_udev);
+			if (c->axe_xfer == NULL)
+				return (ENOBUFS);
+			c->axe_buf = usbd_alloc_buffer(c->axe_xfer,
+			    sc->axe_bufsz);
+			if (c->axe_buf == NULL) {
+				usbd_free_xfer(c->axe_xfer);
+				return (ENOBUFS);
+			}
+		}
+	}
 
-	c->ue_mbuf = usb_ether_newbuf();
-	if (c->ue_mbuf == NULL) {
-		printf("%s: no memory for rx list "
-		    "-- packet dropped!\n", USBDEVNAME(sc->axe_dev));
-		ifp->if_ierrors++;
-		AXE_UNLOCK(sc);
-		return;
+	return (0);
+}
+
+static void
+axe_rx_list_free(struct axe_softc *sc)
+{
+	int i;
+
+	for (i = 0; i < AXE_RX_LIST_CNT; i++) {
+		if (sc->axe_cdata.axe_rx_chain[i].axe_mbuf != NULL) {
+			m_freem(sc->axe_cdata.axe_rx_chain[i].axe_mbuf);
+			sc->axe_cdata.axe_rx_chain[i].axe_mbuf = NULL;
+		}
+		if (sc->axe_cdata.axe_rx_chain[i].axe_xfer != NULL) {
+			usbd_free_xfer(sc->axe_cdata.axe_rx_chain[i].axe_xfer);
+			sc->axe_cdata.axe_rx_chain[i].axe_xfer = NULL;
+		}
 	}
+}
 
-	/* Setup new transfer. */
-	usbd_setup_xfer(c->ue_xfer, sc->axe_ep[AXE_ENDPT_RX],
-	    c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
-	    USBD_NO_TIMEOUT, axe_rxeof);
-	usbd_transfer(c->ue_xfer);
-	AXE_UNLOCK(sc);
+static int
+axe_tx_list_init(struct axe_softc *sc)
+{
+	struct axe_cdata	*cd;
+	struct axe_chain	*c;
+	int			i;
 
-	return;
+	cd = &sc->axe_cdata;
+	for (i = 0; i < AXE_TX_LIST_CNT; i++) {
+		c = &cd->axe_tx_chain[i];
+		c->axe_sc = sc;
+		c->axe_idx = i;
+		c->axe_mbuf = NULL;
+		if (c->axe_xfer == NULL) {
+			c->axe_xfer = usbd_alloc_xfer(sc->axe_udev);
+			if (c->axe_xfer == NULL)
+				return (ENOBUFS);
+			c->axe_buf = usbd_alloc_buffer(c->axe_xfer,
+			    sc->axe_bufsz);
+			if (c->axe_buf == NULL) {
+				usbd_free_xfer(c->axe_xfer);
+				return (ENOBUFS);
+			}
+		}
+	}
+
+	return (0);
+}
+
+static void
+axe_tx_list_free(struct axe_softc *sc)
+{
+	int i;
+
+	/* Free TX resources. */
+	for (i = 0; i < AXE_TX_LIST_CNT; i++) {
+		if (sc->axe_cdata.axe_tx_chain[i].axe_mbuf != NULL) {
+			m_freem(sc->axe_cdata.axe_tx_chain[i].axe_mbuf);
+			sc->axe_cdata.axe_tx_chain[i].axe_mbuf = NULL;
+		}
+		if (sc->axe_cdata.axe_tx_chain[i].axe_xfer != NULL) {
+			usbd_free_xfer(sc->axe_cdata.axe_tx_chain[i].axe_xfer);
+			sc->axe_cdata.axe_tx_chain[i].axe_xfer = NULL;
+		}
+	}
 }
 
 /*
  * A frame has been uploaded: pass the resulting mbuf chain up to
  * the higher level protocols.
  */
-Static void
+static void
 axe_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 {
 	struct axe_softc	*sc;
-	struct ue_chain	*c;
+	struct axe_chain	*c = (struct axe_chain *) priv;
         struct mbuf		*m;
+	u_char			*buf;
         struct ifnet		*ifp;
+	struct axe_sframe_hdr	*hdr;
 	int			total_len = 0;
+	int			pktlen = 0;
 
-	c = priv;
-	sc = c->ue_sc;
+	sc = c->axe_sc;
 	AXE_LOCK(sc);
 	ifp = sc->axe_ifp;
 
@@ -606,7 +835,7 @@
 			return;
 		}
 		if (usbd_ratecheck(&sc->axe_rx_notice))
-			printf("axe%d: usb error on rx: %s\n", sc->axe_unit,
+			device_printf(sc->axe_dev, "usb error on rx: %s\n",
 			    usbd_errstr(status));
 		if (status == USBD_STALLED)
 			usbd_clear_endpoint_stall(sc->axe_ep[AXE_ENDPT_RX]);
@@ -615,28 +844,61 @@
 
 	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
 
-	m = c->ue_mbuf;
-
-	if (total_len < sizeof(struct ether_header)) {
-		ifp->if_ierrors++;
-		goto done;
-	}
+	buf = c->axe_buf;
 
-	ifp->if_ipackets++;
-	m->m_pkthdr.rcvif = (void *)&sc->axe_qdat;
-	m->m_pkthdr.len = m->m_len = total_len;
+	do {
+		if (sc->axe_flags & (AX178|AX772)) {
+			if (total_len < sizeof(struct axe_sframe_hdr)) {
+				ifp->if_ierrors++;
+				goto done;
+			}
+			if ((pktlen % 2) != 0)
+				pktlen++;
+			buf += pktlen;
+
+			hdr = (struct axe_sframe_hdr *) buf;
+			total_len -= sizeof(struct axe_sframe_hdr);
+			if ((hdr->len ^ hdr->ilen) != 0xffff) {
+				ifp->if_ierrors++;
+				goto done;
+			}
+			pktlen = le16toh(hdr->len);
+			if (pktlen > total_len) {
+				ifp->if_ierrors++;
+				goto done;
+			}
 
-	/* Put the packet on the special USB input queue. */
-	usb_ether_input(m);
-	AXE_UNLOCK(sc);
+			buf += sizeof(struct axe_sframe_hdr);
+			total_len -= pktlen + (pktlen % 2);
+		} else {
+			pktlen = total_len;
+			total_len = 0;
+		}
 
-	return;
+		if (pktlen < sizeof(struct ether_header)) {
+			ifp->if_ierrors++;
+			goto done;
+		}
+		m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+		if (m == NULL) {
+			ifp->if_ierrors++;
+			goto done;
+		}
+		m->m_data += ETHER_ALIGN;
+		memcpy(mtod(m, void *), buf, pktlen);
+		m->m_pkthdr.len = m->m_len = pktlen;
+		m->m_pkthdr.rcvif = ifp;
+
+		ifp->if_input(ifp, m);
+		ifp->if_ipackets++;
+	} while (total_len > 0);
+	/* fall thru... */
 done:
 	/* Setup new transfer. */
-	usbd_setup_xfer(c->ue_xfer, sc->axe_ep[AXE_ENDPT_RX],
-	    c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
+	usbd_setup_xfer(xfer, sc->axe_ep[AXE_ENDPT_RX],
+	    c, c->axe_buf, sc->axe_bufsz, USBD_SHORT_XFER_OK | USBD_NO_COPY,
 	    USBD_NO_TIMEOUT, axe_rxeof);
-	usbd_transfer(c->ue_xfer);
+	usbd_transfer(xfer);
 	AXE_UNLOCK(sc);
 
 	return;
@@ -647,16 +909,16 @@
  * the list buffers.
  */
 
-Static void
+static void
 axe_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 {
 	struct axe_softc	*sc;
-	struct ue_chain	*c;
+	struct axe_chain	*c;
 	struct ifnet		*ifp;
 	usbd_status		err;
 
 	c = priv;
-	sc = c->ue_sc;
+	sc = c->axe_sc;
 	AXE_LOCK(sc);
 	ifp = sc->axe_ifp;
 
@@ -665,7 +927,7 @@
 			AXE_UNLOCK(sc);
 			return;
 		}
-		printf("axe%d: usb error on tx: %s\n", sc->axe_unit,
+		device_printf(sc->axe_dev, "usb error on tx: %s\n",
 		    usbd_errstr(status));
 		if (status == USBD_STALLED)
 			usbd_clear_endpoint_stall(sc->axe_ep[AXE_ENDPT_TX]);
@@ -675,12 +937,11 @@
 
 	ifp->if_timer = 0;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-	usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
+	usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &err);
 
-	if (c->ue_mbuf != NULL) {
-		c->ue_mbuf->m_pkthdr.rcvif = ifp;
-		usb_tx_done(c->ue_mbuf);
-		c->ue_mbuf = NULL;
+	if (c->axe_mbuf != NULL) {
+		m_freem(c->axe_mbuf);
+		c->axe_mbuf = NULL;
 	}
 
 	if (err)
@@ -690,12 +951,29 @@
 
 	AXE_UNLOCK(sc);
 
+	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+		axe_start(ifp);
+
 	return;
 }
 
-Static void
+static void
 axe_tick(void *xsc)
 {
+	struct axe_softc *sc = xsc;
+
+	if (sc == NULL)
+		return;
+	if (sc->axe_dying)
+		return;
+
+	/* Perform periodic stuff in process context */
+	usb_add_task(sc->axe_udev, &sc->axe_tick_task);
+}
+
+static void
+axe_tick_task(void *xsc)
+{
 	struct axe_softc	*sc;
 	struct ifnet		*ifp;
 	struct mii_data		*mii;
@@ -705,12 +983,14 @@
 	if (sc == NULL)
 		return;
 
+	AXE_SLEEPLOCK(sc);
 	AXE_LOCK(sc);
 
 	ifp = sc->axe_ifp;
 	mii = GET_MII(sc);
 	if (mii == NULL) {
 		AXE_UNLOCK(sc);
+		AXE_SLEEPUNLOCK(sc);
 		return;
 	}
 
@@ -725,42 +1005,66 @@
 	sc->axe_stat_ch = timeout(axe_tick, sc, hz);
 
 	AXE_UNLOCK(sc);
+	AXE_SLEEPUNLOCK(sc);
 
 	return;
 }
 
-Static int
+static int
 axe_encap(struct axe_softc *sc, struct mbuf *m, int idx)
 {
-	struct ue_chain	*c;
+	struct axe_chain	*c;
 	usbd_status		err;
+	struct axe_sframe_hdr	hdr;
+	int			length;
 
-	c = &sc->axe_cdata.ue_tx_chain[idx];
+	c = &sc->axe_cdata.axe_tx_chain[idx];
 
 	/*
 	 * Copy the mbuf data into a contiguous buffer, leaving two
 	 * bytes at the beginning to hold the frame length.
 	 */
-	m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf);
-	c->ue_mbuf = m;
+	if (sc->axe_flags & (AX178|AX772)) {
+		hdr.len = htole16(m->m_pkthdr.len);
+		hdr.ilen = ~hdr.len;
+
+		memcpy(c->axe_buf, &hdr, sizeof(hdr));
+		length = sizeof(hdr);
+
+		m_copydata(m, 0, m->m_pkthdr.len, c->axe_buf + length);
+		length += m->m_pkthdr.len;
+
+		if ((length % sc->axe_boundary) == 0) {
+			hdr.len = 0;
+			hdr.ilen = 0xffff;
+			memcpy(c->axe_buf + length, &hdr, sizeof(hdr));
+			length += sizeof(hdr);
+		}
+	} else {
+		m_copydata(m, 0, m->m_pkthdr.len, c->axe_buf);
+		length = m->m_pkthdr.len;
+	}
+	c->axe_mbuf = m;
 
-	usbd_setup_xfer(c->ue_xfer, sc->axe_ep[AXE_ENDPT_TX],
-	    c, c->ue_buf, m->m_pkthdr.len, USBD_FORCE_SHORT_XFER,
-	    10000, axe_txeof);
+	usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_TX],
+	    c, c->axe_buf, length, USBD_FORCE_SHORT_XFER, 10000, axe_txeof);
 
 	/* Transmit */
-	err = usbd_transfer(c->ue_xfer);
+	err = usbd_transfer(c->axe_xfer);
 	if (err != USBD_IN_PROGRESS) {
+		/* XXX probably don't want to sleep here */
+		AXE_SLEEPLOCK(sc);
 		axe_stop(sc);
+		AXE_SLEEPUNLOCK(sc);
 		return(EIO);
 	}
 
-	sc->axe_cdata.ue_tx_cnt++;
+	sc->axe_cdata.axe_tx_cnt++;
 
 	return(0);
 }
 
-Static void
+static void
 axe_start(struct ifnet *ifp)
 {
 	struct axe_softc	*sc;
@@ -809,12 +1113,12 @@
 	return;
 }
 
-Static void
+static void
 axe_init(void *xsc)
 {
 	struct axe_softc	*sc = xsc;
 	struct ifnet		*ifp = sc->axe_ifp;
-	struct ue_chain	*c;
+	struct axe_chain	*c;
 	usbd_status		err;
 	int			i;
 	int			rxmode;
@@ -822,6 +1126,7 @@
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 		return;
 
+	AXE_SLEEPLOCK(sc);
 	AXE_LOCK(sc);
 
 	/*
@@ -832,34 +1137,44 @@
 
 #ifdef notdef
 	/* Set MAC address */
-	axe_mac(sc, IFP2ENADDR(sc->axe_ifp), 1);
+	axe_mac(sc, IF_LLADDR(sc->axe_ifp), 1);
 #endif
 
 	/* Enable RX logic. */
 
 	/* Init TX ring. */
-	if (usb_ether_tx_list_init(sc, &sc->axe_cdata,
-	    sc->axe_udev) == ENOBUFS) {
-		printf("axe%d: tx list init failed\n", sc->axe_unit);
+	if (axe_tx_list_init(sc) == ENOBUFS) {
+		device_printf(sc->axe_dev, "tx list init failed\n");
 		AXE_UNLOCK(sc);
+		AXE_SLEEPUNLOCK(sc);
 		return;
 	}
 
 	/* Init RX ring. */
-	if (usb_ether_rx_list_init(sc, &sc->axe_cdata,
-	    sc->axe_udev) == ENOBUFS) {
-		printf("axe%d: rx list init failed\n", sc->axe_unit);
+	if (axe_rx_list_init(sc) == ENOBUFS) {
+		device_printf(sc->axe_dev, "rx list init failed\n");
 		AXE_UNLOCK(sc);
+		AXE_SLEEPUNLOCK(sc);
 		return;
 	}
 
 	/* Set transmitter IPG values */
-	axe_cmd(sc, AXE_CMD_WRITE_IPG0, 0, sc->axe_ipgs[0], NULL);
-	axe_cmd(sc, AXE_CMD_WRITE_IPG1, 0, sc->axe_ipgs[1], NULL);
-	axe_cmd(sc, AXE_CMD_WRITE_IPG2, 0, sc->axe_ipgs[2], NULL);
+	if (sc->axe_flags & (AX178|AX772)) {
+		axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->axe_ipgs[2],
+		    (sc->axe_ipgs[1]<<8) | sc->axe_ipgs[0], NULL);
+	} else {
+		axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->axe_ipgs[0], NULL);
+		axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->axe_ipgs[1], NULL);
+		axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->axe_ipgs[2], NULL);
+	}
 
 	/* Enable receiver, set RX mode */
-	rxmode = AXE_RXCMD_UNICAST|AXE_RXCMD_MULTICAST|AXE_RXCMD_ENABLE;
+	rxmode = AXE_RXCMD_MULTICAST|AXE_RXCMD_ENABLE;
+	if (sc->axe_flags & (AX178|AX772)) {
+		if (sc->axe_bufsz == AXE_178_MAX_BUFSZ)
+			rxmode |= AXE_178_RXCMD_MFB;
+	} else
+		rxmode |= AXE_172_RXCMD_UNICAST;
 
 	/* If we want promiscuous mode, set the allframes bit. */
 	if (ifp->if_flags & IFF_PROMISC)
@@ -877,41 +1192,45 @@
 	err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_RX],
 	    USBD_EXCLUSIVE_USE, &sc->axe_ep[AXE_ENDPT_RX]);
 	if (err) {
-		printf("axe%d: open rx pipe failed: %s\n",
-		    sc->axe_unit, usbd_errstr(err));
+		device_printf(sc->axe_dev, "open rx pipe failed: %s\n",
+		    usbd_errstr(err));
 		AXE_UNLOCK(sc);
+		AXE_SLEEPUNLOCK(sc);
 		return;
 	}
 
 	err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_TX],
 	    USBD_EXCLUSIVE_USE, &sc->axe_ep[AXE_ENDPT_TX]);
 	if (err) {
-		printf("axe%d: open tx pipe failed: %s\n",
-		    sc->axe_unit, usbd_errstr(err));
+		device_printf(sc->axe_dev, "open tx pipe failed: %s\n",
+		    usbd_errstr(err));
 		AXE_UNLOCK(sc);
+		AXE_SLEEPUNLOCK(sc);
 		return;
 	}
 
 	/* Start up the receive pipe. */
-	for (i = 0; i < UE_RX_LIST_CNT; i++) {
-		c = &sc->axe_cdata.ue_rx_chain[i];
-		usbd_setup_xfer(c->ue_xfer, sc->axe_ep[AXE_ENDPT_RX],
-		    c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
-		    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, axe_rxeof);
-		usbd_transfer(c->ue_xfer);
+	for (i = 0; i < AXE_RX_LIST_CNT; i++) {
+		c = &sc->axe_cdata.axe_rx_chain[i];
+		usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_RX],
+		    c, c->axe_buf, sc->axe_bufsz,
+		    USBD_SHORT_XFER_OK | USBD_NO_COPY,
+		    USBD_NO_TIMEOUT, axe_rxeof);
+		usbd_transfer(c->axe_xfer);
 	}
 
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
 	AXE_UNLOCK(sc);
+	AXE_SLEEPUNLOCK(sc);
 
 	sc->axe_stat_ch = timeout(axe_tick, sc, hz);
 
 	return;
 }
 
-Static int
+static int
 axe_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 {
 	struct axe_softc	*sc = ifp->if_softc;
@@ -926,6 +1245,7 @@
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
 			    ifp->if_flags & IFF_PROMISC &&
 			    !(sc->axe_if_flags & IFF_PROMISC)) {
+				AXE_SLEEPLOCK(sc);
 				AXE_LOCK(sc);
 				axe_cmd(sc, AXE_CMD_RXCTL_READ,
 					0, 0, (void *)&rxmode);
@@ -934,9 +1254,11 @@
 					0, rxmode, NULL);
 				AXE_UNLOCK(sc);
 				axe_setmulti(sc);
+				AXE_SLEEPUNLOCK(sc);
 			} else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
 			    !(ifp->if_flags & IFF_PROMISC) &&
 			    sc->axe_if_flags & IFF_PROMISC) {
+				AXE_SLEEPLOCK(sc);
 				AXE_LOCK(sc);
 				axe_cmd(sc, AXE_CMD_RXCTL_READ,
 					0, 0, (void *)&rxmode);
@@ -945,24 +1267,32 @@
 					0, rxmode, NULL);
 				AXE_UNLOCK(sc);
 				axe_setmulti(sc);
+				AXE_SLEEPUNLOCK(sc);
 			} else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
 				axe_init(sc);
 		} else {
-			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+				AXE_SLEEPLOCK(sc);
 				axe_stop(sc);
+				AXE_SLEEPUNLOCK(sc);
+			}
 		}
 		sc->axe_if_flags = ifp->if_flags;
 		error = 0;
 		break;
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
+		AXE_SLEEPLOCK(sc);
 		axe_setmulti(sc);
+		AXE_SLEEPUNLOCK(sc);
 		error = 0;
 		break;
 	case SIOCGIFMEDIA:
 	case SIOCSIFMEDIA:
+		AXE_SLEEPLOCK(sc);
 		mii = GET_MII(sc);
 		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
+		AXE_SLEEPUNLOCK(sc);
 		break;
 
 	default:
@@ -970,27 +1300,25 @@
 		break;
 	}
 
-	AXE_UNLOCK(sc);
-
 	return(error);
 }
 
-Static void
+static void
 axe_watchdog(struct ifnet *ifp)
 {
 	struct axe_softc	*sc;
-	struct ue_chain	*c;
+	struct axe_chain	*c;
 	usbd_status		stat;
 
 	sc = ifp->if_softc;
 	AXE_LOCK(sc);
 
 	ifp->if_oerrors++;
-	printf("axe%d: watchdog timeout\n", sc->axe_unit);
+	device_printf(sc->axe_dev, "watchdog timeout\n");
 
-	c = &sc->axe_cdata.ue_tx_chain[0];
-	usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
-	axe_txeof(c->ue_xfer, c, stat);
+	c = &sc->axe_cdata.axe_tx_chain[0];
+	usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &stat);
+	axe_txeof(c->axe_xfer, c, stat);
 
 	AXE_UNLOCK(sc);
 
@@ -1004,12 +1332,13 @@
  * Stop the adapter and free any mbufs allocated to the
  * RX and TX lists.
  */
-Static void
+static void
 axe_stop(struct axe_softc *sc)
 {
 	usbd_status		err;
 	struct ifnet		*ifp;
 
+	AXE_SLEEPLOCKASSERT(sc);
 	AXE_LOCK(sc);
 
 	ifp = sc->axe_ifp;
@@ -1021,13 +1350,13 @@
 	if (sc->axe_ep[AXE_ENDPT_RX] != NULL) {
 		err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_RX]);
 		if (err) {
-			printf("axe%d: abort rx pipe failed: %s\n",
-		    	sc->axe_unit, usbd_errstr(err));
+			device_printf(sc->axe_dev, "abort rx pipe failed: %s\n",
+			    usbd_errstr(err));
 		}
 		err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_RX]);
 		if (err) {
-			printf("axe%d: close rx pipe failed: %s\n",
-		    	sc->axe_unit, usbd_errstr(err));
+			device_printf(sc->axe_dev, "close rx pipe failed: %s\n",
+			    usbd_errstr(err));
 		}
 		sc->axe_ep[AXE_ENDPT_RX] = NULL;
 	}
@@ -1035,13 +1364,13 @@
 	if (sc->axe_ep[AXE_ENDPT_TX] != NULL) {
 		err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_TX]);
 		if (err) {
-			printf("axe%d: abort tx pipe failed: %s\n",
-		    	sc->axe_unit, usbd_errstr(err));
+			device_printf(sc->axe_dev, "abort tx pipe failed: %s\n",
+			    usbd_errstr(err));
 		}
 		err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_TX]);
 		if (err) {
-			printf("axe%d: close tx pipe failed: %s\n",
-			    sc->axe_unit, usbd_errstr(err));
+			device_printf(sc->axe_dev, "close tx pipe failed: %s\n",
+			    usbd_errstr(err));
 		}
 		sc->axe_ep[AXE_ENDPT_TX] = NULL;
 	}
@@ -1049,13 +1378,13 @@
 	if (sc->axe_ep[AXE_ENDPT_INTR] != NULL) {
 		err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
 		if (err) {
-			printf("axe%d: abort intr pipe failed: %s\n",
-		    	sc->axe_unit, usbd_errstr(err));
+			device_printf(sc->axe_dev,
+			    "abort intr pipe failed: %s\n", usbd_errstr(err));
 		}
 		err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
 		if (err) {
-			printf("axe%d: close intr pipe failed: %s\n",
-			    sc->axe_unit, usbd_errstr(err));
+			device_printf(sc->axe_dev,
+			    "close intr pipe failed: %s\n", usbd_errstr(err));
 		}
 		sc->axe_ep[AXE_ENDPT_INTR] = NULL;
 	}
@@ -1063,9 +1392,9 @@
 	axe_reset(sc);
 
 	/* Free RX resources. */
-	usb_ether_rx_list_free(&sc->axe_cdata);
+	axe_rx_list_free(sc);
 	/* Free TX resources. */
-	usb_ether_tx_list_free(&sc->axe_cdata);
+	axe_tx_list_free(sc);
 
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
         sc->axe_link = 0;
@@ -1078,14 +1407,16 @@
  * Stop all chip I/O so that the kernel's probe routines don't
  * get confused by errant DMAs when rebooting.
  */
-Static void
-axe_shutdown(device_ptr_t dev)
+static int
+axe_shutdown(device_t dev)
 {
 	struct axe_softc	*sc;
 
 	sc = device_get_softc(dev);
 
+	AXE_SLEEPLOCK(sc);
 	axe_stop(sc);
+	AXE_SLEEPUNLOCK(sc);
 
-	return;
+	return (0);
 }
--- dev/usb/if_axereg.h.orig	2008-01-18 18:04:21.000000000 +0000
+++ dev/usb/if_axereg.h	2008-01-18 18:04:36.000000000 +0000
@@ -29,7 +29,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/usb/if_axereg.h,v 1.8.2.1 2007/05/21 18:10:48 brueffer Exp $
+ * $FreeBSD: src/sys/dev/usb/if_axereg.h,v 1.17 2007/11/10 16:23:38 sam Exp $
  */
 
 /*
@@ -53,9 +53,11 @@
 #define AXE_CMD_LEN(x)	(((x) & 0xF000) >> 12)
 #define AXE_CMD_CMD(x)	((x) & 0x00FF)
 
-#define AXE_CMD_READ_RXTX_SRAM			0x2002
-#define AXE_CMD_WRITE_RX_SRAM			0x0103
-#define AXE_CMD_WRITE_TX_SRAM			0x0104
+#define AXE_172_CMD_READ_RXTX_SRAM		0x2002
+#define AXE_182_CMD_READ_RXTX_SRAM		0x8002
+#define AXE_172_CMD_WRITE_RX_SRAM		0x0103
+#define AXE_172_CMD_WRITE_TX_SRAM		0x0104
+#define AXE_182_CMD_WRITE_RXTX_SRAM		0x8103
 #define AXE_CMD_MII_OPMODE_SW			0x0106
 #define AXE_CMD_MII_READ_REG			0x2007
 #define AXE_CMD_MII_WRITE_REG			0x2108
@@ -68,35 +70,115 @@
 #define AXE_CMD_RXCTL_READ			0x200F
 #define AXE_CMD_RXCTL_WRITE			0x0110
 #define AXE_CMD_READ_IPG012			0x3011
-#define AXE_CMD_WRITE_IPG0			0x0112
-#define AXE_CMD_WRITE_IPG1			0x0113
-#define AXE_CMD_WRITE_IPG2			0x0114
+#define AXE_172_CMD_WRITE_IPG0			0x0112
+#define AXE_172_CMD_WRITE_IPG1			0x0113
+#define AXE_172_CMD_WRITE_IPG2			0x0114
+#define AXE_178_CMD_WRITE_IPG012		0x0112
 #define AXE_CMD_READ_MCAST			0x8015
 #define AXE_CMD_WRITE_MCAST			0x8116
-#define AXE_CMD_READ_NODEID			0x6017
-#define AXE_CMD_WRITE_NODEID			0x6118
+#define AXE_172_CMD_READ_NODEID			0x6017
+#define AXE_172_CMD_WRITE_NODEID		0x6118
+#define AXE_178_CMD_READ_NODEID			0x6013
+#define AXE_178_CMD_WRITE_NODEID		0x6114
 #define AXE_CMD_READ_PHYID			0x2019
-#define AXE_CMD_READ_MEDIA			0x101A
+#define AXE_172_CMD_READ_MEDIA			0x101A
+#define AXE_178_CMD_READ_MEDIA			0x201A
 #define AXE_CMD_WRITE_MEDIA			0x011B
 #define AXE_CMD_READ_MONITOR_MODE		0x101C
 #define AXE_CMD_WRITE_MONITOR_MODE		0x011D
 #define AXE_CMD_READ_GPIO			0x101E
 #define AXE_CMD_WRITE_GPIO			0x011F
+#define AXE_CMD_SW_RESET_REG			0x0120
+#define AXE_CMD_SW_PHY_STATUS			0x0021
+#define AXE_CMD_SW_PHY_SELECT			0x0122
+
+#define AXE_SW_RESET_CLEAR			0x00
+#define AXE_SW_RESET_RR				0x01
+#define AXE_SW_RESET_RT				0x02
+#define AXE_SW_RESET_PRTE			0x04
+#define AXE_SW_RESET_PRL			0x08
+#define AXE_SW_RESET_BZ				0x10
+#define AXE_SW_RESET_IPRL			0x20
+#define AXE_SW_RESET_IPPD			0x40
+
+/* AX88178 documentation says to always write this bit... */
+#define AXE_178_RESET_MAGIC			0x40
+
+#define AXE_178_MEDIA_GMII			0x0001
+#define AXE_MEDIA_FULL_DUPLEX			0x0002
+#define AXE_172_MEDIA_TX_ABORT_ALLOW		0x0004
+/* AX88178/88772 documentation says to always write 1 to bit 2 */
+#define AXE_178_MEDIA_MAGIC			0x0004
+/* AX88772 documentation says to always write 0 to bit 3 */
+#define AXE_178_MEDIA_ENCK			0x0008
+#define AXE_172_MEDIA_FLOW_CONTROL_EN		0x0010
+#define AXE_178_MEDIA_RXFLOW_CONTROL_EN		0x0010
+#define AXE_178_MEDIA_TXFLOW_CONTROL_EN		0x0020
+#define AXE_178_MEDIA_JUMBO_EN			0x0040
+#define AXE_178_MEDIA_LTPF_ONLY			0x0080
+#define AXE_178_MEDIA_RX_EN			0x0100
+#define AXE_178_MEDIA_100TX			0x0200
+#define AXE_178_MEDIA_SBP			0x0800
+#define AXE_178_MEDIA_SUPERMAC			0x1000
 
 #define AXE_RXCMD_PROMISC			0x0001
 #define AXE_RXCMD_ALLMULTI			0x0002
-#define AXE_RXCMD_UNICAST			0x0004
+#define AXE_172_RXCMD_UNICAST			0x0004
+#define AXE_178_RXCMD_KEEP_INVALID_CRC		0x0004
 #define AXE_RXCMD_BROADCAST			0x0008
 #define AXE_RXCMD_MULTICAST			0x0010
+#define AXE_178_RXCMD_AP			0x0020
 #define AXE_RXCMD_ENABLE			0x0080
+#define AXE_178_RXCMD_MFB_2048			0x0000	/* 2K max frame burst */
+#define AXE_178_RXCMD_MFB_4096			0x0100	/* 4K max frame burst */
+#define AXE_178_RXCMD_MFB_8192			0x0200	/* 8K max frame burst */
+#define AXE_178_RXCMD_MFB_16384			0x0300	/* 16K max frame burst*/
 
 #define AXE_NOPHY				0xE0
+#define AXE_INTPHY				0x10
 
 #define AXE_TIMEOUT		1000
+#define AXE_172_BUFSZ		1536
+#define AXE_178_MIN_BUFSZ	2048
 #define AXE_MIN_FRAMELEN	60
 #define AXE_RX_FRAMES		1
 #define AXE_TX_FRAMES		1
 
+#if AXE_178_MAX_FRAME_BURST == 0
+#define AXE_178_RXCMD_MFB	AXE_178_RXCMD_MFB_2048
+#define AXE_178_MAX_BUFSZ	2048
+#elif AXE_178_MAX_FRAME_BURST == 1
+#define AXE_178_RXCMD_MFB	AXE_178_RXCMD_MFB_4096
+#define AXE_178_MAX_BUFSZ	4096
+#elif AXE_178_MAX_FRAME_BURST == 2
+#define AXE_178_RXCMD_MFB	AXE_178_RXCMD_MFB_8192
+#define AXE_178_MAX_BUFSZ	8192
+#else
+#define AXE_178_RXCMD_MFB	AXE_178_RXCMD_MFB_16384
+#define AXE_178_MAX_BUFSZ	16384
+#endif
+
+#define AXE_RX_LIST_CNT		1
+#define AXE_TX_LIST_CNT		1
+
+struct axe_chain {
+	struct axe_softc	*axe_sc;
+	usbd_xfer_handle	axe_xfer;
+	char			*axe_buf;
+	struct mbuf		*axe_mbuf;
+	int			axe_accum;
+	int			axe_idx;
+};
+
+struct axe_cdata {
+	struct axe_chain	axe_tx_chain[AXE_TX_LIST_CNT];
+	struct axe_chain	axe_rx_chain[AXE_RX_LIST_CNT];
+	int			axe_tx_prod;
+	int			axe_tx_cons;
+	int			axe_tx_cnt;
+	int			axe_rx_prod;
+};
+
 #define AXE_CTL_READ		0x01
 #define AXE_CTL_WRITE		0x02
 
@@ -112,9 +194,17 @@
 #define AXE_ENDPT_INTR		0x2
 #define AXE_ENDPT_MAX		0x3
 
+struct axe_sframe_hdr {
+	uint16_t	len;
+	uint16_t	ilen;
+} __packed;
+
 struct axe_type {
-	u_int16_t		axe_vid;
-	u_int16_t		axe_did;
+	struct usb_devno        axe_dev;
+	uint32_t                axe_flags;
+#define	AX172	0x0000		/* AX88172 */
+#define	AX178	0x0001		/* AX88178 */
+#define	AX772	0x0002		/* AX88772 */
 };
 
 #define AXE_INC(x, y)		(x) = (x + 1) % y
@@ -132,19 +222,24 @@
 	device_t		axe_dev;
 	usbd_device_handle	axe_udev;
 	usbd_interface_handle	axe_iface;
+	u_int16_t		axe_vendor;
+	u_int16_t		axe_product;
+	u_int16_t		axe_flags;
 	int			axe_ed[AXE_ENDPT_MAX];
 	usbd_pipe_handle	axe_ep[AXE_ENDPT_MAX];
-	int			axe_unit;
 	int			axe_if_flags;
-	struct ue_cdata		axe_cdata;
+	struct axe_cdata	axe_cdata;
 	struct callout_handle	axe_stat_ch;
 	struct mtx		axe_mtx;
+	struct sx		axe_sleeplock;
 	char			axe_dying;
 	int			axe_link;
 	unsigned char		axe_ipgs[3];
 	unsigned char 		axe_phyaddrs[2];
 	struct timeval		axe_rx_notice;
-	struct usb_qdat		axe_qdat;
+	struct usb_task		axe_tick_task;
+	int			axe_bufsz;
+	int			axe_boundary;
 };
 
 #if 0
@@ -154,3 +249,6 @@
 #define	AXE_LOCK(_sc)
 #define	AXE_UNLOCK(_sc)
 #endif
+#define	AXE_SLEEPLOCK(_sc)	sx_xlock(&(_sc)->axe_sleeplock)
+#define	AXE_SLEEPUNLOCK(_sc)	sx_xunlock(&(_sc)->axe_sleeplock)
+#define	AXE_SLEEPLOCKASSERT(_sc) sx_assert(&(_sc)->axe_sleeplock, SX_XLOCKED)
--- dev/usb/usbdevs.orig	2008-01-18 18:04:29.000000000 +0000
+++ dev/usb/usbdevs	2008-01-18 18:14:44.000000000 +0000
@@ -481,6 +481,7 @@
 vendor ACDC		0x0d7e	ACDC
 vendor ABC		0x0d8c	ABC
 vendor MSI		0x0db0	Micro Star International
+vendor SITECOMEU	0x0df6	Sitecom Europe
 vendor HAWKING		0x0e66	Hawking
 vendor GMATE		0x0e7e	G.Mate, Inc
 vendor OTI		0x0ea0	Ours
@@ -518,16 +519,20 @@
 vendor RALINK		0x148f	Ralink Technology
 vendor IMAGINATION	0x149a	Imagination Technologies
 vendor CONCEPTRONIC	0x14b2	Conceptronic
+vendor PLANEX3		0x14ea	Planex Communications
 vendor SILICONPORTALS	0x1527	Silicon Portals
 vendor UBIQUAM		0x1529	UBIQUAM Co., Ltd.
 vendor PNY		0x154b	PNY
+vendor OQO		0x1557	OQO
 vendor SOHOWARE		0x15e8	SOHOware
 vendor UMAX		0x1606	UMAX
 vendor INSIDEOUT	0x1608	Inside Out Networks
+vendor GOODWAY		0x1631	Good Way Technology
 vendor ENTREGA		0x1645	Entrega
 vendor ACTIONTEC	0x1668	Actiontec
 vendor ANYDATA		0x16d5	AnyData Corporation
 vendor CMOTECH		0x16d8	CMOTECH CO., LTD.
+vendor LINKSYS5		0x1737	Linksys
 vendor LINKSYS3		0x1915	Linksys
 vendor DLINK		0x2001	D-Link
 vendor ERICSSON		0x2282	Ericsson
@@ -584,6 +589,7 @@
 product ABOCOM XX7		0x400c	XX7
 product ABOCOM XX8		0x4102	XX8
 product ABOCOM XX9		0x4104	XX9
+product ABOCOM UF200		0x420a	UF200 Ethernet
 product ABOCOM XX10		0xabc1	XX10
 
 /* Accton products */
@@ -593,6 +599,9 @@
 /* Aceeca products */
 product ACEECA MEZ1000		0x0001	Aceeca Mez1000 RDA
 
+/* Acer Communications & Multimedia (oemd by Surecom) */
+product ACERCM EP1427X2		0x0893	EP-1427X-2 Ethernet Adapter
+
 /* Acer Peripherals, Inc. products */
 product ACERP ACERSCAN_C310U	0x12a6	Acerscan C310U
 product ACERP ACERSCAN_320U	0x2022	Acerscan 320U
@@ -694,6 +703,8 @@
 
 /* ASIX Electronics products */
 product ASIX AX88172		0x1720  10/100 ethernet
+product ASIX AX88178		0x1780	AX88178
+product ASIX AX88772		0x7720	AX88772
 
 /* ASUS products */
 product ASUS WL167G		0x1707	WL-167g wireless adapter
@@ -701,6 +712,8 @@
 /* ATen products */
 product ATEN UC1284		0x2001	Parallel printer
 product ATEN UC10T		0x2002	10Mbps ethernet
+product ATEN UC110T		0x2007	UC-110T Ethernet
+product ATEN UC210T		0x2009	UC-210T Ethernet
 product ATEN UC232A		0x2008	Serial
 
 /* Atmel Comp. products */
@@ -726,6 +739,7 @@
 product BELKIN F5U409		0x0409	F5U409 Serial
 product BELKIN F6C550AVR	0x0551	F6C550-AVR UPS
 product BELKIN F5U120		0x1203	F5U120-PC Hub
+product BELKIN F5D5055		0x5055	F5D5055
 product BELKIN F5D7050		0x7050	F5D7050 wireless adapter
 
 /* Billionton products */
@@ -733,6 +747,7 @@
 product BILLIONTON USBLP100	0x0987	USB100LP
 product BILLIONTON USBEL100	0x0988	USB100EL
 product BILLIONTON USBE100	0x8511	USBE100
+product BILLIONTON USB2AR	0x90ff	USB2AR Ethernet
 
 /* Broadcom products */
 product BROADCOM BCM2033	0x2033	BCM2033 Bluetooth USB dongle
@@ -790,6 +805,7 @@
 product COREGA ETHER_USB_T	0x0001	Ether USB-T
 product COREGA FETHER_USB_TX	0x0004	FEther USB-TX
 product COREGA FETHER_USB_TXS	0x000d	FEther USB-TXS
+product COREGA FETHER_USB2_TX	0x0017	FEther USB2-TX
 product COREGA FETHER_USB_TXC	0x9601	FEther USB-TXC
 
 /* Creative products */
@@ -850,6 +866,7 @@
 product DLINK DUBE100		0x1a00	10/100 ethernet
 product DLINK DSB650TX4		0x200c	10/100 ethernet
 product DLINK DWLG122		0x3c00	DWL-G122 b1 wireless adapter
+product DLINK DUBE100B1		0x3c05	DUB-E100 rev B1
 product DLINK DSB650C		0x4000	10Mbps ethernet
 product DLINK DSB650TX1		0x4001	10/100 ethernet
 product DLINK DSB650TX		0x4002	10/100 ethernet
@@ -931,6 +948,9 @@
 /* GoHubs products */
 product GOHUBS GOCOM232		0x1001	GoCOM232 Serial
 
+/* Good Way Technology products */
+product GOODWAY GWUSB2E		0x6200	GWUSB2E
+
 /* Gravis products */
 product GRAVIS GAMEPADPRO	0x4001	GamePad Pro
 
@@ -1078,6 +1098,7 @@
 product IODATA USBETT		0x0901	USB ETT
 product IODATA USBETTX		0x0904	USB ETTX
 product IODATA USBETTXS		0x0913	USB ETTX
+product IODATA ETGUS2		0x0930	ETG-US2
 product IODATA USBRSAQ		0x0a03	Serial USB-RSAQ1
 
 /* Iomega products */
@@ -1184,7 +1205,10 @@
 product LINKSYS3 WUSB11v28	0x2233	WUSB11 v2.8 wireless adapter
 product LINKSYS4 WUSB54G	0x000d	WUSB54G wireless adapter
 product LINKSYS4 WUSB54GP	0x0011	WUSB54GP wireless adapter
+product LINKSYS4 USB200MV2	0x0018	USB200M v2
 product LINKSYS4 HU200TS	0x001a	HU200TS wireless adapter
+product LINKSYS5 USB1000	0x0039	USB1000
+
 
 /* Logitech products */
 product LOGITECH M2452		0x0203	M2452 keyboard
@@ -1370,6 +1394,9 @@
 /* OnSpec Electronic, Inc. */
 product ONSPEC UCF100		0xa400	FlashLink UCF-100 CompactFlash Reader
 
+/* OQO */
+product OQO ETHER01PLUS		0x7720	model 01+ Ethernet
+
 /* Palm Computing, Inc. product */
 product PALM SERIAL		0x0080	USB Serial
 product PALM M500		0x0001	Palm m500
@@ -1412,6 +1439,9 @@
 /* P.I. Engineering products */
 product PIENGINEERING PS2USB	0x020b	PS2 to Mac USB Adapter
 
+/* Planex Communications products */
+product PLANEX3 GU1000T		0xab11	GU-1000T
+
 /* Plextor Corp. */
 product PLEXTOR 40_12_40U	0x0011	PlexWriter 40/12/40U
 
@@ -1561,6 +1591,9 @@
 product SITECOM LN029		0x182d	USB 2.0 Ethernet
 product SITECOM SERIAL		0x2068	USB to serial cable (v2)
 
+/* Sitecom Europe products */
+product SITECOMEU LN028		0x061c	LN-028
+
 /* SmartBridges products */
 product SMARTBRIDGES SMARTLINK	0x0001	SmartLink USB ethernet
 product SMARTBRIDGES SMARTNIC	0x0003	smartNIC 2 PnP ethernet

--------------010506070101090909000909--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4790D699.9000403>