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

Reply via email to