diff options
Diffstat (limited to 'sys/dev/usb')
-rw-r--r-- | sys/dev/usb/controller/uhci_pci.c | 7 | ||||
-rw-r--r-- | sys/dev/usb/controller/xhci_pci.c | 18 | ||||
-rw-r--r-- | sys/dev/usb/quirk/usb_quirk.c | 140 | ||||
-rw-r--r-- | sys/dev/usb/serial/u3g.c | 1 | ||||
-rw-r--r-- | sys/dev/usb/usbdevs | 2 |
5 files changed, 161 insertions, 7 deletions
diff --git a/sys/dev/usb/controller/uhci_pci.c b/sys/dev/usb/controller/uhci_pci.c index 4ac0d54..a7db9a9 100644 --- a/sys/dev/usb/controller/uhci_pci.c +++ b/sys/dev/usb/controller/uhci_pci.c @@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$"); #include "usb_if.h" #define PCI_UHCI_VENDORID_INTEL 0x8086 +#define PCI_UHCI_VENDORID_HP 0x103c #define PCI_UHCI_VENDORID_VIA 0x1106 /* PIIX4E has no separate stepping */ @@ -222,6 +223,9 @@ uhci_pci_match(device_t self) case 0x76028086: return ("Intel 82372FB/82468GX USB controller"); + case 0x3300103c: + return ("HP iLO Standard Virtual USB controller"); + case 0x30381106: return ("VIA 83C572 USB controller"); @@ -309,6 +313,9 @@ uhci_pci_attach(device_t self) case PCI_UHCI_VENDORID_INTEL: sprintf(sc->sc_vendor, "Intel"); break; + case PCI_UHCI_VENDORID_HP: + sprintf(sc->sc_vendor, "HP"); + break; case PCI_UHCI_VENDORID_VIA: sprintf(sc->sc_vendor, "VIA"); break; diff --git a/sys/dev/usb/controller/xhci_pci.c b/sys/dev/usb/controller/xhci_pci.c index c2367f4..c4295aa 100644 --- a/sys/dev/usb/controller/xhci_pci.c +++ b/sys/dev/usb/controller/xhci_pci.c @@ -99,11 +99,14 @@ xhci_pci_match(device_t self) case 0x01941033: return ("NEC uPD720200 USB 3.0 controller"); + case 0x10001b73: + return ("Fresco Logic FL1000G USB 3.0 controller"); + case 0x10421b21: return ("ASMedia ASM1042 USB 3.0 controller"); case 0x0f358086: - return ("Intel Intel BayTrail USB 3.0 controller"); + return ("Intel BayTrail USB 3.0 controller"); case 0x9c318086: case 0x1e318086: return ("Intel Panther Point USB 3.0 controller"); @@ -112,6 +115,9 @@ xhci_pci_match(device_t self) case 0x8cb18086: return ("Intel Wildcat Point USB 3.0 controller"); + case 0xa01b177d: + return ("Cavium ThunderX USB 3.0 controller"); + default: break; } @@ -180,7 +186,8 @@ xhci_pci_attach(device_t self) { struct xhci_softc *sc = device_get_softc(self); int count, err, rid; - uint8_t usedma32; + uint8_t usemsi = 1; + uint8_t usedma32 = 0; rid = PCI_XHCI_CBMEM; sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, @@ -198,8 +205,9 @@ xhci_pci_attach(device_t self) case 0x01941033: /* NEC uPD720200 USB 3.0 controller */ usedma32 = 1; break; - default: - usedma32 = 0; + case 0x10001b73: /* FL1000G */ + /* Fresco Logic host doesn't support MSI. */ + usemsi = 0; break; } @@ -215,7 +223,7 @@ xhci_pci_attach(device_t self) usb_callout_init_mtx(&sc->sc_callout, &sc->sc_bus.bus_mtx, 0); rid = 0; - if (xhci_use_msi) { + if (xhci_use_msi && usemsi) { count = 1; if (pci_alloc_msi(self, &count) == 0) { if (bootverbose) diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c index c756b24..a4f4b42 100644 --- a/sys/dev/usb/quirk/usb_quirk.c +++ b/sys/dev/usb/quirk/usb_quirk.c @@ -61,6 +61,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; @@ -97,6 +98,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { 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), @@ -607,8 +609,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); } /*------------------------------------------------------------------------* @@ -853,12 +879,122 @@ 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) { + char envkey[sizeof(USB_QUIRK_ENVROOT) + 2]; /* 2 digits max, 0 to 99 */ + int i; + /* initialize mutex */ mtx_init(&usb_quirk_mtx, "USB quirk", NULL, MTX_DEF); + /* 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, getenv(envkey)); + } + /* register our function */ usb_test_quirk_p = &usb_test_quirk_by_info; usb_quirk_ioctl_p = &usb_quirk_ioctl; diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index 1fe9b21..9e55cb1 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -316,6 +316,7 @@ static const STRUCT_USB_HOST_ID u3g_devs[] = { U3G_DEV(HUAWEI, E220, U3GINIT_HUAWEI), U3G_DEV(HUAWEI, E220BIS, U3GINIT_HUAWEI), U3G_DEV(HUAWEI, E392, U3GINIT_HUAWEISCSI), + U3G_DEV(HUAWEI, ME909U, U3GINIT_HUAWEISCSI2), U3G_DEV(HUAWEI, MOBILE, U3GINIT_HUAWEI), U3G_DEV(HUAWEI, E1752, U3GINIT_HUAWEISCSI), U3G_DEV(HUAWEI, E1820, U3GINIT_HUAWEISCSI), diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index d649402..99b7655 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -1407,6 +1407,7 @@ product CISCOLINKSYS WUSB54GC 0x0020 WUSB54GC product CISCOLINKSYS WUSB54GR 0x0023 WUSB54GR product CISCOLINKSYS WUSBF54G 0x0024 WUSBF54G product CISCOLINKSYS AE1000 0x002f AE1000 +product CISCOLINKSYS USB3GIGV1 0x0041 USB3GIGV1 USB Ethernet Adapter product CISCOLINKSYS2 RT3070 0x4001 RT3070 product CISCOLINKSYS3 RT3070 0x0101 RT3070 @@ -2364,6 +2365,7 @@ product HUAWEI K3765_INIT 0x1520 K3765 Initial product HUAWEI K4505_INIT 0x1521 K4505 Initial product HUAWEI K3772_INIT 0x1526 K3772 Initial product HUAWEI E3272_INIT 0x155b LTE modem initial +product HUAWEI ME909U 0x1573 LTE modem product HUAWEI R215_INIT 0x1582 LTE modem initial product HUAWEI R215 0x1588 LTE modem product HUAWEI ETS2055 0x1803 CDMA modem |