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