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