ChangeSet 1.1929, 2004/04/22 13:32:24-07:00, [EMAIL PROTECTED]
[PATCH] USB: fix cdc-acm as it is still (differently) broken
drivers/usb/class/cdc-acm.c | 83 ++++++++++++++++++++++++--------------------
1 files changed, 47 insertions(+), 36 deletions(-)
diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
--- a/drivers/usb/class/cdc-acm.c Thu Apr 22 14:41:35 2004
+++ b/drivers/usb/class/cdc-acm.c Thu Apr 22 14:41:35 2004
@@ -581,45 +581,51 @@
dev = interface_to_usbdev (intf);
- cfacm = dev->actconfig;
-
- for (j = 0; j < cfacm->desc.bNumInterfaces - 1; j++) {
-
- if (usb_interface_claimed(cfacm->interface[j]) ||
- usb_interface_claimed(cfacm->interface[j + 1]))
- continue;
+ cfacm = dev->actconfig;
+
+ /* We know we're probe()d with the control interface. */
+ ifcom = intf->cur_altsetting;
- /* We know we're probe()d with the control interface.
- * FIXME ACM doesn't guarantee the data interface is
+ /* ACM doesn't guarantee the data interface is
* adjacent to the control interface, or that if one
- * is there it's not for call management ... so use
- * the cdc union descriptor whenever there is one.
+ * is there it's not for call management ... so find
+ * it
*/
- ifcom = intf->cur_altsetting;
- if (intf == cfacm->interface[j]) {
- ifdata = cfacm->interface[j + 1]->cur_altsetting;
- data = cfacm->interface[j + 1];
- } else if (intf == cfacm->interface[j + 1]) {
+ for (j = 0; j < cfacm->desc.bNumInterfaces; j++) {
ifdata = cfacm->interface[j]->cur_altsetting;
data = cfacm->interface[j];
- } else
- continue;
- if (ifdata->desc.bInterfaceClass != 10 ||
ifdata->desc.bNumEndpoints < 2)
- continue;
+ if (ifdata->desc.bInterfaceClass == 10 &&
+ ifdata->desc.bNumEndpoints == 2) {
+ epctrl = &ifcom->endpoint[0].desc;
+ epread = &ifdata->endpoint[0].desc;
+ epwrite = &ifdata->endpoint[1].desc;
+
+ if ((epctrl->bEndpointAddress & 0x80) != 0x80
||
+ (epctrl->bmAttributes & 3) != 3 ||
+ (epread->bmAttributes & 3) != 2 ||
+ (epwrite->bmAttributes & 3) != 2 ||
+ ((epread->bEndpointAddress & 0x80) ^
(epwrite->bEndpointAddress & 0x80)) != 0x80)
+ goto next_interface;
+
+ if ((epread->bEndpointAddress & 0x80) != 0x80)
{
+ epread = &ifdata->endpoint[1].desc;
+ epwrite = &ifdata->endpoint[0].desc;
+ }
+ dbg("found data interface at %d\n", j);
+ break;
+ } else {
+next_interface:
+ ifdata = NULL;
+ data = NULL;
+ }
+ }
+
+ /* there's been a problem */
+ if (!ifdata) {
+ dbg("interface not found (%p)\n", ifdata);
+ return -ENODEV;
- epctrl = &ifcom->endpoint[0].desc;
- epread = &ifdata->endpoint[0].desc;
- epwrite = &ifdata->endpoint[1].desc;
-
- if ((epctrl->bEndpointAddress & 0x80) != 0x80 ||
(epctrl->bmAttributes & 3) != 3 ||
- (epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes &
3) != 2 ||
- ((epread->bEndpointAddress & 0x80) ^
(epwrite->bEndpointAddress & 0x80)) != 0x80)
- continue;
-
- if ((epread->bEndpointAddress & 0x80) != 0x80) {
- epread = &ifdata->endpoint[1].desc;
- epwrite = &ifdata->endpoint[0].desc;
}
for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor];
minor++);
@@ -696,16 +702,21 @@
acm->line.databits = 8;
acm_set_line(acm, &acm->line);
- usb_driver_claim_interface(&acm_driver, data, acm);
+ if ( (j = usb_driver_claim_interface(&acm_driver, data, acm))
!= 0) {
+ err("claim failed");
+ usb_free_urb(acm->ctrlurb);
+ usb_free_urb(acm->readurb);
+ usb_free_urb(acm->writeurb);
+ kfree(acm);
+ kfree(buf);
+ return j;
+ }
tty_register_device(acm_tty_driver, minor, &intf->dev);
acm_table[minor] = acm;
usb_set_intfdata (intf, acm);
return 0;
- }
-
- return -EIO;
}
static void acm_disconnect(struct usb_interface *intf)
-------------------------------------------------------
This SF.net email is sponsored by: The Robotic Monkeys at ThinkGeek
For a limited time only, get FREE Ground shipping on all orders of $35
or more. Hurry up and shop folks, this offer expires April 30th!
http://www.thinkgeek.com/freeshipping/?cpg297
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel