diff options
author | hselasky <hselasky@FreeBSD.org> | 2011-02-03 18:25:55 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2011-02-03 18:25:55 +0000 |
commit | 1ff02faff3610173bf0703cd8a1ee050e8e3abf7 (patch) | |
tree | 1497cf3400d6d0f851aa865025c67cf409c402b4 /sys | |
parent | 2a507fec610eff56c65ef13a1c713fea35ea8ded (diff) | |
download | FreeBSD-src-1ff02faff3610173bf0703cd8a1ee050e8e3abf7.zip FreeBSD-src-1ff02faff3610173bf0703cd8a1ee050e8e3abf7.tar.gz |
Fix for detection of MTK 3329 GPS USB devices.
Submitted by: Mykhaylo Yehorov
PR: usb/153929
Approved by: thompsa (mentor)
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/usb/serial/umodem.c | 59 | ||||
-rw-r--r-- | sys/dev/usb/usbdevs | 4 |
2 files changed, 58 insertions, 5 deletions
diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c index 77f6a08..c6d517b 100644 --- a/sys/dev/usb/serial/umodem.c +++ b/sys/dev/usb/serial/umodem.c @@ -197,6 +197,8 @@ static void *umodem_get_desc(struct usb_attach_arg *, uint8_t, uint8_t); static usb_error_t umodem_set_comm_feature(struct usb_device *, uint8_t, uint16_t, uint16_t); static void umodem_poll(struct ucom_softc *ucom); +static void umodem_find_data_iface(struct usb_attach_arg *uaa, + uint8_t, uint8_t *, uint8_t *); static const struct usb_config umodem_config[UMODEM_N_TRANSFER] = { @@ -311,13 +313,30 @@ umodem_attach(device_t dev) 0 - 1, UDESCSUB_CDC_UNION, 0 - 1); if ((cud == NULL) || (cud->bLength < sizeof(*cud))) { - device_printf(dev, "Missing descriptor. " + DPRINTF("Missing descriptor. " "Assuming data interface is next.\n"); - if (sc->sc_ctrl_iface_no == 0xFF) + if (sc->sc_ctrl_iface_no == 0xFF) { goto detach; - else - sc->sc_data_iface_no = - sc->sc_ctrl_iface_no + 1; + } else { + uint8_t class_match = 0; + + /* set default interface number */ + sc->sc_data_iface_no = 0xFF; + + /* try to find the data interface backwards */ + umodem_find_data_iface(uaa, + uaa->info.bIfaceIndex - 1, + &sc->sc_data_iface_no, &class_match); + + /* try to find the data interface forwards */ + umodem_find_data_iface(uaa, + uaa->info.bIfaceIndex + 1, + &sc->sc_data_iface_no, &class_match); + + /* check if nothing was found */ + if (sc->sc_data_iface_no == 0xFF) + goto detach; + } } else { sc->sc_data_iface_no = cud->bSlaveInterface[0]; } @@ -398,6 +417,36 @@ detach: } static void +umodem_find_data_iface(struct usb_attach_arg *uaa, + uint8_t iface_index, uint8_t *p_data_no, uint8_t *p_match_class) +{ + struct usb_interface_descriptor *id; + struct usb_interface *iface; + + iface = usbd_get_iface(uaa->device, iface_index); + + /* check for end of interfaces */ + if (iface == NULL) + return; + + id = usbd_get_interface_descriptor(iface); + + /* check for non-matching interface class */ + if (id->bInterfaceClass != UICLASS_CDC_DATA || + id->bInterfaceSubClass != UISUBCLASS_DATA) { + /* if we got a class match then return */ + if (*p_match_class) + return; + } else { + *p_match_class = 1; + } + + DPRINTFN(11, "Match at index %u\n", iface_index); + + *p_data_no = id->bInterfaceNumber; +} + +static void umodem_start_read(struct ucom_softc *ucom) { struct umodem_softc *sc = ucom->sc_parent; diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 851274b..0402efc 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -536,6 +536,7 @@ vendor SPEEDDRAGON 0x0e55 Speed Dragon Multimedia vendor HAWKING 0x0e66 Hawking vendor FOSSIL 0x0e67 Fossil, Inc vendor GMATE 0x0e7e G.Mate, Inc +vendor MEDIATEK 0x0e8d MediaTek, Inc. vendor OTI 0x0ea0 Ours Technology vendor YISO 0x0eab Yiso Wireless Co. vendor PILOTECH 0x0eaf Pilotech @@ -2120,6 +2121,9 @@ product MCT DU_H3SP_USB232 0x0200 D-Link DU-H3SP USB BAY Hub product MCT USB232 0x0210 USB-232 Interface product MCT SITECOM_USB232 0x0230 Sitecom USB-232 Products +/* MediaTek, Inc. */ +product MEDIATEK MTK3329 0x3329 MTK II GPS Receiver + /* Meizu Electronics */ product MEIZU M6_SL 0x0140 MiniPlayer M6 (SL) |