On Friday 08 June 2007, Alan Stern wrote: > This patch (as904) adds code to check for endpoint descriptor bInterval > values outside the legal limits. Illegal values are set to 32 ms, which > seems like a reasonable default. > > This fixes Bugzilla #8432. > > Signed-off-by: Alan Stern <[EMAIL PROTECTED]>
>From my experience, a common cause of bogus bInterval values is developers forgetting that the value has a different meaning for high-speed and low-speed/full-speed devices. I've come across a device reporting interrupt bInterval set to 32 instead of 9. By sheer luck your patch fixes this properly, but it would set a wrong bInterval value for devices setting bInterval to 16 instead of 8 for instance. The USB developers FAQ (available at http://www.lvr.com/usbfaq.htm) states that "Reports are that many device manufacturers are using full-speed bInterval values in high-speed descriptors. Reports also say that under Windows, a device may receive its intended polling rate (rather than its requested polling rate) in spite of this error. Other operating systems are likely to attempt to provide the requested polling rate, or may report an illegal bInterval value." For high-speed interrupt endpoints, wouldn't it be better to set bInterval to fls(bInterval*8) if the requested value is higher than 16 ? Laurent Pinchart > Index: usb-2.6/drivers/usb/core/config.c > =================================================================== > --- usb-2.6.orig/drivers/usb/core/config.c > +++ usb-2.6/drivers/usb/core/config.c > @@ -1,4 +1,5 @@ > #include <linux/usb.h> > +#include <linux/usb/ch9.h> > #include <linux/module.h> > #include <linux/init.h> > #include <linux/slab.h> > @@ -49,7 +50,7 @@ static int usb_parse_endpoint(struct dev > unsigned char *buffer0 = buffer; > struct usb_endpoint_descriptor *d; > struct usb_host_endpoint *endpoint; > - int n, i; > + int n, i, j; > > d = (struct usb_endpoint_descriptor *) buffer; > buffer += d->bLength; > @@ -84,6 +85,45 @@ static int usb_parse_endpoint(struct dev > memcpy(&endpoint->desc, d, n); > INIT_LIST_HEAD(&endpoint->urb_list); > > + /* If the bInterval value is outside the legal range, > + * set it to a default value: 32 ms */ > + i = 0; /* i = min, j = max, n = default */ > + j = 255; > + if (usb_endpoint_xfer_int(d)) { > + i = 1; > + switch (to_usb_device(ddev)->speed) { > + case USB_SPEED_HIGH: > + n = 9; /* 32 ms = 2^(9-1) uframes */ > + j = 16; > + break; > + default: /* USB_SPEED_FULL or _LOW */ > + /* For low-speed, 10 ms is the official minimum. > + * But some "overclocked" devices might want faster > + * polling so we'll allow it. */ > + n = 32; > + break; > + } > + } else if (usb_endpoint_xfer_isoc(d)) { > + i = 1; > + j = 16; > + switch (to_usb_device(ddev)->speed) { > + case USB_SPEED_HIGH: > + n = 9; /* 32 ms = 2^(9-1) uframes */ > + break; > + default: /* USB_SPEED_FULL */ > + n = 6; /* 32 ms = 2^(6-1) frames */ > + break; > + } > + } > + if (d->bInterval < i || d->bInterval > j) { > + dev_warn(ddev, "config %d interface %d altsetting %d " > + "endpoint 0x%X has an invalid bInterval %d, " > + "changing to %d\n", > + cfgno, inum, asnum, > + d->bEndpointAddress, d->bInterval, n); > + endpoint->desc.bInterval = n; > + } > + > /* Skip over any Class Specific or Vendor Specific descriptors; > * find the next endpoint or interface descriptor */ > endpoint->extra = buffer; ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel