usb/153929: The umodem driver doesn't support the MTK 3329 GPS
chipset.
Mykhaylo Yehorov
yehorov at gmail.com
Wed Jan 12 13:10:10 UTC 2011
>Number: 153929
>Category: usb
>Synopsis: The umodem driver doesn't support the MTK 3329 GPS chipset.
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-usb
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Wed Jan 12 13:10:09 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator: Mykhaylo Yehorov
>Release: FreeBSD 8-STABLE
>Organization:
>Environment:
FreeBSD box.interexc.com 8.2-PRERELEASE FreeBSD 8.2-PRERELEASE #1 r197782M: Tue Jan 4 14:49:50 EET 2011 mika at box.interexc.com:/usr/obj/usr/src/sys/MINI i386
>Description:
I'm trying to connect my GPS receiver based on the MTK 3329 GPS chipset to a FreeBSD box.
The umodem driver matches to the device but fails to attach to it.
My kernel is built with "options USB_DEBUG".
Sysctl variable syshw.usb.umodem.debug is set to 11.
After attaching the GPS receiver to an USB port the following lines appear in dmesg.
ugen1.3: <MTK> at usbus1
umodem_probe:
umodem_probe:
umodem_probe:
umodem0: <GPS COM(comm_if)> on usbus1
umodem_get_caps: no CM desc (faking one)
umodem_get_caps: no ACM desc
umodem0: Missing descriptor. Assuming data interface is next.
umodem0: data interface 2, has CM over data, has no break
umodem0: no data interface
umodem_detach: sc=0xc907aa00
device_attach: umodem0 attach returned 6
umodem_probe:
umodem0: <GPS COM(comm_if)> on usbus1
umodem_get_caps: no CM desc (faking one)
umodem_get_caps: no ACM desc
umodem0: Missing descriptor. Assuming data interface is next.
umodem0: data interface 2, has CM over data, has no break
umodem0: no data interface
umodem_detach: sc=0xc9ddf800
device_attach: umodem0 attach returned 6
usbconfig shows the following.
ugen1.3: <GPS Receiver MTK> at usbus1, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON
bLength = 0x0012
bDescriptorType = 0x0001
bcdUSB = 0x0200
bDeviceClass = 0x0002
bDeviceSubClass = 0x0000
bDeviceProtocol = 0x0000
bMaxPacketSize0 = 0x0040
idVendor = 0x0e8d
idProduct = 0x3329
bcdDevice = 0x0100
iManufacturer = 0x0003 <MTK>
iProduct = 0x0004 <GPS Receiver>
iSerialNumber = 0x0000 <no string>
bNumConfigurations = 0x0001
Configuration index 0
bLength = 0x0009
bDescriptorType = 0x0002
wTotalLength = 0x0043
bNumInterfaces = 0x0002
bConfigurationValue = 0x0001
iConfiguration = 0x0000 <no string>
bmAttributes = 0x0080
bMaxPower = 0x00fa
Interface 0
bLength = 0x0009
bDescriptorType = 0x0004
bInterfaceNumber = 0x0000
bAlternateSetting = 0x0000
bNumEndpoints = 0x0002
bInterfaceClass = 0x000a
bInterfaceSubClass = 0x0000
bInterfaceProtocol = 0x0000
iInterface = 0x0001 <GPS COM(data_if)>
Endpoint 0
bLength = 0x0007
bDescriptorType = 0x0005
bEndpointAddress = 0x0081 <IN>
bmAttributes = 0x0002 <BULK>
wMaxPacketSize = 0x0040
bInterval = 0x0000
bRefresh = 0x0000
bSynchAddress = 0x0000
Endpoint 1
bLength = 0x0007
bDescriptorType = 0x0005
bEndpointAddress = 0x0001 <OUT>
bmAttributes = 0x0002 <BULK>
wMaxPacketSize = 0x0040
bInterval = 0x0000
bRefresh = 0x0000
bSynchAddress = 0x0000
Interface 1
bLength = 0x001c
bDescriptorType = 0x0004
bInterfaceNumber = 0x0001
bAlternateSetting = 0x0000
bNumEndpoints = 0x0001
bInterfaceClass = 0x0002
bInterfaceSubClass = 0x0002
bInterfaceProtocol = 0x0001
iInterface = 0x0002 <GPS COM(comm_if)>
Endpoint 0
bLength = 0x0007
bDescriptorType = 0x0005
bEndpointAddress = 0x0082 <IN>
bmAttributes = 0x0003 <INTERRUPT>
wMaxPacketSize = 0x0040
bInterval = 0x0001
bRefresh = 0x0000
bSynchAddress = 0x0000
>How-To-Repeat:
Attach a GPS receiver based on the MTK 3329 chipset to an USB port.
>Fix:
If driver cannot obtain descriptors about data interface it assumes data interface is next that is wrong for this device.
Data interface can be find by bInterfaceClass and bInterfaceSubClass codes.
My patch fixes driver behaviour.
After applying the umodem driver can attach to the device.
And GPS software works fine with the GPS receiver.
ugen1.3: <MTK> at usbus1
umodem_probe:
umodem_probe:
umodem_probe:
umodem0: <GPS COM(comm_if)> on usbus1
umodem_get_caps: no CM desc (faking one)
umodem_get_caps: no ACM desc
umodem0: data interface 0, has CM over data, has no break
Patch attached with submission follows:
--- orig/sys/dev/usb/serial/umodem.c 2010-04-30 01:44:04.000000000 +0300
+++ sys/dev/usb/serial/umodem.c 2011-01-12 14:32:14.000000000 +0200
@@ -198,6 +198,7 @@
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 int umodem_find_data_interface(struct usb_attach_arg *, uint8_t *);
static const struct usb_config umodem_config[UMODEM_N_TRANSFER] = {
@@ -312,13 +313,15 @@
0 - 1, UDESCSUB_CDC_UNION, 0 - 1);
if ((cud == NULL) || (cud->bLength < sizeof(*cud))) {
- device_printf(dev, "Missing descriptor. "
- "Assuming data interface is next.\n");
if (sc->sc_ctrl_iface_no == 0xFF)
goto detach;
- else
+ else if (!umodem_find_data_interface(uaa,
+ &sc->sc_data_iface_no)) {
+ device_printf(dev, "Missing descriptor. "
+ "Assuming data interface is next.\n");
sc->sc_data_iface_no =
sc->sc_ctrl_iface_no + 1;
+ }
} else {
sc->sc_data_iface_no = cud->bSlaveInterface[0];
}
@@ -829,3 +832,31 @@
struct umodem_softc *sc = ucom->sc_parent;
usbd_transfer_poll(sc->sc_xfer, UMODEM_N_TRANSFER);
}
+
+static int
+umodem_find_data_interface(struct usb_attach_arg *uaa, uint8_t *data_iface)
+{
+ uint8_t i;
+
+ for (i = 0;; i++) {
+ struct usb_interface *iface;
+ struct usb_interface_descriptor *id;
+
+ iface = usbd_get_iface(uaa->device, i);
+
+ if (iface) {
+
+ id = usbd_get_interface_descriptor(iface);
+
+ if (id->bInterfaceClass == UICLASS_CDC_DATA &&
+ id->bInterfaceSubClass == UISUBCLASS_DATA) {
+ *data_iface = i;
+ return (1);
+ }
+ }
+ else
+ break;
+ }
+
+ return (0);
+}
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-usb
mailing list