ChangeSet 1.1419, 2003/09/05 16:23:05-07:00, david-b@pacbell.net [PATCH] USB: usb_epnum_to_ep_desc only look Original patch from oliverthered@oliverthered.com ... this updates it: - usb_epnum_to_ep_desc() only looks at the active altsetting - docs clarified It's possible some user mode drivers will have relied on the previous buggy behavior, since usbfs uses this call. The fix will be for them to set the appropriate altsetting. drivers/usb/core/usb.c | 34 ++++++++++++++++++---------------- 1 files changed, 18 insertions(+), 16 deletions(-) diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c Fri Sep 5 17:59:14 2003 +++ b/drivers/usb/core/usb.c Fri Sep 5 17:59:14 2003 @@ -217,33 +217,35 @@ /** * 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; + + /* only endpoints in current altseting are active */ + intf = dev->actconfig->interface[i]; + alt = intf->altsetting + intf->act_altsetting; + + for (k = 0; k < alt->desc.bNumEndpoints; k++) + if (epnum == alt->endpoint[k].desc.bEndpointAddress) + return &alt->endpoint[k].desc; + } return NULL; }