[EMAIL PROTECTED] wrote:
diff -Nru linux-2.5.68/drivers/usb/core/usb.c linux-2.5.68/drivers/usb_patch/core/usb.c

Here's an updated version, against 2.6.0-test4. It updates the doc and also adds a bit of paranoia in case the altsettings are out of order.

This has gotten some discussion from time to time,
I saw agreement that inactive altsettings must be
ignored.  Potentially affects user-mode drivers,
ones relying on usbfs misbehavior.

- Dave


--- 1.138/drivers/usb/core/usb.c        Wed Aug 27 10:04:01 2003
+++ edited/drivers/usb/core/usb.c       Tue Sep  2 12:33:30 2003
@@ -217,33 +217,48 @@
 
 /**
  * usb_epnum_to_ep_desc - get the endpoint object with a given endpoint number
- * @dev: the device whose current configuration is considered
- * @epnum: the desired endpoint
+ * @dev: the device whose current configuration+altsettings is considered
+ * @epnum: the desired endpoint, masked with USB_DIR_IN as appropriate.
  *
  * This walks the device descriptor for the currently active configuration,
  * and returns a pointer to the endpoint with that particular endpoint
  * number, or null.
  *
- * Note that interface descriptors are not required to assign endpont
- * numbers sequentially, so that it would be incorrect to assume that
- * the first endpoint in that descriptor corresponds to interface zero.
+ * Note that interface descriptors are not required to list endpoint
+ * numbers in any standardized order, so that it would be wrong to
+ * assume that ep2in precedes either ep5in, ep2out, or even ep1out.
  * This routine helps device drivers avoid such mistakes.
  */
 struct usb_endpoint_descriptor *
 usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum)
 {
-       int i, j, k;
+       int i, k;
 
-       for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++)
-               for (j = 0; j < dev->actconfig->interface[i]->num_altsetting; j++)
-                       for (k = 0; k < dev->actconfig->interface[i]->
-                               altsetting[j].desc.bNumEndpoints; k++)
-                               if (epnum == dev->actconfig->interface[i]->
-                                               altsetting[j].endpoint[k]
-                                               .desc.bEndpointAddress)
-                                       return &dev->actconfig->interface[i]->
-                                               altsetting[j].endpoint[k]
-                                               .desc;
+       for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
+               struct usb_interface            *intf;
+               struct usb_host_interface       *alt = 0;
+
+               /* paranoia, in case altsettings aren't sequential */
+               intf = dev->actconfig->interface[i];
+               for (k = 0; k < intf->num_altsetting; k++) {
+                       if (intf->altsetting [k].desc.bAlternateSetting
+                                       == intf->act_altsetting) {
+                               alt = intf->altsetting + k;
+                               break;
+                       }
+               }
+               if (!alt) {
+                       dev_dbg(&dev->dev,
+                               "interface %d has no altsetting %d!\n",
+                               i, intf->act_altsetting);
+                       continue;
+               }
+
+               /* only endpoints in current altseting are active */
+               for (k = 0; k < alt->desc.bNumEndpoints; k++)
+                       if (epnum == alt->endpoint[k].desc.bEndpointAddress)
+                               return &alt->endpoint[k].desc;
+       }
 
        return NULL;
 }

Reply via email to