summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2011-02-03 18:25:55 +0000
committerhselasky <hselasky@FreeBSD.org>2011-02-03 18:25:55 +0000
commit1ff02faff3610173bf0703cd8a1ee050e8e3abf7 (patch)
tree1497cf3400d6d0f851aa865025c67cf409c402b4 /sys/dev
parent2a507fec610eff56c65ef13a1c713fea35ea8ded (diff)
downloadFreeBSD-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/dev')
-rw-r--r--sys/dev/usb/serial/umodem.c59
-rw-r--r--sys/dev/usb/usbdevs4
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)
OpenPOWER on IntegriCloud