[rtems-libbsd commit] USB: Update to FreeBSD trunk 2015-11-10

Sebastian Huber sebh at rtems.org
Thu Nov 12 12:10:28 UTC 2015


Module:    rtems-libbsd
Branch:    master
Commit:    02279d6272b22e96ca418c5a2dd9d32c46d16ee1
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=02279d6272b22e96ca418c5a2dd9d32c46d16ee1

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Nov 12 13:01:12 2015 +0100

USB: Update to FreeBSD trunk 2015-11-10

---

 freebsd/sys/dev/usb/controller/ehci.c           |  56 ++--
 freebsd/sys/dev/usb/controller/ehci.h           |   4 +-
 freebsd/sys/dev/usb/controller/ohci.c           |  40 +--
 freebsd/sys/dev/usb/controller/usb_controller.c | 121 ++++---
 freebsd/sys/dev/usb/quirk/usb_quirk.c           | 151 ++++++++-
 freebsd/sys/dev/usb/quirk/usb_quirk.h           |   2 +-
 freebsd/sys/dev/usb/storage/umass.c             |  49 ++-
 freebsd/sys/dev/usb/ufm_ioctl.h                 |   6 +-
 freebsd/sys/dev/usb/usb.h                       |  49 ++-
 freebsd/sys/dev/usb/usb_bus.h                   |  30 +-
 freebsd/sys/dev/usb/usb_busdma.c                |  41 ++-
 freebsd/sys/dev/usb/usb_busdma.h                |   5 +
 freebsd/sys/dev/usb/usb_controller.h            |   7 +-
 freebsd/sys/dev/usb/usb_core.c                  |  10 +-
 freebsd/sys/dev/usb/usb_core.h                  |   6 +
 freebsd/sys/dev/usb/usb_debug.c                 |  43 ++-
 freebsd/sys/dev/usb/usb_debug.h                 |   2 +-
 freebsd/sys/dev/usb/usb_dev.c                   |  10 +-
 freebsd/sys/dev/usb/usb_dev.h                   |   2 +
 freebsd/sys/dev/usb/usb_device.c                | 168 +++++++---
 freebsd/sys/dev/usb/usb_device.h                |  16 +-
 freebsd/sys/dev/usb/usb_dynamic.c               |  41 ++-
 freebsd/sys/dev/usb/usb_dynamic.h               |   3 +
 freebsd/sys/dev/usb/usb_endian.h                |   2 +
 freebsd/sys/dev/usb/usb_error.c                 |   4 +
 freebsd/sys/dev/usb/usb_freebsd.h               |  18 ++
 freebsd/sys/dev/usb/usb_generic.c               |  30 +-
 freebsd/sys/dev/usb/usb_handle_request.c        |   4 +
 freebsd/sys/dev/usb/usb_hid.c                   |   9 +-
 freebsd/sys/dev/usb/usb_hub.c                   | 157 ++++++---
 freebsd/sys/dev/usb/usb_hub.h                   |   4 +
 freebsd/sys/dev/usb/usb_ioctl.h                 |   6 +
 freebsd/sys/dev/usb/usb_lookup.c                |   6 +-
 freebsd/sys/dev/usb/usb_mbuf.c                  |   4 +
 freebsd/sys/dev/usb/usb_msctest.c               | 297 +++++++++++++++--
 freebsd/sys/dev/usb/usb_msctest.h               |  11 +
 freebsd/sys/dev/usb/usb_parse.c                 |  18 +-
 freebsd/sys/dev/usb/usb_process.c               |  13 +-
 freebsd/sys/dev/usb/usb_process.h               |   3 +
 freebsd/sys/dev/usb/usb_request.c               |  99 ++++--
 freebsd/sys/dev/usb/usb_request.h               |   5 +-
 freebsd/sys/dev/usb/usb_transfer.c              | 225 ++++++++++---
 freebsd/sys/dev/usb/usb_transfer.h              | 114 +++++++
 freebsd/sys/dev/usb/usb_util.c                  |   4 +
 freebsd/sys/dev/usb/usbdi.h                     |  27 +-
 freebsd/sys/dev/usb/usbhid.h                    |   2 +
 rtemsbsd/include/rtems/bsd/local/opt_usb.h      |   2 +
 rtemsbsd/include/rtems/bsd/local/usbdevs.h      |  83 ++++-
 rtemsbsd/include/rtems/bsd/local/usbdevs_data.h | 404 +++++++++++++++++++++++-
 49 files changed, 2000 insertions(+), 413 deletions(-)

diff --git a/freebsd/sys/dev/usb/controller/ehci.c b/freebsd/sys/dev/usb/controller/ehci.c
index 3eb63c6..85f41f1 100644
--- a/freebsd/sys/dev/usb/controller/ehci.c
+++ b/freebsd/sys/dev/usb/controller/ehci.c
@@ -1,5 +1,6 @@
 #include <machine/rtems-bsd-kernel-space.h>
 
+/* $FreeBSD$ */
 /*-
  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
  * Copyright (c) 2004 The NetBSD Foundation, Inc. All rights reserved.
@@ -45,9 +46,9 @@
  * 1) command failures are not recovered correctly
  */
 
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -83,6 +84,8 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/usb/usb_controller.h>
 #include <dev/usb/usb_bus.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
+
 #include <dev/usb/controller/ehci.h>
 #include <dev/usb/controller/ehcireg.h>
 
@@ -97,19 +100,14 @@ static int ehciiaadbug = 0;
 static int ehcilostintrbug = 0;
 
 static SYSCTL_NODE(_hw_usb, OID_AUTO, ehci, CTLFLAG_RW, 0, "USB ehci");
