You are pointing out 2 valid bugs:
-findintfep, findintfif, and usb_epnum_to_ep_desc incorrectly check
inactive alternate settings.
-proc_submiturb does not set the interval for ISO transfers.
however findintfep should _not_ check if the interface is claimed, as
that's the job of checkintf.
Also, you don't need to throw all that code into proc_submiturb, as
usb_epnum_to_ep_desc (the function that was already in use by
proc_submiturb) already does all that.
On Tue, 14 Jan 2003, oliverthered wrote:
>
>Devio is failing to set the interval for ISO transfers, causing
>usb_submit_urb to return an error.
>
>endpoints and interfaces are located using the first matching entry in
>the list.
>
>
>The patch below to
>set the interval for ISO and interrupt transfers using the interval
>value from an endpoint descriptor.
>
>find an interface for an endpoint from the interface's claimed by the
>driver, instead of anyold interface.
>
>lookup the endpoint using the act_altsetting instead of the first one in
>the list of altsettings.
>
>
>Any comments?
>
>
>
>
>--- linux-2.5.54/drivers/usb/core/devio.c 2003-01-02
>03:22:02.000000000 +0000
>+++ /usr/src/linux/drivers/usb/core/devio.c 2003-01-14
>22:50:15.000000000 +0000
>@@ -30,6 +30,11 @@
> * Revision history
> * 22.12.1999 0.1 Initial release (split from proc_usb.c)
> * 04.01.2000 0.2 Turned into its own filesystem
>+ * 14.01.2003 0.3 use the active alt_setting for endpoint lookup
>+ * only perform lookup against interfaces that
>+ * have been claimed
>+ * use the endpoint interval for ISO transfers
>+ *
> */
>
>
>/*****************************************************************************/
>@@ -403,9 +408,9 @@
> return claimintf(ps, intf);
> }
>
>-static int findintfep(struct usb_device *dev, unsigned int ep)
>+static int findintfep(struct usb_device *dev, unsigned int ep,unsigned
>long ifclaimed)
> {
>- unsigned int i, j, e;
>+ unsigned int i, e;
> struct usb_interface *iface;
> struct usb_host_interface *alts;
> struct usb_endpoint_descriptor *endpt;
>@@ -413,15 +418,22 @@
> if (ep & ~(USB_DIR_IN|0xf))
> return -EINVAL;
> for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
>+
> iface = &dev->actconfig->interface[i];
>- for (j = 0; j < iface->num_altsetting; j++) {
>- alts = &iface->altsetting[j];
>+
>+ alts = &iface->altsetting[iface->act_altsetting];
>+ /*
>+ *Makes sure we've claimed the interface,
>+ * the interface should really be explicit not implisit
>+ * as more than one interface could have the same
>endpointaddress?
>+ */
>+ if(!test_bit(alts->desc.bInterfaceNumber,
>&ifclaimed))
>+ continue;
> for (e = 0; e < alts->desc.bNumEndpoints; e++) {
> endpt = &alts->endpoint[e].desc;
> if (endpt->bEndpointAddress == ep)
> return i;
>- }
>- }
>+ }
> }
> return -ENOENT;
> }
>@@ -454,7 +466,7 @@
>
> switch (requesttype & USB_RECIP_MASK) {
> case USB_RECIP_ENDPOINT:
>- if ((ret = findintfep(ps->dev, index & 0xff)) < 0)
>+ if ((ret = findintfep(ps->dev, index &
>0xff,ps->ifclaimed)) < 0)
> return ret;
> if ((ret = checkintf(ps, ret)))
> return ret;
>@@ -594,7 +606,7 @@
>
> if (copy_from_user(&bulk, (void *)arg, sizeof(bulk)))
> return -EFAULT;
>- if ((ret = findintfep(ps->dev, bulk.ep)) < 0)
>+ if ((ret = findintfep(ps->dev, bulk.ep,ps->ifclaimed)) < 0)
> return ret;
> if ((ret = checkintf(ps, ret)))
> return ret;
>@@ -645,7 +657,7 @@
>
> if (get_user(ep, (unsigned int *)arg))
> return -EFAULT;
>- if ((ret = findintfep(ps->dev, ep)) < 0)
>+ if ((ret = findintfep(ps->dev, ep,ps->ifclaimed)) < 0)
> return ret;
> if ((ret = checkintf(ps, ret)))
> return ret;
>@@ -661,7 +673,7 @@
>
> if (get_user(ep, (unsigned int *)arg))
> return -EFAULT;
>- if ((ret = findintfep(ps->dev, ep)) < 0)
>+ if ((ret = findintfep(ps->dev, ep,ps->ifclaimed)) < 0)
> return ret;
> if ((ret = checkintf(ps, ret)))
> return ret;
>@@ -770,8 +782,9 @@
> struct usb_endpoint_descriptor *ep_desc;
> struct async *as;
> struct usb_ctrlrequest *dr = NULL;
>+ struct usb_interface* interface = NULL;
> unsigned int u, totlen, isofrmlen;
>- int ret, interval = 0, intf = -1;
>+ int ret, interval = 0, intf = -1, epn;
>
> if (copy_from_user(&uurb, arg, sizeof(uurb)))
> return -EFAULT;
>@@ -783,10 +796,12 @@
> if (uurb.signr != 0 && (uurb.signr < SIGRTMIN || uurb.signr >
>SIGRTMAX))
> return -EINVAL;
> if (!(uurb.type == USBDEVFS_URB_TYPE_CONTROL && (uurb.endpoint &
>~USB_ENDPOINT_DIR_MASK) == 0)) {
>- if ((intf = findintfep(ps->dev, uurb.endpoint)) < 0)
>- return intf;
>+ if ((intf = findintfep(ps->dev,
>uurb.endpoint,ps->ifclaimed)) < 0)
>+ return intf;
> if ((ret = checkintf(ps, intf)))
> return ret;
>+ /*grab a pointer to the interface*/
>+ interface = usb_ifnum_to_if(ps->dev,intf);
> }
> switch(uurb.type) {
> case USBDEVFS_URB_TYPE_CONTROL:
>@@ -854,13 +869,56 @@
> return -EINVAL;
> }
> uurb.buffer_length = totlen;
>+ /*
>+ * set the value of the interval based upon the interval
>+ * of the selected interface/alt_setting that matches
>+ * the requested endpoint
>+ * TODO Tidy up the code,
>+ * e.g. move the lookup into a function
>+ */
>+ for(epn=0
>+
>;epn<interface->altsetting[interface->act_altsetting]
>+ .desc.bNumEndpoints
>+ ;epn++){
>+
>+ if(interface->altsetting[interface->act_altsetting]
>+ .endpoint[epn].desc.bEndpointAddress==uurb.endpoint){
>+
>+ interval=
>+ interface->altsetting[interface->act_altsetting]
>+ .endpoint[epn].desc.bInterval;
>+ break;
>+ }
>+ }
>+ if(epn==interface->altsetting[interface->act_altsetting]
>+ .desc.bNumEndpoints)
>+ return -ENOENT;
>+
>+/* interval =1;*/
> break;
>
> case USBDEVFS_URB_TYPE_INTERRUPT:
> uurb.number_of_packets = 0;
>- if (!(ep_desc = usb_epnum_to_ep_desc(ps->dev,
>uurb.endpoint)))
>+
>+ for(epn=0
>+
>;epn<interface->altsetting[interface->act_altsetting]
>+ .desc.bNumEndpoints
>+ ;epn++){
>+
>+ if(interface->altsetting[interface->act_altsetting]
>+ .endpoint[epn].desc.bEndpointAddress==uurb.endpoint){
>+
>+ interval=
>+ interface->altsetting[interface->act_altsetting]
>+ .endpoint[epn].desc.bInterval;
>+ break;
>+ }
>+ }
>+ if(epn==interface->altsetting[interface->act_altsetting]
>+ .desc.bNumEndpoints)
> return -ENOENT;
>- interval = ep_desc->bInterval;
>+
>+
> if (uurb.buffer_length > 16384)
> return -EINVAL;
> if (!access_ok((uurb.endpoint & USB_DIR_IN) ?
>VERIFY_WRITE : VERIFY_READ, uurb.buffer, uurb.buffer_length))
>
>
>
>-------------------------------------------------------
>This SF.NET email is sponsored by: Take your first step towards giving
>your online business a competitive advantage. Test-drive a Thawte SSL
>certificate - our easy online guide will show you how. Click here to get
>started: http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0027en
>_______________________________________________
>[EMAIL PROTECTED]
>To unsubscribe, use the last form field at:
>https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
>
--
Dan Streetman
[EMAIL PROTECTED]
---------------------
186,272 miles per second:
It isn't just a good idea, it's the law!
-------------------------------------------------------
This SF.NET email is sponsored by: Take your first step towards giving
your online business a competitive advantage. Test-drive a Thawte SSL
certificate - our easy online guide will show you how. Click here to get
started: http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0027en
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel