I am still fighting with a Siemens Gigaset M34 USB DECT adapter (ID 0681:0026) advertizing, among others, four CDC ACM shared control/data interfaces. The current probe code in cdc-acm.c refuses to touch these because of the test for usb_interface_claimed(data_interface) in line 1031. Also, the endpoint assignments following that test don't look right for the case where data_interface == control_interface. Does the following patch look sensible, or am I completely on the wrong track? Thanks, Tilman diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index d50a99f..8d38813 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1027,22 +1027,35 @@ skip_normal_probe: /* Accept probe requests only for the control interface */ if (intf != control_interface) return -ENODEV; - - if (usb_interface_claimed(data_interface)) { /* valid in this context */ - dev_dbg(&intf->dev,"The data interface isn't available\n"); - return -EBUSY; - } - - - if (data_interface->cur_altsetting->desc.bNumEndpoints < 2) - return -EINVAL; + /* find endpoints */ epctrl = &control_interface->cur_altsetting->endpoint[0].desc; - epread = &data_interface->cur_altsetting->endpoint[0].desc; - epwrite = &data_interface->cur_altsetting->endpoint[1].desc; - + if (data_interface == control_interface) { + /* shared interface */ + if (data_interface->cur_altsetting->desc.bNumEndpoints < 3) + return -EINVAL; + dev_dbg(&intf->dev, "Shared interface, shifting data EPs.\n"); + epread = &data_interface->cur_altsetting->endpoint[1].desc; + epwrite = &data_interface->cur_altsetting->endpoint[2].desc; + } else { + /* separate interfaces */ + if (usb_interface_claimed(data_interface)) { + /* valid in this context */ + dev_dbg(&intf->dev, + "The data interface isn't available\n"); + return -EBUSY; + } + if (data_interface->cur_altsetting->desc.bNumEndpoints < 2) + return -EINVAL; + epread = &data_interface->cur_altsetting->endpoint[0].desc; + epwrite = &data_interface->cur_altsetting->endpoint[1].desc; + } /* workaround for switched endpoints */ + if (usb_endpoint_dir_in(epread) == usb_endpoint_dir_in(epwrite)) { + err("Bad data endpoint directions.\n"); + return -EINVAL; + } if (!usb_endpoint_dir_in(epread)) { /* descriptors are swapped */ struct usb_endpoint_descriptor *t; -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html