mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-07-02 01:49:11 +08:00
USB: Update to FreeBSD trunk 2015-11-10
This commit is contained in:
parent
c1644467b1
commit
02279d6272
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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:
|
||||
|
@ -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_ */
|
||||
|
@ -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_ */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
@ -131,6 +135,35 @@ usbd_get_page(struct usb_page_cache *pc, usb_frlength_t offset,
|
||||
#endif
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* 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
|
||||
*------------------------------------------------------------------------*/
|
||||
@ -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;
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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__)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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,14 +107,18 @@ 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);
|
||||
|
||||
udev->usb_template_ptr = NULL;
|
||||
}
|
||||
usbd_free_config_desc(udev, udev->usb_template_ptr);
|
||||
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
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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_ */
|
||||
|
@ -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) {
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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++;
|
||||
|
||||
@ -1264,11 +1271,50 @@ done:
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* 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);
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
|
@ -27,6 +27,120 @@
|
||||
#ifndef _USB_TRANSFER_H_
|
||||
#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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -17,3 +17,5 @@
|
||||
#define USB_HAVE_TT_SUPPORT 1
|
||||
|
||||
#define USB_HAVE_POWERD 1
|
||||
|
||||
#define USB_HAVE_PER_BUS_PROCESS 1
|
||||
|
@ -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 */
|
||||
|
@ -453,6 +453,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Accton Technology",
|
||||
"ZD1211B",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_WN7512,
|
||||
0,
|
||||
"Accton Technology",
|
||||
"WN7512",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_ACEECA, USB_PRODUCT_ACEECA_MEZ1000,
|
||||
0,
|
||||
@ -1857,6 +1863,36 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Atheros Communications",
|
||||
"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,
|
||||
@ -1905,6 +1941,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Avision",
|
||||
"1200U scanner",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_AVM, USB_PRODUCT_AVM_FRITZWLAN,
|
||||
0,
|
||||
"AVM",
|
||||
"FRITZ!WLAN N",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_AXESSTEL, USB_PRODUCT_AXESSTEL_DATAMODEM,
|
||||
0,
|
||||
@ -2385,6 +2427,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Behavior Tech. Computer",
|
||||
"Keyboard with mouse port",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_CACE, USB_PRODUCT_CACE_AIRPCAPNX,
|
||||
0,
|
||||
"CACE Technologies",
|
||||
"AirPcap NX",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_CANON, USB_PRODUCT_CANON_N656U,
|
||||
0,
|
||||
@ -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",
|
||||
},
|
||||
{
|
||||
@ -2679,6 +2727,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Cisco-Linksys",
|
||||
"AE1000",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB3GIGV1,
|
||||
0,
|
||||
"Cisco-Linksys",
|
||||
"USB3GIGV1 USB Ethernet Adapter",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_CISCOLINKSYS2, USB_PRODUCT_CISCOLINKSYS2_RT3070,
|
||||
0,
|
||||
@ -3471,6 +3525,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"D-Link",
|
||||
"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,
|
||||
@ -3705,6 +3765,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"D-Link",
|
||||
"DWA-131 A1",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160A2,
|
||||
0,
|
||||
"D-Link",
|
||||
"DWA-160 A2",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA120,
|
||||
0,
|
||||
@ -3717,6 +3783,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"D-Link",
|
||||
"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,
|
||||
@ -3777,6 +3849,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"D-Link",
|
||||
"RT3070",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160A1,
|
||||
0,
|
||||
"D-Link",
|
||||
"DWA-160 A1",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT2870_2,
|
||||
0,
|
||||
@ -3807,6 +3885,126 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Dlink",
|
||||
"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,
|
||||
@ -3855,6 +4053,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"dresden elektronik",
|
||||
"Levelshifter Stick Low Cost",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_DYMO, USB_PRODUCT_DYMO_LABELMANAGERPNP,
|
||||
0,
|
||||
"DYMO",
|
||||
"DYMO LabelManager PnP",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTDEVBOARD,
|
||||
0,
|
||||
@ -4011,6 +4215,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Elecom",
|
||||
"LD-USBL/TX",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_WDC150SU2M,
|
||||
0,
|
||||
"Elecom",
|
||||
"WDC-150SU2M",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX2,
|
||||
0,
|
||||
@ -4551,6 +4761,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Fujitsu Siemens Computers",
|
||||
"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,
|
||||
@ -7245,6 +7461,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Huawei Technologies",
|
||||
"LTE modem initial",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_ME909U,
|
||||
0,
|
||||
"Huawei Technologies",
|
||||
"LTE modem",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_R215_INIT,
|
||||
0,
|
||||
@ -7557,6 +7779,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"I-O Data",
|
||||
"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,
|
||||
@ -8199,6 +8427,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Leadtek",
|
||||
"9531 GPS",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_GIGALAN,
|
||||
0,
|
||||
"Lenovo",
|
||||
"USB 3.0 Ethernet",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_ETHERNET,
|
||||
0,
|
||||
@ -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,
|
||||
@ -10317,6 +10551,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Melco",
|
||||
"WLI-UC-GNM",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCG300HPV1,
|
||||
0,
|
||||
"Melco",
|
||||
"WLI-UC-G300HP-V1",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCGNM2,
|
||||
0,
|
||||
@ -10383,6 +10623,24 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"MEI",
|
||||
"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,
|
||||
@ -11049,6 +11307,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"NEC",
|
||||
"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,
|
||||
@ -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",
|
||||
@ -11181,12 +11445,42 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"BayNETGEAR",
|
||||
"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,
|
||||
@ -12393,6 +12687,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Planex Communications",
|
||||
"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,
|
||||
@ -13317,6 +13617,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Qualcomm, Incorporated",
|
||||
"3G modem",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_MF112,
|
||||
0,
|
||||
"Qualcomm, Incorporated",
|
||||
"3G modem",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_SURFSTICK,
|
||||
0,
|
||||
@ -13635,6 +13941,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Realtek",
|
||||
"USBKR100 USB Ethernet",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8153,
|
||||
0,
|
||||
"Realtek",
|
||||
"RTL8153 USB Ethernet",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CE_0,
|
||||
0,
|
||||
@ -13707,6 +14019,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Realtek",
|
||||
"RTL8187B Wireless Adapter",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_3,
|
||||
0,
|
||||
"Realtek",
|
||||
"RTL8188CU",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8196EU,
|
||||
0,
|
||||
@ -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",
|
||||
"Aircard 875 HSDPA",
|
||||
"MC7354",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC7355,
|
||||
0,
|
||||
"Sierra Wireless",
|
||||
"MC7355",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC313U,
|
||||
@ -16671,6 +16995,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"TRENDnet",
|
||||
"RTL8192CU",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_TEW646UBH,
|
||||
0,
|
||||
"TRENDnet",
|
||||
"TEW-646UBH",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8188CU,
|
||||
0,
|
||||
@ -17217,6 +17547,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"WinMaxGroup",
|
||||
"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,
|
||||
@ -17229,6 +17565,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Wistron NeWeb",
|
||||
"UR055G",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_O8494,
|
||||
0,
|
||||
"Wistron NeWeb",
|
||||
"ORiNOCO 802.11n",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_AR5523_1,
|
||||
0,
|
||||
@ -17409,12 +17751,24 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Z-Com",
|
||||
"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,
|
||||
@ -17475,6 +17829,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Zydas Technology Corporation",
|
||||
"ZD1211B",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1221,
|
||||
0,
|
||||
"Zydas Technology Corporation",
|
||||
"ZD1221",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_OMNI56K,
|
||||
0,
|
||||
@ -17529,6 +17889,18 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"ZyXEL Communication",
|
||||
"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,
|
||||
@ -19935,6 +20307,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"GoHubs",
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
USB_VENDOR_DYMO, 0,
|
||||
USB_KNOWNDEV_NOPROD,
|
||||
"DYMO",
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
USB_VENDOR_XEROX, 0,
|
||||
USB_KNOWNDEV_NOPROD,
|
||||
@ -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,
|
||||
},
|
||||
{
|
||||
@ -21339,6 +21717,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Kamstrup A/S",
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
USB_VENDOR_DISPLAYLINK, 0,
|
||||
USB_KNOWNDEV_NOPROD,
|
||||
"DisplayLink",
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
USB_VENDOR_LENOVO, 0,
|
||||
USB_KNOWNDEV_NOPROD,
|
||||
@ -21867,6 +22251,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"3Com",
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
USB_VENDOR_CACE, 0,
|
||||
USB_KNOWNDEV_NOPROD,
|
||||
"CACE Technologies",
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
USB_VENDOR_EVOLUTION, 0,
|
||||
USB_KNOWNDEV_NOPROD,
|
||||
|
Loading…
x
Reference in New Issue
Block a user