-SYSCTL_INT(_hw_usb_ehci, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_INT(_hw_usb_ehci, OID_AUTO, debug, CTLFLAG_RWTUN,
     &ehcidebug, 0, "Debug level");
-TUNABLE_INT("hw.usb.ehci.debug", &ehcidebug);
-SYSCTL_INT(_hw_usb_ehci, OID_AUTO, no_hs, CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_INT(_hw_usb_ehci, OID_AUTO, no_hs, CTLFLAG_RWTUN,
     &ehcinohighspeed, 0, "Disable High Speed USB");
-TUNABLE_INT("hw.usb.ehci.no_hs", &ehcinohighspeed);
-SYSCTL_INT(_hw_usb_ehci, OID_AUTO, iaadbug, CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_INT(_hw_usb_ehci, OID_AUTO, iaadbug, CTLFLAG_RWTUN,
     &ehciiaadbug, 0, "Enable doorbell bug workaround");
-TUNABLE_INT("hw.usb.ehci.iaadbug", &ehciiaadbug);
-SYSCTL_INT(_hw_usb_ehci, OID_AUTO, lostintrbug, CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_INT(_hw_usb_ehci, OID_AUTO, lostintrbug, CTLFLAG_RWTUN,
     &ehcilostintrbug, 0, "Enable lost interrupt bug workaround");
-TUNABLE_INT("hw.usb.ehci.lostintrbug", &ehcilostintrbug);
-
 
 static void ehci_dump_regs(ehci_softc_t *sc);
 static void ehci_dump_sqh(ehci_softc_t *sc, ehci_qh_t *sqh);
@@ -118,12 +116,12 @@ static void ehci_dump_sqh(ehci_softc_t *sc, ehci_qh_t *sqh);
 
 #define	EHCI_INTR_ENDPT 1
 
-extern struct usb_bus_methods ehci_bus_methods;
-extern struct usb_pipe_methods ehci_device_bulk_methods;
-extern struct usb_pipe_methods ehci_device_ctrl_methods;
-extern struct usb_pipe_methods ehci_device_intr_methods;
-extern struct usb_pipe_methods ehci_device_isoc_fs_methods;
-extern struct usb_pipe_methods ehci_device_isoc_hs_methods;
+static const struct usb_bus_methods ehci_bus_methods;
+static const struct usb_pipe_methods ehci_device_bulk_methods;
+static const struct usb_pipe_methods ehci_device_ctrl_methods;
+static const struct usb_pipe_methods ehci_device_intr_methods;
+static const struct usb_pipe_methods ehci_device_isoc_fs_methods;
+static const struct usb_pipe_methods ehci_device_isoc_hs_methods;
 
 static void ehci_do_poll(struct usb_bus *);
 static void ehci_device_done(struct usb_xfer *, usb_error_t);
@@ -1289,7 +1287,7 @@ done:
 static uint8_t
 ehci_check_transfer(struct usb_xfer *xfer)
 {
-	struct usb_pipe_methods *methods = xfer->endpoint->methods;
+	const struct usb_pipe_methods *methods = xfer->endpoint->methods;
 	ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
 
 	uint32_t status;
@@ -1781,7 +1779,7 @@ static void
 ehci_setup_standard_chain(struct usb_xfer *xfer, ehci_qh_t **qh_last)
 {
 	struct ehci_std_temp temp;
-	struct usb_pipe_methods *methods;
+	const struct usb_pipe_methods *methods;
 	ehci_qh_t *qh;
 	ehci_qtd_t *td;
 	uint32_t qh_endp;
@@ -2201,7 +2199,7 @@ ehci_isoc_hs_done(ehci_softc_t *sc, struct usb_xfer *xfer)
 static void
 ehci_device_done(struct usb_xfer *xfer, usb_error_t error)
 {
-	struct usb_pipe_methods *methods = xfer->endpoint->methods;
+	const struct usb_pipe_methods *methods = xfer->endpoint->methods;
 	ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
 
 	USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
@@ -2305,7 +2303,7 @@ ehci_device_bulk_start(struct usb_xfer *xfer)
 	ehci_doorbell_async(sc);
 }
 
-struct usb_pipe_methods ehci_device_bulk_methods =
+static const struct usb_pipe_methods ehci_device_bulk_methods =
 {
 	.open = ehci_device_bulk_open,
 	.close = ehci_device_bulk_close,
@@ -2346,7 +2344,7 @@ ehci_device_ctrl_start(struct usb_xfer *xfer)
 	ehci_transfer_intr_enqueue(xfer);
 }
 
-struct usb_pipe_methods ehci_device_ctrl_methods =
+static const struct usb_pipe_methods ehci_device_ctrl_methods =
 {
 	.open = ehci_device_ctrl_open,
 	.close = ehci_device_ctrl_close,
@@ -2427,7 +2425,7 @@ ehci_device_intr_start(struct usb_xfer *xfer)
 	ehci_transfer_intr_enqueue(xfer);
 }
 
-struct usb_pipe_methods ehci_device_intr_methods =
+static const struct usb_pipe_methods ehci_device_intr_methods =
 {
 	.open = ehci_device_intr_open,
 	.close = ehci_device_intr_close,
@@ -2719,7 +2717,7 @@ ehci_device_isoc_fs_start(struct usb_xfer *xfer)
 	ehci_transfer_intr_enqueue(xfer);
 }
 
-struct usb_pipe_methods ehci_device_isoc_fs_methods =
+static const struct usb_pipe_methods ehci_device_isoc_fs_methods =
 {
 	.open = ehci_device_isoc_fs_open,
 	.close = ehci_device_isoc_fs_close,
@@ -2999,7 +2997,7 @@ ehci_device_isoc_hs_start(struct usb_xfer *xfer)
 	ehci_transfer_intr_enqueue(xfer);
 }
 
-struct usb_pipe_methods ehci_device_isoc_hs_methods =
+static const struct usb_pipe_methods ehci_device_isoc_hs_methods =
 {
 	.open = ehci_device_isoc_hs_open,
 	.close = ehci_device_isoc_hs_close,
@@ -3806,7 +3804,7 @@ ehci_device_resume(struct usb_device *udev)
 {
 	ehci_softc_t *sc = EHCI_BUS2SC(udev->bus);
 	struct usb_xfer *xfer;
-	struct usb_pipe_methods *methods;
+	const struct usb_pipe_methods *methods;
 
 	DPRINTF("\n");
 
@@ -3840,7 +3838,7 @@ ehci_device_suspend(struct usb_device *udev)
 {
 	ehci_softc_t *sc = EHCI_BUS2SC(udev->bus);
 	struct usb_xfer *xfer;
-	struct usb_pipe_methods *methods;
+	const struct usb_pipe_methods *methods;
 
 	DPRINTF("\n");
 
@@ -3954,7 +3952,7 @@ ehci_start_dma_delay(struct usb_xfer *xfer)
 	    (void (*)(void *))&ehci_start_dma_delay_second, 4);
 }
 
-struct usb_bus_methods ehci_bus_methods =
+static const struct usb_bus_methods ehci_bus_methods =
 {
 	.endpoint_init = ehci_ep_init,
 	.xfer_setup = ehci_xfer_setup,
diff --git a/freebsd/sys/dev/usb/controller/ehci.h b/freebsd/sys/dev/usb/controller/ehci.h
index 76ac75f..aaa1ced 100644
--- a/freebsd/sys/dev/usb/controller/ehci.h
+++ b/freebsd/sys/dev/usb/controller/ehci.h
@@ -90,7 +90,7 @@ struct ehci_itd {
 #define	EHCI_ITD_GET_PG(x)	(((x) >> 12) & 0x7)
 #define	EHCI_ITD_SET_OFFS(x)	(x)
 #define	EHCI_ITD_GET_OFFS(x)	(((x) >> 0) & 0xFFF)
-#define	EHCI_ITD_ACTIVE		(1 << 31)
+#define	EHCI_ITD_ACTIVE		(1U << 31)
 #define	EHCI_ITD_DATABUFERR	(1 << 30)
 #define	EHCI_ITD_BABBLE		(1 << 29)
 #define	EHCI_ITD_XACTERR	(1 << 28)
@@ -126,7 +126,7 @@ struct ehci_sitd {
 	volatile uint32_t sitd_next;
 	volatile uint32_t sitd_portaddr;
 #define	EHCI_SITD_SET_DIR_OUT	(0 << 31)
-#define	EHCI_SITD_SET_DIR_IN	(1 << 31)
+#define	EHCI_SITD_SET_DIR_IN	(1U << 31)
 #define	EHCI_SITD_SET_ADDR(x)	(x)
 #define	EHCI_SITD_GET_ADDR(x)	((x) & 0x7F)
 #define	EHCI_SITD_SET_ENDPT(x)	((x) << 8)
diff --git a/freebsd/sys/dev/usb/controller/ohci.c b/freebsd/sys/dev/usb/controller/ohci.c
index 05c5e19..0b2de8a 100644
--- a/freebsd/sys/dev/usb/controller/ohci.c
+++ b/freebsd/sys/dev/usb/controller/ohci.c
@@ -1,5 +1,6 @@
 #include <machine/rtems-bsd-kernel-space.h>
 
+/* $FreeBSD$ */
 /*-
  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
  * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
@@ -27,9 +28,6 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
 /*
  * USB Open Host Controller driver.
  *
@@ -37,6 +35,9 @@ __FBSDID("$FreeBSD$");
  * USB spec:  http://www.usb.org/developers/docs/usbspec.zip
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -72,6 +73,8 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/usb/usb_controller.h>
 #include <dev/usb/usb_bus.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
+
 #include <dev/usb/controller/ohci.h>
 #include <dev/usb/controller/ohcireg.h>
 
@@ -83,9 +86,8 @@ __FBSDID("$FreeBSD$");
 static int ohcidebug = 0;
 
 static SYSCTL_NODE(_hw_usb, OID_AUTO, ohci, CTLFLAG_RW, 0, "USB ohci");
-SYSCTL_INT(_hw_usb_ohci, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_INT(_hw_usb_ohci, OID_AUTO, debug, CTLFLAG_RWTUN,
     &ohcidebug, 0, "ohci debug level");
-TUNABLE_INT("hw.usb.ohci.debug", &ohcidebug);
 
 static void ohci_dumpregs(ohci_softc_t *);
 static void ohci_dump_tds(ohci_td_t *);
@@ -110,11 +112,11 @@ static void ohci_dump_itds(ohci_itd_t *);
 
 #define	OHCI_INTR_ENDPT 1
 
-extern struct usb_bus_methods ohci_bus_methods;
-extern struct usb_pipe_methods ohci_device_bulk_methods;
-extern struct usb_pipe_methods ohci_device_ctrl_methods;
-extern struct usb_pipe_methods ohci_device_intr_methods;
-extern struct usb_pipe_methods ohci_device_isoc_methods;
+static const struct usb_bus_methods ohci_bus_methods;
+static const struct usb_pipe_methods ohci_device_bulk_methods;
+static const struct usb_pipe_methods ohci_device_ctrl_methods;
+static const struct usb_pipe_methods ohci_device_intr_methods;
+static const struct usb_pipe_methods ohci_device_isoc_methods;
 
 static void ohci_do_poll(struct usb_bus *bus);
 static void ohci_device_done(struct usb_xfer *xfer, usb_error_t error);
@@ -1392,7 +1394,7 @@ static void
 ohci_setup_standard_chain(struct usb_xfer *xfer, ohci_ed_t **ed_last)
 {
 	struct ohci_std_temp temp;
-	struct usb_pipe_methods *methods;
+	const struct usb_pipe_methods *methods;
 	ohci_ed_t *ed;
 	ohci_td_t *td;
 	uint32_t ed_flags;
@@ -1631,7 +1633,7 @@ ohci_root_intr(ohci_softc_t *sc)
 static void
 ohci_device_done(struct usb_xfer *xfer, usb_error_t error)
 {
-	struct usb_pipe_methods *methods = xfer->endpoint->methods;
+	const struct usb_pipe_methods *methods = xfer->endpoint->methods;
 	ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
 	ohci_ed_t *ed;
 
@@ -1697,7 +1699,7 @@ ohci_device_bulk_start(struct usb_xfer *xfer)
 	ohci_transfer_intr_enqueue(xfer);
 }
 
-struct usb_pipe_methods ohci_device_bulk_methods =
+static const struct usb_pipe_methods ohci_device_bulk_methods =
 {
 	.open = ohci_device_bulk_open,
 	.close = ohci_device_bulk_close,
@@ -1738,7 +1740,7 @@ ohci_device_ctrl_start(struct usb_xfer *xfer)
 	ohci_transfer_intr_enqueue(xfer);
 }
 
-struct usb_pipe_methods ohci_device_ctrl_methods =
+static const struct usb_pipe_methods ohci_device_ctrl_methods =
 {
 	.open = ohci_device_ctrl_open,
 	.close = ohci_device_ctrl_close,
@@ -1810,7 +1812,7 @@ ohci_device_intr_start(struct usb_xfer *xfer)
 	ohci_transfer_intr_enqueue(xfer);
 }
 
-struct usb_pipe_methods ohci_device_intr_methods =
+static const struct usb_pipe_methods ohci_device_intr_methods =
 {
 	.open = ohci_device_intr_open,
 	.close = ohci_device_intr_close,
@@ -2018,7 +2020,7 @@ ohci_device_isoc_start(struct usb_xfer *xfer)
 	ohci_transfer_intr_enqueue(xfer);
 }
 
-struct usb_pipe_methods ohci_device_isoc_methods =
+static const struct usb_pipe_methods ohci_device_isoc_methods =
 {
 	.open = ohci_device_isoc_open,
 	.close = ohci_device_isoc_close,
@@ -2597,7 +2599,7 @@ ohci_device_resume(struct usb_device *udev)
 {
 	struct ohci_softc *sc = OHCI_BUS2SC(udev->bus);
 	struct usb_xfer *xfer;
-	struct usb_pipe_methods *methods;
+	const struct usb_pipe_methods *methods;
 	ohci_ed_t *ed;
 
 	DPRINTF("\n");
@@ -2635,7 +2637,7 @@ ohci_device_suspend(struct usb_device *udev)
 {
 	struct ohci_softc *sc = OHCI_BUS2SC(udev->bus);
 	struct usb_xfer *xfer;
-	struct usb_pipe_methods *methods;
+	const struct usb_pipe_methods *methods;
 	ohci_ed_t *ed;
 
 	DPRINTF("\n");
@@ -2719,7 +2721,7 @@ ohci_set_hw_power(struct usb_bus *bus)
 	return;
 }
 
-struct usb_bus_methods ohci_bus_methods =
+static const struct usb_bus_methods ohci_bus_methods =
 {
 	.endpoint_init = ohci_ep_init,
 	.xfer_setup = ohci_xfer_setup,
diff --git a/freebsd/sys/dev/usb/controller/usb_controller.c b/freebsd/sys/dev/usb/controller/usb_controller.c
index 90e09bb..8ee4ced 100644
--- a/freebsd/sys/dev/usb/controller/usb_controller.c
+++ b/freebsd/sys/dev/usb/controller/usb_controller.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <rtems/bsd/local/opt_ddb.h>
 
 #include <sys/stdint.h>
@@ -65,6 +68,7 @@
 #include <dev/usb/usb_bus.h>
 #include <dev/usb/usb_pf.h>
 #include <rtems/bsd/local/usb_if.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 /* function prototypes  */
 
@@ -83,24 +87,23 @@ static void	usb_attach_sub(device_t, struct usb_bus *);
 static int usb_ctrl_debug = 0;
 
 static SYSCTL_NODE(_hw_usb, OID_AUTO, ctrl, CTLFLAG_RW, 0, "USB controller");
-SYSCTL_INT(_hw_usb_ctrl, OID_AUTO, debug, CTLFLAG_RW, &usb_ctrl_debug, 0,
+SYSCTL_INT(_hw_usb_ctrl, OID_AUTO, debug, CTLFLAG_RWTUN, &usb_ctrl_debug, 0,
     "Debug level");
 #endif
 
-#ifndef __rtems__
+#if USB_HAVE_ROOT_MOUNT_HOLD
 static int usb_no_boot_wait = 0;
-TUNABLE_INT("hw.usb.no_boot_wait", &usb_no_boot_wait);
-SYSCTL_INT(_hw_usb, OID_AUTO, no_boot_wait, CTLFLAG_RD|CTLFLAG_TUN, &usb_no_boot_wait, 0,
+SYSCTL_INT(_hw_usb, OID_AUTO, no_boot_wait, CTLFLAG_RDTUN, &usb_no_boot_wait, 0,
     "No USB device enumerate waiting at boot.");
+#endif
 
+#ifndef __rtems__
 static int usb_no_suspend_wait = 0;
-TUNABLE_INT("hw.usb.no_suspend_wait", &usb_no_suspend_wait);
-SYSCTL_INT(_hw_usb, OID_AUTO, no_suspend_wait, CTLFLAG_RW|CTLFLAG_TUN,
+SYSCTL_INT(_hw_usb, OID_AUTO, no_suspend_wait, CTLFLAG_RWTUN,
     &usb_no_suspend_wait, 0, "No USB device waiting at system suspend.");
 
 static int usb_no_shutdown_wait = 0;
-TUNABLE_INT("hw.usb.no_shutdown_wait", &usb_no_shutdown_wait);
-SYSCTL_INT(_hw_usb, OID_AUTO, no_shutdown_wait, CTLFLAG_RW|CTLFLAG_TUN,
+SYSCTL_INT(_hw_usb, OID_AUTO, no_shutdown_wait, CTLFLAG_RWTUN,
     &usb_no_shutdown_wait, 0, "No USB device waiting at system shutdown.");
 #endif /* __rtems__ */
 
@@ -113,7 +116,8 @@ static device_method_t usb_methods[] = {
 	DEVMETHOD(device_suspend, usb_suspend),
 	DEVMETHOD(device_resume, usb_resume),
 	DEVMETHOD(device_shutdown, usb_shutdown),
-	{0, 0}
+
+	DEVMETHOD_END
 };
 
 static driver_t usb_driver = {
@@ -132,6 +136,11 @@ DRIVER_MODULE(usbus, xhci, usb_driver, usb_devclass, 0, 0);
 DRIVER_MODULE(usbus, at91_udp, usb_driver, usb_devclass, 0, 0);
 DRIVER_MODULE(usbus, musbotg, usb_driver, usb_devclass, 0, 0);
 DRIVER_MODULE(usbus, uss820dci, usb_driver, usb_devclass, 0, 0);
+DRIVER_MODULE(usbus, octusb, usb_driver, usb_devclass, 0, 0);
+
+/* Dual Mode Drivers */
+DRIVER_MODULE(usbus, dwcotg, usb_driver, usb_devclass, 0, 0);
+DRIVER_MODULE(usbus, saf1761otg, usb_driver, usb_devclass, 0, 0);
 
 /*------------------------------------------------------------------------*
  *	usb_probe
@@ -145,6 +154,7 @@ usb_probe(device_t dev)
 	return (0);
 }
 
+#if USB_HAVE_ROOT_MOUNT_HOLD
 static void
 usb_root_mount_rel(struct usb_bus *bus)
 {
@@ -156,6 +166,7 @@ usb_root_mount_rel(struct usb_bus *bus)
 	}
 #endif /* __rtems__ */
 }
+#endif
 
 /*------------------------------------------------------------------------*
  *	usb_attach
@@ -172,12 +183,12 @@ usb_attach(device_t dev)
 		return (ENXIO);
 	}
 
-#ifndef __rtems__
+#if USB_HAVE_ROOT_MOUNT_HOLD
 	if (usb_no_boot_wait == 0) {
 		/* delay vfs_mountroot until the bus is explored */
 		bus->bus_roothold = root_mount_hold(device_get_nameunit(dev));
 	}
-#endif /* __rtems__ */
+#endif
 
 	usb_attach_sub(dev, bus);
 
@@ -201,38 +212,43 @@ usb_detach(device_t dev)
 	/* Stop power watchdog */
 	usb_callout_drain(&bus->power_wdog);
 
+#if USB_HAVE_ROOT_MOUNT_HOLD
 	/* Let the USB explore process detach all devices. */
 	usb_root_mount_rel(bus);
+#endif
 
 	USB_BUS_LOCK(bus);
 
 	/* Queue detach job */
-	usb_proc_msignal(&bus->explore_proc,
+	usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
 	    &bus->detach_msg[0], &bus->detach_msg[1]);
 
 	/* Wait for detach to complete */
-	usb_proc_mwait(&bus->explore_proc,
+	usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
 	    &bus->detach_msg[0], &bus->detach_msg[1]);
 
 #if USB_HAVE_UGEN
 	/* Wait for cleanup to complete */
-	usb_proc_mwait(&bus->explore_proc,
+	usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
 	    &bus->cleanup_msg[0], &bus->cleanup_msg[1]);
 #endif
 	USB_BUS_UNLOCK(bus);
 
+#if USB_HAVE_PER_BUS_PROCESS
 	/* Get rid of USB callback processes */
 
-	usb_proc_free(&bus->giant_callback_proc);
-	usb_proc_free(&bus->non_giant_callback_proc);
+	usb_proc_free(USB_BUS_GIANT_PROC(bus));
+	usb_proc_free(USB_BUS_NON_GIANT_ISOC_PROC(bus));
+	usb_proc_free(USB_BUS_NON_GIANT_BULK_PROC(bus));
 
 	/* Get rid of USB explore process */
 
-	usb_proc_free(&bus->explore_proc);
+	usb_proc_free(USB_BUS_EXPLORE_PROC(bus));
 
 	/* Get rid of control transfer process */
 
-	usb_proc_free(&bus->control_xfer_proc);
+	usb_proc_free(USB_BUS_CONTROL_XFER_PROC(bus));
+#endif
 
 #if USB_HAVE_PF
 	usbpf_detach(bus);
@@ -256,12 +272,12 @@ usb_suspend(device_t dev)
 	}
 
 	USB_BUS_LOCK(bus);
-	usb_proc_msignal(&bus->explore_proc,
+	usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
 	    &bus->suspend_msg[0], &bus->suspend_msg[1]);
 #ifndef __rtems__
 	if (usb_no_suspend_wait == 0) {
 		/* wait for suspend callback to be executed */
-		usb_proc_mwait(&bus->explore_proc,
+		usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
 		    &bus->suspend_msg[0], &bus->suspend_msg[1]);
 	}
 #endif /* __rtems__ */
@@ -286,7 +302,7 @@ usb_resume(device_t dev)
 	}
 
 	USB_BUS_LOCK(bus);
-	usb_proc_msignal(&bus->explore_proc,
+	usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
 	    &bus->resume_msg[0], &bus->resume_msg[1]);
 	USB_BUS_UNLOCK(bus);
 
@@ -311,7 +327,7 @@ usb_bus_reset_async_locked(struct usb_bus *bus)
 
 	device_printf(bus->parent, "Resetting controller\n");
 
-	usb_proc_msignal(&bus->explore_proc,
+	usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
 	    &bus->reset_msg[0], &bus->reset_msg[1]);
 }
 
@@ -334,11 +350,11 @@ usb_shutdown(device_t dev)
 
 	USB_BUS_LOCK(bus);
 #ifndef __rtems__
-	usb_proc_msignal(&bus->explore_proc,
+	usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
 	    &bus->shutdown_msg[0], &bus->shutdown_msg[1]);
 	if (usb_no_shutdown_wait == 0) {
 		/* wait for shutdown callback to be executed */
-		usb_proc_mwait(&bus->explore_proc,
+		usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
 		    &bus->shutdown_msg[0], &bus->shutdown_msg[1]);
 	}
 #endif /* __rtems__ */
@@ -389,9 +405,10 @@ usb_bus_explore(struct usb_proc_msg *pm)
 		 * The following three lines of code are only here to
 		 * recover from DDB:
 		 */
-		usb_proc_rewakeup(&bus->control_xfer_proc);
-		usb_proc_rewakeup(&bus->giant_callback_proc);
-		usb_proc_rewakeup(&bus->non_giant_callback_proc);
+		usb_proc_rewakeup(USB_BUS_CONTROL_XFER_PROC(bus));
+		usb_proc_rewakeup(USB_BUS_GIANT_PROC(bus));
+		usb_proc_rewakeup(USB_BUS_NON_GIANT_ISOC_PROC(bus));
+		usb_proc_rewakeup(USB_BUS_NON_GIANT_BULK_PROC(bus));
 #endif
 
 		USB_BUS_UNLOCK(bus);
@@ -406,7 +423,9 @@ usb_bus_explore(struct usb_proc_msg *pm)
 		(udev->hub->explore) (udev);
 		USB_BUS_LOCK(bus);
 	}
+#if USB_HAVE_ROOT_MOUNT_HOLD
 	usb_root_mount_rel(bus);
+#endif
 }
 
 /*------------------------------------------------------------------------*
@@ -672,7 +691,7 @@ usb_power_wdog(void *arg)
 	 * The following line of code is only here to recover from
 	 * DDB:
 	 */
-	usb_proc_rewakeup(&bus->explore_proc);	/* recover from DDB */
+	usb_proc_rewakeup(USB_BUS_EXPLORE_PROC(bus));	/* recover from DDB */
 #endif
 
 #if USB_HAVE_POWERD
@@ -731,7 +750,9 @@ usb_bus_attach(struct usb_proc_msg *pm)
 
 	default:
 		device_printf(bus->bdev, "Unsupported USB revision\n");
+#if USB_HAVE_ROOT_MOUNT_HOLD
 		usb_root_mount_rel(bus);
+#endif
 		return;
 	}
 
@@ -773,7 +794,9 @@ usb_bus_attach(struct usb_proc_msg *pm)
 	if (err) {
 		device_printf(bus->bdev, "Root HUB problem, error=%s\n",
 		    usbd_errstr(err));
+#if USB_HAVE_ROOT_MOUNT_HOLD
 		usb_root_mount_rel(bus);
+#endif
 	}
 
 	/* set softc - we are ready */
@@ -791,8 +814,6 @@ usb_bus_attach(struct usb_proc_msg *pm)
 static void
 usb_attach_sub(device_t dev, struct usb_bus *bus)
 {
-	const char *pname = device_get_nameunit(dev);
-
 	mtx_lock(&Giant);
 	if (usb_devclass_ptr == NULL)
 		usb_devclass_ptr = devclass_find("usbus");
@@ -845,28 +866,35 @@ usb_attach_sub(device_t dev, struct usb_bus *bus)
 	bus->cleanup_msg[1].bus = bus;
 #endif
 
+#if USB_HAVE_PER_BUS_PROCESS
 	/* Create USB explore and callback processes */
 
-	if (usb_proc_create(&bus->giant_callback_proc,
-	    &bus->bus_mtx, pname, USB_PRI_MED)) {
+	if (usb_proc_create(USB_BUS_GIANT_PROC(bus),
+	    &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
 		device_printf(dev, "WARNING: Creation of USB Giant "
 		    "callback process failed.\n");
-	} else if (usb_proc_create(&bus->non_giant_callback_proc,
-	    &bus->bus_mtx, pname, USB_PRI_HIGH)) {
-		device_printf(dev, "WARNING: Creation of USB non-Giant "
+	} else if (usb_proc_create(USB_BUS_NON_GIANT_ISOC_PROC(bus),
+	    &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_HIGHEST)) {
+		device_printf(dev, "WARNING: Creation of USB non-Giant ISOC "
 		    "callback process failed.\n");
-	} else if (usb_proc_create(&bus->explore_proc,
-	    &bus->bus_mtx, pname, USB_PRI_MED)) {
+	} else if (usb_proc_create(USB_BUS_NON_GIANT_BULK_PROC(bus),
+	    &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_HIGH)) {
+		device_printf(dev, "WARNING: Creation of USB non-Giant BULK "
+		    "callback process failed.\n");
+	} else if (usb_proc_create(USB_BUS_EXPLORE_PROC(bus),
+	    &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
 		device_printf(dev, "WARNING: Creation of USB explore "
 		    "process failed.\n");
-	} else if (usb_proc_create(&bus->control_xfer_proc,
-	    &bus->bus_mtx, pname, USB_PRI_MED)) {
+	} else if (usb_proc_create(USB_BUS_CONTROL_XFER_PROC(bus),
+	    &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
 		device_printf(dev, "WARNING: Creation of USB control transfer "
 		    "process failed.\n");
-	} else {
+	} else
+#endif
+	{
 		/* Get final attach going */
 		USB_BUS_LOCK(bus);
-		usb_proc_msignal(&bus->explore_proc,
+		usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
 		    &bus->attach_msg[0], &bus->attach_msg[1]);
 		USB_BUS_UNLOCK(bus);
 
@@ -874,7 +902,6 @@ usb_attach_sub(device_t dev, struct usb_bus *bus)
 		usb_needs_explore(bus, 1);
 	}
 }
-
 SYSUNINIT(usb_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb_bus_unload, NULL);
 
 /*------------------------------------------------------------------------*
@@ -933,7 +960,10 @@ usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat,
 	bus->alloc_failed = 0;
 
 	mtx_init(&bus->bus_mtx, device_get_nameunit(bus->parent),
-	    NULL, MTX_DEF | MTX_RECURSE);
+	    "usb_def_mtx", MTX_DEF | MTX_RECURSE);
+
+	mtx_init(&bus->bus_spin_lock, device_get_nameunit(bus->parent),
+	    "usb_spin_mtx", MTX_SPIN | MTX_RECURSE);
 
 	usb_callout_init_mtx(&bus->power_wdog,
 	    &bus->bus_mtx, 0);
@@ -988,19 +1018,20 @@ usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
 #endif
 
 	mtx_destroy(&bus->bus_mtx);
+	mtx_destroy(&bus->bus_spin_lock);
 }
 
 /* convenience wrappers */
 void
 usb_proc_explore_mwait(struct usb_device *udev, void *pm1, void *pm2)
 {
-	usb_proc_mwait(&udev->bus->explore_proc, pm1, pm2);
+	usb_proc_mwait(USB_BUS_EXPLORE_PROC(udev->bus), pm1, pm2);
 }
 
 void	*
 usb_proc_explore_msignal(struct usb_device *udev, void *pm1, void *pm2)
 {
-	return (usb_proc_msignal(&udev->bus->explore_proc, pm1, pm2));
+	return (usb_proc_msignal(USB_BUS_EXPLORE_PROC(udev->bus), pm1, pm2));
 }
 
 void
diff --git a/freebsd/sys/dev/usb/quirk/usb_quirk.c b/freebsd/sys/dev/usb/quirk/usb_quirk.c
index 7447ea8..a3d7282 100644
--- a/freebsd/sys/dev/usb/quirk/usb_quirk.c
+++ b/freebsd/sys/dev/usb/quirk/usb_quirk.c
@@ -63,6 +63,7 @@ MODULE_VERSION(usb_quirk, 1);
 
 #define	USB_DEV_QUIRKS_MAX 384
 #define	USB_SUB_QUIRKS_MAX 8
+#define	USB_QUIRK_ENVROOT "hw.usb.quirk."
 
 struct usb_quirk_entry {
 	uint16_t vid;
@@ -96,8 +97,10 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	USB_QUIRK(SILICONPORTALS, YAPPHONE, 0x100, 0x100, UQ_AU_INP_ASYNC),
 	USB_QUIRK(LOGITECH, UN53B, 0x0000, 0xffff, UQ_NO_STRINGS),
 	USB_QUIRK(REALTEK, RTL8196EU, 0x0000, 0xffff, UQ_CFG_INDEX_1),
+	USB_QUIRK(REALTEK, RTL8153, 0x0000, 0xffff, UQ_CFG_INDEX_1),
 	USB_QUIRK(ELSA, MODEM1, 0x0000, 0xffff, UQ_CFG_INDEX_1),
 	USB_QUIRK(PLANEX2, MZKUE150N, 0x0000, 0xffff, UQ_CFG_INDEX_1),
+	USB_QUIRK(CISCOLINKSYS, USB3GIGV1, 0x0000, 0xffff, UQ_CFG_INDEX_1),
 	/* Quirks for printer devices */
 	USB_QUIRK(HP, 895C, 0x0000, 0xffff, UQ_BROKEN_BIDIR),
 	USB_QUIRK(HP, 880C, 0x0000, 0xffff, UQ_BROKEN_BIDIR),
@@ -112,6 +115,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	USB_QUIRK(CYBERPOWER, 1500CAVRLCD, 0x0000, 0xffff, UQ_HID_IGNORE),
 	USB_QUIRK(CYPRESS, SILVERSHIELD, 0x0000, 0xffff, UQ_HID_IGNORE),
 	USB_QUIRK(DELORME, EARTHMATE, 0x0000, 0xffff, UQ_HID_IGNORE),
+	USB_QUIRK(DREAMLINK, DL100B, 0x0000, 0xffff, UQ_HID_IGNORE),
 	USB_QUIRK(ITUNERNET, USBLCD2X20, 0x0000, 0xffff, UQ_HID_IGNORE),
 	USB_QUIRK(ITUNERNET, USBLCD4X20, 0x0000, 0xffff, UQ_HID_IGNORE),
 	USB_QUIRK(LIEBERT, POWERSURE_PXT, 0x0000, 0xffff, UQ_HID_IGNORE),
@@ -524,6 +528,9 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	USB_QUIRK(FEIYA, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY),
 	USB_QUIRK(REALTEK, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY),
 	USB_QUIRK(INITIO, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY),
+
+	/* DYMO LabelManager Pnp */
+	USB_QUIRK(DYMO, LABELMANAGERPNP, 0x0000, 0xffff, UQ_MSC_DYMO_EJECT),
 };
 #undef USB_QUIRK_VP
 #undef USB_QUIRK
@@ -547,7 +554,6 @@ static const char *usb_quirk_str[USB_QUIRK_MAX] = {
 	[UQ_MS_LEADING_BYTE]	= "UQ_MS_LEADING_BYTE",
 	[UQ_MS_REVZ]		= "UQ_MS_REVZ",
 	[UQ_NO_STRINGS]		= "UQ_NO_STRINGS",
-	[UQ_OPEN_CLEARSTALL]	= "UQ_OPEN_CLEARSTALL",
 	[UQ_POWER_CLAIM]	= "UQ_POWER_CLAIM",
 	[UQ_SPUR_BUT_UP]	= "UQ_SPUR_BUT_UP",
 	[UQ_SWAP_UNICODE]	= "UQ_SWAP_UNICODE",
@@ -594,6 +600,7 @@ static const char *usb_quirk_str[USB_QUIRK_MAX] = {
 	[UQ_BAD_MIDI]			= "UQ_BAD_MIDI",
 	[UQ_AU_VENDOR_CLASS]		= "UQ_AU_VENDOR_CLASS",
 	[UQ_SINGLE_CMD_MIDI]		= "UQ_SINGLE_CMD_MIDI",
+	[UQ_MSC_DYMO_EJECT]		= "UQ_MSC_DYMO_EJECT",
 };
 
 /*------------------------------------------------------------------------*
@@ -604,8 +611,32 @@ static const char *usb_quirk_str[USB_QUIRK_MAX] = {
 static const char *
 usb_quirkstr(uint16_t quirk)
 {
-	return ((quirk < USB_QUIRK_MAX) ?
-	    usb_quirk_str[quirk] : "USB_QUIRK_UNKNOWN");
+	return ((quirk < USB_QUIRK_MAX && usb_quirk_str[quirk] != NULL) ?
+	    usb_quirk_str[quirk] : "UQ_UNKNOWN");
+}
+
+/*------------------------------------------------------------------------*
+ *	usb_strquirk
+ *
+ * This function converts a string into a USB quirk code.
+ *
+ * Returns:
+ * Less than USB_QUIRK_MAX: Quirk code
+ * Else: Quirk code not found
+ *------------------------------------------------------------------------*/
+static uint16_t
+usb_strquirk(const char *str, size_t len)
+{
+	const char *quirk;
+	uint16_t x;
+
+	for (x = 0; x != USB_QUIRK_MAX; x++) {
+		quirk = usb_quirkstr(x);
+		if (strncmp(str, quirk, len) == 0 &&
+		    quirk[len] == 0)
+			break;
+	}
+	return (x);
 }
 
 /*------------------------------------------------------------------------*
@@ -850,12 +881,126 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
 	return (ENOIOCTL);
 }
 
+/*------------------------------------------------------------------------*
+ *	usb_quirk_strtou16
+ *
+ * Helper function to scan a 16-bit integer.
+ *------------------------------------------------------------------------*/
+static uint16_t
+usb_quirk_strtou16(const char **pptr, const char *name, const char *what)
+{
+	unsigned long value;
+	char *end;
+
+	value = strtoul(*pptr, &end, 0);
+	if (value > 65535 || *pptr == end || (*end != ' ' && *end != '\t')) {
+		printf("%s: %s 16-bit %s value set to zero\n",
+		    name, what, *end == 0 ? "incomplete" : "invalid");
+		return (0);
+	}
+	*pptr = end + 1;
+	return ((uint16_t)value);
+}
+
+/*------------------------------------------------------------------------*
+ *	usb_quirk_add_entry_from_str
+ *
+ * Add a USB quirk entry from string.
+ *     "VENDOR PRODUCT LO_REV HI_REV QUIRK[,QUIRK[,...]]"
+ *------------------------------------------------------------------------*/
+static void
+usb_quirk_add_entry_from_str(const char *name, const char *env)
+{
+	struct usb_quirk_entry entry = { };
+	struct usb_quirk_entry *new;
+	uint16_t quirk_idx;
+	uint16_t quirk;
+	const char *end;
+
+	/* check for invalid environment variable */
+	if (name == NULL || env == NULL)
+		return;
+
+	if (bootverbose)
+		printf("Adding USB QUIRK '%s' = '%s'\n", name, env);
+
+	/* parse device information */
+	entry.vid = usb_quirk_strtou16(&env, name, "Vendor ID");
+	entry.pid = usb_quirk_strtou16(&env, name, "Product ID");
+	entry.lo_rev = usb_quirk_strtou16(&env, name, "Low revision");
+	entry.hi_rev = usb_quirk_strtou16(&env, name, "High revision");
+
+	/* parse quirk information */
+	quirk_idx = 0;
+	while (*env != 0 && quirk_idx != USB_SUB_QUIRKS_MAX) {
+		/* skip whitespace before quirks */
+		while (*env == ' ' || *env == '\t')
+			env++;
+
+		/* look for quirk separation character */
+		end = strchr(env, ',');
+		if (end == NULL)
+			end = env + strlen(env);
+
+		/* lookup quirk in string table */
+		quirk = usb_strquirk(env, end - env);
+		if (quirk < USB_QUIRK_MAX) {
+			entry.quirks[quirk_idx++] = quirk;
+		} else {
+			printf("%s: unknown USB quirk '%.*s' (skipped)\n",
+			    name, (int)(end - env), env);
+		}
+		env = end;
+
+		/* skip quirk delimiter, if any */
+		if (*env != 0)
+			env++;
+	}
+
+	/* register quirk */
+	if (quirk_idx != 0) {
+		if (*env != 0) {
+			printf("%s: Too many USB quirks, only %d allowed!\n",
+			    name, USB_SUB_QUIRKS_MAX);
+		}
+		mtx_lock(&usb_quirk_mtx);
+		new = usb_quirk_get_entry(entry.vid, entry.pid,
+		    entry.lo_rev, entry.hi_rev, 1);
+		if (new == NULL)
+			printf("%s: USB quirks table is full!\n", name);
+		else
+			memcpy(new->quirks, entry.quirks, sizeof(entry.quirks));
+		mtx_unlock(&usb_quirk_mtx);
+	} else {
+		printf("%s: No USB quirks found!\n", name);
+	}
+}
+
 static void
 usb_quirk_init(void *arg)
 {
+#ifndef __rtems__
+	char envkey[sizeof(USB_QUIRK_ENVROOT) + 2];	/* 2 digits max, 0 to 99 */
+	int i;
+#endif /* __rtems__ */
+  
 	/* initialize mutex */
 	mtx_init(&usb_quirk_mtx, "USB quirk", NULL, MTX_DEF);
 
+#ifndef __rtems__
+	/* look for quirks defined by the environment variable */
+	for (i = 0; i != 100; i++) {
+		snprintf(envkey, sizeof(envkey), USB_QUIRK_ENVROOT "%d", i);
+
+		/* Stop at first undefined var */
+		if (!testenv(envkey))
+			break;
+
+		/* parse environment variable */
+		usb_quirk_add_entry_from_str(envkey, kern_getenv(envkey));
+	}
+#endif /* __rtems__ */
+	
 	/* register our function */
 	usb_test_quirk_p = &usb_test_quirk_by_info;
 	usb_quirk_ioctl_p = &usb_quirk_ioctl;
diff --git a/freebsd/sys/dev/usb/quirk/usb_quirk.h b/freebsd/sys/dev/usb/quirk/usb_quirk.h
index bddc2c5..7010916 100644
--- a/freebsd/sys/dev/usb/quirk/usb_quirk.h
+++ b/freebsd/sys/dev/usb/quirk/usb_quirk.h
@@ -54,7 +54,6 @@ enum {
 	UQ_MS_LEADING_BYTE,	/* mouse sends an unknown leading byte */
 	UQ_MS_REVZ,		/* mouse has Z-axis reversed */
 	UQ_NO_STRINGS,		/* string descriptors are broken */
-	UQ_OPEN_CLEARSTALL,	/* device needs clear endpoint stall */
 	UQ_POWER_CLAIM,		/* hub lies about power status */
 	UQ_SPUR_BUT_UP,		/* spurious mouse button up events */
 	UQ_SWAP_UNICODE,	/* has some Unicode strings swapped */
@@ -109,6 +108,7 @@ enum {
 	UQ_BAD_MIDI,		/* device claims MIDI class, but isn't */
 	UQ_AU_VENDOR_CLASS,	/* audio device uses vendor and not audio class */
 	UQ_SINGLE_CMD_MIDI,	/* at most one command per USB packet */
+	UQ_MSC_DYMO_EJECT,	/* ejects Dymo MSC device */
 
 	USB_QUIRK_MAX
 };
diff --git a/freebsd/sys/dev/usb/storage/umass.c b/freebsd/sys/dev/usb/storage/umass.c
index 39d3269..e800987 100644
--- a/freebsd/sys/dev/usb/storage/umass.c
+++ b/freebsd/sys/dev/usb/storage/umass.c
@@ -169,12 +169,10 @@ static int umass_debug;
 static int umass_throttle;
 
 static SYSCTL_NODE(_hw_usb, OID_AUTO, umass, CTLFLAG_RW, 0, "USB umass");
-SYSCTL_INT(_hw_usb_umass, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_INT(_hw_usb_umass, OID_AUTO, debug, CTLFLAG_RWTUN,
     &umass_debug, 0, "umass debug level");
-TUNABLE_INT("hw.usb.umass.debug", &umass_debug);
-SYSCTL_INT(_hw_usb_umass, OID_AUTO, throttle, CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_INT(_hw_usb_umass, OID_AUTO, throttle, CTLFLAG_RWTUN,
     &umass_throttle, 0, "Forced delay between commands in milliseconds");
-TUNABLE_INT("hw.usb.umass.throttle", &umass_throttle);
 #else
 #define	DIF(...) do { } while (0)
 #define	DPRINTF(...) do { } while (0)
@@ -702,7 +700,8 @@ static device_method_t umass_methods[] = {
 	DEVMETHOD(device_probe, umass_probe),
 	DEVMETHOD(device_attach, umass_attach),
 	DEVMETHOD(device_detach, umass_detach),
-	{0, 0}
+
+	DEVMETHOD_END
 };
 
 static driver_t umass_driver = {
@@ -2125,10 +2124,9 @@ umass_cam_attach(struct umass_softc *sc)
 #ifndef USB_DEBUG
 	if (bootverbose)
 #endif
-		printf("%s:%d:%d:%d: Attached to scbus%d\n",
+		printf("%s:%d:%d: Attached to scbus%d\n",
 		    sc->sc_name, cam_sim_path(sc->sc_sim),
-		    sc->sc_unit, CAM_LUN_WILDCARD,
-		    cam_sim_path(sc->sc_sim));
+		    sc->sc_unit, cam_sim_path(sc->sc_sim));
 }
 #endif /* __rtems__ */
 
@@ -2180,19 +2178,19 @@ umass_cam_action(struct cam_sim *sim, union ccb *ccb)
 				cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_bytes);
 			}
 
-			DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:XPT_SCSI_IO: "
+			DPRINTF(sc, UDMASS_SCSI, "%d:%d:%jx:XPT_SCSI_IO: "
 			    "cmd: 0x%02x, flags: 0x%02x, "
 			    "%db cmd/%db data/%db sense\n",
 			    cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
-			    ccb->ccb_h.target_lun, cmd[0],
+			    (uintmax_t)ccb->ccb_h.target_lun, cmd[0],
 			    ccb->ccb_h.flags & CAM_DIR_MASK, ccb->csio.cdb_len,
 			    ccb->csio.dxfer_len, ccb->csio.sense_len);
 
 			if (sc->sc_transfer.ccb) {
-				DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:XPT_SCSI_IO: "
+				DPRINTF(sc, UDMASS_SCSI, "%d:%d:%jx:XPT_SCSI_IO: "
 				    "I/O in progress, deferring\n",
 				    cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
-				    ccb->ccb_h.target_lun);
+				    (uintmax_t)ccb->ccb_h.target_lun);
 				ccb->ccb_h.status = CAM_SCSI_BUSY;
 				xpt_done(ccb);
 				goto done;
@@ -2310,9 +2308,9 @@ umass_cam_action(struct cam_sim *sim, union ccb *ccb)
 		{
 			struct ccb_pathinq *cpi = &ccb->cpi;
 
-			DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:XPT_PATH_INQ:.\n",
+			DPRINTF(sc, UDMASS_SCSI, "%d:%d:%jx:XPT_PATH_INQ:.\n",
 			    sc ? cam_sim_path(sc->sc_sim) : -1, ccb->ccb_h.target_id,
-			    ccb->ccb_h.target_lun);
+			    (uintmax_t)ccb->ccb_h.target_lun);
 
 			/* host specific information */
 			cpi->version_num = 1;
@@ -2365,9 +2363,9 @@ umass_cam_action(struct cam_sim *sim, union ccb *ccb)
 		}
 	case XPT_RESET_DEV:
 		{
-			DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:XPT_RESET_DEV:.\n",
+			DPRINTF(sc, UDMASS_SCSI, "%d:%d:%jx:XPT_RESET_DEV:.\n",
 			    cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
-			    ccb->ccb_h.target_lun);
+			    (uintmax_t)ccb->ccb_h.target_lun);
 
 			umass_reset(sc);
 
@@ -2379,9 +2377,9 @@ umass_cam_action(struct cam_sim *sim, union ccb *ccb)
 		{
 			struct ccb_trans_settings *cts = &ccb->cts;
 
-			DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:XPT_GET_TRAN_SETTINGS:.\n",
+			DPRINTF(sc, UDMASS_SCSI, "%d:%d:%jx:XPT_GET_TRAN_SETTINGS:.\n",
 			    cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
-			    ccb->ccb_h.target_lun);
+			    (uintmax_t)ccb->ccb_h.target_lun);
 
 			cts->protocol = PROTO_SCSI;
 			cts->protocol_version = SCSI_REV_2;
@@ -2395,9 +2393,9 @@ umass_cam_action(struct cam_sim *sim, union ccb *ccb)
 		}
 	case XPT_SET_TRAN_SETTINGS:
 		{
-			DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:XPT_SET_TRAN_SETTINGS:.\n",
+			DPRINTF(sc, UDMASS_SCSI, "%d:%d:%jx:XPT_SET_TRAN_SETTINGS:.\n",
 			    cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
-			    ccb->ccb_h.target_lun);
+			    (uintmax_t)ccb->ccb_h.target_lun);
 
 			ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
 			xpt_done(ccb);
@@ -2413,19 +2411,19 @@ umass_cam_action(struct cam_sim *sim, union ccb *ccb)
 #endif /* __rtems__ */
 	case XPT_NOOP:
 		{
-			DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:XPT_NOOP:.\n",
+			DPRINTF(sc, UDMASS_SCSI, "%d:%d:%jx:XPT_NOOP:.\n",
 			    sc ? cam_sim_path(sc->sc_sim) : -1, ccb->ccb_h.target_id,
-			    ccb->ccb_h.target_lun);
+			    (uintmax_t)ccb->ccb_h.target_lun);
 
 			ccb->ccb_h.status = CAM_REQ_CMP;
 			xpt_done(ccb);
 			break;
 		}
 	default:
-		DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:func_code 0x%04x: "
+		DPRINTF(sc, UDMASS_SCSI, "%d:%d:%jx:func_code 0x%04x: "
 		    "Not implemented\n",
 		    sc ? cam_sim_path(sc->sc_sim) : -1, ccb->ccb_h.target_id,
-		    ccb->ccb_h.target_lun, ccb->ccb_h.func_code);
+		    (uintmax_t)ccb->ccb_h.target_lun, ccb->ccb_h.func_code);
 
 		ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
 		xpt_done(ccb);
@@ -2710,8 +2708,7 @@ umass_rbc_transform(struct umass_softc *sc, uint8_t *cmd_ptr, uint8_t cmd_len)
 	case START_STOP_UNIT:
 	case SYNCHRONIZE_CACHE:
 	case WRITE_10:
-	case 0x2f:			/* VERIFY_10 is absent from
-					 * scsi_all.h??? */
+	case VERIFY_10:
 	case INQUIRY:
 	case MODE_SELECT_10:
 	case MODE_SENSE_10:
diff --git a/freebsd/sys/dev/usb/ufm_ioctl.h b/freebsd/sys/dev/usb/ufm_ioctl.h
index 921b3d4..5a23388 100644
--- a/freebsd/sys/dev/usb/ufm_ioctl.h
+++ b/freebsd/sys/dev/usb/ufm_ioctl.h
@@ -1,3 +1,4 @@
+/* $FreeBSD$ */
 /*-
  * Copyright (c) 2001 M. Warner Losh
  * All rights reserved.
@@ -28,7 +29,8 @@
  * its contributors.
  */
 
-/*  $FreeBSD$ */
+#ifndef _UFM_IOCTL_H_
+#define	_UFM_IOCTL_H_
 
 #include <sys/ioccom.h>
 
@@ -37,3 +39,5 @@
 #define	FM_START	_IOWR('U', 202, int)
 #define	FM_STOP		_IOWR('U', 203, int)
 #define	FM_GET_STAT	_IOWR('U', 204, int)
+
+#endif			/* _UFM_IOCTL_H_ */
diff --git a/freebsd/sys/dev/usb/usb.h b/freebsd/sys/dev/usb/usb.h
index bb5a60c..95b4f4a 100644
--- a/freebsd/sys/dev/usb/usb.h
+++ b/freebsd/sys/dev/usb/usb.h
@@ -40,22 +40,27 @@
 #define	_USB_STANDARD_H_
 
 #if defined(_KERNEL)
+#ifndef USB_GLOBAL_INCLUDE_FILE
 #include <rtems/bsd/local/opt_usb.h>
+#endif
 
 /* Declare parent SYSCTL USB node. */
 #ifdef SYSCTL_DECL
 SYSCTL_DECL(_hw_usb);
 #endif
 
+#ifndef USB_GLOBAL_INCLUDE_FILE
 #include <sys/malloc.h>
+#endif
 
 MALLOC_DECLARE(M_USB);
 MALLOC_DECLARE(M_USBDEV);
-MALLOC_DECLARE(M_USBHC);
 #endif /* _KERNEL */
 
+#ifndef USB_GLOBAL_INCLUDE_FILE
 #include <dev/usb/usb_endian.h>
 #include <dev/usb/usb_freebsd.h>
+#endif
 
 #define	USB_STACK_VERSION 2000		/* 2.0 */
 
@@ -107,7 +112,7 @@ MALLOC_DECLARE(M_USBHC);
 
 /* Allow for marginal and non-conforming devices. */
 #define	USB_PORT_RESET_DELAY		50	/* ms */
-#define	USB_PORT_ROOT_RESET_DELAY	250	/* ms */
+#define	USB_PORT_ROOT_RESET_DELAY	200	/* ms */
 #define	USB_PORT_RESET_RECOVERY		250	/* ms */
 #define	USB_PORT_POWERUP_DELAY		300	/* ms */
 #define	USB_PORT_RESUME_DELAY		(20*2)	/* ms */
@@ -435,6 +440,7 @@ typedef struct usb_interface_assoc_descriptor usb_interface_assoc_descriptor_t;
 #define	UISUBCLASS_ETHERNET_EMULATION_MODEL 12
 #define	UISUBCLASS_NETWORK_CONTROL_MODEL 13
 
+#define	UIPROTO_CDC_NONE		0
 #define	UIPROTO_CDC_AT			1
 
 #define	UICLASS_HID		0x03
@@ -536,6 +542,11 @@ struct usb_endpoint_descriptor {
 #define	UE_ISO_ADAPT	0x08
 #define	UE_ISO_SYNC	0x0c
 #define	UE_GET_ISO_TYPE(a)	((a) & UE_ISO_TYPE)
+#define	UE_ISO_USAGE	0x30
+#define	UE_ISO_USAGE_DATA	0x00
+#define	UE_ISO_USAGE_FEEDBACK	0x10
+#define	UE_ISO_USAGE_IMPLICT_FB	0x20
+#define	UE_GET_ISO_USAGE(a)	((a) & UE_ISO_USAGE)
 	uWord	wMaxPacketSize;
 #define	UE_ZERO_MPS 0xFFFF		/* for internal use only */
 	uByte	bInterval;
@@ -547,6 +558,8 @@ struct usb_endpoint_ss_comp_descriptor {
 	uByte	bDescriptorType;
 	uByte	bMaxBurst;
 	uByte	bmAttributes;
+#define	UE_GET_BULK_STREAMS(x) ((x) & 0x0F)
+#define	UE_GET_SS_ISO_MULT(x) ((x) & 0x03)
 	uWord	wBytesPerInterval;
 } __packed;
 typedef struct usb_endpoint_ss_comp_descriptor
@@ -561,17 +574,23 @@ struct usb_string_descriptor {
 typedef struct usb_string_descriptor usb_string_descriptor_t;
 
 #define	USB_MAKE_STRING_DESC(m,name)	\
-struct name {				\
+static const struct {			\
   uByte bLength;			\
   uByte bDescriptorType;		\
   uByte bData[sizeof((uint8_t []){m})];	\
-} __packed;				\
-static const struct name name = {	\
-  .bLength = sizeof(struct name),	\
+} __packed name = {			\
+  .bLength = sizeof(name),		\
   .bDescriptorType = UDESC_STRING,	\
   .bData = { m },			\
 }
 
+struct usb_string_lang {
+	uByte bLength;
+	uByte bDescriptorType;
+	uByte bData[2];
+} __packed;
+typedef struct usb_string_lang usb_string_lang_t;
+
 struct usb_hub_descriptor {
 	uByte	bDescLength;
 	uByte	bDescriptorType;
@@ -745,7 +764,7 @@ enum usb_revision {
 #define	USB_REV_MAX	(USB_REV_3_0+1)
 
 /*
- * Supported host contoller modes.
+ * Supported host controller modes.
  */
 enum usb_hc_mode {
 	USB_MODE_HOST,		/* initiates transfers */
@@ -755,7 +774,7 @@ enum usb_hc_mode {
 #define	USB_MODE_MAX	(USB_MODE_DUAL+1)
 
 /*
- * The "USB_MODE" macros defines all the supported device states.
+ * The "USB_STATE" enums define all the supported device states.
  */
 enum usb_dev_state {
 	USB_STATE_DETACHED,
@@ -765,4 +784,18 @@ enum usb_dev_state {
 	USB_STATE_CONFIGURED,
 };
 #define	USB_STATE_MAX	(USB_STATE_CONFIGURED+1)
+
+/*
+ * The "USB_EP_MODE" macros define all the currently supported
+ * endpoint modes.
+ */
+enum usb_ep_mode {
+	USB_EP_MODE_DEFAULT,
+	USB_EP_MODE_STREAMS,	/* USB3.0 specific */
+	USB_EP_MODE_HW_MASS_STORAGE,
+	USB_EP_MODE_HW_SERIAL,
+	USB_EP_MODE_HW_ETHERNET_CDC,
+	USB_EP_MODE_HW_ETHERNET_NCM,
+	USB_EP_MODE_MAX
+};
 #endif					/* _USB_STANDARD_H_ */
diff --git a/freebsd/sys/dev/usb/usb_bus.h b/freebsd/sys/dev/usb/usb_bus.h
index 0a7350c..3ceeb1e 100644
--- a/freebsd/sys/dev/usb/usb_bus.h
+++ b/freebsd/sys/dev/usb/usb_bus.h
@@ -53,22 +53,37 @@ struct usb_bus_stat {
 struct usb_bus {
 	struct usb_bus_stat stats_err;
 	struct usb_bus_stat stats_ok;
-#ifndef __rtems__
+#if USB_HAVE_ROOT_MOUNT_HOLD
 	struct root_hold_token *bus_roothold;
-#endif /* __rtems__ */
+#endif
+
+/* convenience macros */
+#define	USB_BUS_TT_PROC(bus) USB_BUS_NON_GIANT_ISOC_PROC(bus)
+#define	USB_BUS_CS_PROC(bus) USB_BUS_NON_GIANT_ISOC_PROC(bus)
+  
+#if USB_HAVE_PER_BUS_PROCESS
+#define	USB_BUS_GIANT_PROC(bus) (&(bus)->giant_callback_proc)
+#define	USB_BUS_NON_GIANT_ISOC_PROC(bus) (&(bus)->non_giant_isoc_callback_proc)
+#define	USB_BUS_NON_GIANT_BULK_PROC(bus) (&(bus)->non_giant_bulk_callback_proc)
+#define	USB_BUS_EXPLORE_PROC(bus) (&(bus)->explore_proc)
+#define	USB_BUS_CONTROL_XFER_PROC(bus) (&(bus)->control_xfer_proc)
 	/*
-	 * There are two callback processes. One for Giant locked
-	 * callbacks. One for non-Giant locked callbacks. This should
-	 * avoid congestion and reduce response time in most cases.
+	 * There are three callback processes. One for Giant locked
+	 * callbacks. One for non-Giant locked non-periodic callbacks
+	 * and one for non-Giant locked periodic callbacks. This
+	 * should avoid congestion and reduce response time in most
+	 * cases.
 	 */
 	struct usb_process giant_callback_proc;
-	struct usb_process non_giant_callback_proc;
+	struct usb_process non_giant_isoc_callback_proc;
+	struct usb_process non_giant_bulk_callback_proc;
 
 	/* Explore process */
 	struct usb_process explore_proc;
 
 	/* Control request process */
 	struct usb_process control_xfer_proc;
+#endif
 
 	struct usb_bus_msg explore_msg[2];
 	struct usb_bus_msg detach_msg[2];
@@ -85,6 +100,7 @@ struct usb_bus {
 	 * This mutex protects the USB hardware:
 	 */
 	struct mtx bus_mtx;
+	struct mtx bus_spin_lock;
 	struct usb_xfer_queue intr_q;
 	struct usb_callout power_wdog;	/* power management */
 
@@ -95,7 +111,7 @@ struct usb_bus {
 	struct usb_dma_parent_tag dma_parent_tag[1];
 	struct usb_dma_tag dma_tags[USB_BUS_DMA_TAG_MAX];
 #endif
-	struct usb_bus_methods *methods;	/* filled by HC driver */
+	const struct usb_bus_methods *methods;	/* filled by HC driver */
 	struct usb_device **devices;
 
 	struct ifnet *ifp;	/* only for USB Packet Filter */
diff --git a/freebsd/sys/dev/usb/usb_busdma.c b/freebsd/sys/dev/usb/usb_busdma.c
index 7d98155..d8946dc 100644
--- a/freebsd/sys/dev/usb/usb_busdma.c
+++ b/freebsd/sys/dev/usb/usb_busdma.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -61,6 +64,7 @@
 
 #include <dev/usb/usb_controller.h>
 #include <dev/usb/usb_bus.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 #if USB_HAVE_BUSDMA
 static void	usb_dma_tag_create(struct usb_dma_tag *, usb_size_t, usb_size_t);
@@ -132,6 +136,35 @@ usbd_get_page(struct usb_page_cache *pc, usb_frlength_t offset,
 }
 
 /*------------------------------------------------------------------------*
+ *  usb_pc_buffer_is_aligned - verify alignment
+ * 
+ * This function is used to check if a page cache buffer is properly
+ * aligned to reduce the use of bounce buffers in PIO mode.
+ *------------------------------------------------------------------------*/
+uint8_t
+usb_pc_buffer_is_aligned(struct usb_page_cache *pc, usb_frlength_t offset,
+    usb_frlength_t len, usb_frlength_t mask)
+{
+	struct usb_page_search buf_res;
+
+	while (len != 0) {
+
+		usbd_get_page(pc, offset, &buf_res);
+
+		if (buf_res.length > len)
+			buf_res.length = len;
+		if (USB_P2U(buf_res.buffer) & mask)
+			return (0);
+		if (buf_res.length & mask)
+			return (0);
+
+		offset += buf_res.length;
+		len -= buf_res.length;
+	}
+	return (1);
+}
+
+/*------------------------------------------------------------------------*
  *  usbd_copy_in - copy directly to DMA-able memory
  *------------------------------------------------------------------------*/
 void
@@ -441,9 +474,13 @@ usb_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs,
 	pc->page_offset_buf = rem;
 	pc->page_offset_end += rem;
 #ifdef USB_DEBUG
-	if (rem != (USB_P2U(pc->buffer) & (USB_PAGE_SIZE - 1))) {
+	if (nseg > 1 &&
+	    ((segs->ds_addr + segs->ds_len) & (USB_PAGE_SIZE - 1)) !=
+	    ((segs + 1)->ds_addr & (USB_PAGE_SIZE - 1))) {
 		/*
-		 * This check verifies that the physical address is correct:
+		 * This check verifies there is no page offset hole
+		 * between the first and second segment. See the
+		 * BUS_DMA_KEEP_PG_OFFSET flag.
 		 */
 		DPRINTFN(0, "Page offset was not preserved\n");
 		error = 1;
diff --git a/freebsd/sys/dev/usb/usb_busdma.h b/freebsd/sys/dev/usb/usb_busdma.h
index ee420bc..077bf8b 100644
--- a/freebsd/sys/dev/usb/usb_busdma.h
+++ b/freebsd/sys/dev/usb/usb_busdma.h
@@ -27,10 +27,12 @@
 #ifndef _USB_BUSDMA_H_
 #define	_USB_BUSDMA_H_
 
+#ifndef USB_GLOBAL_INCLUDE_FILE
 #include <sys/uio.h>
 #include <sys/mbuf.h>
 
 #include <machine/bus.h>
+#endif
 
 /* defines */
 
@@ -157,5 +159,8 @@ void	usb_pc_cpu_flush(struct usb_page_cache *pc);
 void	usb_pc_cpu_invalidate(struct usb_page_cache *pc);
 void	usb_pc_dmamap_destroy(struct usb_page_cache *pc);
 void	usb_pc_free_mem(struct usb_page_cache *pc);
+uint8_t	usb_pc_buffer_is_aligned(struct usb_page_cache *pc,
+	    usb_frlength_t offset, usb_frlength_t len,
+	    usb_frlength_t mask);
 
 #endif					/* _USB_BUSDMA_H_ */
diff --git a/freebsd/sys/dev/usb/usb_controller.h b/freebsd/sys/dev/usb/usb_controller.h
index f23ade2..6a2f6b0 100644
--- a/freebsd/sys/dev/usb/usb_controller.h
+++ b/freebsd/sys/dev/usb/usb_controller.h
@@ -107,7 +107,8 @@ struct usb_bus_methods {
 	/* USB Device mode only - Mandatory */
 
 	void    (*get_hw_ep_profile) (struct usb_device *udev, const struct usb_hw_ep_profile **ppf, uint8_t ep_addr);
-	void    (*set_stall) (struct usb_device *udev, struct usb_xfer *xfer, struct usb_endpoint *ep, uint8_t *did_stall);
+	void    (*xfer_stall) (struct usb_xfer *xfer);
+	void    (*set_stall) (struct usb_device *udev, struct usb_endpoint *ep, uint8_t *did_stall);
 
 	/* USB Device mode mandatory. USB Host mode optional. */
 
@@ -142,6 +143,10 @@ struct usb_bus_methods {
 	/* Optional for host mode */
 
 	usb_error_t	(*set_address) (struct usb_device *, struct mtx *, uint16_t);
+
+	/* Optional for device and host mode */
+
+	usb_error_t	(*set_endpoint_mode) (struct usb_device *, struct usb_endpoint *, uint8_t);
 };
 
 /*
diff --git a/freebsd/sys/dev/usb/usb_core.c b/freebsd/sys/dev/usb/usb_core.c
index 80f5ecd..7bc784e 100644
--- a/freebsd/sys/dev/usb/usb_core.c
+++ b/freebsd/sys/dev/usb/usb_core.c
@@ -32,6 +32,9 @@
  * http://www.usb.org/developers/devclass_docs/
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -53,9 +56,14 @@
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
+
+const struct usb_string_lang usb_string_lang_en = {
+	sizeof(usb_string_lang_en), UDESC_STRING,
+	{ 0x09, 0x04 } /* American English */
+};
 
 MALLOC_DEFINE(M_USB, "USB", "USB");
 MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device");
-MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
 
 MODULE_VERSION(usb, 1);
diff --git a/freebsd/sys/dev/usb/usb_core.h b/freebsd/sys/dev/usb/usb_core.h
index 287e69f..739a003 100644
--- a/freebsd/sys/dev/usb/usb_core.h
+++ b/freebsd/sys/dev/usb/usb_core.h
@@ -44,6 +44,9 @@
 #define	USB_BUS_LOCK(_b)		mtx_lock(&(_b)->bus_mtx)
 #define	USB_BUS_UNLOCK(_b)		mtx_unlock(&(_b)->bus_mtx)
 #define	USB_BUS_LOCK_ASSERT(_b, _t)	mtx_assert(&(_b)->bus_mtx, _t)
+#define	USB_BUS_SPIN_LOCK(_b)		mtx_lock_spin(&(_b)->bus_spin_lock)
+#define	USB_BUS_SPIN_UNLOCK(_b)		mtx_unlock_spin(&(_b)->bus_spin_lock)
+#define	USB_BUS_SPIN_LOCK_ASSERT(_b, _t)	mtx_assert(&(_b)->bus_spin_lock, _t)
 #define	USB_XFER_LOCK(_x)		mtx_lock((_x)->xroot->xfer_mtx)
 #define	USB_XFER_UNLOCK(_x)		mtx_unlock((_x)->xroot->xfer_mtx)
 #define	USB_XFER_LOCK_ASSERT(_x, _t)	mtx_assert((_x)->xroot->xfer_mtx, _t)
@@ -69,6 +72,7 @@ struct usb_page;
 struct usb_page_cache;
 struct usb_xfer;
 struct usb_xfer_root;
+struct usb_string_lang;
 
 /* typedefs */
 
@@ -154,6 +158,7 @@ struct usb_xfer {
 	usb_frcount_t nframes;		/* number of USB frames to transfer */
 	usb_frcount_t aframes;		/* actual number of USB frames
 					 * transferred */
+	usb_stream_t stream_id;		/* USB3.0 specific field */
 
 	uint16_t max_packet_size;
 	uint16_t max_frame_size;
@@ -176,6 +181,7 @@ struct usb_xfer {
 /* external variables */
 
 extern struct mtx usb_ref_lock;
+extern const struct usb_string_lang usb_string_lang_en;
 
 /* typedefs */
 
diff --git a/freebsd/sys/dev/usb/usb_debug.c b/freebsd/sys/dev/usb/usb_debug.c
index ab949ec..3d5ddcd 100644
--- a/freebsd/sys/dev/usb/usb_debug.c
+++ b/freebsd/sys/dev/usb/usb_debug.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -57,6 +60,7 @@
 
 #include <ddb/ddb.h>
 #include <ddb/db_sym.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 /*
  * Define this unconditionally in case a kernel module is loaded that
@@ -65,9 +69,8 @@
 int	usb_debug = 0;
 
 SYSCTL_NODE(_hw, OID_AUTO, usb, CTLFLAG_RW, 0, "USB debugging");
-SYSCTL_INT(_hw_usb, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_INT(_hw_usb, OID_AUTO, debug, CTLFLAG_RWTUN,
     &usb_debug, 0, "Debug level");
-TUNABLE_INT("hw.usb.debug", &usb_debug);
 
 #ifdef USB_DEBUG
 /*
@@ -76,44 +79,34 @@ TUNABLE_INT("hw.usb.debug", &usb_debug);
 static SYSCTL_NODE(_hw_usb, OID_AUTO, timings, CTLFLAG_RW, 0, "Timings");
 static int usb_timings_sysctl_handler(SYSCTL_HANDLER_ARGS);
 
-TUNABLE_INT("hw.usb.timings.port_reset_delay", (int *)&usb_port_reset_delay);
-SYSCTL_PROC(_hw_usb_timings, OID_AUTO, port_reset_delay, CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_PROC(_hw_usb_timings, OID_AUTO, port_reset_delay, CTLTYPE_UINT | CTLFLAG_RWTUN,
     &usb_port_reset_delay, sizeof(usb_port_reset_delay),
     usb_timings_sysctl_handler, "IU", "Port Reset Delay");
-TUNABLE_INT("hw.usb.timings.port_root_reset_delay", (int *)&usb_port_root_reset_delay);
-SYSCTL_PROC(_hw_usb_timings, OID_AUTO, port_root_reset_delay, CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_PROC(_hw_usb_timings, OID_AUTO, port_root_reset_delay, CTLTYPE_UINT | CTLFLAG_RWTUN,
     &usb_port_root_reset_delay, sizeof(usb_port_root_reset_delay),
     usb_timings_sysctl_handler, "IU", "Root Port Reset Delay");
-TUNABLE_INT("hw.usb.timings.port_reset_recovery", (int *)&usb_port_reset_recovery);
-SYSCTL_PROC(_hw_usb_timings, OID_AUTO, port_reset_recovery, CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_PROC(_hw_usb_timings, OID_AUTO, port_reset_recovery, CTLTYPE_UINT | CTLFLAG_RWTUN,
     &usb_port_reset_recovery, sizeof(usb_port_reset_recovery),
     usb_timings_sysctl_handler, "IU", "Port Reset Recovery");
-TUNABLE_INT("hw.usb.timings.port_powerup_delay", (int *)&usb_port_powerup_delay);
-SYSCTL_PROC(_hw_usb_timings, OID_AUTO, port_powerup_delay, CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_PROC(_hw_usb_timings, OID_AUTO, port_powerup_delay, CTLTYPE_UINT | CTLFLAG_RWTUN,
     &usb_port_powerup_delay, sizeof(usb_port_powerup_delay),
     usb_timings_sysctl_handler, "IU", "Port PowerUp Delay");
-TUNABLE_INT("hw.usb.timings.port_resume_delay", (int *)&usb_port_resume_delay);
-SYSCTL_PROC(_hw_usb_timings, OID_AUTO, port_resume_delay, CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_PROC(_hw_usb_timings, OID_AUTO, port_resume_delay, CTLTYPE_UINT | CTLFLAG_RWTUN,
     &usb_port_resume_delay, sizeof(usb_port_resume_delay),
     usb_timings_sysctl_handler, "IU", "Port Resume Delay");
-TUNABLE_INT("hw.usb.timings.set_address_settle", (int *)&usb_set_address_settle);
-SYSCTL_PROC(_hw_usb_timings, OID_AUTO, set_address_settle, CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_PROC(_hw_usb_timings, OID_AUTO, set_address_settle, CTLTYPE_UINT | CTLFLAG_RWTUN,
     &usb_set_address_settle, sizeof(usb_set_address_settle),
     usb_timings_sysctl_handler, "IU", "Set Address Settle");
-TUNABLE_INT("hw.usb.timings.resume_delay", (int *)&usb_resume_delay);
-SYSCTL_PROC(_hw_usb_timings, OID_AUTO, resume_delay, CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_PROC(_hw_usb_timings, OID_AUTO, resume_delay, CTLTYPE_UINT | CTLFLAG_RWTUN,
     &usb_resume_delay, sizeof(usb_resume_delay),
     usb_timings_sysctl_handler, "IU", "Resume Delay");
-TUNABLE_INT("hw.usb.timings.resume_wait", (int *)&usb_resume_wait);
-SYSCTL_PROC(_hw_usb_timings, OID_AUTO, resume_wait, CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_PROC(_hw_usb_timings, OID_AUTO, resume_wait, CTLTYPE_UINT | CTLFLAG_RWTUN,
     &usb_resume_wait, sizeof(usb_resume_wait),
     usb_timings_sysctl_handler, "IU", "Resume Wait");
-TUNABLE_INT("hw.usb.timings.resume_recovery", (int *)&usb_resume_recovery);
-SYSCTL_PROC(_hw_usb_timings, OID_AUTO, resume_recovery, CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_PROC(_hw_usb_timings, OID_AUTO, resume_recovery, CTLTYPE_UINT | CTLFLAG_RWTUN,
     &usb_resume_recovery, sizeof(usb_resume_recovery),
     usb_timings_sysctl_handler, "IU", "Resume Recovery");
-TUNABLE_INT("hw.usb.timings.extra_power_up_time", (int *)&usb_extra_power_up_time);
-SYSCTL_PROC(_hw_usb_timings, OID_AUTO, extra_power_up_time, CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_PROC(_hw_usb_timings, OID_AUTO, extra_power_up_time, CTLTYPE_UINT | CTLFLAG_RWTUN,
     &usb_extra_power_up_time, sizeof(usb_extra_power_up_time),
     usb_timings_sysctl_handler, "IU", "Extra PowerUp Time");
 #endif
@@ -163,10 +156,12 @@ void
 usb_dump_queue(struct usb_endpoint *ep)
 {
 	struct usb_xfer *xfer;
+	usb_stream_t x;
 
 	printf("usb_dump_queue: endpoint=%p xfer: ", ep);
-	TAILQ_FOREACH(xfer, &ep->endpoint_q.head, wait_entry) {
-		printf(" %p", xfer);
+	for (x = 0; x != USB_MAX_EP_STREAMS; x++) {
+		TAILQ_FOREACH(xfer, &ep->endpoint_q[x].head, wait_entry)
+			printf(" %p", xfer);
 	}
 	printf("\n");
 }
diff --git a/freebsd/sys/dev/usb/usb_debug.h b/freebsd/sys/dev/usb/usb_debug.h
index 038ba7f..e30f2c2 100644
--- a/freebsd/sys/dev/usb/usb_debug.h
+++ b/freebsd/sys/dev/usb/usb_debug.h
@@ -38,7 +38,7 @@ extern int usb_debug;
 #define	DPRINTFN(n,fmt,...) do {		\
   if ((USB_DEBUG_VAR) >= (n)) {			\
     printf("%s: " fmt,				\
-	   __FUNCTION__,## __VA_ARGS__);	\
+	   __FUNCTION__ ,##__VA_ARGS__);	\
   }						\
 } while (0)
 #define	DPRINTF(...)	DPRINTFN(1, __VA_ARGS__)
diff --git a/freebsd/sys/dev/usb/usb_dev.c b/freebsd/sys/dev/usb/usb_dev.c
index ce107cf..bd2941a 100644
--- a/freebsd/sys/dev/usb/usb_dev.c
+++ b/freebsd/sys/dev/usb/usb_dev.c
@@ -29,6 +29,9 @@
  * usb_dev.c - An abstraction layer for creating devices under /dev/...
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -77,6 +80,7 @@
 #include <sys/syscallsubr.h>
 
 #include <machine/stdarg.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 #if USB_HAVE_UGEN
 
@@ -84,9 +88,8 @@
 static int usb_fifo_debug = 0;
 
 static SYSCTL_NODE(_hw_usb, OID_AUTO, dev, CTLFLAG_RW, 0, "USB device");
-SYSCTL_INT(_hw_usb_dev, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_INT(_hw_usb_dev, OID_AUTO, debug, CTLFLAG_RWTUN,
     &usb_fifo_debug, 0, "Debug Level");
-TUNABLE_INT("hw.usb.dev.debug", &usb_fifo_debug);
 #endif
 
 #if ((__FreeBSD_version >= 700001) || (__FreeBSD_version == 0) || \
@@ -829,7 +832,8 @@ usb_fifo_close(struct usb_fifo *f, int fflags)
 			    (!f->flag_iserror)) {
 				/* wait until all data has been written */
 				f->flag_sleeping = 1;
-				err = cv_wait_sig(&f->cv_io, f->priv_mtx);
+				err = cv_timedwait_sig(&f->cv_io, f->priv_mtx,
+				    USB_MS_TO_TICKS(USB_DEFAULT_TIMEOUT));
 				if (err) {
 					DPRINTF("signal received\n");
 					break;
diff --git a/freebsd/sys/dev/usb/usb_dev.h b/freebsd/sys/dev/usb/usb_dev.h
index 9a7cf21..f87ba53 100644
--- a/freebsd/sys/dev/usb/usb_dev.h
+++ b/freebsd/sys/dev/usb/usb_dev.h
@@ -27,11 +27,13 @@
 #ifndef _USB_DEV_H_
 #define	_USB_DEV_H_
 
+#ifndef USB_GLOBAL_INCLUDE_FILE
 #include <sys/file.h>
 #include <sys/selinfo.h>
 #include <sys/poll.h>
 #include <sys/signalvar.h>
 #include <sys/proc.h>
+#endif
 
 struct usb_fifo;
 struct usb_mbuf;
diff --git a/freebsd/sys/dev/usb/usb_device.c b/freebsd/sys/dev/usb/usb_device.c
index 8e0144c..d7789d0 100644
--- a/freebsd/sys/dev/usb/usb_device.c
+++ b/freebsd/sys/dev/usb/usb_device.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -80,6 +83,7 @@
 
 #include <dev/usb/usb_controller.h>
 #include <dev/usb/usb_bus.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 /* function prototypes  */
 
@@ -110,11 +114,14 @@ static void	usb_cdev_free(struct usb_device *);
 
 /* This variable is global to allow easy access to it: */
 
-int	usb_template = 0;
+#ifdef	USB_TEMPLATE
+int	usb_template = USB_TEMPLATE;
+#else
+int	usb_template;
+#endif
 
 #ifndef __rtems__
-TUNABLE_INT("hw.usb.usb_template", &usb_template);
-SYSCTL_INT(_hw_usb, OID_AUTO, template, CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_INT(_hw_usb, OID_AUTO, template, CTLFLAG_RWTUN,
     &usb_template, 0, "Selected USB device side template");
 #endif /* __rtems__ */
 
@@ -124,12 +131,10 @@ static int usb_lang_id = 0x0009;
 static int usb_lang_mask = 0x00FF;
 
 #ifndef __rtems__
-TUNABLE_INT("hw.usb.usb_lang_id", &usb_lang_id);
-SYSCTL_INT(_hw_usb, OID_AUTO, usb_lang_id, CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_INT(_hw_usb, OID_AUTO, usb_lang_id, CTLFLAG_RWTUN,
     &usb_lang_id, 0, "Preferred USB language ID");
 
-TUNABLE_INT("hw.usb.usb_lang_mask", &usb_lang_mask);
-SYSCTL_INT(_hw_usb, OID_AUTO, usb_lang_mask, CTLFLAG_RW | CTLFLAG_TUN,
+SYSCTL_INT(_hw_usb, OID_AUTO, usb_lang_mask, CTLFLAG_RWTUN,
     &usb_lang_mask, 0, "Preferred USB language mask");
 #endif /* __rtems__ */
 
@@ -208,7 +213,7 @@ usbd_get_ep_by_addr(struct usb_device *udev, uint8_t ea_val)
 	/*
 	 * The default endpoint is always present and is checked separately:
 	 */
-	if ((udev->ctrl_ep.edesc) &&
+	if ((udev->ctrl_ep.edesc != NULL) &&
 	    ((udev->ctrl_ep.edesc->bEndpointAddress & EA_MASK) == ea_val)) {
 		ep = &udev->ctrl_ep;
 		goto found;
@@ -326,7 +331,7 @@ usbd_get_endpoint(struct usb_device *udev, uint8_t iface_index,
 	 * address" and "any direction" returns the first endpoint of the
 	 * interface. "iface_index" and "direction" is ignored:
 	 */
-	if ((udev->ctrl_ep.edesc) &&
+	if ((udev->ctrl_ep.edesc != NULL) &&
 	    ((udev->ctrl_ep.edesc->bEndpointAddress & ea_mask) == ea_val) &&
 	    ((udev->ctrl_ep.edesc->bmAttributes & type_mask) == type_val) &&
 	    (!index)) {
@@ -361,7 +366,6 @@ usbd_interface_count(struct usb_device *udev, uint8_t *count)
 	return (USB_ERR_NORMAL_COMPLETION);
 }
 
-
 /*------------------------------------------------------------------------*
  *	usb_init_endpoint
  *
@@ -375,7 +379,8 @@ usb_init_endpoint(struct usb_device *udev, uint8_t iface_index,
     struct usb_endpoint_ss_comp_descriptor *ecomp,
     struct usb_endpoint *ep)
 {
-	struct usb_bus_methods *methods;
+	const struct usb_bus_methods *methods;
+	usb_stream_t x;
 
 	methods = udev->bus->methods;
 
@@ -385,13 +390,26 @@ usb_init_endpoint(struct usb_device *udev, uint8_t iface_index,
 	ep->edesc = edesc;
 	ep->ecomp = ecomp;
 	ep->iface_index = iface_index;
-	TAILQ_INIT(&ep->endpoint_q.head);
-	ep->endpoint_q.command = &usbd_pipe_start;
+
+	/* setup USB stream queues */
+	for (x = 0; x != USB_MAX_EP_STREAMS; x++) {
+		TAILQ_INIT(&ep->endpoint_q[x].head);
+		ep->endpoint_q[x].command = &usbd_pipe_start;
+	}
 
 	/* the pipe is not supported by the hardware */
  	if (ep->methods == NULL)
 		return;
 
+	/* check for SUPER-speed streams mode endpoint */
+	if (udev->speed == USB_SPEED_SUPER && ecomp != NULL &&
+	    (edesc->bmAttributes & UE_XFERTYPE) == UE_BULK &&
+	    (UE_GET_BULK_STREAMS(ecomp->bmAttributes) != 0)) {
+		usbd_set_endpoint_mode(udev, ep, USB_EP_MODE_STREAMS);
+	} else {
+		usbd_set_endpoint_mode(udev, ep, USB_EP_MODE_DEFAULT);
+	}
+
 	/* clear stall, if any */
 	if (methods->clear_stall != NULL) {
 		USB_BUS_LOCK(udev->bus);
@@ -494,8 +512,8 @@ usb_unconfigure(struct usb_device *udev, uint8_t flag)
 
 #if USB_HAVE_COMPAT_LINUX
 	/* free Linux compat device, if any */
-	if (udev->linux_endpoint_start) {
-		usb_linux_free_device(udev);
+	if (udev->linux_endpoint_start != NULL) {
+		usb_linux_free_device_p(udev);
 		udev->linux_endpoint_start = NULL;
 	}
 #endif
@@ -505,7 +523,7 @@ usb_unconfigure(struct usb_device *udev, uint8_t flag)
 	/* free "cdesc" after "ifaces" and "endpoints", if any */
 	if (udev->cdesc != NULL) {
 		if (udev->flags.usb_mode != USB_MODE_DEVICE)
-			free(udev->cdesc, M_USB);
+			usbd_free_config_desc(udev, udev->cdesc);
 		udev->cdesc = NULL;
 	}
 	/* set unconfigured state */
@@ -564,7 +582,7 @@ usbd_set_config_index(struct usb_device *udev, uint8_t index)
 	} else {
 		/* normal request */
 		err = usbd_req_get_config_desc_full(udev,
-		    NULL, &cdp, M_USB, index);
+		    NULL, &cdp, index);
 	}
 	if (err) {
 		goto done;
@@ -741,10 +759,6 @@ usb_config_parse(struct usb_device *udev, uint8_t iface_index, uint8_t cmd)
 
 	while ((id = usb_idesc_foreach(udev->cdesc, &ips))) {
 
-		/* check for interface overflow */
-		if (ips.iface_index == USB_IFACE_MAX)
-			break;			/* crazy */
-
 		iface = udev->ifaces + ips.iface_index;
 
 		/* check for specific interface match */
@@ -791,8 +805,11 @@ usb_config_parse(struct usb_device *udev, uint8_t iface_index, uint8_t cmd)
 		/* iterate all the endpoint descriptors */
 		while ((ed = usb_edesc_foreach(udev->cdesc, ed))) {
 
-			if (temp == USB_EP_MAX)
-				break;			/* crazy */
+			/* check if endpoint limit has been reached */
+			if (temp >= USB_MAX_EP_UNITS) {
+				DPRINTF("Endpoint limit reached\n");
+				break;
+			}
 
 			ep = udev->endpoints + temp;
 
@@ -819,6 +836,7 @@ usb_config_parse(struct usb_device *udev, uint8_t iface_index, uint8_t cmd)
 
 	if (cmd == USB_CFG_ALLOC) {
 		udev->ifaces_max = ips.iface_index;
+#if (USB_HAVE_FIXED_IFACE == 0)
 		udev->ifaces = NULL;
 		if (udev->ifaces_max != 0) {
 			udev->ifaces = malloc(sizeof(*iface) * udev->ifaces_max,
@@ -828,6 +846,8 @@ usb_config_parse(struct usb_device *udev, uint8_t iface_index, uint8_t cmd)
 				goto done;
 			}
 		}
+#endif
+#if (USB_HAVE_FIXED_ENDPOINT == 0)
 		if (ep_max != 0) {
 			udev->endpoints = malloc(sizeof(*ep) * ep_max,
 			        M_USB, M_WAITOK | M_ZERO);
@@ -838,14 +858,16 @@ usb_config_parse(struct usb_device *udev, uint8_t iface_index, uint8_t cmd)
 		} else {
 			udev->endpoints = NULL;
 		}
+#endif
 		USB_BUS_LOCK(udev->bus);
 		udev->endpoints_max = ep_max;
 		/* reset any ongoing clear-stall */
 		udev->ep_curr = NULL;
 		USB_BUS_UNLOCK(udev->bus);
 	}
-
+#if (USB_HAVE_FIXED_IFACE == 0) || (USB_HAVE_FIXED_ENDPOINT == 0) 
 done:
+#endif
 	if (err) {
 		if (cmd == USB_CFG_ALLOC) {
 cleanup:
@@ -855,14 +877,14 @@ cleanup:
 			udev->ep_curr = NULL;
 			USB_BUS_UNLOCK(udev->bus);
 
-			/* cleanup */
-			if (udev->ifaces != NULL)
-				free(udev->ifaces, M_USB);
-			if (udev->endpoints != NULL)
-				free(udev->endpoints, M_USB);
-
+#if (USB_HAVE_FIXED_IFACE == 0)
+			free(udev->ifaces, M_USB);
 			udev->ifaces = NULL;
+#endif
+#if (USB_HAVE_FIXED_ENDPOINT == 0)
+			free(udev->endpoints, M_USB);
 			udev->endpoints = NULL;
+#endif
 			udev->ifaces_max = 0;
 		}
 	}
@@ -948,6 +970,7 @@ usbd_set_endpoint_stall(struct usb_device *udev, struct usb_endpoint *ep,
     uint8_t do_stall)
 {
 	struct usb_xfer *xfer;
+	usb_stream_t x;
 	uint8_t et;
 	uint8_t was_stalled;
 
@@ -990,18 +1013,22 @@ usbd_set_endpoint_stall(struct usb_device *udev, struct usb_endpoint *ep,
 
 	if (do_stall || (!was_stalled)) {
 		if (!was_stalled) {
-			/* lookup the current USB transfer, if any */
-			xfer = ep->endpoint_q.curr;
-		} else {
-			xfer = NULL;
+			for (x = 0; x != USB_MAX_EP_STREAMS; x++) {
+				/* lookup the current USB transfer, if any */
+				xfer = ep->endpoint_q[x].curr;
+				if (xfer != NULL) {
+					/*
+					 * The "xfer_stall" method
+					 * will complete the USB
+					 * transfer like in case of a
+					 * timeout setting the error
+					 * code "USB_ERR_STALLED".
+					 */
+					(udev->bus->methods->xfer_stall) (xfer);
+				}
+			}
 		}
-
-		/*
-		 * If "xfer" is non-NULL the "set_stall" method will
-		 * complete the USB transfer like in case of a timeout
-		 * setting the error code "USB_ERR_STALLED".
-		 */
-		(udev->bus->methods->set_stall) (udev, xfer, ep, &do_stall);
+		(udev->bus->methods->set_stall) (udev, ep, &do_stall);
 	}
 	if (!do_stall) {
 		ep->toggle_next = 0;	/* reset data toggle */
@@ -1009,8 +1036,11 @@ usbd_set_endpoint_stall(struct usb_device *udev, struct usb_endpoint *ep,
 
 		(udev->bus->methods->clear_stall) (udev, ep);
 
-		/* start up the current or next transfer, if any */
-		usb_command_wrapper(&ep->endpoint_q, ep->endpoint_q.curr);
+		/* start the current or next transfer, if any */
+		for (x = 0; x != USB_MAX_EP_STREAMS; x++) {
+			usb_command_wrapper(&ep->endpoint_q[x],
+			    ep->endpoint_q[x].curr);
+		}
 	}
 	USB_BUS_UNLOCK(udev->bus);
 	return (0);
@@ -1319,6 +1349,12 @@ usb_probe_and_attach(struct usb_device *udev, uint8_t iface_index)
 	 */
 	if (iface_index == USB_IFACE_INDEX_ANY) {
 
+		if (usb_test_quirk(&uaa, UQ_MSC_DYMO_EJECT) != 0 &&
+		    usb_dymo_eject(udev, 0) == 0) {
+			/* success, mark the udev as disappearing */
+			uaa.dev_state = UAA_DEV_EJECTING;
+		}
+
 		EVENTHANDLER_INVOKE(usb_dev_configured, udev, &uaa);
 
 		if (uaa.dev_state != UAA_DEV_READY) {
@@ -1861,6 +1897,7 @@ repeat_set_config:
 			config_index++;
 			goto repeat_set_config;
 		}
+#if USB_HAVE_MSCTEST
 		if (config_index == 0) {
 			/*
 			 * Try to figure out if we have an
@@ -1873,7 +1910,9 @@ repeat_set_config:
 				goto repeat_set_config;
 			}
 		}
+#endif
 	}
+#if USB_HAVE_MSCTEST
 	if (set_config_failed == 0 && config_index == 0 &&
 	    usb_test_quirk(&uaa, UQ_MSC_NO_SYNC_CACHE) == 0 &&
 	    usb_test_quirk(&uaa, UQ_MSC_NO_GETMAXLUN) == 0) {
@@ -1889,6 +1928,7 @@ repeat_set_config:
 			goto repeat_set_config;
 		}
 	}
+#endif
 
 config_done:
 	DPRINTF("new dev (addr %d), udev=%p, parent_hub=%p\n",
@@ -1998,7 +2038,7 @@ usb_destroy_dev(struct usb_fs_privdata *pd)
 	USB_BUS_LOCK(bus);
 	LIST_INSERT_HEAD(&bus->pd_cleanup_list, pd, pd_next);
 	/* get cleanup going */
-	usb_proc_msignal(&bus->explore_proc,
+	usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
 	    &bus->cleanup_msg[0], &bus->cleanup_msg[1]);
 	USB_BUS_UNLOCK(bus);
 }
@@ -2147,7 +2187,7 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
 	 * anywhere:
 	 */
 	USB_BUS_LOCK(udev->bus);
-	usb_proc_mwait(&udev->bus->non_giant_callback_proc,
+	usb_proc_mwait(USB_BUS_CS_PROC(udev->bus),
 	    &udev->cs_msg[0], &udev->cs_msg[1]);
 	USB_BUS_UNLOCK(udev->bus);
 
@@ -2811,3 +2851,41 @@ usbd_add_dynamic_quirk(struct usb_device *udev, uint16_t quirk)
 	}
 	return (USB_ERR_NOMEM);
 }
+
+/*
+ * The following function is used to select the endpoint mode. It
+ * should not be called outside enumeration context.
+ */
+
+usb_error_t
+usbd_set_endpoint_mode(struct usb_device *udev, struct usb_endpoint *ep,
+    uint8_t ep_mode)
+{   
+	usb_error_t error;
+	uint8_t do_unlock;
+
+	/* Prevent re-enumeration */
+	do_unlock = usbd_enum_lock(udev);
+
+	if (udev->bus->methods->set_endpoint_mode != NULL) {
+		error = (udev->bus->methods->set_endpoint_mode) (
+		    udev, ep, ep_mode);
+	} else if (ep_mode != USB_EP_MODE_DEFAULT) {
+		error = USB_ERR_INVAL;
+	} else {
+		error = 0;
+	}
+
+	/* only set new mode regardless of error */
+	ep->ep_mode = ep_mode;
+
+	if (do_unlock)
+		usbd_enum_unlock(udev);
+	return (error);
+}
+
+uint8_t
+usbd_get_endpoint_mode(struct usb_device *udev, struct usb_endpoint *ep)
+{
+	return (ep->ep_mode);
+}
diff --git a/freebsd/sys/dev/usb/usb_device.h b/freebsd/sys/dev/usb/usb_device.h
index 309bd05..4e9dbc4 100644
--- a/freebsd/sys/dev/usb/usb_device.h
+++ b/freebsd/sys/dev/usb/usb_device.h
@@ -42,7 +42,7 @@ struct usb_symlink;		/* UGEN */
 
 #define	USB_CTRL_XFER_MAX 2
 
-/* "usb_parse_config()" commands */
+/* "usb_config_parse()" commands */
 
 #define	USB_CFG_ALLOC 0
 #define	USB_CFG_FREE 1
@@ -139,7 +139,7 @@ struct usb_hw_ep_scratch {
 	struct usb_hw_ep_scratch_sub *ep_max;
 	struct usb_config_descriptor *cd;
 	struct usb_device *udev;
-	struct usb_bus_methods *methods;
+	const struct usb_bus_methods *methods;
 	uint8_t	bmOutAlloc[(USB_EP_MAX + 15) / 16];
 	uint8_t	bmInAlloc[(USB_EP_MAX + 15) / 16];
 };
@@ -186,9 +186,17 @@ struct usb_device {
 	struct mtx device_mtx;
 	struct cv ctrlreq_cv;
 	struct cv ref_cv;
+#if (USB_HAVE_FIXED_IFACE == 0)
 	struct usb_interface *ifaces;
+#else
+	struct usb_interface ifaces[USB_IFACE_MAX];
+#endif
 	struct usb_endpoint ctrl_ep;	/* Control Endpoint 0 */
+#if (USB_HAVE_FIXED_ENDPOINT == 0)
 	struct usb_endpoint *endpoints;
+#else
+	struct usb_endpoint endpoints[USB_MAX_EP_UNITS];
+#endif
 	struct usb_power_save pwr_save;/* power save data */
 	struct usb_bus *bus;		/* our USB BUS */
 	device_t parent_dev;		/* parent device */
@@ -264,6 +272,10 @@ struct usb_device {
 	uint32_t clear_stall_errors;	/* number of clear-stall failures */
 
 	union usb_device_scratch scratch;
+
+#if (USB_HAVE_FIXED_CONFIG != 0)
+	uint32_t config_data[(USB_CONFIG_MAX + 3) / 4];
+#endif
 };
 
 /* globals */
diff --git a/freebsd/sys/dev/usb/usb_dynamic.c b/freebsd/sys/dev/usb/usb_dynamic.c
index 65c9a7d..db8a523 100644
--- a/freebsd/sys/dev/usb/usb_dynamic.c
+++ b/freebsd/sys/dev/usb/usb_dynamic.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -52,10 +55,15 @@
 #include <dev/usb/usb_process.h>
 #include <dev/usb/usb_device.h>
 #include <dev/usb/usb_dynamic.h>
+#include <dev/usb/usb_request.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 /* function prototypes */
 static usb_handle_req_t usb_temp_get_desc_w;
 static usb_temp_setup_by_index_t usb_temp_setup_by_index_w;
+#if USB_HAVE_COMPAT_LINUX
+static usb_linux_free_device_t usb_linux_free_device_w;
+#endif
 static usb_temp_unsetup_t usb_temp_unsetup_w;
 static usb_test_quirk_t usb_test_quirk_w;
 static usb_quirk_ioctl_t usb_quirk_ioctl_w;
@@ -63,6 +71,9 @@ static usb_quirk_ioctl_t usb_quirk_ioctl_w;
 /* global variables */
 usb_handle_req_t *usb_temp_get_desc_p = &usb_temp_get_desc_w;
 usb_temp_setup_by_index_t *usb_temp_setup_by_index_p = &usb_temp_setup_by_index_w;
+#if USB_HAVE_COMPAT_LINUX
+usb_linux_free_device_t *usb_linux_free_device_p = &usb_linux_free_device_w;
+#endif
 usb_temp_unsetup_t *usb_temp_unsetup_p = &usb_temp_unsetup_w;
 usb_test_quirk_t *usb_test_quirk_p = &usb_test_quirk_w;
 usb_quirk_ioctl_t *usb_quirk_ioctl_p = &usb_quirk_ioctl_w;
@@ -96,13 +107,17 @@ usb_temp_get_desc_w(struct usb_device *udev, struct usb_device_request *req, con
 static void
 usb_temp_unsetup_w(struct usb_device *udev)
 {
-	if (udev->usb_template_ptr) {
-
-		free(udev->usb_template_ptr, M_USB);
+	usbd_free_config_desc(udev, udev->usb_template_ptr);
+	udev->usb_template_ptr = NULL;
+}
 
-		udev->usb_template_ptr = NULL;
-	}
+#if USB_HAVE_COMPAT_LINUX
+static void
+usb_linux_free_device_w(struct usb_device *udev)
+{
+	/* NOP */
 }
+#endif
 
 void
 usb_quirk_unload(void *arg)
@@ -148,3 +163,19 @@ usb_bus_unload(void *arg)
 
 	pause("WAIT", hz);
 }
+
+#if USB_HAVE_COMPAT_LINUX
+void
+usb_linux_unload(void *arg)
+{
+	/* reset function pointers */
+
+	usb_linux_free_device_p = &usb_linux_free_device_w;
+  
+	/* wait for CPU to exit the loaded functions, if any */
+
+	/* XXX this is a tradeoff */
+
+	pause("WAIT", hz);
+}
+#endif
diff --git a/freebsd/sys/dev/usb/usb_dynamic.h b/freebsd/sys/dev/usb/usb_dynamic.h
index 5684942..e52c46f 100644
--- a/freebsd/sys/dev/usb/usb_dynamic.h
+++ b/freebsd/sys/dev/usb/usb_dynamic.h
@@ -42,11 +42,13 @@ typedef uint8_t		(usb_test_quirk_t)(const struct usbd_lookup_info *info,
 typedef int		(usb_quirk_ioctl_t)(unsigned long cmd, caddr_t data,
 			    int fflag, struct thread *td);
 typedef void		(usb_temp_unsetup_t)(struct usb_device *udev);
+typedef void		(usb_linux_free_device_t)(struct usb_device *udev);
 
 /* global function pointers */
 
 extern usb_handle_req_t *usb_temp_get_desc_p;
 extern usb_temp_setup_by_index_t *usb_temp_setup_by_index_p;
+extern usb_linux_free_device_t *usb_linux_free_device_p;
 extern usb_temp_unsetup_t *usb_temp_unsetup_p;
 extern usb_test_quirk_t *usb_test_quirk_p;
 extern usb_quirk_ioctl_t *usb_quirk_ioctl_p;
@@ -54,6 +56,7 @@ extern devclass_t usb_devclass_ptr;
 
 /* function prototypes */
 
+void	usb_linux_unload(void *);
 void	usb_temp_unload(void *);
 void	usb_quirk_unload(void *);
 void	usb_bus_unload(void *);
diff --git a/freebsd/sys/dev/usb/usb_endian.h b/freebsd/sys/dev/usb/usb_endian.h
index 29479f1..0bbcb9b 100644
--- a/freebsd/sys/dev/usb/usb_endian.h
+++ b/freebsd/sys/dev/usb/usb_endian.h
@@ -27,8 +27,10 @@
 #ifndef _USB_ENDIAN_H_
 #define	_USB_ENDIAN_H_
 
+#ifndef USB_GLOBAL_INCLUDE_FILE
 #include <sys/stdint.h>
 #include <sys/endian.h>
+#endif
 
 /*
  * Declare the basic USB record types. USB records have an alignment
diff --git a/freebsd/sys/dev/usb/usb_error.c b/freebsd/sys/dev/usb/usb_error.c
index f25f95e..e27fb5e 100644
--- a/freebsd/sys/dev/usb/usb_error.c
+++ b/freebsd/sys/dev/usb/usb_error.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -47,6 +50,7 @@
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 static const char* usb_errstr_table[USB_ERR_MAX] = {
 	[USB_ERR_NORMAL_COMPLETION]	= "USB_ERR_NORMAL_COMPLETION",
diff --git a/freebsd/sys/dev/usb/usb_freebsd.h b/freebsd/sys/dev/usb/usb_freebsd.h
index ed2c6bb..0d2e810 100644
--- a/freebsd/sys/dev/usb/usb_freebsd.h
+++ b/freebsd/sys/dev/usb/usb_freebsd.h
@@ -42,7 +42,16 @@
 #define	USB_HAVE_TT_SUPPORT 1
 #define	USB_HAVE_POWERD 1
 #define	USB_HAVE_MSCTEST 1
+#define	USB_HAVE_MSCTEST_DETACH 1
 #define	USB_HAVE_PF 1
+#define	USB_HAVE_ROOT_MOUNT_HOLD 1
+#define	USB_HAVE_ID_SECTION 1
+#define	USB_HAVE_PER_BUS_PROCESS 1
+#define	USB_HAVE_FIXED_ENDPOINT 0
+#define	USB_HAVE_FIXED_IFACE 0
+#define	USB_HAVE_FIXED_CONFIG 0
+#define	USB_HAVE_FIXED_PORT 0
+#define	USB_HAVE_DISABLE_ENUM 1
 #endif /* __rtems__ */
 
 /* define zero ticks callout value */
@@ -54,8 +63,12 @@
 #if (!defined(USB_HOST_ALIGN)) || (USB_HOST_ALIGN <= 0)
 /* Use default value. */
 #undef USB_HOST_ALIGN
+#if defined(__arm__) || defined(__mips__) || defined(__powerpc__)
+#define USB_HOST_ALIGN	32		/* Arm and MIPS need at least this much, if not more */
+#else
 #define	USB_HOST_ALIGN    8		/* bytes, must be power of two */
 #endif
+#endif
 /* Sanity check for USB_HOST_ALIGN: Verify power of two. */
 #if ((-USB_HOST_ALIGN) & USB_HOST_ALIGN) != USB_HOST_ALIGN
 #error "USB_HOST_ALIGN is not power of two."
@@ -63,8 +76,12 @@
 #define	USB_FS_ISOC_UFRAME_MAX 4	/* exclusive unit */
 #define	USB_BUS_MAX 256			/* units */
 #define	USB_MAX_DEVICES 128		/* units */
+#define	USB_CONFIG_MAX 65535		/* bytes */
 #define	USB_IFACE_MAX 32		/* units */
 #define	USB_FIFO_MAX 128		/* units */
+#define	USB_MAX_EP_STREAMS 8		/* units */
+#define	USB_MAX_EP_UNITS 32		/* units */
+#define	USB_MAX_PORTS 255		/* units */
 
 #define	USB_MAX_FS_ISOC_FRAMES_PER_XFER (120)	/* units */
 #define	USB_MAX_HS_ISOC_FRAMES_PER_XFER (8*120)	/* units */
@@ -81,5 +98,6 @@ typedef uint32_t usb_frcount_t;		/* units */
 typedef uint32_t usb_size_t;		/* bytes */
 typedef uint32_t usb_ticks_t;		/* system defined */
 typedef uint16_t usb_power_mask_t;	/* see "USB_HW_POWER_XXX" */
+typedef uint16_t usb_stream_t;		/* stream ID */
 
 #endif	/* _USB_FREEBSD_H_ */
diff --git a/freebsd/sys/dev/usb/usb_generic.c b/freebsd/sys/dev/usb/usb_generic.c
index d617290..c5a0377 100644
--- a/freebsd/sys/dev/usb/usb_generic.c
+++ b/freebsd/sys/dev/usb/usb_generic.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -69,6 +72,7 @@
 
 #include <dev/usb/usb_controller.h>
 #include <dev/usb/usb_bus.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 #if USB_HAVE_UGEN
 
@@ -129,9 +133,8 @@ struct usb_fifo_methods usb_ugen_methods = {
 static int ugen_debug = 0;
 
 static SYSCTL_NODE(_hw_usb, OID_AUTO, ugen, CTLFLAG_RW, 0, "USB generic");
-SYSCTL_INT(_hw_usb_ugen, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN, &ugen_debug,
+SYSCTL_INT(_hw_usb_ugen, OID_AUTO, debug, CTLFLAG_RWTUN, &ugen_debug,
     0, "Debug level");
-TUNABLE_INT("hw.usb.ugen.debug", &ugen_debug);
 #endif
 
 
@@ -254,6 +257,7 @@ ugen_open_pipe_write(struct usb_fifo *f)
 
 	usb_config[0].type = ed->bmAttributes & UE_XFERTYPE;
 	usb_config[0].endpoint = ed->bEndpointAddress & UE_ADDR;
+	usb_config[0].stream_id = 0;	/* XXX support more stream ID's */
 	usb_config[0].direction = UE_DIR_TX;
 	usb_config[0].interval = USB_DEFAULT_INTERVAL;
 	usb_config[0].flags.proxy_buffer = 1;
@@ -322,6 +326,7 @@ ugen_open_pipe_read(struct usb_fifo *f)
 
 	usb_config[0].type = ed->bmAttributes & UE_XFERTYPE;
 	usb_config[0].endpoint = ed->bEndpointAddress & UE_ADDR;
+	usb_config[0].stream_id = 0;	/* XXX support more stream ID's */
 	usb_config[0].direction = UE_DIR_RX;
 	usb_config[0].interval = USB_DEFAULT_INTERVAL;
 	usb_config[0].flags.proxy_buffer = 1;
@@ -677,18 +682,21 @@ ugen_get_cdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd)
 	if ((ugd->ugd_config_index == USB_UNCONFIG_INDEX) ||
 	    (ugd->ugd_config_index == udev->curr_config_index)) {
 		cdesc = usbd_get_config_descriptor(udev);
-		if (cdesc == NULL) {
+		if (cdesc == NULL)
 			return (ENXIO);
-		}
 		free_data = 0;
 
 	} else {
+#if (USB_HAVE_FIXED_CONFIG == 0)
 		if (usbd_req_get_config_desc_full(udev,
-		    NULL, &cdesc, M_USBDEV,
-		    ugd->ugd_config_index)) {
+		    NULL, &cdesc, ugd->ugd_config_index)) {
 			return (ENXIO);
 		}
 		free_data = 1;
+#else
+		/* configuration descriptor data is shared */
+		return (EINVAL);
+#endif
 	}
 
 	len = UGETW(cdesc->wTotalLength);
@@ -702,9 +710,9 @@ ugen_get_cdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd)
 
 	error = copyout(cdesc, ugd->ugd_data, len);
 
-	if (free_data) {
-		free(cdesc, M_USBDEV);
-	}
+	if (free_data)
+		usbd_free_config_desc(udev, cdesc);
+
 	return (error);
 }
 
@@ -1387,6 +1395,7 @@ ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
 		struct usb_fs_start *pstart;
 		struct usb_fs_stop *pstop;
 		struct usb_fs_open *popen;
+		struct usb_fs_open_stream *popen_stream;
 		struct usb_fs_close *pclose;
 		struct usb_fs_clear_stall_sync *pstall;
 		void   *addr;
@@ -1451,6 +1460,7 @@ ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
 		break;
 
 	case USB_FS_OPEN:
+	case USB_FS_OPEN_STREAM:
 		if (u.popen->ep_index >= f->fs_ep_max) {
 			error = EINVAL;
 			break;
@@ -1502,6 +1512,8 @@ ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
 		usb_config[0].frames = u.popen->max_frames;
 		usb_config[0].bufsize = u.popen->max_bufsize;
 		usb_config[0].usb_mode = USB_MODE_DUAL;	/* both modes */
+		if (cmd == USB_FS_OPEN_STREAM)
+			usb_config[0].stream_id = u.popen_stream->stream_id;
 
 		if (usb_config[0].type == UE_CONTROL) {
 			if (f->udev->flags.usb_mode != USB_MODE_HOST) {
diff --git a/freebsd/sys/dev/usb/usb_handle_request.c b/freebsd/sys/dev/usb/usb_handle_request.c
index 296548e..b746411 100644
--- a/freebsd/sys/dev/usb/usb_handle_request.c
+++ b/freebsd/sys/dev/usb/usb_handle_request.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -63,6 +66,7 @@
 
 #include <dev/usb/usb_controller.h>
 #include <dev/usb/usb_bus.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 /* function prototypes */
 
diff --git a/freebsd/sys/dev/usb/usb_hid.c b/freebsd/sys/dev/usb/usb_hid.c
index 737237b..f6591a8 100644
--- a/freebsd/sys/dev/usb/usb_hid.c
+++ b/freebsd/sys/dev/usb/usb_hid.c
@@ -1,10 +1,7 @@
 #include <machine/rtems-bsd-kernel-space.h>
 
+/* $FreeBSD$ */
 /*	$NetBSD: hid.c,v 1.17 2001/11/13 06:24:53 lukem Exp $	*/
-
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -35,6 +32,9 @@ __FBSDID("$FreeBSD$");
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/usb/usb_process.h>
 #include <dev/usb/usb_device.h>
 #include <dev/usb/usb_request.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 static void hid_clear_local(struct hid_item *);
 static uint8_t hid_get_byte(struct hid_data *s, const uint16_t wSize);
diff --git a/freebsd/sys/dev/usb/usb_hub.c b/freebsd/sys/dev/usb/usb_hub.c
index 0c62ee0..cae8377 100644
--- a/freebsd/sys/dev/usb/usb_hub.c
+++ b/freebsd/sys/dev/usb/usb_hub.c
@@ -32,6 +32,9 @@
  * USB spec: http://www.usb.org/developers/docs/usbspec.zip 
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -70,6 +73,7 @@
 
 #include <dev/usb/usb_controller.h>
 #include <dev/usb/usb_bus.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 #define	UHUB_INTR_INTERVAL 250		/* ms */
 enum {
@@ -84,18 +88,27 @@ enum {
 static int uhub_debug = 0;
 
 static SYSCTL_NODE(_hw_usb, OID_AUTO, uhub, CTLFLAG_RW, 0, "USB HUB");
-SYSCTL_INT(_hw_usb_uhub, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN, &uhub_debug, 0,
+SYSCTL_INT(_hw_usb_uhub, OID_AUTO, debug, CTLFLAG_RWTUN, &uhub_debug, 0,
     "Debug level");
-TUNABLE_INT("hw.usb.uhub.debug", &uhub_debug);
 #endif
 
 #if USB_HAVE_POWERD
 static int usb_power_timeout = 30;	/* seconds */
 
-SYSCTL_INT(_hw_usb, OID_AUTO, power_timeout, CTLFLAG_RW,
+SYSCTL_INT(_hw_usb, OID_AUTO, power_timeout, CTLFLAG_RWTUN,
     &usb_power_timeout, 0, "USB power timeout");
 #endif
 
+#if USB_HAVE_DISABLE_ENUM
+static int usb_disable_enumeration = 0;
+SYSCTL_INT(_hw_usb, OID_AUTO, disable_enumeration, CTLFLAG_RWTUN,
+    &usb_disable_enumeration, 0, "Set to disable all USB device enumeration.");
+
+static int usb_disable_port_power = 0;
+SYSCTL_INT(_hw_usb, OID_AUTO, disable_port_power, CTLFLAG_RWTUN,
+    &usb_disable_port_power, 0, "Set to disable all USB port power.");
+#endif
+
 struct uhub_current_state {
 	uint16_t port_change;
 	uint16_t port_status;
@@ -103,13 +116,19 @@ struct uhub_current_state {
 
 struct uhub_softc {
 	struct uhub_current_state sc_st;/* current state */
+#if (USB_HAVE_FIXED_PORT != 0)
+	struct usb_hub sc_hub;
+#endif
 	device_t sc_dev;		/* base device */
 	struct mtx sc_mtx;		/* our mutex */
 	struct usb_device *sc_udev;	/* USB device */
 	struct usb_xfer *sc_xfer[UHUB_N_TRANSFER];	/* interrupt xfer */
+#if USB_HAVE_DISABLE_ENUM
+	int sc_disable_enumeration;
+	int sc_disable_port_power;
+#endif
 	uint8_t	sc_flags;
 #define	UHUB_FLAG_DID_EXPLORE 0x01
-	char	sc_name[32];
 };
 
 #define	UHUB_PROTO(sc) ((sc)->sc_udev->ddesc.bDeviceProtocol)
@@ -181,7 +200,7 @@ static device_method_t uhub_methods[] = {
 	DEVMETHOD(bus_child_location_str, uhub_child_location_string),
 	DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_string),
 	DEVMETHOD(bus_driver_added, uhub_driver_added),
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static driver_t uhub_driver = {
@@ -329,7 +348,7 @@ uhub_tt_buffer_reset_async_locked(struct usb_device *child, struct usb_endpoint
 	}
 	up->req_reset_tt = req;
 	/* get reset transfer started */
-	usb_proc_msignal(&udev->bus->non_giant_callback_proc,
+	usb_proc_msignal(USB_BUS_TT_PROC(udev->bus),
 	    &hub->tt_msg[0], &hub->tt_msg[1]);
 }
 #endif
@@ -615,9 +634,9 @@ repeat:
 	err = usbd_req_clear_port_feature(udev, NULL,
 	    portno, UHF_C_PORT_CONNECTION);
 
-	if (err) {
+	if (err)
 		goto error;
-	}
+
 	/* check if there is a child */
 
 	if (child != NULL) {
@@ -630,14 +649,22 @@ repeat:
 	/* get fresh status */
 
 	err = uhub_read_port_status(sc, portno);
-	if (err) {
+	if (err)
+		goto error;
+
+#if USB_HAVE_DISABLE_ENUM
+	/* check if we should skip enumeration from this USB HUB */
+	if (usb_disable_enumeration != 0 ||
+	    sc->sc_disable_enumeration != 0) {
+		DPRINTF("Enumeration is disabled!\n");
 		goto error;
 	}
+#endif
 	/* check if nothing is connected to the port */
 
-	if (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS)) {
+	if (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS))
 		goto error;
-	}
+
 	/* check if there is no power on the port and print a warning */
 
 	switch (udev->speed) {
@@ -1185,9 +1212,13 @@ uhub_attach(device_t dev)
 	struct usb_hub *hub;
 	struct usb_hub_descriptor hubdesc20;
 	struct usb_hub_ss_descriptor hubdesc30;
+#if USB_HAVE_DISABLE_ENUM
+	struct sysctl_ctx_list *sysctl_ctx;
+	struct sysctl_oid *sysctl_tree;
+#endif
 	uint16_t pwrdly;
+	uint16_t nports;
 	uint8_t x;
-	uint8_t nports;
 	uint8_t portno;
 	uint8_t removable;
 	uint8_t iface_index;
@@ -1198,9 +1229,6 @@ uhub_attach(device_t dev)
 
 	mtx_init(&sc->sc_mtx, "USB HUB mutex", NULL, MTX_DEF);
 
-	snprintf(sc->sc_name, sizeof(sc->sc_name), "%s",
-	    device_get_nameunit(dev));
-
 	device_set_usb_desc(dev);
 
 	DPRINTFN(2, "depth=%d selfpowered=%d, parent=%p, "
@@ -1334,12 +1362,19 @@ uhub_attach(device_t dev)
 		DPRINTFN(0, "portless HUB\n");
 		goto error;
 	}
+	if (nports > USB_MAX_PORTS) {
+		DPRINTF("Port limit exceeded\n");
+		goto error;
+	}
+#if (USB_HAVE_FIXED_PORT == 0)
 	hub = malloc(sizeof(hub[0]) + (sizeof(hub->ports[0]) * nports),
 	    M_USBDEV, M_WAITOK | M_ZERO);
 
-	if (hub == NULL) {
+	if (hub == NULL)
 		goto error;
-	}
+#else
+	hub = &sc->sc_hub;
+#endif
 	udev->hub = hub;
 
 	/* initialize HUB structure */
@@ -1378,6 +1413,24 @@ uhub_attach(device_t dev)
 	/* wait with power off for a while */
 	usb_pause_mtx(NULL, USB_MS_TO_TICKS(USB_POWER_DOWN_TIME));
 
+#if USB_HAVE_DISABLE_ENUM
+	/* Add device sysctls */
+
+	sysctl_ctx = device_get_sysctl_ctx(dev);
+	sysctl_tree = device_get_sysctl_tree(dev);
+
+	if (sysctl_ctx != NULL && sysctl_tree != NULL) {
+		(void) SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
+		    OID_AUTO, "disable_enumeration", CTLFLAG_RWTUN,
+		    &sc->sc_disable_enumeration, 0,
+		    "Set to disable enumeration on this USB HUB.");
+
+		(void) SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
+		    OID_AUTO, "disable_port_power", CTLFLAG_RWTUN,
+		    &sc->sc_disable_port_power, 0,
+		    "Set to disable USB port power on this USB HUB.");
+	}
+#endif
 	/*
 	 * To have the best chance of success we do things in the exact same
 	 * order as Windoze98.  This should not be necessary, but some
@@ -1432,13 +1485,27 @@ uhub_attach(device_t dev)
 			removable++;
 			break;
 		}
-		if (!err) {
-			/* turn the power on */
-			err = usbd_req_set_port_feature(udev, NULL,
-			    portno, UHF_PORT_POWER);
+		if (err == 0) {
+#if USB_HAVE_DISABLE_ENUM
+			/* check if we should disable USB port power or not */
+			if (usb_disable_port_power != 0 ||
+			    sc->sc_disable_port_power != 0) {
+				/* turn the power off */
+				DPRINTFN(2, "Turning port %d power off\n", portno);
+				err = usbd_req_clear_port_feature(udev, NULL,
+				    portno, UHF_PORT_POWER);
+			} else {
+#endif
+				/* turn the power on */
+				DPRINTFN(2, "Turning port %d power on\n", portno);
+				err = usbd_req_set_port_feature(udev, NULL,
+				    portno, UHF_PORT_POWER);
+#if USB_HAVE_DISABLE_ENUM
+			}
+#endif
 		}
-		if (err) {
-			DPRINTFN(0, "port %d power on failed, %s\n",
+		if (err != 0) {
+			DPRINTFN(0, "port %d power on or off failed, %s\n",
 			    portno, usbd_errstr(err));
 		}
 		DPRINTF("turn on port %d power\n",
@@ -1467,10 +1534,10 @@ uhub_attach(device_t dev)
 error:
 	usbd_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
 
-	if (udev->hub) {
-		free(udev->hub, M_USBDEV);
-		udev->hub = NULL;
-	}
+#if (USB_HAVE_FIXED_PORT == 0)
+	free(udev->hub, M_USBDEV);
+#endif
+	udev->hub = NULL;
 
 	mtx_destroy(&sc->sc_mtx);
 
@@ -1514,11 +1581,14 @@ uhub_detach(device_t dev)
 #if USB_HAVE_TT_SUPPORT
 	/* Make sure our TT messages are not queued anywhere */
 	USB_BUS_LOCK(bus);
-	usb_proc_mwait(&bus->non_giant_callback_proc,
+	usb_proc_mwait(USB_BUS_TT_PROC(bus),
 	    &hub->tt_msg[0], &hub->tt_msg[1]);
 	USB_BUS_UNLOCK(bus);
 #endif
+
+#if (USB_HAVE_FIXED_PORT == 0)
 	free(hub, M_USBDEV);
+#endif
 	sc->sc_udev->hub = NULL;
 
 	mtx_destroy(&sc->sc_mtx);
@@ -1614,16 +1684,19 @@ uhub_child_location_string(device_t parent, device_t child,
 		}
 		goto done;
 	}
+	snprintf(buf, buflen, "bus=%u hubaddr=%u port=%u devaddr=%u"
+	    " interface=%u"
 #if USB_HAVE_UGEN
-	ugen_name = res.udev->ugen_name;
-#else
-	ugen_name = "?";
+	    " ugen=%s"
 #endif
-	snprintf(buf, buflen, "bus=%u hubaddr=%u port=%u devaddr=%u interface=%u"
-	    " ugen=%s",
-	    (res.udev->parent_hub != NULL) ? res.udev->parent_hub->device_index : 0,
-	    res.portno, device_get_unit(res.udev->bus->bdev),
-	    res.udev->device_index, res.iface_index, ugen_name);
+	    , device_get_unit(res.udev->bus->bdev)
+	    , (res.udev->parent_hub != NULL) ?
+	    res.udev->parent_hub->device_index : 0
+	    , res.portno, res.udev->device_index, res.iface_index
+#if USB_HAVE_UGEN
+	    , res.udev->ugen_name
+#endif
+	    );
 done:
 	mtx_unlock(&Giant);
 
@@ -2049,9 +2122,11 @@ usbd_fs_isoc_schedule_alloc_slot(struct usb_xfer *isoc_xfer, uint16_t isoc_time)
 			data_len += len;
 		}
 
-		/* check double buffered transfers */
-
-		TAILQ_FOREACH(pipe_xfer, &xfer->endpoint->endpoint_q.head,
+		/*
+		 * Check double buffered transfers. Only stream ID
+		 * equal to zero is valid here!
+		 */
+		TAILQ_FOREACH(pipe_xfer, &xfer->endpoint->endpoint_q[0].head,
 		    wait_entry) {
 
 			/* skip self, if any */
@@ -2205,7 +2280,7 @@ usb_needs_explore(struct usb_bus *bus, uint8_t do_probe)
 	if (do_probe) {
 		bus->do_probe = 1;
 	}
-	if (usb_proc_msignal(&bus->explore_proc,
+	if (usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
 	    &bus->explore_msg[0], &bus->explore_msg[1])) {
 		/* ignore */
 	}
@@ -2788,7 +2863,7 @@ usbd_set_power_mode(struct usb_device *udev, uint8_t power_mode)
 uint8_t
 usbd_filter_power_mode(struct usb_device *udev, uint8_t power_mode)
 {
-	struct usb_bus_methods *mtod;
+	const struct usb_bus_methods *mtod;
 	int8_t temp;
 
 	mtod = udev->bus->methods;
diff --git a/freebsd/sys/dev/usb/usb_hub.h b/freebsd/sys/dev/usb/usb_hub.h
index 557a056..16430d9 100644
--- a/freebsd/sys/dev/usb/usb_hub.h
+++ b/freebsd/sys/dev/usb/usb_hub.h
@@ -54,7 +54,11 @@ struct usb_hub {
 	uint16_t portpower;		/* mA per USB port */
 	uint8_t	isoc_last_time;
 	uint8_t	nports;
+#if (USB_HAVE_FIXED_PORT == 0)
 	struct usb_port ports[0];
+#else
+	struct usb_port ports[USB_MAX_PORTS];
+#endif
 };
 
 /* function prototypes */
diff --git a/freebsd/sys/dev/usb/usb_ioctl.h b/freebsd/sys/dev/usb/usb_ioctl.h
index d5be169..683f3e6 100644
--- a/freebsd/sys/dev/usb/usb_ioctl.h
+++ b/freebsd/sys/dev/usb/usb_ioctl.h
@@ -29,6 +29,7 @@
 #ifndef _USB_IOCTL_H_
 #define	_USB_IOCTL_H_
 
+#ifndef USB_GLOBAL_INCLUDE_FILE
 #include <sys/ioccom.h>
 #include <sys/cdefs.h>
 
@@ -36,6 +37,7 @@
 
 #include <dev/usb/usb_endian.h>
 #include <dev/usb/usb.h>
+#endif
 
 #define	USB_DEVICE_NAME "usbctl"
 #define	USB_DEVICE_DIR "usb"
@@ -62,6 +64,9 @@ enum {
 	USB_TEMP_AUDIO,		/* USB Audio */
 	USB_TEMP_KBD,		/* USB Keyboard */
 	USB_TEMP_MOUSE,		/* USB Mouse */
+	USB_TEMP_PHONE,		/* USB Phone */
+	USB_TEMP_SERIALNET,	/* USB CDC Ethernet and Modem */
+	USB_TEMP_MIDI,		/* USB MIDI */
 	USB_TEMP_MAX,
 };
 
@@ -329,6 +334,7 @@ struct usb_gen_quirk {
 #define	USB_FS_OPEN		_IOWR('U', 197, struct usb_fs_open)
 #define	USB_FS_CLOSE		_IOW ('U', 198, struct usb_fs_close)
 #define	USB_FS_CLEAR_STALL_SYNC _IOW ('U', 199, struct usb_fs_clear_stall_sync)
+#define	USB_FS_OPEN_STREAM	_IOWR('U', 200, struct usb_fs_open_stream)
 
 /* USB quirk system interface */
 #define	USB_DEV_QUIRK_GET	_IOWR('Q', 0, struct usb_gen_quirk)
diff --git a/freebsd/sys/dev/usb/usb_lookup.c b/freebsd/sys/dev/usb/usb_lookup.c
index b9ff593..ebbb03e 100644
--- a/freebsd/sys/dev/usb/usb_lookup.c
+++ b/freebsd/sys/dev/usb/usb_lookup.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -49,6 +52,7 @@
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 /*------------------------------------------------------------------------*
  *	usbd_lookup_id_by_info
@@ -176,7 +180,7 @@ usbd_lookup_id_by_uaa(const struct usb_device_id *id, usb_size_t sizeof_id,
 #define	MFL_SIZE "0"
 #endif
 
-#ifdef KLD_MODULE
+#if defined(KLD_MODULE) && (USB_HAVE_ID_SECTION != 0)
 static const char __section("bus_autoconf_format") __used usb_id_format[] = {
 
 	/* Declare that three different sections use the same format */
diff --git a/freebsd/sys/dev/usb/usb_mbuf.c b/freebsd/sys/dev/usb/usb_mbuf.c
index 37fa2a1..d98b7e2 100644
--- a/freebsd/sys/dev/usb/usb_mbuf.c
+++ b/freebsd/sys/dev/usb/usb_mbuf.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -49,6 +52,7 @@
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usb_dev.h>
 #include <dev/usb/usb_mbuf.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 /*------------------------------------------------------------------------*
  *      usb_alloc_mbufs - allocate mbufs to an usbd interface queue
diff --git a/freebsd/sys/dev/usb/usb_msctest.c b/freebsd/sys/dev/usb/usb_msctest.c
index 19accdd..095bba0 100644
--- a/freebsd/sys/dev/usb/usb_msctest.c
+++ b/freebsd/sys/dev/usb/usb_msctest.c
@@ -34,6 +34,9 @@
  * mass storage quirks for not supported SCSI commands!
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -68,6 +71,7 @@
 #include <dev/usb/usb_request.h>
 #include <dev/usb/usb_util.h>
 #include <dev/usb/quirk/usb_quirk.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 enum {
 	ST_COMMAND,
@@ -85,9 +89,10 @@ enum {
 	DIR_NONE,
 };
 
-#define	SCSI_MAX_LEN	MAX(0x100, BULK_SIZE)
+#define	SCSI_MAX_LEN	MAX(SCSI_FIXED_BLOCK_SIZE, USB_MSCTEST_BULK_SIZE)
 #define	SCSI_INQ_LEN	0x24
 #define	SCSI_SENSE_LEN	0xFF
+#define	SCSI_FIXED_BLOCK_SIZE 512	/* bytes */
 
 static uint8_t scsi_test_unit_ready[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 static uint8_t scsi_inquiry[] = { 0x12, 0x00, 0x00, 0x00, SCSI_INQ_LEN, 0x00 };
@@ -113,7 +118,10 @@ static uint8_t scsi_read_capacity[] =	{ 0x25, 0x00, 0x00, 0x00, 0x00, 0x00,
 static uint8_t scsi_prevent_removal[] =	{ 0x1e, 0, 0, 0, 1, 0 };
 static uint8_t scsi_allow_removal[] =	{ 0x1e, 0, 0, 0, 0, 0 };
 
-#define	BULK_SIZE		64	/* dummy */
+#ifndef USB_MSCTEST_BULK_SIZE
+#define	USB_MSCTEST_BULK_SIZE	64	/* dummy */
+#endif
+
 #define	ERR_CSW_FAILED		-1
 
 /* Command Block Wrapper */
@@ -175,6 +183,7 @@ static usb_callback_t bbb_data_rd_cs_callback;
 static usb_callback_t bbb_data_write_callback;
 static usb_callback_t bbb_data_wr_cs_callback;
 static usb_callback_t bbb_status_callback;
+static usb_callback_t bbb_raw_write_callback;
 
 static void	bbb_done(struct bbb_transfer *, int);
 static void	bbb_transfer_start(struct bbb_transfer *, uint8_t);
@@ -182,7 +191,7 @@ static void	bbb_data_clear_stall_callback(struct usb_xfer *, uint8_t,
 		    uint8_t);
 static int	bbb_command_start(struct bbb_transfer *, uint8_t, uint8_t,
 		    void *, size_t, void *, size_t, usb_timeout_t);
-static struct bbb_transfer *bbb_attach(struct usb_device *, uint8_t);
+static struct bbb_transfer *bbb_attach(struct usb_device *, uint8_t, uint8_t);
 static void	bbb_detach(struct bbb_transfer *);
 
 static const struct usb_config bbb_config[ST_MAX] = {
@@ -245,6 +254,19 @@ static const struct usb_config bbb_config[ST_MAX] = {
 	},
 };
 
+static const struct usb_config bbb_raw_config[1] = {
+
+	[0] = {
+		.type = UE_BULK_INTR,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_OUT,
+		.bufsize = SCSI_MAX_LEN,
+		.flags = {.ext_buffer = 1,.proxy_buffer = 1,},
+		.callback = &bbb_raw_write_callback,
+		.timeout = 1 * USB_MS_HZ,	/* 1 second */
+	},
+};
+
 static void
 bbb_done(struct bbb_transfer *sc, int error)
 {
@@ -465,6 +487,47 @@ bbb_status_callback(struct usb_xfer *xfer, usb_error_t error)
 	}
 }
 
+static void
+bbb_raw_write_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct bbb_transfer *sc = usbd_xfer_softc(xfer);
+	usb_frlength_t max_bulk = usbd_xfer_max_len(xfer);
+	int actlen, sumlen;
+
+	usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		sc->data_rem -= actlen;
+		sc->data_ptr += actlen;
+		sc->actlen += actlen;
+
+		if (actlen < sumlen) {
+			/* short transfer */
+			sc->data_rem = 0;
+		}
+	case USB_ST_SETUP:
+		DPRINTF("max_bulk=%d, data_rem=%d\n",
+		    max_bulk, sc->data_rem);
+
+		if (sc->data_rem == 0) {
+			bbb_done(sc, 0);
+			break;
+		}
+		if (max_bulk > sc->data_rem) {
+			max_bulk = sc->data_rem;
+		}
+		usbd_xfer_set_timeout(xfer, sc->data_timeout);
+		usbd_xfer_set_frame_data(xfer, 0, sc->data_ptr, max_bulk);
+		usbd_transfer_submit(xfer);
+		break;
+
+	default:			/* Error */
+		bbb_done(sc, error);
+		break;
+	}
+}
+
 /*------------------------------------------------------------------------*
  *	bbb_command_start - execute a SCSI command synchronously
  *
@@ -500,13 +563,47 @@ bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun,
 	return (sc->error);
 }
 
+/*------------------------------------------------------------------------*
+ *	bbb_raw_write - write a raw BULK message synchronously
+ *
+ * Return values
+ * 0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+static int
+bbb_raw_write(struct bbb_transfer *sc, const void *data_ptr, size_t data_len,
+    usb_timeout_t data_timeout)
+{
+	sc->data_ptr = __DECONST(void *, data_ptr);
+	sc->data_len = data_len;
+	sc->data_rem = data_len;
+	sc->data_timeout = (data_timeout + USB_MS_HZ);
+	sc->actlen = 0;
+	sc->error = 0;
+
+	DPRINTFN(1, "BULK DATA = %*D\n", (int)data_len,
+	    (const char *)data_ptr, ":");
+
+	mtx_lock(&sc->mtx);
+	usbd_transfer_start(sc->xfer[0]);
+	while (usbd_transfer_pending(sc->xfer[0]))
+		cv_wait(&sc->cv, &sc->mtx);
+	mtx_unlock(&sc->mtx);
+	return (sc->error);
+}
+
 static struct bbb_transfer *
-bbb_attach(struct usb_device *udev, uint8_t iface_index)
+bbb_attach(struct usb_device *udev, uint8_t iface_index,
+    uint8_t bInterfaceClass)
 {
 	struct usb_interface *iface;
 	struct usb_interface_descriptor *id;
+	const struct usb_config *pconfig;
 	struct bbb_transfer *sc;
 	usb_error_t err;
+	int nconfig;
+
+#if USB_HAVE_MSCTEST_DETACH
 	uint8_t do_unlock;
 
 	/* Prevent re-enumeration */
@@ -520,28 +617,46 @@ bbb_attach(struct usb_device *udev, uint8_t iface_index)
 
 	if (do_unlock)
 		usbd_enum_unlock(udev);
+#endif
 
 	iface = usbd_get_iface(udev, iface_index);
 	if (iface == NULL)
 		return (NULL);
 
 	id = iface->idesc;
-	if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
+	if (id == NULL || id->bInterfaceClass != bInterfaceClass)
 		return (NULL);
 
-	switch (id->bInterfaceSubClass) {
-	case UISUBCLASS_SCSI:
-	case UISUBCLASS_UFI:
-	case UISUBCLASS_SFF8020I:
-	case UISUBCLASS_SFF8070I:
+	switch (id->bInterfaceClass) {
+	case UICLASS_MASS:
+		switch (id->bInterfaceSubClass) {
+		case UISUBCLASS_SCSI:
+		case UISUBCLASS_UFI:
+		case UISUBCLASS_SFF8020I:
+		case UISUBCLASS_SFF8070I:
+			break;
+		default:
+			return (NULL);
+		}
+		switch (id->bInterfaceProtocol) {
+		case UIPROTO_MASS_BBB_OLD:
+		case UIPROTO_MASS_BBB:
+			break;
+		default:
+			return (NULL);
+		}
+		pconfig = bbb_config;
+		nconfig = ST_MAX;
 		break;
-	default:
-		return (NULL);
-	}
-
-	switch (id->bInterfaceProtocol) {
-	case UIPROTO_MASS_BBB_OLD:
-	case UIPROTO_MASS_BBB:
+	case UICLASS_HID:
+		switch (id->bInterfaceSubClass) {
+		case 0:
+			break;
+		default:
+			return (NULL);
+		}
+		pconfig = bbb_raw_config;
+		nconfig = 1;
 		break;
 	default:
 		return (NULL);
@@ -551,22 +666,27 @@ bbb_attach(struct usb_device *udev, uint8_t iface_index)
 	mtx_init(&sc->mtx, "USB autoinstall", NULL, MTX_DEF);
 	cv_init(&sc->cv, "WBBB");
 
-	err = usbd_transfer_setup(udev, &iface_index, sc->xfer, bbb_config,
-	    ST_MAX, sc, &sc->mtx);
+	err = usbd_transfer_setup(udev, &iface_index, sc->xfer, pconfig,
+	    nconfig, sc, &sc->mtx);
 	if (err) {
 		bbb_detach(sc);
 		return (NULL);
 	}
-	/* store pointer to DMA buffers */
-	sc->buffer = usbd_xfer_get_frame_buffer(
-	    sc->xfer[ST_DATA_RD], 0);
-	sc->buffer_size =
-	    usbd_xfer_max_len(sc->xfer[ST_DATA_RD]);
-	sc->cbw = usbd_xfer_get_frame_buffer(
-	    sc->xfer[ST_COMMAND], 0);
-	sc->csw = usbd_xfer_get_frame_buffer(
-	    sc->xfer[ST_STATUS], 0);
-
+	switch (id->bInterfaceClass) {
+	case UICLASS_MASS:
+		/* store pointer to DMA buffers */
+		sc->buffer = usbd_xfer_get_frame_buffer(
+		    sc->xfer[ST_DATA_RD], 0);
+		sc->buffer_size =
+		    usbd_xfer_max_len(sc->xfer[ST_DATA_RD]);
+		sc->cbw = usbd_xfer_get_frame_buffer(
+		    sc->xfer[ST_COMMAND], 0);
+		sc->csw = usbd_xfer_get_frame_buffer(
+		    sc->xfer[ST_STATUS], 0);
+		break;
+	default:
+		break;
+	}
 	return (sc);
 }
 
@@ -595,7 +715,7 @@ usb_iface_is_cdrom(struct usb_device *udev, uint8_t iface_index)
 	uint8_t sid_type;
 	int err;
 
-	sc = bbb_attach(udev, iface_index);
+	sc = bbb_attach(udev, iface_index, UICLASS_MASS);
 	if (sc == NULL)
 		return (0);
 
@@ -651,7 +771,7 @@ usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index)
 	uint8_t sid_type;
 	int err;
 
-	sc = bbb_attach(udev, iface_index);
+	sc = bbb_attach(udev, iface_index, UICLASS_MASS);
 	if (sc == NULL)
 		return (0);
 
@@ -820,7 +940,7 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method)
 	struct bbb_transfer *sc;
 	usb_error_t err;
 
-	sc = bbb_attach(udev, iface_index);
+	sc = bbb_attach(udev, iface_index, UICLASS_MASS);
 	if (sc == NULL)
 		return (USB_ERR_INVAL);
 
@@ -879,3 +999,116 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method)
 	bbb_detach(sc);
 	return (0);
 }
+
+usb_error_t
+usb_dymo_eject(struct usb_device *udev, uint8_t iface_index)
+{
+	static const uint8_t data[3] = { 0x1b, 0x5a, 0x01 };
+	struct bbb_transfer *sc;
+	usb_error_t err;
+
+	sc = bbb_attach(udev, iface_index, UICLASS_HID);
+	if (sc == NULL)
+		return (USB_ERR_INVAL);
+	err = bbb_raw_write(sc, data, sizeof(data), USB_MS_HZ);
+	bbb_detach(sc);
+	return (err);
+}
+
+usb_error_t
+usb_msc_read_10(struct usb_device *udev, uint8_t iface_index,
+    uint32_t lba, uint32_t blocks, void *buffer)
+{
+	struct bbb_transfer *sc;
+	uint8_t cmd[10];
+	usb_error_t err;
+
+	cmd[0] = 0x28;		/* READ_10 */
+	cmd[1] = 0;
+	cmd[2] = lba >> 24;
+	cmd[3] = lba >> 16;
+	cmd[4] = lba >> 8;
+	cmd[5] = lba >> 0;
+	cmd[6] = 0;
+	cmd[7] = blocks >> 8;
+	cmd[8] = blocks;
+	cmd[9] = 0;
+
+	sc = bbb_attach(udev, iface_index, UICLASS_MASS);
+	if (sc == NULL)
+		return (USB_ERR_INVAL);
+
+	err = bbb_command_start(sc, DIR_IN, 0, buffer,
+	    blocks * SCSI_FIXED_BLOCK_SIZE, cmd, 10, USB_MS_HZ);
+
+	bbb_detach(sc);
+
+	return (err);
+}
+
+usb_error_t
+usb_msc_write_10(struct usb_device *udev, uint8_t iface_index,
+    uint32_t lba, uint32_t blocks, void *buffer)
+{
+	struct bbb_transfer *sc;
+	uint8_t cmd[10];
+	usb_error_t err;
+
+	cmd[0] = 0x2a;		/* WRITE_10 */
+	cmd[1] = 0;
+	cmd[2] = lba >> 24;
+	cmd[3] = lba >> 16;
+	cmd[4] = lba >> 8;
+	cmd[5] = lba >> 0;
+	cmd[6] = 0;
+	cmd[7] = blocks >> 8;
+	cmd[8] = blocks;
+	cmd[9] = 0;
+
+	sc = bbb_attach(udev, iface_index, UICLASS_MASS);
+	if (sc == NULL)
+		return (USB_ERR_INVAL);
+
+	err = bbb_command_start(sc, DIR_OUT, 0, buffer,
+	    blocks * SCSI_FIXED_BLOCK_SIZE, cmd, 10, USB_MS_HZ);
+
+	bbb_detach(sc);
+
+	return (err);
+}
+
+usb_error_t
+usb_msc_read_capacity(struct usb_device *udev, uint8_t iface_index,
+    uint32_t *lba_last, uint32_t *block_size)
+{
+	struct bbb_transfer *sc;
+	usb_error_t err;
+
+	sc = bbb_attach(udev, iface_index, UICLASS_MASS);
+	if (sc == NULL)
+		return (USB_ERR_INVAL);
+
+	err = bbb_command_start(sc, DIR_IN, 0, sc->buffer, 8,
+	    &scsi_read_capacity, sizeof(scsi_read_capacity),
+	    USB_MS_HZ);
+
+	*lba_last =
+	    (sc->buffer[0] << 24) | 
+	    (sc->buffer[1] << 16) |
+	    (sc->buffer[2] << 8) |
+	    (sc->buffer[3]);
+
+	*block_size =
+	    (sc->buffer[4] << 24) | 
+	    (sc->buffer[5] << 16) |
+	    (sc->buffer[6] << 8) |
+	    (sc->buffer[7]);
+
+	/* we currently only support one block size */
+	if (*block_size != SCSI_FIXED_BLOCK_SIZE)
+		err = USB_ERR_INVAL;
+
+	bbb_detach(sc);
+
+	return (err);
+}
diff --git a/freebsd/sys/dev/usb/usb_msctest.h b/freebsd/sys/dev/usb/usb_msctest.h
index 4f64f84..d3f26c2 100644
--- a/freebsd/sys/dev/usb/usb_msctest.h
+++ b/freebsd/sys/dev/usb/usb_msctest.h
@@ -43,5 +43,16 @@ usb_error_t usb_msc_eject(struct usb_device *udev,
 	    uint8_t iface_index, int method);
 usb_error_t usb_msc_auto_quirk(struct usb_device *udev,
 	    uint8_t iface_index);
+usb_error_t usb_msc_read_10(struct usb_device *udev,
+	    uint8_t iface_index, uint32_t lba, uint32_t blocks,
+	    void *buffer);
+usb_error_t usb_msc_write_10(struct usb_device *udev,
+	    uint8_t iface_index, uint32_t lba, uint32_t blocks,
+	    void *buffer);
+usb_error_t usb_msc_read_capacity(struct usb_device *udev,
+	    uint8_t iface_index, uint32_t *lba_last,
+	    uint32_t *block_size);
+usb_error_t usb_dymo_eject(struct usb_device *udev,
+	    uint8_t iface_index);
 
 #endif					/* _USB_MSCTEST_H_ */
diff --git a/freebsd/sys/dev/usb/usb_parse.c b/freebsd/sys/dev/usb/usb_parse.c
index e543a90..ef1ec53 100644
--- a/freebsd/sys/dev/usb/usb_parse.c
+++ b/freebsd/sys/dev/usb/usb_parse.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -49,6 +52,11 @@
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdi_util.h>
 
+#define	USB_DEBUG_VAR usb_debug
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_debug.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 /*------------------------------------------------------------------------*
  *	usb_desc_foreach
@@ -141,7 +149,7 @@ usb_idesc_foreach(struct usb_config_descriptor *cd,
 	}
 
 	if (ps->desc == NULL) {
-		/* first time */
+		/* first time or zero descriptors */
 	} else if (new_iface) {
 		/* new interface */
 		ps->iface_index ++;
@@ -150,6 +158,14 @@ usb_idesc_foreach(struct usb_config_descriptor *cd,
 		/* new alternate interface */
 		ps->iface_index_alt ++;
 	}
+#if (USB_IFACE_MAX <= 0)
+#error "USB_IFACE_MAX must be defined greater than zero"
+#endif
+	/* check for too many interfaces */
+	if (ps->iface_index >= USB_IFACE_MAX) {
+		DPRINTF("Interface limit reached\n");
+		id = NULL;
+	}
 
 	/* store and return current descriptor */
 	ps->desc = (struct usb_descriptor *)id;
diff --git a/freebsd/sys/dev/usb/usb_process.c b/freebsd/sys/dev/usb/usb_process.c
index a5426e1..ab687e4 100644
--- a/freebsd/sys/dev/usb/usb_process.c
+++ b/freebsd/sys/dev/usb/usb_process.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -57,6 +60,7 @@
 #include <sys/proc.h>
 #include <sys/kthread.h>
 #include <sys/sched.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 #if (__FreeBSD_version < 700000)
 #define	thread_lock(td) mtx_lock_spin(&sched_lock)
@@ -69,13 +73,17 @@ static int usb_pcount;
 #define	USB_THREAD_CREATE(f, s, p, ...) \
 		kproc_kthread_add((f), (s), &usbproc, (p), RFHIGHPID, \
 		    0, "usb", __VA_ARGS__)
+#if (__FreeBSD_version >= 900000)
 #define	USB_THREAD_SUSPEND_CHECK() kthread_suspend_check()
+#else
+#define	USB_THREAD_SUSPEND_CHECK() kthread_suspend_check(curthread)
+#endif
 #define	USB_THREAD_SUSPEND(p)   kthread_suspend(p,0)
 #define	USB_THREAD_EXIT(err)	kthread_exit()
 #else
 #define	USB_THREAD_CREATE(f, s, p, ...) \
 		kthread_create((f), (s), (p), RFHIGHPID, 0, __VA_ARGS__)
-#define	USB_THREAD_SUSPEND_CHECK() kthread_suspend_check()
+#define	USB_THREAD_SUSPEND_CHECK() kthread_suspend_check(curproc)
 #define	USB_THREAD_SUSPEND(p)   kthread_suspend(p,0)
 #define	USB_THREAD_EXIT(err)	kthread_exit(err)
 #endif
@@ -84,9 +92,8 @@ static int usb_pcount;
 static int usb_proc_debug;
 
 static SYSCTL_NODE(_hw_usb, OID_AUTO, proc, CTLFLAG_RW, 0, "USB process");
-SYSCTL_INT(_hw_usb_proc, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN, &usb_proc_debug, 0,
+SYSCTL_INT(_hw_usb_proc, OID_AUTO, debug, CTLFLAG_RWTUN, &usb_proc_debug, 0,
     "Debug level");
-TUNABLE_INT("hw.usb.proc.debug", &usb_proc_debug);
 #endif
 
 /*------------------------------------------------------------------------*
diff --git a/freebsd/sys/dev/usb/usb_process.h b/freebsd/sys/dev/usb/usb_process.h
index 06feee8..dd20afd 100644
--- a/freebsd/sys/dev/usb/usb_process.h
+++ b/freebsd/sys/dev/usb/usb_process.h
@@ -27,11 +27,14 @@
 #ifndef _USB_PROCESS_H_
 #define	_USB_PROCESS_H_
 
+#ifndef USB_GLOBAL_INCLUDE_FILE
 #include <sys/interrupt.h>
 #include <sys/priority.h>
 #include <sys/runq.h>
+#endif
 
 /* defines */
+#define	USB_PRI_HIGHEST	PI_SWI(SWI_TTY)
 #define	USB_PRI_HIGH	PI_SWI(SWI_NET)
 #define	USB_PRI_MED	PI_SWI(SWI_CAMBIO)
 
diff --git a/freebsd/sys/dev/usb/usb_request.c b/freebsd/sys/dev/usb/usb_request.c
index 6f9d7b1..39e03c6 100644
--- a/freebsd/sys/dev/usb/usb_request.c
+++ b/freebsd/sys/dev/usb/usb_request.c
@@ -28,6 +28,9 @@
  * SUCH DAMAGE.
  */ 
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -67,15 +70,16 @@
 #include <dev/usb/usb_controller.h>
 #include <dev/usb/usb_bus.h>
 #include <sys/ctype.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 static int usb_no_cs_fail;
 
-SYSCTL_INT(_hw_usb, OID_AUTO, no_cs_fail, CTLFLAG_RW,
+SYSCTL_INT(_hw_usb, OID_AUTO, no_cs_fail, CTLFLAG_RWTUN,
     &usb_no_cs_fail, 0, "USB clear stall failures are ignored, if set");
 
 static int usb_full_ddesc;
 
-SYSCTL_INT(_hw_usb, OID_AUTO, full_ddesc, CTLFLAG_RW,
+SYSCTL_INT(_hw_usb, OID_AUTO, full_ddesc, CTLFLAG_RWTUN,
     &usb_full_ddesc, 0, "USB always read complete device descriptor, if set");
 
 #ifdef USB_DEBUG
@@ -109,21 +113,21 @@ static struct usb_ctrl_debug usb_ctrl_debug = {
 	.bRequest_value = -1,
 };
 
-SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_bus_fail, CTLFLAG_RW,
+SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_bus_fail, CTLFLAG_RWTUN,
     &usb_ctrl_debug.bus_index, 0, "USB controller index to fail");
-SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_dev_fail, CTLFLAG_RW,
+SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_dev_fail, CTLFLAG_RWTUN,
     &usb_ctrl_debug.dev_index, 0, "USB device address to fail");
-SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ds_fail, CTLFLAG_RW,
+SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ds_fail, CTLFLAG_RWTUN,
     &usb_ctrl_debug.ds_fail, 0, "USB fail data stage");
-SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ss_fail, CTLFLAG_RW,
+SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ss_fail, CTLFLAG_RWTUN,
     &usb_ctrl_debug.ss_fail, 0, "USB fail status stage");
-SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ds_delay, CTLFLAG_RW,
+SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ds_delay, CTLFLAG_RWTUN,
     &usb_ctrl_debug.ds_delay, 0, "USB data stage delay in ms");
-SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ss_delay, CTLFLAG_RW,
+SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ss_delay, CTLFLAG_RWTUN,
     &usb_ctrl_debug.ss_delay, 0, "USB status stage delay in ms");
-SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_rt_fail, CTLFLAG_RW,
+SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_rt_fail, CTLFLAG_RWTUN,
     &usb_ctrl_debug.bmRequestType_value, 0, "USB bmRequestType to fail");
-SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_rv_fail, CTLFLAG_RW,
+SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_rv_fail, CTLFLAG_RWTUN,
     &usb_ctrl_debug.bRequest_value, 0, "USB bRequest to fail");
 
 /*------------------------------------------------------------------------*
@@ -226,6 +230,7 @@ usb_do_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error)
 	struct usb_endpoint *ep;
 	struct usb_endpoint *ep_end;
 	struct usb_endpoint *ep_first;
+	usb_stream_t x;
 	uint8_t to;
 
 	udev = xfer->xroot->udev;
@@ -253,9 +258,11 @@ tr_transferred:
 			ep->is_stalled = 0;
 			/* some hardware needs a callback to clear the data toggle */
 			usbd_clear_stall_locked(udev, ep);
-			/* start up the current or next transfer, if any */
-			usb_command_wrapper(&ep->endpoint_q,
-			    ep->endpoint_q.curr);
+			for (x = 0; x != USB_MAX_EP_STREAMS; x++) {
+				/* start the current or next transfer, if any */
+				usb_command_wrapper(&ep->endpoint_q[x],
+				    ep->endpoint_q[x].curr);
+			}
 		}
 		ep++;
 
@@ -1265,10 +1272,49 @@ done:
 }
 
 /*------------------------------------------------------------------------*
+ *	usbd_alloc_config_desc
+ *
+ * This function is used to allocate a zeroed configuration
+ * descriptor.
+ *
+ * Returns:
+ * NULL: Failure
+ * Else: Success
+ *------------------------------------------------------------------------*/
+void *
+usbd_alloc_config_desc(struct usb_device *udev, uint32_t size)
+{
+	if (size > USB_CONFIG_MAX) {
+		DPRINTF("Configuration descriptor too big\n");
+		return (NULL);
+	}
+#if (USB_HAVE_FIXED_CONFIG == 0)
+	return (malloc(size, M_USBDEV, M_ZERO | M_WAITOK));
+#else
+	memset(udev->config_data, 0, sizeof(udev->config_data));
+	return (udev->config_data);
+#endif
+}
+
+/*------------------------------------------------------------------------*
+ *	usbd_alloc_config_desc
+ *
+ * This function is used to free a configuration descriptor.
+ *------------------------------------------------------------------------*/
+void
+usbd_free_config_desc(struct usb_device *udev, void *ptr)
+{
+#if (USB_HAVE_FIXED_CONFIG == 0)
+	free(ptr, M_USBDEV);
+#endif
+}
+
+/*------------------------------------------------------------------------*
  *	usbd_req_get_config_desc_full
  *
  * This function gets the complete USB configuration descriptor and
- * ensures that "wTotalLength" is correct.
+ * ensures that "wTotalLength" is correct. The returned configuration
+ * descriptor is freed by calling "usbd_free_config_desc()".
  *
  * Returns:
  *    0: Success
@@ -1276,12 +1322,11 @@ done:
  *------------------------------------------------------------------------*/
 usb_error_t
 usbd_req_get_config_desc_full(struct usb_device *udev, struct mtx *mtx,
-    struct usb_config_descriptor **ppcd, struct malloc_type *mtype,
-    uint8_t index)
+    struct usb_config_descriptor **ppcd, uint8_t index)
 {
 	struct usb_config_descriptor cd;
 	struct usb_config_descriptor *cdesc;
-	uint16_t len;
+	uint32_t len;
 	usb_error_t err;
 
 	DPRINTFN(4, "index=%d\n", index);
@@ -1289,23 +1334,25 @@ usbd_req_get_config_desc_full(struct usb_device *udev, struct mtx *mtx,
 	*ppcd = NULL;
 
 	err = usbd_req_get_config_desc(udev, mtx, &cd, index);
-	if (err) {
+	if (err)
 		return (err);
-	}
+
 	/* get full descriptor */
 	len = UGETW(cd.wTotalLength);
-	if (len < sizeof(*cdesc)) {
+	if (len < (uint32_t)sizeof(*cdesc)) {
 		/* corrupt descriptor */
 		return (USB_ERR_INVAL);
+	} else if (len > USB_CONFIG_MAX) {
+		DPRINTF("Configuration descriptor was truncated\n");
+		len = USB_CONFIG_MAX;
 	}
-	cdesc = malloc(len, mtype, M_WAITOK);
-	if (cdesc == NULL) {
+	cdesc = usbd_alloc_config_desc(udev, len);
+	if (cdesc == NULL)
 		return (USB_ERR_NOMEM);
-	}
 	err = usbd_req_get_desc(udev, mtx, NULL, cdesc, len, len, 0,
 	    UDESC_CONFIG, index, 3);
 	if (err) {
-		free(cdesc, mtype);
+		usbd_free_config_desc(udev, cdesc);
 		return (err);
 	}
 	/* make sure that the device is not fooling us: */
@@ -1915,9 +1962,9 @@ usbd_setup_device_desc(struct usb_device *udev, struct mtx *mtx)
 		break;
 
 	default:
-		DPRINTF("Minimum MaxPacketSize is large enough "
+		DPRINTF("Minimum bMaxPacketSize is large enough "
 		    "to hold the complete device descriptor or "
-		    "only once MaxPacketSize choice\n");
+		    "only one bMaxPacketSize choice\n");
 
 		/* get the full device descriptor */
 		err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc);
diff --git a/freebsd/sys/dev/usb/usb_request.h b/freebsd/sys/dev/usb/usb_request.h
index 5fcedd5..9f0a4e6 100644
--- a/freebsd/sys/dev/usb/usb_request.h
+++ b/freebsd/sys/dev/usb/usb_request.h
@@ -44,7 +44,7 @@ usb_error_t usbd_req_get_config_desc(struct usb_device *udev, struct mtx *mtx,
 		    struct usb_config_descriptor *d, uint8_t conf_index);
 usb_error_t usbd_req_get_config_desc_full(struct usb_device *udev,
 		    struct mtx *mtx, struct usb_config_descriptor **ppcd,
-		    struct malloc_type *mtype, uint8_t conf_index);
+		    uint8_t conf_index);
 usb_error_t usbd_req_get_desc(struct usb_device *udev, struct mtx *mtx,
 		    uint16_t *actlen, void *desc, uint16_t min_len,
 		    uint16_t max_len, uint16_t id, uint8_t type,
@@ -94,4 +94,7 @@ usb_error_t usbd_req_set_port_link_state(struct usb_device *udev,
 usb_error_t usbd_req_set_lpm_info(struct usb_device *udev, struct mtx *mtx,
 		    uint8_t port, uint8_t besl, uint8_t addr, uint8_t rwe);
 
+void *	usbd_alloc_config_desc(struct usb_device *, uint32_t);
+void	usbd_free_config_desc(struct usb_device *, void *);
+
 #endif					/* _USB_REQUEST_H_ */
diff --git a/freebsd/sys/dev/usb/usb_transfer.c b/freebsd/sys/dev/usb/usb_transfer.c
index ab5558e..5bbc1e0 100644
--- a/freebsd/sys/dev/usb/usb_transfer.c
+++ b/freebsd/sys/dev/usb/usb_transfer.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -63,6 +66,7 @@
 #include <dev/usb/usb_controller.h>
 #include <dev/usb/usb_bus.h>
 #include <dev/usb/usb_pf.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 #ifdef __rtems__
 #include <machine/rtems-bsd-cache.h>
 #endif /* __rtems__ */
@@ -161,7 +165,7 @@ usbd_update_max_frame_size(struct usb_xfer *xfer)
 usb_timeout_t
 usbd_get_dma_delay(struct usb_device *udev)
 {
-	struct usb_bus_methods *mtod;
+	const struct usb_bus_methods *mtod;
 	uint32_t temp;
 
 	mtod = udev->bus->methods;
@@ -186,6 +190,10 @@ usbd_get_dma_delay(struct usb_device *udev)
  * according to "size", "align" and "count" arguments. "ppc" is
  * pointed to a linear array of USB page caches afterwards.
  *
+ * If the "align" argument is equal to "1" a non-contiguous allocation
+ * can happen. Else if the "align" argument is greater than "1", the
+ * allocation will always be contiguous in memory.
+ *
  * Returns:
  *    0: Success
  * Else: Failure
@@ -200,13 +208,14 @@ usbd_transfer_setup_sub_malloc(struct usb_setup_params *parm,
 	struct usb_page *pg;
 	void *buf;
 	usb_size_t n_dma_pc;
+	usb_size_t n_dma_pg;
 	usb_size_t n_obj;
 	usb_size_t x;
 	usb_size_t y;
 	usb_size_t r;
 	usb_size_t z;
 
-	USB_ASSERT(align > 1, ("Invalid alignment, 0x%08x\n",
+	USB_ASSERT(align > 0, ("Invalid alignment, 0x%08x\n",
 	    align));
 	USB_ASSERT(size > 0, ("Invalid size = 0\n"));
 
@@ -229,24 +238,43 @@ usbd_transfer_setup_sub_malloc(struct usb_setup_params *parm,
 	 * Try multi-allocation chunks to reduce the number of DMA
 	 * allocations, hence DMA allocations are slow.
 	 */
-	if (size >= USB_PAGE_SIZE) {
+	if (align == 1) {
+		/* special case - non-cached multi page DMA memory */
+		n_dma_pc = count;
+		n_dma_pg = (2 + (size / USB_PAGE_SIZE));
+		n_obj = 1;
+	} else if (size >= USB_PAGE_SIZE) {
 		n_dma_pc = count;
+		n_dma_pg = 1;
 		n_obj = 1;
 	} else {
 		/* compute number of objects per page */
+#ifdef USB_DMA_SINGLE_ALLOC
+		n_obj = 1;
+#else
 		n_obj = (USB_PAGE_SIZE / size);
+#endif
 		/*
 		 * Compute number of DMA chunks, rounded up
 		 * to nearest one:
 		 */
 		n_dma_pc = ((count + n_obj - 1) / n_obj);
+		n_dma_pg = 1;
 	}
 
+	/*
+	 * DMA memory is allocated once, but mapped twice. That's why
+	 * there is one list for auto-free and another list for
+	 * non-auto-free which only holds the mapping and not the
+	 * allocation.
+	 */
 	if (parm->buf == NULL) {
-		/* for the future */
-		parm->dma_page_ptr += n_dma_pc;
+		/* reserve memory (auto-free) */
+		parm->dma_page_ptr += n_dma_pc * n_dma_pg;
 		parm->dma_page_cache_ptr += n_dma_pc;
-		parm->dma_page_ptr += count;
+
+		/* reserve memory (no-auto-free) */
+		parm->dma_page_ptr += count * n_dma_pg;
 		parm->xfer_page_cache_ptr += count;
 		return (0);
 	}
@@ -261,15 +289,33 @@ usbd_transfer_setup_sub_malloc(struct usb_setup_params *parm,
 		    &parm->curr_xfer->xroot->dma_parent_tag;
 	}
 
-	if (ppc) {
-		*ppc = parm->xfer_page_cache_ptr;
+	if (ppc != NULL) {
+		if (n_obj != 1)
+			*ppc = parm->xfer_page_cache_ptr;
+		else
+			*ppc = parm->dma_page_cache_ptr;
 	}
 	r = count;			/* set remainder count */
 	z = n_obj * size;		/* set allocation size */
 	pc = parm->xfer_page_cache_ptr;
 	pg = parm->dma_page_ptr;
 
-	for (x = 0; x != n_dma_pc; x++) {
+	if (n_obj == 1) {
+	    /*
+	     * Avoid mapping memory twice if only a single object
+	     * should be allocated per page cache:
+	     */
+	    for (x = 0; x != n_dma_pc; x++) {
+		if (usb_pc_alloc_mem(parm->dma_page_cache_ptr,
+		    pg, z, align)) {
+			return (1);	/* failure */
+		}
+		/* Make room for one DMA page cache and "n_dma_pg" pages */
+		parm->dma_page_cache_ptr++;
+		pg += n_dma_pg;
+	    }
+	} else {
+	    for (x = 0; x != n_dma_pc; x++) {
 
 		if (r < n_obj) {
 			/* compute last remainder */
@@ -282,11 +328,11 @@ usbd_transfer_setup_sub_malloc(struct usb_setup_params *parm,
 		}
 		/* Set beginning of current buffer */
 		buf = parm->dma_page_cache_ptr->buffer;
-		/* Make room for one DMA page cache and one page */
+		/* Make room for one DMA page cache and "n_dma_pg" pages */
 		parm->dma_page_cache_ptr++;
-		pg++;
+		pg += n_dma_pg;
 
-		for (y = 0; (y != n_obj); y++, r--, pc++, pg++) {
+		for (y = 0; (y != n_obj); y++, r--, pc++, pg += n_dma_pg) {
 
 			/* Load sub-chunk into DMA */
 			if (usb_pc_dmamap_create(pc, size)) {
@@ -302,6 +348,7 @@ usbd_transfer_setup_sub_malloc(struct usb_setup_params *parm,
 			}
 			mtx_unlock(pc->tag_parent->mtx);
 		}
+	    }
 	}
 
 	parm->xfer_page_cache_ptr = pc;
@@ -371,7 +418,8 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm)
 		switch (type) {
 		case UE_ISOCHRONOUS:
 		case UE_INTERRUPT:
-			xfer->max_packet_count += (xfer->max_packet_size >> 11) & 3;
+			xfer->max_packet_count +=
+			    (xfer->max_packet_size >> 11) & 3;
 
 			/* check for invalid max packet count */
 			if (xfer->max_packet_count > 3)
@@ -400,7 +448,8 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm)
 			if (ecomp != NULL) {
 				uint8_t mult;
 
-				mult = (ecomp->bmAttributes & 3) + 1;
+				mult = UE_GET_SS_ISO_MULT(
+				    ecomp->bmAttributes) + 1;
 				if (mult > 3)
 					mult = 3;
 
@@ -711,7 +760,26 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm)
 	 */
 
 	if (!xfer->flags.ext_buffer) {
+#if USB_HAVE_BUSDMA
+		struct usb_page_search page_info;
+		struct usb_page_cache *pc;
+
+		if (usbd_transfer_setup_sub_malloc(parm,
+		    &pc, parm->bufsize, 1, 1)) {
+			parm->err = USB_ERR_NOMEM;
+		} else if (parm->buf != NULL) {
+
+			usbd_get_page(pc, 0, &page_info);
+
+			xfer->local_buffer = page_info.buffer;
 
+			usbd_xfer_set_frame_offset(xfer, 0, 0);
+
+			if ((type == UE_CONTROL) && (n_frbuffers > 1)) {
+				usbd_xfer_set_frame_offset(xfer, REQ_SIZE, 1);
+			}
+		}
+#else
 		/* align data */
 #ifdef __rtems__
 #ifdef CPU_DATA_CACHE_ALIGNMENT
@@ -721,8 +789,7 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm)
 		parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
 #endif /* __rtems__ */
 
-		if (parm->buf) {
-
+		if (parm->buf != NULL) {
 			xfer->local_buffer =
 			    USB_ADD_BYTES(parm->buf, parm->size[0]);
 #ifdef __rtems__
@@ -748,6 +815,7 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm)
 #endif /* CPU_DATA_CACHE_ALIGNMENT */
 #endif /* __rtems__ */
 		parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
+#endif
 	}
 	/*
 	 * Compute maximum buffer size
@@ -834,6 +902,19 @@ done:
 	}
 }
 
+static uint8_t
+usbd_transfer_setup_has_bulk(const struct usb_config *setup_start,
+    uint16_t n_setup)
+{
+	while (n_setup--) {
+		uint8_t type = setup_start[n_setup].type;
+		if (type == UE_BULK || type == UE_BULK_INTR ||
+		    type == UE_TYPE_ANY)
+			return (1);
+	}
+	return (0);
+}
+
 /*------------------------------------------------------------------------*
  *	usbd_transfer_setup - setup an array of USB transfers
  *
@@ -970,14 +1051,17 @@ usbd_transfer_setup(struct usb_device *udev,
 			 * deadlock!
 			 */
 			if (setup_start == usb_control_ep_cfg)
-				info->done_p = 
-				    &udev->bus->control_xfer_proc;
+				info->done_p =
+				    USB_BUS_CONTROL_XFER_PROC(udev->bus);
 			else if (xfer_mtx == &Giant)
-				info->done_p = 
-				    &udev->bus->giant_callback_proc;
+				info->done_p =
+				    USB_BUS_GIANT_PROC(udev->bus);
+			else if (usbd_transfer_setup_has_bulk(setup_start, n_setup))
+				info->done_p =
+				    USB_BUS_NON_GIANT_BULK_PROC(udev->bus);
 			else
-				info->done_p = 
-				    &udev->bus->non_giant_callback_proc;
+				info->done_p =
+				    USB_BUS_NON_GIANT_ISOC_PROC(udev->bus);
 		}
 		/* reset sizes */
 
@@ -996,7 +1080,20 @@ usbd_transfer_setup(struct usb_device *udev,
 			ep = usbd_get_endpoint(udev,
 			    ifaces[setup->if_index], setup);
 
-			if ((ep == NULL) || (ep->methods == NULL)) {
+			/*
+			 * Check that the USB PIPE is valid and that
+			 * the endpoint mode is proper.
+			 *
+			 * Make sure we don't allocate a streams
+			 * transfer when such a combination is not
+			 * valid.
+			 */
+			if ((ep == NULL) || (ep->methods == NULL) ||
+			    ((ep->ep_mode != USB_EP_MODE_STREAMS) &&
+			    (ep->ep_mode != USB_EP_MODE_DEFAULT)) ||
+			    (setup->stream_id != 0 &&
+			    (setup->stream_id >= USB_MAX_EP_STREAMS ||
+			    (ep->ep_mode != USB_EP_MODE_STREAMS)))) {
 				if (setup->flags.no_pipe_ok)
 					continue;
 				if ((setup->usb_mode != USB_MODE_DUAL) &&
@@ -1040,6 +1137,9 @@ usbd_transfer_setup(struct usb_device *udev,
 			/* set transfer endpoint pointer */
 			xfer->endpoint = ep;
 
+			/* set transfer stream ID */
+			xfer->stream_id = setup->stream_id;
+
 			parm->size[0] += sizeof(xfer[0]);
 			parm->methods = xfer->endpoint->methods;
 			parm->curr_xfer = xfer;
@@ -1110,9 +1210,12 @@ usbd_transfer_setup(struct usb_device *udev,
 		 * The number of DMA tags required depends on
 		 * the number of endpoints. The current estimate
 		 * for maximum number of DMA tags per endpoint
-		 * is two.
+		 * is three:
+		 * 1) for loading memory
+		 * 2) for allocating memory
+		 * 3) for fixing memory [UHCI]
 		 */
-		parm->dma_tag_max += 2 * MIN(n_setup, USB_EP_MAX);
+		parm->dma_tag_max += 3 * MIN(n_setup, USB_EP_MAX);
 
 		/*
 		 * DMA tags for QH, TD, Data and more.
@@ -1660,7 +1763,8 @@ usbd_transfer_submit(struct usb_xfer *xfer)
 			USB_BUS_LOCK(bus);
 			xfer->flags_int.can_cancel_immed = 1;
 			/* start the transfer */
-			usb_command_wrapper(&xfer->endpoint->endpoint_q, xfer);
+			usb_command_wrapper(&xfer->endpoint->
+			    endpoint_q[xfer->stream_id], xfer);
 			USB_BUS_UNLOCK(bus);
 			return;
 		}
@@ -1781,7 +1885,7 @@ usbd_pipe_enter(struct usb_xfer *xfer)
 	}
 
 	/* start the transfer */
-	usb_command_wrapper(&ep->endpoint_q, xfer);
+	usb_command_wrapper(&ep->endpoint_q[xfer->stream_id], xfer);
 	USB_BUS_UNLOCK(xfer->xroot->bus);
 }
 
@@ -1902,8 +2006,9 @@ usbd_transfer_stop(struct usb_xfer *xfer)
 		 * If the current USB transfer is completing we need
 		 * to start the next one:
 		 */
-		if (ep->endpoint_q.curr == xfer) {
-			usb_command_wrapper(&ep->endpoint_q, NULL);
+		if (ep->endpoint_q[xfer->stream_id].curr == xfer) {
+			usb_command_wrapper(
+			    &ep->endpoint_q[xfer->stream_id], NULL);
 		}
 	}
 
@@ -2221,10 +2326,8 @@ usbd_callback_ss_done_defer(struct usb_xfer *xfer)
 	         * will have a Lock Order Reversal, LOR, if we try to
 	         * proceed !
 	         */
-		if (usb_proc_msignal(info->done_p,
-		    &info->done_m[0], &info->done_m[1])) {
-			/* ignore */
-		}
+		(void) usb_proc_msignal(info->done_p,
+		    &info->done_m[0], &info->done_m[1]);
 	} else {
 		/* clear second recurse flag */
 		pq->recurse_2 = 0;
@@ -2248,23 +2351,26 @@ usbd_callback_wrapper(struct usb_xfer_queue *pq)
 	struct usb_xfer_root *info = xfer->xroot;
 
 	USB_BUS_LOCK_ASSERT(info->bus, MA_OWNED);
-	if (!mtx_owned(info->xfer_mtx) && !SCHEDULER_STOPPED()) {
+	if ((pq->recurse_3 != 0 || mtx_owned(info->xfer_mtx) == 0) &&
+	    SCHEDULER_STOPPED() == 0) {
 		/*
 	       	 * Cases that end up here:
 		 *
 		 * 5) HW interrupt done callback or other source.
+		 * 6) HW completed transfer during callback
 		 */
-		DPRINTFN(3, "case 5\n");
+		DPRINTFN(3, "case 5 and 6\n");
 
 		/*
 	         * We have to postpone the callback due to the fact we
 	         * will have a Lock Order Reversal, LOR, if we try to
-	         * proceed !
+	         * proceed!
+		 *
+		 * Postponing the callback also ensures that other USB
+		 * transfer queues get a chance.
 	         */
-		if (usb_proc_msignal(info->done_p,
-		    &info->done_m[0], &info->done_m[1])) {
-			/* ignore */
-		}
+		(void) usb_proc_msignal(info->done_p,
+		    &info->done_m[0], &info->done_m[1]);
 		return;
 	}
 	/*
@@ -2322,8 +2428,11 @@ usbd_callback_wrapper(struct usb_xfer_queue *pq)
 	}
 
 #if USB_HAVE_PF
-	if (xfer->usb_state != USB_ST_SETUP)
+	if (xfer->usb_state != USB_ST_SETUP) {
+		USB_BUS_LOCK(info->bus);
 		usbpf_xfertap(xfer, USBPF_XFERTAP_DONE);
+		USB_BUS_UNLOCK(info->bus);
+	}
 #endif
 	/* call processing routine */
 	(xfer->callback) (xfer, xfer->error);
@@ -2631,11 +2740,11 @@ usbd_pipe_start(struct usb_xfer_queue *pq)
 
 			if (udev->flags.usb_mode == USB_MODE_DEVICE) {
 				(udev->bus->methods->set_stall) (
-				    udev, NULL, ep, &did_stall);
+				    udev, ep, &did_stall);
 			} else if (udev->ctrl_xfer[1]) {
 				info = udev->ctrl_xfer[1]->xroot;
 				usb_proc_msignal(
-				    &info->bus->non_giant_callback_proc,
+				    USB_BUS_CS_PROC(info->bus),
 				    &udev->cs_msg[0], &udev->cs_msg[1]);
 			} else {
 				/* should not happen */
@@ -2914,10 +3023,11 @@ usbd_callback_wrapper_sub(struct usb_xfer *xfer)
 	 * next one:
 	 */
 	USB_BUS_LOCK(bus);
-	if (ep->endpoint_q.curr == xfer) {
-		usb_command_wrapper(&ep->endpoint_q, NULL);
+	if (ep->endpoint_q[xfer->stream_id].curr == xfer) {
+		usb_command_wrapper(&ep->endpoint_q[xfer->stream_id], NULL);
 
-		if (ep->endpoint_q.curr || TAILQ_FIRST(&ep->endpoint_q.head)) {
+		if (ep->endpoint_q[xfer->stream_id].curr != NULL ||
+		    TAILQ_FIRST(&ep->endpoint_q[xfer->stream_id].head) != NULL) {
 			/* there is another USB transfer waiting */
 		} else {
 			/* this is the last USB transfer */
@@ -2959,9 +3069,11 @@ usb_command_wrapper(struct usb_xfer_queue *pq, struct usb_xfer *xfer)
 
 	if (!pq->recurse_1) {
 
-		do {
+		/* clear third recurse flag */
+		pq->recurse_3 = 0;
 
-			/* set both recurse flags */
+		do {
+			/* set two first recurse flags */
 			pq->recurse_1 = 1;
 			pq->recurse_2 = 1;
 
@@ -2980,6 +3092,12 @@ usb_command_wrapper(struct usb_xfer_queue *pq, struct usb_xfer *xfer)
 			(pq->command) (pq);
 			DPRINTFN(6, "cb %p (leave)\n", pq->curr);
 
+			/*
+			 * Set third recurse flag to indicate
+			 * recursion happened:
+			 */
+			pq->recurse_3 = 1;
+
 		} while (!pq->recurse_2);
 
 		/* clear first recurse flag */
@@ -3251,11 +3369,14 @@ usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max)
 			drop_xfer++;
 		}
 
+#if USB_HAVE_PER_BUS_PROCESS
 		/* Make sure cv_signal() and cv_broadcast() is not called */
-		udev->bus->control_xfer_proc.up_msleep = 0;
-		udev->bus->explore_proc.up_msleep = 0;
-		udev->bus->giant_callback_proc.up_msleep = 0;
-		udev->bus->non_giant_callback_proc.up_msleep = 0;
+		USB_BUS_CONTROL_XFER_PROC(udev->bus)->up_msleep = 0;
+		USB_BUS_EXPLORE_PROC(udev->bus)->up_msleep = 0;
+		USB_BUS_GIANT_PROC(udev->bus)->up_msleep = 0;
+		USB_BUS_NON_GIANT_ISOC_PROC(udev->bus)->up_msleep = 0;
+		USB_BUS_NON_GIANT_BULK_PROC(udev->bus)->up_msleep = 0;
+#endif
 
 		/* poll USB hardware */
 		(udev->bus->methods->xfer_poll) (udev->bus);
diff --git a/freebsd/sys/dev/usb/usb_transfer.h b/freebsd/sys/dev/usb/usb_transfer.h
index 71157ca..f035240 100644
--- a/freebsd/sys/dev/usb/usb_transfer.h
+++ b/freebsd/sys/dev/usb/usb_transfer.h
@@ -28,6 +28,120 @@
 #define	_USB_TRANSFER_H_
 
 /*
+ * Definition of internal USB transfer states:
+ * ===========================================
+ *
+ * The main reason there are many USB states is that we are allowed to
+ * cancel USB transfers, then start the USB transfer again and that
+ * this state transaction cannot always be done in a single atomic
+ * operation without blocking the calling thread. One reason for this
+ * is that the USB hardware sometimes needs to wait for DMA
+ * controllers to finish which is done asynchronously and grows the
+ * statemachine.
+ *
+ * When extending the following statemachine there are basically two
+ * things you should think about: Which states should be executed or
+ * modified in case of USB transfer stop and which states should be
+ * executed or modified in case of USB transfer start. Also respect
+ * the "can_cancel_immed" flag which basically tells if you can go
+ * directly from a wait state to the cancelling states.
+ */
+
+enum {
+	/* XFER start execute state */
+
+	/* USB_ST_SETUP = 0 (already defined) */
+
+	/* XFER transferred execute state */
+
+	/* USB_ST_TRANSFERRED = 1 (already defined) */
+
+	/* XFER error execute state */
+
+	/* USB_ST_ERROR = 2 (already defined) */
+
+	/* XFER restart after error execute state */
+
+	USB_ST_RESTART = 8,
+
+	/* XFER transfer idle state */
+
+	USB_ST_WAIT_SETUP,
+
+	/* Other XFER execute states */
+
+	USB_ST_PIPE_OPEN = 16,
+	USB_ST_PIPE_OPEN_ERROR,
+	USB_ST_PIPE_OPEN_RESTART,
+
+	USB_ST_BDMA_LOAD,
+	USB_ST_BDMA_LOAD_ERROR,
+	USB_ST_BDMA_LOAD_RESTART,
+
+	USB_ST_IVAL_DLY,
+	USB_ST_IVAL_DLY_ERROR,
+	USB_ST_IVAL_DLY_RESTART,
+
+	USB_ST_PIPE_STALL,
+	USB_ST_PIPE_STALL_ERROR,
+	USB_ST_PIPE_STALL_RESTART,
+
+	USB_ST_ENTER,
+	USB_ST_ENTER_ERROR,
+	USB_ST_ENTER_RESTART,
+
+	USB_ST_START,
+	USB_ST_START_ERROR,
+	USB_ST_START_RESTART,
+
+	USB_ST_PIPE_CLOSE,
+	USB_ST_PIPE_CLOSE_ERROR,
+	USB_ST_PIPE_CLOSE_RESTART,
+
+	USB_ST_BDMA_DLY,
+	USB_ST_BDMA_DLY_ERROR,
+	USB_ST_BDMA_DLY_RESTART,
+
+	/* XFER transfer wait states */
+
+	USB_ST_WAIT_PIPE_OPEN = 64,
+	USB_ST_WAIT_PIPE_OPEN_ERROR,
+	USB_ST_WAIT_PIPE_OPEN_RESTART,
+
+	USB_ST_WAIT_BDMA_LOAD,
+	USB_ST_WAIT_BDMA_LOAD_ERROR,
+	USB_ST_WAIT_BDMA_LOAD_RESTART,
+
+	USB_ST_WAIT_IVAL_DLY,
+	USB_ST_WAIT_IVAL_DLY_ERROR,
+	USB_ST_WAIT_IVAL_DLY_RESTART,
+
+	USB_ST_WAIT_PIPE_STALL,
+	USB_ST_WAIT_PIPE_STALL_ERROR,
+	USB_ST_WAIT_PIPE_STALL_RESTART,
+
+	USB_ST_WAIT_ENTER,
+	USB_ST_WAIT_ENTER_ERROR,
+	USB_ST_WAIT_ENTER_RESTART,
+
+	USB_ST_WAIT_START,
+	USB_ST_WAIT_START_ERROR,
+	USB_ST_WAIT_START_RESTART,
+
+	USB_ST_WAIT_PIPE_CLOSE,
+	USB_ST_WAIT_PIPE_CLOSE_ERROR,
+	USB_ST_WAIT_PIPE_CLOSE_RESTART,
+
+	USB_ST_WAIT_BDMA_DLY,
+	USB_ST_WAIT_BDMA_DLY_ERROR,
+	USB_ST_WAIT_BDMA_DLY_RESTART,
+
+	USB_ST_WAIT_TRANSFERRED,
+	USB_ST_WAIT_TRANSFERRED_ERROR,
+	USB_ST_WAIT_TRANSFERRED_RESTART,
+};
+
+/*
  * The following structure defines the messages that is used to signal
  * the "done_p" USB process.
  */
diff --git a/freebsd/sys/dev/usb/usb_util.c b/freebsd/sys/dev/usb/usb_util.c
index 24558b8..316e9de 100644
--- a/freebsd/sys/dev/usb/usb_util.c
+++ b/freebsd/sys/dev/usb/usb_util.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/stdint.h>
 #include <sys/stddef.h>
 #include <rtems/bsd/sys/param.h>
@@ -58,6 +61,7 @@
 
 #include <dev/usb/usb_controller.h>
 #include <dev/usb/usb_bus.h>
+#endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 /*------------------------------------------------------------------------*
  *	device_set_usb_desc
diff --git a/freebsd/sys/dev/usb/usbdi.h b/freebsd/sys/dev/usb/usbdi.h
index 6ec26a4..ecd5a81 100644
--- a/freebsd/sys/dev/usb/usbdi.h
+++ b/freebsd/sys/dev/usb/usbdi.h
@@ -102,7 +102,9 @@ typedef void (usb_fifo_filter_t)(struct usb_fifo *fifo, struct usb_mbuf *m);
 
 
 /* USB events */
+#ifndef USB_GLOBAL_INCLUDE_FILE
 #include <sys/eventhandler.h>
+#endif
 typedef void (*usb_dev_configured_t)(void *, struct usb_device *,
     struct usb_attach_arg *);
 EVENTHANDLER_DECLARE(usb_dev_configured, usb_dev_configured_t);
@@ -126,6 +128,8 @@ struct usb_xfer_queue {
 	void    (*command) (struct usb_xfer_queue *pq);
 	uint8_t	recurse_1:1;
 	uint8_t	recurse_2:1;
+	uint8_t	recurse_3:1;
+	uint8_t	reserved:5;
 };
 
 /*
@@ -133,11 +137,12 @@ struct usb_xfer_queue {
  * USB endpoint.
  */
 struct usb_endpoint {
-	struct usb_xfer_queue endpoint_q;	/* queue of USB transfers */
+	/* queue of USB transfers */
+	struct usb_xfer_queue endpoint_q[USB_MAX_EP_STREAMS];
 
 	struct usb_endpoint_descriptor *edesc;
 	struct usb_endpoint_ss_comp_descriptor *ecomp;
-	struct usb_pipe_methods *methods;	/* set by HC driver */
+	const struct usb_pipe_methods *methods;	/* set by HC driver */
 
 	uint16_t isoc_next;
 
@@ -156,6 +161,10 @@ struct usb_endpoint {
 	uint8_t	usb_smask;		/* USB start mask */
 	uint8_t	usb_cmask;		/* USB complete mask */
 	uint8_t	usb_uframe;		/* USB microframe */
+
+	/* USB endpoint mode, see USB_EP_MODE_XXX */
+
+	uint8_t ep_mode;
 };
 
 /*
@@ -220,6 +229,7 @@ struct usb_config {
 #define	USB_DEFAULT_INTERVAL	0
 	usb_timeout_t timeout;		/* transfer timeout in milliseconds */
 	struct usb_xfer_flags flags;	/* transfer flags */
+	usb_stream_t stream_id;		/* USB3.0 specific */
 	enum usb_hc_mode usb_mode;	/* host or device mode */
 	uint8_t	type;			/* pipe type */
 	uint8_t	endpoint;		/* pipe number */
@@ -233,21 +243,21 @@ struct usb_config {
  * have your driver module automatically loaded in host, device or
  * both modes respectivly:
  */
-#ifndef __rtems__
+#if USB_HAVE_ID_SECTION
 #define	STRUCT_USB_HOST_ID \
     struct usb_device_id __section("usb_host_id")
 #define	STRUCT_USB_DEVICE_ID \
     struct usb_device_id __section("usb_device_id")
 #define	STRUCT_USB_DUAL_ID \
     struct usb_device_id __section("usb_dual_id")
-#else /* __rtems__ */
+#else
 #define	STRUCT_USB_HOST_ID \
     struct usb_device_id
 #define	STRUCT_USB_DEVICE_ID \
     struct usb_device_id
 #define	STRUCT_USB_DUAL_ID \
     struct usb_device_id
-#endif /* __rtems__ */
+#endif			/* USB_HAVE_ID_SECTION */
 
 /*
  * The following structure is used when looking up an USB driver for
@@ -486,6 +496,10 @@ usb_error_t	usbd_set_pnpinfo(struct usb_device *udev,
 			uint8_t iface_index, const char *pnpinfo);
 usb_error_t	usbd_add_dynamic_quirk(struct usb_device *udev,
 			uint16_t quirk);
+usb_error_t	usbd_set_endpoint_mode(struct usb_device *udev,
+			struct usb_endpoint *ep, uint8_t ep_mode);
+uint8_t		usbd_get_endpoint_mode(struct usb_device *udev,
+			struct usb_endpoint *ep);
 
 const struct usb_device_id *usbd_lookup_id_by_info(
 	    const struct usb_device_id *id, usb_size_t sizeof_id,
@@ -529,8 +543,7 @@ usb_frlength_t
 	usbd_xfer_old_frame_length(struct usb_xfer *xfer, usb_frcount_t frindex);
 void	usbd_xfer_status(struct usb_xfer *xfer, int *actlen, int *sumlen,
 	    int *aframes, int *nframes);
-struct usb_page_cache *usbd_xfer_get_frame(struct usb_xfer *xfer,
-	    usb_frcount_t frindex);
+struct usb_page_cache *usbd_xfer_get_frame(struct usb_xfer *, usb_frcount_t);
 void	*usbd_xfer_get_frame_buffer(struct usb_xfer *, usb_frcount_t);
 void	*usbd_xfer_softc(struct usb_xfer *xfer);
 void	*usbd_xfer_get_priv(struct usb_xfer *xfer);
diff --git a/freebsd/sys/dev/usb/usbhid.h b/freebsd/sys/dev/usb/usbhid.h
index f6c447c..28dfede 100644
--- a/freebsd/sys/dev/usb/usbhid.h
+++ b/freebsd/sys/dev/usb/usbhid.h
@@ -29,7 +29,9 @@
 #ifndef _USB_HID_H_
 #define	_USB_HID_H_
 
+#ifndef USB_GLOBAL_INCLUDE_FILE
 #include <dev/usb/usb_endian.h>
+#endif
 
 #define	UR_GET_HID_DESCRIPTOR	0x06
 #define	UDESC_HID		0x21
diff --git a/rtemsbsd/include/rtems/bsd/local/opt_usb.h b/rtemsbsd/include/rtems/bsd/local/opt_usb.h
index f964317..2945bc9 100644
--- a/rtemsbsd/include/rtems/bsd/local/opt_usb.h
+++ b/rtemsbsd/include/rtems/bsd/local/opt_usb.h
@@ -17,3 +17,5 @@
 #define USB_HAVE_TT_SUPPORT 1
 
 #define USB_HAVE_POWERD 1
+
+#define USB_HAVE_PER_BUS_PROCESS 1
diff --git a/rtemsbsd/include/rtems/bsd/local/usbdevs.h b/rtemsbsd/include/rtems/bsd/local/usbdevs.h
index 7472c00..cee4d28 100644
--- a/rtemsbsd/include/rtems/bsd/local/usbdevs.h
+++ b/rtemsbsd/include/rtems/bsd/local/usbdevs.h
@@ -459,6 +459,7 @@
 #define	USB_VENDOR_CONCORDCAMERA	0x0919		/* Concord Camera */
 #define	USB_VENDOR_GARMIN	0x091e		/* Garmin International */
 #define	USB_VENDOR_GOHUBS	0x0921		/* GoHubs */
+#define	USB_VENDOR_DYMO	0x0922		/* DYMO */
 #define	USB_VENDOR_XEROX	0x0924		/* Xerox */
 #define	USB_VENDOR_BIOMETRIC	0x0929		/* American Biometric Company */
 #define	USB_VENDOR_TOSHIBA	0x0930		/* Toshiba */
@@ -531,7 +532,7 @@
 #define	USB_VENDOR_CANYON	0x0c10		/* Canyon */
 #define	USB_VENDOR_ICOM	0x0c26		/* Icom Inc. */
 #define	USB_VENDOR_GNOTOMETRICS	0x0c33		/* GN Otometrics */
-#define	USB_VENDOR_CHICONY2	0x0c45		/* Chicony */
+#define	USB_VENDOR_CHICONY2	0x0c45		/* Chicony / Microdia / Sonix Technology Co., Ltd. */
 #define	USB_VENDOR_REINERSCT	0x0c4b		/* Reiner-SCT */
 #define	USB_VENDOR_SEALEVEL	0x0c52		/* Sealevel System */
 #define	USB_VENDOR_JETI	0x0c6c		/* Jeti */
@@ -693,6 +694,7 @@
 #define	USB_VENDOR_SWEEX2	0x177f		/* Sweex */
 #define	USB_VENDOR_METAGEEK	0x1781		/* MetaGeek */
 #define	USB_VENDOR_KAMSTRUP	0x17a8		/* Kamstrup A/S */
+#define	USB_VENDOR_DISPLAYLINK	0x17e9		/* DisplayLink */
 #define	USB_VENDOR_LENOVO	0x17ef		/* Lenovo */
 #define	USB_VENDOR_WAVESENSE	0x17f4		/* WaveSense */
 #define	USB_VENDOR_VAISALA	0x1843		/* Vaisala */
@@ -781,6 +783,7 @@
 #define	USB_VENDOR_NETGEAR4	0x9846		/* Netgear */
 #define	USB_VENDOR_MARVELL	0x9e88		/* Marvell Technology Group Ltd. */
 #define	USB_VENDOR_3COM3	0xa727		/* 3Com */
+#define	USB_VENDOR_CACE	0xcace		/* CACE Technologies */
 #define	USB_VENDOR_EVOLUTION	0xdeee		/* Evolution Robotics products */
 #define	USB_VENDOR_DATAAPEX	0xdaae		/* DataApex */
 #define	USB_VENDOR_HP2	0xf003		/* Hewlett Packard */
@@ -868,6 +871,7 @@
 #define	USB_PRODUCT_ACCTON_RT3070_5	0xd522		/* RT3070 */
 #define	USB_PRODUCT_ACCTON_RTL8192SU	0xc512		/* RTL8192SU */
 #define	USB_PRODUCT_ACCTON_ZD1211B	0xe501		/* ZD1211B */
+#define	USB_PRODUCT_ACCTON_WN7512	0xf522		/* WN7512 */
 
 /* Aceeca products */
 #define	USB_PRODUCT_ACEECA_MEZ1000	0x0001		/* MEZ1000 RDA */
@@ -1228,6 +1232,11 @@
 #define	USB_PRODUCT_ATHEROS2_AR5523_2_NF	0x0004		/* AR5523 (no firmware) */
 #define	USB_PRODUCT_ATHEROS2_AR5523_3	0x0005		/* AR5523 */
 #define	USB_PRODUCT_ATHEROS2_AR5523_3_NF	0x0006		/* AR5523 (no firmware) */
+#define	USB_PRODUCT_ATHEROS2_TG121N	0x1001		/* TG121N */
+#define	USB_PRODUCT_ATHEROS2_WN821NV2	0x1002		/* WN821NV2 */
+#define	USB_PRODUCT_ATHEROS2_3CRUSBN275	0x1010		/* 3CRUSBN275 */
+#define	USB_PRODUCT_ATHEROS2_WN612	0x1011		/* WN612 */
+#define	USB_PRODUCT_ATHEROS2_AR9170	0x9170		/* AR9170 */
 
 /* Atmel Comp. products */
 #define	USB_PRODUCT_ATMEL_STK541	0x2109		/* Zigbee Controller */
@@ -1243,6 +1252,9 @@
 /* Avision products */
 #define	USB_PRODUCT_AVISION_1200U	0x0268		/* 1200U scanner */
 
+/* AVM products */
+#define	USB_PRODUCT_AVM_FRITZWLAN	0x8401		/* FRITZ!WLAN N */
+
 /* Axesstel products */
 #define	USB_PRODUCT_AXESSTEL_DATAMODEM	0x1000		/* Data Modem */
 
@@ -1345,6 +1357,9 @@
 #define	USB_PRODUCT_BTC_BTC6100	0x5550		/* 6100C Keyboard */
 #define	USB_PRODUCT_BTC_BTC7932	0x6782		/* Keyboard with mouse port */
 
+/* CACE Technologies products */
+#define	USB_PRODUCT_CACE_AIRPCAPNX	0x0300		/* AirPcap NX */
+
 /* Canon, Inc. products */
 #define	USB_PRODUCT_CANON_N656U	0x2206		/* CanoScan N656U */
 #define	USB_PRODUCT_CANON_N1220U	0x2207		/* CanoScan N1220U */
@@ -1413,6 +1428,7 @@
 #define	USB_PRODUCT_CISCOLINKSYS_WUSB54GR	0x0023		/* WUSB54GR */
 #define	USB_PRODUCT_CISCOLINKSYS_WUSBF54G	0x0024		/* WUSBF54G */
 #define	USB_PRODUCT_CISCOLINKSYS_AE1000	0x002f		/* AE1000 */
+#define	USB_PRODUCT_CISCOLINKSYS_USB3GIGV1	0x0041		/* USB3GIGV1 USB Ethernet Adapter */
 #define	USB_PRODUCT_CISCOLINKSYS2_RT3070	0x4001		/* RT3070 */
 #define	USB_PRODUCT_CISCOLINKSYS3_RT3070	0x0101		/* RT3070 */
 
@@ -1604,6 +1620,7 @@
 #define	USB_PRODUCT_DLINK_DSB650TX4	0x200c		/* 10/100 Ethernet */
 #define	USB_PRODUCT_DLINK_DWL120E	0x3200		/* DWL-120 rev E */
 #define	USB_PRODUCT_DLINK_DWA125D1	0x330f		/* DWA-125 rev D1 */
+#define	USB_PRODUCT_DLINK_DWA123D1	0x3310		/* DWA-123 rev D1 */
 #define	USB_PRODUCT_DLINK_DWL122	0x3700		/* DWL-122 */
 #define	USB_PRODUCT_DLINK_DWLG120	0x3701		/* DWL-G120 */
 #define	USB_PRODUCT_DLINK_DWL120F	0x3702		/* DWL-120 rev F */
@@ -1643,8 +1660,10 @@
 #define	USB_PRODUCT_DLINK2_RTL8192SU_1	0x3300		/* RTL8192SU */
 #define	USB_PRODUCT_DLINK2_RTL8192SU_2	0x3302		/* RTL8192SU */
 #define	USB_PRODUCT_DLINK2_DWA131A1	0x3303		/* DWA-131 A1 */
+#define	USB_PRODUCT_DLINK2_DWA160A2	0x3a09		/* DWA-160 A2 */
 #define	USB_PRODUCT_DLINK2_DWA120	0x3a0c		/* DWA-120 */
 #define	USB_PRODUCT_DLINK2_DWA120_NF	0x3a0d		/* DWA-120 (no firmware) */
+#define	USB_PRODUCT_DLINK2_DWA130D1	0x3a0f		/* DWA-130 D1 */
 #define	USB_PRODUCT_DLINK2_DWLG122C1	0x3c03		/* DWL-G122 c1 */
 #define	USB_PRODUCT_DLINK2_WUA1340	0x3c04		/* WUA-1340 */
 #define	USB_PRODUCT_DLINK2_DWA111	0x3c06		/* DWA-111 */
@@ -1655,12 +1674,35 @@
 #define	USB_PRODUCT_DLINK2_RT3070_1	0x3c0d		/* RT3070 */
 #define	USB_PRODUCT_DLINK2_RT3070_2	0x3c0e		/* RT3070 */
 #define	USB_PRODUCT_DLINK2_RT3070_3	0x3c0f		/* RT3070 */
+#define	USB_PRODUCT_DLINK2_DWA160A1	0x3c10		/* DWA-160 A1 */
 #define	USB_PRODUCT_DLINK2_RT2870_2	0x3c11		/* RT2870 */
 #define	USB_PRODUCT_DLINK2_DWA130	0x3c13		/* DWA-130 */
 #define	USB_PRODUCT_DLINK2_RT3070_4	0x3c15		/* RT3070 */
 #define	USB_PRODUCT_DLINK2_RT3070_5	0x3c16		/* RT3070 */
 #define	USB_PRODUCT_DLINK3_DWM652	0x3e04		/* DWM-652 */
 
+/* DisplayLink products */
+#define	USB_PRODUCT_DISPLAYLINK_LCD4300U	0x01ba		/* LCD-4300U */
+#define	USB_PRODUCT_DISPLAYLINK_LCD8000U	0x01bb		/* LCD-8000U */
+#define	USB_PRODUCT_DISPLAYLINK_LD220	0x0100		/* Samsung LD220 */
+#define	USB_PRODUCT_DISPLAYLINK_GUC2020	0x0059		/* IOGEAR DVI GUC2020 */
+#define	USB_PRODUCT_DISPLAYLINK_VCUD60	0x0136		/* Rextron DVI */
+#define	USB_PRODUCT_DISPLAYLINK_CONV	0x0138		/* StarTech CONV-USB2DVI */
+#define	USB_PRODUCT_DISPLAYLINK_DLDVI	0x0141		/* DisplayLink DVI */
+#define	USB_PRODUCT_DISPLAYLINK_VGA10	0x015a		/* CMP-USBVGA10 */
+#define	USB_PRODUCT_DISPLAYLINK_WSDVI	0x0198		/* WS Tech DVI */
+#define	USB_PRODUCT_DISPLAYLINK_EC008	0x019b		/* EasyCAP008 DVI */
+#define	USB_PRODUCT_DISPLAYLINK_HPDOCK	0x01d4		/* HP USB Docking */
+#define	USB_PRODUCT_DISPLAYLINK_NL571	0x01d7		/* HP USB DVI */
+#define	USB_PRODUCT_DISPLAYLINK_M01061	0x01e2		/* Lenovo DVI */
+#define	USB_PRODUCT_DISPLAYLINK_SWDVI	0x024c		/* SUNWEIT DVI */
+#define	USB_PRODUCT_DISPLAYLINK_NBDOCK	0x0215		/* VideoHome NBdock1920 */
+#define	USB_PRODUCT_DISPLAYLINK_LUM70	0x02a9		/* Lilliput UM-70 */
+#define	USB_PRODUCT_DISPLAYLINK_UM7X0	0x401a		/* nanovision MiMo */
+#define	USB_PRODUCT_DISPLAYLINK_LT1421	0x03e0		/* Lenovo ThinkVision LT1421 */
+#define	USB_PRODUCT_DISPLAYLINK_POLARIS2	0x0117		/* Polaris2 USB dock */
+#define	USB_PRODUCT_DISPLAYLINK_PLUGABLE	0x0377		/* Plugable docking station */
+
 /* DMI products */
 #define	USB_PRODUCT_DMI_CFSM_RW	0xa109		/* CF/SM Reader/Writer */
 #define	USB_PRODUCT_DMI_DISK	0x2bcf		/* Generic Disk */
@@ -1677,6 +1719,9 @@
 #define	USB_PRODUCT_DRESDENELEKTRONIK_DE_RFNODE	0x001c		/* deRFnode */
 #define	USB_PRODUCT_DRESDENELEKTRONIK_LEVELSHIFTERSTICKLOWCOST	0x0022		/* Levelshifter Stick Low Cost */
 
+/* DYMO */
+#define	USB_PRODUCT_DYMO_LABELMANAGERPNP	0x1001		/* DYMO LabelManager PnP */
+
 /* Dynastream Innovations */
 #define	USB_PRODUCT_DYNASTREAM_ANTDEVBOARD	0x1003		/* ANT dev board */
 #define	USB_PRODUCT_DYNASTREAM_ANT2USB	0x1004		/* ANT2USB */
@@ -1718,6 +1763,7 @@
 #define	USB_PRODUCT_ELECOM_LDUSBTX0	0x200c		/* LD-USB/TX */
 #define	USB_PRODUCT_ELECOM_LDUSBTX1	0x4002		/* LD-USB/TX */
 #define	USB_PRODUCT_ELECOM_LDUSBLTX	0x4005		/* LD-USBL/TX */
+#define	USB_PRODUCT_ELECOM_WDC150SU2M	0x4008		/* WDC-150SU2M */
 #define	USB_PRODUCT_ELECOM_LDUSBTX2	0x400b		/* LD-USB/TX */
 #define	USB_PRODUCT_ELECOM_LDUSB20	0x4010		/* LD-USB20 */
 #define	USB_PRODUCT_ELECOM_UCSGT	0x5003		/* UC-SGT */
@@ -1854,6 +1900,7 @@
 #define	USB_PRODUCT_FSC_E5400	0x1009		/* PrismGT USB 2.0 WLAN */
 
 /* Future Technology Devices products */
+#define	USB_PRODUCT_FTDI_SCX8_USB_PHOENIX	0x5259		/* SCx8 USB Phoenix interface */
 #define	USB_PRODUCT_FTDI_SERIAL_8U100AX	0x8372		/* 8U100AX Serial */
 #define	USB_PRODUCT_FTDI_SERIAL_8U232AM	0x6001		/* 8U232AM Serial */
 #define	USB_PRODUCT_FTDI_SERIAL_8U232AM4	0x6004		/* 8U232AM Serial */
@@ -2366,6 +2413,7 @@
 #define	USB_PRODUCT_HUAWEI_K4505_INIT	0x1521		/* K4505 Initial */
 #define	USB_PRODUCT_HUAWEI_K3772_INIT	0x1526		/* K3772 Initial */
 #define	USB_PRODUCT_HUAWEI_E3272_INIT	0x155b		/* LTE modem initial */
+#define	USB_PRODUCT_HUAWEI_ME909U	0x1573		/* LTE modem */
 #define	USB_PRODUCT_HUAWEI_R215_INIT	0x1582		/* LTE modem initial */
 #define	USB_PRODUCT_HUAWEI_R215	0x1588		/* LTE modem */
 #define	USB_PRODUCT_HUAWEI_ETS2055	0x1803		/* CDMA modem */
@@ -2444,6 +2492,7 @@
 #define	USB_PRODUCT_IODATA_USBWNB11A	0x0919		/* USB WN-B11 */
 #define	USB_PRODUCT_IODATA_USBWNB11	0x0922		/* USB Airport WN-B11 */
 #define	USB_PRODUCT_IODATA_ETGUS2	0x0930		/* ETG-US2 */
+#define	USB_PRODUCT_IODATA_WNGDNUS2	0x093f		/* WN-GDN/US2 */
 #define	USB_PRODUCT_IODATA_RT3072_1	0x0944		/* RT3072 */
 #define	USB_PRODUCT_IODATA_RT3072_2	0x0945		/* RT3072 */
 #define	USB_PRODUCT_IODATA_RT3072_3	0x0947		/* RT3072 */
@@ -2609,6 +2658,7 @@
 #define	USB_PRODUCT_LEADTEK_9531	0x2101		/* 9531 GPS */
 
 /* Lenovo products */
+#define	USB_PRODUCT_LENOVO_GIGALAN	0x304b		/* USB 3.0 Ethernet */
 #define	USB_PRODUCT_LENOVO_ETHERNET	0x7203		/* USB 2.0 Ethernet */
 
 /* Lexar products */
@@ -2998,11 +3048,12 @@
 #define	USB_PRODUCT_MELCO_WLRUCGAOSS	0x0119		/* WLR-UC-G-AOSS */
 #define	USB_PRODUCT_MELCO_WLIUCAG300N	0x012e		/* WLI-UC-AG300N */
 #define	USB_PRODUCT_MELCO_WLIUCG	0x0137		/* WLI-UC-G */
-#define	USB_PRODUCT_MELCO_RT2870_1	0x0148		/* RT2870 */
+#define	USB_PRODUCT_MELCO_WLIUCG300HP	0x0148		/* WLI-UC-G300HP */
 #define	USB_PRODUCT_MELCO_RT2870_2	0x0150		/* RT2870 */
 #define	USB_PRODUCT_MELCO_WLIUCGN	0x015d		/* WLI-UC-GN */
 #define	USB_PRODUCT_MELCO_WLIUCG301N	0x016f		/* WLI-UC-G301N */
 #define	USB_PRODUCT_MELCO_WLIUCGNM	0x01a2		/* WLI-UC-GNM */
+#define	USB_PRODUCT_MELCO_WLIUCG300HPV1	0x01a8		/* WLI-UC-G300HP-V1 */
 #define	USB_PRODUCT_MELCO_WLIUCGNM2	0x01ee		/* WLI-UC-GNM2 */
 
 /* Merlin products */
@@ -3025,6 +3076,11 @@
 #define	USB_PRODUCT_MEI_CASHFLOW_SC	0x1100		/* Cashflow-SC Cash Acceptor */
 #define	USB_PRODUCT_MEI_S2000	0x1101		/* Series 2000 Combo Acceptor */
 
+/* Microdia / Sonix Techonology Co., Ltd. products */
+#define	USB_PRODUCT_CHICONY2_YUREX	0x1010		/* YUREX */
+#define	USB_PRODUCT_CHICONY2_CAM_1	0x62c0		/* CAM_1 */
+#define	USB_PRODUCT_CHICONY2_TEMPER	0x7401		/* TEMPer sensor */
+
 /* Micro Star International products */
 #define	USB_PRODUCT_MSI_BT_DONGLE	0x1967		/* Bluetooth USB dongle */
 #define	USB_PRODUCT_MSI_RT3070_1	0x3820		/* RT3070 */
@@ -3177,6 +3233,7 @@
 /* NEC products */
 #define	USB_PRODUCT_NEC_HUB_0050	0x0050		/* USB 2.0 7-Port Hub */
 #define	USB_PRODUCT_NEC_HUB_005A	0x005a		/* USB 2.0 4-Port Hub */
+#define	USB_PRODUCT_NEC_WL300NUG	0x0249		/* WL300NU-G */
 #define	USB_PRODUCT_NEC_HUB	0x55aa		/* hub */
 #define	USB_PRODUCT_NEC_HUB_B	0x55ab		/* hub */
 
@@ -3204,12 +3261,17 @@
 #define	USB_PRODUCT_NETGEAR_FA101	0x1020		/* Ethernet 10/100, USB1.1 */
 #define	USB_PRODUCT_NETGEAR_FA120	0x1040		/* USB 2.0 Ethernet */
 #define	USB_PRODUCT_NETGEAR_M4100	0x1100		/* M4100/M5300/M7100 series switch */
-#define	USB_PRODUCT_NETGEAR_WG111V2_2	0x4240		/* PrismGT USB 2.0 WLAN */
+#define	USB_PRODUCT_NETGEAR_WG111V1_2	0x4240		/* PrismGT USB 2.0 WLAN */
 #define	USB_PRODUCT_NETGEAR_WG111V3	0x4260		/* WG111v3 */
 #define	USB_PRODUCT_NETGEAR_WG111U	0x4300		/* WG111U */
 #define	USB_PRODUCT_NETGEAR_WG111U_NF	0x4301		/* WG111U (no firmware) */
 #define	USB_PRODUCT_NETGEAR_WG111V2	0x6a00		/* WG111V2 */
+#define	USB_PRODUCT_NETGEAR_WN111V2	0x9001		/* WN111V2 */
+#define	USB_PRODUCT_NETGEAR_WNDA3100	0x9010		/* WNDA3100 */
+#define	USB_PRODUCT_NETGEAR_WNDA4100	0x9012		/* WNDA4100 */
+#define	USB_PRODUCT_NETGEAR_WNDA3200	0x9018		/* WNDA3200 */
 #define	USB_PRODUCT_NETGEAR_RTL8192CU	0x9021		/* RTL8192CU */
+#define	USB_PRODUCT_NETGEAR_WNA1000	0x9040		/* WNA1000 */
 #define	USB_PRODUCT_NETGEAR_WNA1000M	0x9041		/* WNA1000M */
 #define	USB_PRODUCT_NETGEAR2_MA101	0x4100		/* MA101 */
 #define	USB_PRODUCT_NETGEAR2_MA101B	0x4102		/* MA101 Rev B */
@@ -3473,6 +3535,7 @@
 #define	USB_PRODUCT_PLANEX2_RTL8188CUS	0x1201		/* RTL8188CUS */
 #define	USB_PRODUCT_PLANEX2_GW_US11S	0x3220		/* GW-US11S WLAN */
 #define	USB_PRODUCT_PLANEX2_GW_US54GXS	0x5303		/* GW-US54GXS WLAN */
+#define	USB_PRODUCT_PLANEX2_GW_US300	0x5304		/* GW-US300 */
 #define	USB_PRODUCT_PLANEX2_RTL8188CU_1	0xab2a		/* RTL8188CU */
 #define	USB_PRODUCT_PLANEX2_RTL8188CU_2	0xed17		/* RTL8188CU */
 #define	USB_PRODUCT_PLANEX2_RTL8188CU_3	0x4902		/* RTL8188CU */
@@ -3653,6 +3716,7 @@
 #define	USB_PRODUCT_QUALCOMMINC_E0078	0x0078		/* 3G modem */
 #define	USB_PRODUCT_QUALCOMMINC_E0082	0x0082		/* 3G modem */
 #define	USB_PRODUCT_QUALCOMMINC_E0086	0x0086		/* 3G modem */
+#define	USB_PRODUCT_QUALCOMMINC_MF112	0x0103		/* 3G modem */
 #define	USB_PRODUCT_QUALCOMMINC_SURFSTICK	0x0117		/* 1&1 Surf Stick */
 #define	USB_PRODUCT_QUALCOMMINC_K3772_Z_INIT	0x1179		/* K3772-Z Initial */
 #define	USB_PRODUCT_QUALCOMMINC_K3772_Z	0x1181		/* K3772-Z */
@@ -3723,6 +3787,7 @@
 #define	USB_PRODUCT_REALTEK_RTL8188ETV	0x0179		/* RTL8188ETV */
 #define	USB_PRODUCT_REALTEK_RTL8188CTV	0x018a		/* RTL8188CTV */
 #define	USB_PRODUCT_REALTEK_USBKR100	0x8150		/* USBKR100 USB Ethernet */
+#define	USB_PRODUCT_REALTEK_RTL8153	0x8153		/* RTL8153 USB Ethernet */
 #define	USB_PRODUCT_REALTEK_RTL8188CE_0	0x8170		/* RTL8188CE */
 #define	USB_PRODUCT_REALTEK_RTL8171	0x8171		/* RTL8171 */
 #define	USB_PRODUCT_REALTEK_RTL8172	0x8172		/* RTL8172 */
@@ -3735,6 +3800,7 @@
 #define	USB_PRODUCT_REALTEK_RTL8188CU_2	0x817b		/* RTL8188CU */
 #define	USB_PRODUCT_REALTEK_RTL8187	0x8187		/* RTL8187 Wireless Adapter */
 #define	USB_PRODUCT_REALTEK_RTL8187B_0	0x8189		/* RTL8187B Wireless Adapter */
+#define	USB_PRODUCT_REALTEK_RTL8188CU_3	0x8191		/* RTL8188CU */
 #define	USB_PRODUCT_REALTEK_RTL8196EU	0x8196		/* RTL8196EU */
 #define	USB_PRODUCT_REALTEK_RTL8187B_1	0x8197		/* RTL8187B Wireless Adapter */
 #define	USB_PRODUCT_REALTEK_RTL8187B_2	0x8198		/* RTL8187B Wireless Adapter */
@@ -4008,7 +4074,8 @@
 #define	USB_PRODUCT_SIERRA_E6892	0x6892		/* E6892 */
 #define	USB_PRODUCT_SIERRA_E6893	0x6893		/* E6893 */
 #define	USB_PRODUCT_SIERRA_MC8700	0x68A3		/* MC8700 */
-#define	USB_PRODUCT_SIERRA_AIRCARD875	0x6820		/* Aircard 875 HSDPA */
+#define	USB_PRODUCT_SIERRA_MC7354	0x68C0		/* MC7354 */
+#define	USB_PRODUCT_SIERRA_MC7355	0x9041		/* MC7355 */
 #define	USB_PRODUCT_SIERRA_AC313U	0x68aa		/* Sierra Wireless AirCard 313U */
 #define	USB_PRODUCT_SIERRA_TRUINSTALL	0x0fff		/* Aircard Tru Installer */
 
@@ -4387,6 +4454,7 @@
 
 /* TRENDnet products */
 #define	USB_PRODUCT_TRENDNET_RTL8192CU	0x624d		/* RTL8192CU */
+#define	USB_PRODUCT_TRENDNET_TEW646UBH	0x646b		/* TEW-646UBH */
 #define	USB_PRODUCT_TRENDNET_RTL8188CU	0x648b		/* RTL8188CU */
 
 /* Tripp-Lite products */
@@ -4540,8 +4608,10 @@
 #define	USB_PRODUCT_WINMAXGROUP_FLASH64MC	0x6660		/* USB Flash Disk 64M-C */
 
 /* Wistron NeWeb products */
+#define	USB_PRODUCT_WISTRONNEWEB_WNC0600	0x0326		/* WNC-0600USB */
 #define	USB_PRODUCT_WISTRONNEWEB_UR045G	0x0427		/* PrismGT USB 2.0 WLAN */
 #define	USB_PRODUCT_WISTRONNEWEB_UR055G	0x0711		/* UR055G */
+#define	USB_PRODUCT_WISTRONNEWEB_O8494	0x0804		/* ORiNOCO 802.11n */
 #define	USB_PRODUCT_WISTRONNEWEB_AR5523_1	0x0826		/* AR5523 */
 #define	USB_PRODUCT_WISTRONNEWEB_AR5523_1_NF	0x0827		/* AR5523 (no firmware) */
 #define	USB_PRODUCT_WISTRONNEWEB_AR5523_2	0x082a		/* AR5523 */
@@ -4590,7 +4660,9 @@
 #define	USB_PRODUCT_ZCOM_XM142	0x0015		/* XM-142 */
 #define	USB_PRODUCT_ZCOM_ZD1211B	0x001a		/* ZD1211B */
 #define	USB_PRODUCT_ZCOM_RT2870_1	0x0022		/* RT2870 */
+#define	USB_PRODUCT_ZCOM_UB81	0x0023		/* UB81 */
 #define	USB_PRODUCT_ZCOM_RT2870_2	0x0025		/* RT2870 */
+#define	USB_PRODUCT_ZCOM_UB82	0x0026		/* UB82 */
 
 /* Zinwell products */
 #define	USB_PRODUCT_ZINWELL_RT2570	0x0260		/* RT2570 */
@@ -4609,6 +4681,7 @@
 /* Zydas Technology Corporation products */
 #define	USB_PRODUCT_ZYDAS_ZD1211	0x1211		/* ZD1211 WLAN abg */
 #define	USB_PRODUCT_ZYDAS_ZD1211B	0x1215		/* ZD1211B */
+#define	USB_PRODUCT_ZYDAS_ZD1221	0x1221		/* ZD1221 */
 
 /* ZyXEL Communication Co. products */
 #define	USB_PRODUCT_ZYXEL_OMNI56K	0x1500		/* Omni 56K Plus */
@@ -4620,6 +4693,8 @@
 #define	USB_PRODUCT_ZYXEL_G220V2	0x340f		/* G-220 v2 */
 #define	USB_PRODUCT_ZYXEL_G202	0x3410		/* G-202 */
 #define	USB_PRODUCT_ZYXEL_RT2870_1	0x3416		/* RT2870 */
+#define	USB_PRODUCT_ZYXEL_NWD271N	0x3417		/* NWD-271N */
+#define	USB_PRODUCT_ZYXEL_NWD211AN	0x3418		/* NWD-211AN */
 #define	USB_PRODUCT_ZYXEL_RT2870_2	0x341a		/* RT2870 */
 #define	USB_PRODUCT_ZYXEL_RT3070	0x341e		/* NWD2105 */
 #define	USB_PRODUCT_ZYXEL_RTL8192CU	0x341f		/* RTL8192CU */
diff --git a/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h b/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h
index 71eee37..945b06c 100644
--- a/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h
+++ b/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h
@@ -454,6 +454,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "ZD1211B",
 	},
 	{
+	    USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_WN7512,
+	    0,
+	    "Accton Technology",
+	    "WN7512",
+	},
+	{
 	    USB_VENDOR_ACEECA, USB_PRODUCT_ACEECA_MEZ1000,
 	    0,
 	    "Aceeca",
@@ -1858,6 +1864,36 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "AR5523 (no firmware)",
 	},
 	{
+	    USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_TG121N,
+	    0,
+	    "Atheros Communications",
+	    "TG121N",
+	},
+	{
+	    USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_WN821NV2,
+	    0,
+	    "Atheros Communications",
+	    "WN821NV2",
+	},
+	{
+	    USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_3CRUSBN275,
+	    0,
+	    "Atheros Communications",
+	    "3CRUSBN275",
+	},
+	{
+	    USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_WN612,
+	    0,
+	    "Atheros Communications",
+	    "WN612",
+	},
+	{
+	    USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9170,
+	    0,
+	    "Atheros Communications",
+	    "AR9170",
+	},
+	{
 	    USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_STK541,
 	    0,
 	    "Atmel",
@@ -1906,6 +1942,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "1200U scanner",
 	},
 	{
+	    USB_VENDOR_AVM, USB_PRODUCT_AVM_FRITZWLAN,
+	    0,
+	    "AVM",
+	    "FRITZ!WLAN N",
+	},
+	{
 	    USB_VENDOR_AXESSTEL, USB_PRODUCT_AXESSTEL_DATAMODEM,
 	    0,
 	    "Axesstel Co., Ltd.",
@@ -2386,6 +2428,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "Keyboard with mouse port",
 	},
 	{
+	    USB_VENDOR_CACE, USB_PRODUCT_CACE_AIRPCAPNX,
+	    0,
+	    "CACE Technologies",
+	    "AirPcap NX",
+	},
+	{
 	    USB_VENDOR_CANON, USB_PRODUCT_CANON_N656U,
 	    0,
 	    "Canon",
@@ -2598,7 +2646,7 @@ const struct usb_knowndev usb_knowndevs[] = {
 	{
 	    USB_VENDOR_CHICONY2, USB_PRODUCT_CHICONY2_TWINKLECAM,
 	    0,
-	    "Chicony",
+	    "Chicony / Microdia / Sonix Technology Co., Ltd.",
 	    "TwinkleCam USB camera",
 	},
 	{
@@ -2680,6 +2728,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "AE1000",
 	},
 	{
+	    USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB3GIGV1,
+	    0,
+	    "Cisco-Linksys",
+	    "USB3GIGV1 USB Ethernet Adapter",
+	},
+	{
 	    USB_VENDOR_CISCOLINKSYS2, USB_PRODUCT_CISCOLINKSYS2_RT3070,
 	    0,
 	    "Cisco-Linksys",
@@ -3472,6 +3526,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "DWA-125 rev D1",
 	},
 	{
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA123D1,
+	    0,
+	    "D-Link",
+	    "DWA-123 rev D1",
+	},
+	{
 	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWL122,
 	    0,
 	    "D-Link",
@@ -3706,6 +3766,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "DWA-131 A1",
 	},
 	{
+	    USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160A2,
+	    0,
+	    "D-Link",
+	    "DWA-160 A2",
+	},
+	{
 	    USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA120,
 	    0,
 	    "D-Link",
@@ -3718,6 +3784,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "DWA-120 (no firmware)",
 	},
 	{
+	    USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA130D1,
+	    0,
+	    "D-Link",
+	    "DWA-130 D1",
+	},
+	{
 	    USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWLG122C1,
 	    0,
 	    "D-Link",
@@ -3778,6 +3850,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT3070",
 	},
 	{
+	    USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160A1,
+	    0,
+	    "D-Link",
+	    "DWA-160 A1",
+	},
+	{
 	    USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT2870_2,
 	    0,
 	    "D-Link",
@@ -3808,6 +3886,126 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "DWM-652",
 	},
 	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LCD4300U,
+	    0,
+	    "DisplayLink",
+	    "LCD-4300U",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LCD8000U,
+	    0,
+	    "DisplayLink",
+	    "LCD-8000U",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LD220,
+	    0,
+	    "DisplayLink",
+	    "Samsung LD220",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_GUC2020,
+	    0,
+	    "DisplayLink",
+	    "IOGEAR DVI GUC2020",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_VCUD60,
+	    0,
+	    "DisplayLink",
+	    "Rextron DVI",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_CONV,
+	    0,
+	    "DisplayLink",
+	    "StarTech CONV-USB2DVI",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_DLDVI,
+	    0,
+	    "DisplayLink",
+	    "DisplayLink DVI",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_VGA10,
+	    0,
+	    "DisplayLink",
+	    "CMP-USBVGA10",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_WSDVI,
+	    0,
+	    "DisplayLink",
+	    "WS Tech DVI",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_EC008,
+	    0,
+	    "DisplayLink",
+	    "EasyCAP008 DVI",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_HPDOCK,
+	    0,
+	    "DisplayLink",
+	    "HP USB Docking",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_NL571,
+	    0,
+	    "DisplayLink",
+	    "HP USB DVI",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_M01061,
+	    0,
+	    "DisplayLink",
+	    "Lenovo DVI",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_SWDVI,
+	    0,
+	    "DisplayLink",
+	    "SUNWEIT DVI",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_NBDOCK,
+	    0,
+	    "DisplayLink",
+	    "VideoHome NBdock1920",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LUM70,
+	    0,
+	    "DisplayLink",
+	    "Lilliput UM-70",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_UM7X0,
+	    0,
+	    "DisplayLink",
+	    "nanovision MiMo",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LT1421,
+	    0,
+	    "DisplayLink",
+	    "Lenovo ThinkVision LT1421",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_POLARIS2,
+	    0,
+	    "DisplayLink",
+	    "Polaris2 USB dock",
+	},
+	{
+	    USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_PLUGABLE,
+	    0,
+	    "DisplayLink",
+	    "Plugable docking station",
+	},
+	{
 	    USB_VENDOR_DMI, USB_PRODUCT_DMI_CFSM_RW,
 	    0,
 	    "DMI",
@@ -3856,6 +4054,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "Levelshifter Stick Low Cost",
 	},
 	{
+	    USB_VENDOR_DYMO, USB_PRODUCT_DYMO_LABELMANAGERPNP,
+	    0,
+	    "DYMO",
+	    "DYMO LabelManager PnP",
+	},
+	{
 	    USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTDEVBOARD,
 	    0,
 	    "Dynastream Innovations",
@@ -4012,6 +4216,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "LD-USBL/TX",
 	},
 	{
+	    USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_WDC150SU2M,
+	    0,
+	    "Elecom",
+	    "WDC-150SU2M",
+	},
+	{
 	    USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX2,
 	    0,
 	    "Elecom",
@@ -4552,6 +4762,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "PrismGT USB 2.0 WLAN",
 	},
 	{
+	    USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCX8_USB_PHOENIX,
+	    0,
+	    "Future Technology Devices",
+	    "SCx8 USB Phoenix interface",
+	},
+	{
 	    USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U100AX,
 	    0,
 	    "Future Technology Devices",
@@ -7246,6 +7462,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "LTE modem initial",
 	},
 	{
+	    USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_ME909U,
+	    0,
+	    "Huawei Technologies",
+	    "LTE modem",
+	},
+	{
 	    USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_R215_INIT,
 	    0,
 	    "Huawei Technologies",
@@ -7558,6 +7780,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "ETG-US2",
 	},
 	{
+	    USB_VENDOR_IODATA, USB_PRODUCT_IODATA_WNGDNUS2,
+	    0,
+	    "I-O Data",
+	    "WN-GDN/US2",
+	},
+	{
 	    USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RT3072_1,
 	    0,
 	    "I-O Data",
@@ -8200,6 +8428,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "9531 GPS",
 	},
 	{
+	    USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_GIGALAN,
+	    0,
+	    "Lenovo",
+	    "USB 3.0 Ethernet",
+	},
+	{
 	    USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_ETHERNET,
 	    0,
 	    "Lenovo",
@@ -10288,10 +10522,10 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "WLI-UC-G",
 	},
 	{
-	    USB_VENDOR_MELCO, USB_PRODUCT_MELCO_RT2870_1,
+	    USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCG300HP,
 	    0,
 	    "Melco",
-	    "RT2870",
+	    "WLI-UC-G300HP",
 	},
 	{
 	    USB_VENDOR_MELCO, USB_PRODUCT_MELCO_RT2870_2,
@@ -10318,6 +10552,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "WLI-UC-GNM",
 	},
 	{
+	    USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCG300HPV1,
+	    0,
+	    "Melco",
+	    "WLI-UC-G300HP-V1",
+	},
+	{
 	    USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCGNM2,
 	    0,
 	    "Melco",
@@ -10384,6 +10624,24 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "Series 2000 Combo Acceptor",
 	},
 	{
+	    USB_VENDOR_CHICONY2, USB_PRODUCT_CHICONY2_YUREX,
+	    0,
+	    "Chicony / Microdia / Sonix Technology Co., Ltd.",
+	    "YUREX",
+	},
+	{
+	    USB_VENDOR_CHICONY2, USB_PRODUCT_CHICONY2_CAM_1,
+	    0,
+	    "Chicony / Microdia / Sonix Technology Co., Ltd.",
+	    "CAM_1",
+	},
+	{
+	    USB_VENDOR_CHICONY2, USB_PRODUCT_CHICONY2_TEMPER,
+	    0,
+	    "Chicony / Microdia / Sonix Technology Co., Ltd.",
+	    "TEMPer sensor",
+	},
+	{
 	    USB_VENDOR_MSI, USB_PRODUCT_MSI_BT_DONGLE,
 	    0,
 	    "Micro Star International",
@@ -11050,6 +11308,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "USB 2.0 4-Port Hub",
 	},
 	{
+	    USB_VENDOR_NEC, USB_PRODUCT_NEC_WL300NUG,
+	    0,
+	    "NEC",
+	    "WL300NU-G",
+	},
+	{
 	    USB_VENDOR_NEC, USB_PRODUCT_NEC_HUB,
 	    0,
 	    "NEC",
@@ -11152,7 +11416,7 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "M4100/M5300/M7100 series switch",
 	},
 	{
-	    USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111V2_2,
+	    USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111V1_2,
 	    0,
 	    "BayNETGEAR",
 	    "PrismGT USB 2.0 WLAN",
@@ -11182,12 +11446,42 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "WG111V2",
 	},
 	{
+	    USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WN111V2,
+	    0,
+	    "BayNETGEAR",
+	    "WN111V2",
+	},
+	{
+	    USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNDA3100,
+	    0,
+	    "BayNETGEAR",
+	    "WNDA3100",
+	},
+	{
+	    USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNDA4100,
+	    0,
+	    "BayNETGEAR",
+	    "WNDA4100",
+	},
+	{
+	    USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNDA3200,
+	    0,
+	    "BayNETGEAR",
+	    "WNDA3200",
+	},
+	{
 	    USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_RTL8192CU,
 	    0,
 	    "BayNETGEAR",
 	    "RTL8192CU",
 	},
 	{
+	    USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000,
+	    0,
+	    "BayNETGEAR",
+	    "WNA1000",
+	},
+	{
 	    USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000M,
 	    0,
 	    "BayNETGEAR",
@@ -12394,6 +12688,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "GW-US54GXS WLAN",
 	},
 	{
+	    USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US300,
+	    0,
+	    "Planex Communications",
+	    "GW-US300",
+	},
+	{
 	    USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_1,
 	    0,
 	    "Planex Communications",
@@ -13318,6 +13618,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "3G modem",
 	},
 	{
+	    USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_MF112,
+	    0,
+	    "Qualcomm, Incorporated",
+	    "3G modem",
+	},
+	{
 	    USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_SURFSTICK,
 	    0,
 	    "Qualcomm, Incorporated",
@@ -13636,6 +13942,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "USBKR100 USB Ethernet",
 	},
 	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8153,
+	    0,
+	    "Realtek",
+	    "RTL8153 USB Ethernet",
+	},
+	{
 	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CE_0,
 	    0,
 	    "Realtek",
@@ -13708,6 +14020,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RTL8187B Wireless Adapter",
 	},
 	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_3,
+	    0,
+	    "Realtek",
+	    "RTL8188CU",
+	},
+	{
 	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8196EU,
 	    0,
 	    "Realtek",
@@ -15058,10 +15376,16 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "MC8700",
 	},
 	{
-	    USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD875,
+	    USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC7354,
+	    0,
+	    "Sierra Wireless",
+	    "MC7354",
+	},
+	{
+	    USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC7355,
 	    0,
 	    "Sierra Wireless",
-	    "Aircard 875 HSDPA",
+	    "MC7355",
 	},
 	{
 	    USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC313U,
@@ -16672,6 +16996,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RTL8192CU",
 	},
 	{
+	    USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_TEW646UBH,
+	    0,
+	    "TRENDnet",
+	    "TEW-646UBH",
+	},
+	{
 	    USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8188CU,
 	    0,
 	    "TRENDnet",
@@ -17218,6 +17548,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "USB Flash Disk 64M-C",
 	},
 	{
+	    USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_WNC0600,
+	    0,
+	    "Wistron NeWeb",
+	    "WNC-0600USB",
+	},
+	{
 	    USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_UR045G,
 	    0,
 	    "Wistron NeWeb",
@@ -17230,6 +17566,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "UR055G",
 	},
 	{
+	    USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_O8494,
+	    0,
+	    "Wistron NeWeb",
+	    "ORiNOCO 802.11n",
+	},
+	{
 	    USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_AR5523_1,
 	    0,
 	    "Wistron NeWeb",
@@ -17410,12 +17752,24 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT2870",
 	},
 	{
+	    USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_UB81,
+	    0,
+	    "Z-Com",
+	    "UB81",
+	},
+	{
 	    USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_RT2870_2,
 	    0,
 	    "Z-Com",
 	    "RT2870",
 	},
 	{
+	    USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_UB82,
+	    0,
+	    "Z-Com",
+	    "UB82",
+	},
+	{
 	    USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT2570,
 	    0,
 	    "Zinwell",
@@ -17476,6 +17830,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "ZD1211B",
 	},
 	{
+	    USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1221,
+	    0,
+	    "Zydas Technology Corporation",
+	    "ZD1221",
+	},
+	{
 	    USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_OMNI56K,
 	    0,
 	    "ZyXEL Communication",
@@ -17530,6 +17890,18 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT2870",
 	},
 	{
+	    USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_NWD271N,
+	    0,
+	    "ZyXEL Communication",
+	    "NWD-271N",
+	},
+	{
+	    USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_NWD211AN,
+	    0,
+	    "ZyXEL Communication",
+	    "NWD-211AN",
+	},
+	{
 	    USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RT2870_2,
 	    0,
 	    "ZyXEL Communication",
@@ -19936,6 +20308,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_DYMO, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "DYMO",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_XEROX, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "Xerox",
@@ -20370,7 +20748,7 @@ const struct usb_knowndev usb_knowndevs[] = {
 	{
 	    USB_VENDOR_CHICONY2, 0,
 	    USB_KNOWNDEV_NOPROD,
-	    "Chicony",
+	    "Chicony / Microdia / Sonix Technology Co., Ltd.",
 	    NULL,
 	},
 	{
@@ -21340,6 +21718,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_DISPLAYLINK, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "DisplayLink",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_LENOVO, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "Lenovo",
@@ -21868,6 +22252,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_CACE, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "CACE Technologies",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_EVOLUTION, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "Evolution Robotics products",




More information about the vc mailing list