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; }