Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Jan 2011 15:41:24 +0100
From:      Hans Petter Selasky <hselasky@c2i.net>
To:        freebsd-usb@freebsd.org
Cc:        freebsd-gnats-submit@freebsd.org
Subject:   Re: usb/153929: The umodem driver doesn't support the MTK 3329 GPS chipset.
Message-ID:  <201101121541.24890.hselasky@c2i.net>
In-Reply-To: <201101121309.p0CD9rRD070704@red.freebsd.org>
References:  <201101121309.p0CD9rRD070704@red.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wednesday 12 January 2011 14:09:53 Mykhaylo Yehorov wrote:
> >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@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);
> +}

Hi,

Your patch looks OK, except it might need some more checks to figure out if 
there are multiple modems or just one, and which DATA interface is the closest 
one. Do you have some ideas about how you would solve that?

--HPS



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201101121541.24890.hselasky>