aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/config.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 2d4fd530e5e4..dd3482328ad2 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -1,4 +1,5 @@
1#include <linux/usb.h> 1#include <linux/usb.h>
2#include <linux/usb/ch9.h>
2#include <linux/module.h> 3#include <linux/module.h>
3#include <linux/init.h> 4#include <linux/init.h>
4#include <linux/slab.h> 5#include <linux/slab.h>
@@ -49,7 +50,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
49 unsigned char *buffer0 = buffer; 50 unsigned char *buffer0 = buffer;
50 struct usb_endpoint_descriptor *d; 51 struct usb_endpoint_descriptor *d;
51 struct usb_host_endpoint *endpoint; 52 struct usb_host_endpoint *endpoint;
52 int n, i; 53 int n, i, j;
53 54
54 d = (struct usb_endpoint_descriptor *) buffer; 55 d = (struct usb_endpoint_descriptor *) buffer;
55 buffer += d->bLength; 56 buffer += d->bLength;
@@ -84,6 +85,45 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
84 memcpy(&endpoint->desc, d, n); 85 memcpy(&endpoint->desc, d, n);
85 INIT_LIST_HEAD(&endpoint->urb_list); 86 INIT_LIST_HEAD(&endpoint->urb_list);
86 87
88 /* If the bInterval value is outside the legal range,
89 * set it to a default value: 32 ms */
90 i = 0; /* i = min, j = max, n = default */
91 j = 255;
92 if (usb_endpoint_xfer_int(d)) {
93 i = 1;
94 switch (to_usb_device(ddev)->speed) {
95 case USB_SPEED_HIGH:
96 n = 9; /* 32 ms = 2^(9-1) uframes */
97 j = 16;
98 break;
99 default: /* USB_SPEED_FULL or _LOW */
100 /* For low-speed, 10 ms is the official minimum.
101 * But some "overclocked" devices might want faster
102 * polling so we'll allow it. */
103 n = 32;
104 break;
105 }
106 } else if (usb_endpoint_xfer_isoc(d)) {
107 i = 1;
108 j = 16;
109 switch (to_usb_device(ddev)->speed) {
110 case USB_SPEED_HIGH:
111 n = 9; /* 32 ms = 2^(9-1) uframes */
112 break;
113 default: /* USB_SPEED_FULL */
114 n = 6; /* 32 ms = 2^(6-1) frames */
115 break;
116 }
117 }
118 if (d->bInterval < i || d->bInterval > j) {
119 dev_warn(ddev, "config %d interface %d altsetting %d "
120 "endpoint 0x%X has an invalid bInterval %d, "
121 "changing to %d\n",
122 cfgno, inum, asnum,
123 d->bEndpointAddress, d->bInterval, n);
124 endpoint->desc.bInterval = n;
125 }
126
87 /* Skip over any Class Specific or Vendor Specific descriptors; 127 /* Skip over any Class Specific or Vendor Specific descriptors;
88 * find the next endpoint or interface descriptor */ 128 * find the next endpoint or interface descriptor */
89 endpoint->extra = buffer; 129 endpoint->extra = buffer;