On Thu, Feb 10, 2011 at 02:21:23AM -0800, Daniel C. Sinclair wrote:
> On Wed, Feb 9, 2011 at 10:52 PM, Jacob Meuser <jake...@sdf.lonestar.org>
> wrote:
> > this actually works?  could you please send usbctl (from the usbutil
> > package) output for this device?  I don't like adding more quirks.
> > if the device has the bulk endpoints in the control interface, then the
> > requirement that the endpoints be in a different interface is overly
> > restrictive.
> 
> DEVICE addr 2
> DEVICE descriptor:
> bLength=18 bDescriptorType=device(1) bcdUSB=2.00 bDeviceClass=2
> bDeviceSubClass=0
> bDeviceProtocol=0 bMaxPacketSize=64 idVendor=0x0e8d idProduct=0x3329
> bcdDevice=100
> iManufacturer=3(MTK) iProduct=4(GPS Receiver) iSerialNumber=0()
> bNumConfigurations=1
> 
> CONFIGURATION descriptor 0:
> bLength=9 bDescriptorType=config(2) wTotalLength=67 bNumInterface=2
> bConfigurationValue=1 iConfiguration=0() bmAttributes=80 bMaxPower=500 mA
> 
> INTERFACE descriptor 0:
> bLength=9 bDescriptorType=interface(4) bInterfaceNumber=0 bAlternateSetting=0
> bNumEndpoints=2 bInterfaceClass=10 bInterfaceSubClass=0
> bInterfaceProtocol=0 iInterface=1(GPS COM(data_if))
> 
> ENDPOINT descriptor:
> bLength=7 bDescriptorType=endpoint(5) bEndpointAddress=1-in
> bmAttributes=bulk wMaxPacketSize=64 bInterval=0
> 
> ENDPOINT descriptor:
> bLength=7 bDescriptorType=endpoint(5) bEndpointAddress=1-out
> bmAttributes=bulk wMaxPacketSize=64 bInterval=0
> 
> INTERFACE descriptor 1:
> bLength=28 bDescriptorType=interface(4) bInterfaceNumber=1
> bAlternateSetting=0
> bNumEndpoints=1 bInterfaceClass=2 bInterfaceSubClass=2
> bInterfaceProtocol=1 iInterface=2(GPS COM(comm_if))
> 
> ENDPOINT descriptor:
> bLength=7 bDescriptorType=endpoint(5) bEndpointAddress=2-in
> bmAttributes=interrupt wMaxPacketSize=64 bInterval=1
> 
> current configuration 1
> 
> ----------

does the following work for you?

-- 
jake...@sdf.lonestar.org
SDF Public Access UNIX System - http://sdf.lonestar.org

Index: umodem.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/umodem.c,v
retrieving revision 1.41
diff -u -p umodem.c
--- umodem.c    25 Jan 2011 20:03:36 -0000      1.41
+++ umodem.c    11 Feb 2011 16:34:47 -0000
@@ -170,9 +170,11 @@ umodem_get_caps(struct usb_attach_arg *uaa, int ctl_if
        const usb_cdc_cm_descriptor_t *cmd;
        const usb_cdc_acm_descriptor_t *acmd;
        const usb_cdc_union_descriptor_t *uniond;
+       const usb_endpoint_descriptor_t *ed;
        usbd_desc_iter_t iter;
-       int current_iface_no = -1;
+       int bulkin, bulkout, current_iface_no;
 
+       *data_iface_no = current_iface_no = bulkin = bulkout = -1;
        *cm_cap = *acm_cap = 0;
        usb_desc_iter_init(uaa->device, &iter);
        desc = usb_desc_iter_next(&iter);
@@ -198,9 +200,26 @@ umodem_get_caps(struct usb_attach_arg *uaa, int ctl_if
                                *data_iface_no = uniond->bSlaveInterface[0];
                                break;
                        }
+               } else if (current_iface_no == ctl_iface_no &&
+                   desc->bDescriptorType == UDESC_CS_ENDPOINT) {
+                       ed = (usb_endpoint_descriptor_t *)desc;
+                       if (UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
+                               if (UE_GET_DIR(ed->bEndpointAddress) ==
+                                   UE_DIR_IN)
+                                       bulkin = ed->bEndpointAddress;
+                               else
+                                       bulkout = ed->bEndpointAddress;
+                       }
                }
                desc = usb_desc_iter_next(&iter);
        }
+
+       /*
+        * Usually, there is a separate data interface.  However, some
+        * devices have the bulk data endpoints in the control interface.
+        */
+       if (*data_iface_no == -1 && (bulkin != -1 && bulkout != -1))
+               *data_iface_no = ctl_iface_no;
 }
 
 int
@@ -234,10 +253,13 @@ umodem_match(struct device *parent, void *match, void 
        if (ret == UMATCH_NONE)
                return (ret);
 
-       /* umodem doesn't yet support devices without a data iface */
+       /*
+        * Check that either the bulk endpoints are in the control interface
+        * or that there is a data interface.
+        */
        umodem_get_caps(uaa, id->bInterfaceNumber, &data_iface_no,
            &cm_cap, &acm_cap);
-       if (data_iface_no == 0)
+       if (data_iface_no == -1)
                ret = UMATCH_NONE;
 
        return (ret);
@@ -267,8 +289,8 @@ umodem_attach(struct device *parent, struct device *se
        /* Get the capabilities. */
        umodem_get_caps(uaa, id->bInterfaceNumber, &data_iface_no,
            &sc->sc_cm_cap, &sc->sc_acm_cap);
-       if (data_iface_no == 0) {
-               printf("%s: no pointer to data interface\n",
+       if (data_iface_no == -1) {
+               printf("%s: no interface with bulk endpoints\n",
                       sc->sc_dev.dv_xname);
                goto bad;
        }

Reply via email to