diff options
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 3eb63c60..85f41f15 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 76ac75f6..aaa1cedc 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 05c5e19b..0b2de8a3 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 90e09bb5..8ee4ced8 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 7447ea80..a3d72820 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 bddc2c55..7010916c 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 39d32698..e8009872 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 921b3d4f..5a233883 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 bb5a60cd..95b4f4ac 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 0a7350c9..3ceeb1ef 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 7d98155c..d8946dce 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 ee420bc6..077bf8b8 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 f23ade21..6a2f6b03 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 80f5ecd4..7bc784ef 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 287e69f2..739a0039 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 ab949ecb..3d5ddcd4 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 038ba7f4..e30f2c2c 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 ce107cf3..bd2941a0 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 9a7cf210..f87ba53b 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 8e0144cc..d7789d0b 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 309bd057..4e9dbc4a 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 65c9a7d7..db8a523a 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 56849420..e52c46fb 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 29479f13..0bbcb9bf 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 f25f95e1..e27fb5eb 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 ed2c6bba..0d2e8105 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 d6172908..c5a03777 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 296548e5..b7464110 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 737237bd..f6591a8f 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 0c62ee08..cae83779 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 557a0565..16430d9b 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 d5be169b..683f3e61 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 b9ff5938..ebbb03ee 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 37fa2a15..d98b7e2e 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 19accddf..095bba04 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 4f64f842..d3f26c2b 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 e543a901..ef1ec530 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 a5426e1e..ab687e41 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 06feee8b..dd20afd4 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 6f9d7b12..39e03c6e 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 5fcedd5e..9f0a4e64 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 ab5558e1..5bbc1e02 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 71157ca7..f035240b 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 24558b84..316e9de8 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 6ec26a4a..ecd5a812 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 f6c447ca..28dfede2 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 f9643174..2945bc9f 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 7472c005..cee4d28f 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 71eee376..945b06c5 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", |