diff options
author | Laurent Pinchart <laurent.pinchart@skynet.be> | 2007-06-12 15:47:17 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-12 19:34:37 -0400 |
commit | 300871cd963e24a68aaa9b762f4a10403697d9be (patch) | |
tree | 2ef076a36b077e15a7a6d65a32703c89685bbcfa /drivers/usb | |
parent | 87d093e25d73249ae92b28ae88db92eaea7df70f (diff) |
USB: Fix up full-speed bInterval values in high-speed interrupt descriptor
Many device manufacturers are using full-speed bInterval values in high-speed
interrupt endpoint descriptors. If the bInterval value is greater than 16,
assume the device uses full-speed descriptors and fix the value accordingly.
Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/config.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 9152e12dcf71..5e113db41b59 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -85,15 +85,21 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | |||
85 | memcpy(&endpoint->desc, d, n); | 85 | memcpy(&endpoint->desc, d, n); |
86 | INIT_LIST_HEAD(&endpoint->urb_list); | 86 | INIT_LIST_HEAD(&endpoint->urb_list); |
87 | 87 | ||
88 | /* If the bInterval value is outside the legal range, | 88 | /* Fix up bInterval values outside the legal range. Use 32 ms if no |
89 | * set it to a default value: 32 ms */ | 89 | * proper value can be guessed. */ |
90 | i = 0; /* i = min, j = max, n = default */ | 90 | i = 0; /* i = min, j = max, n = default */ |
91 | j = 255; | 91 | j = 255; |
92 | if (usb_endpoint_xfer_int(d)) { | 92 | if (usb_endpoint_xfer_int(d)) { |
93 | i = 1; | 93 | i = 1; |
94 | switch (to_usb_device(ddev)->speed) { | 94 | switch (to_usb_device(ddev)->speed) { |
95 | case USB_SPEED_HIGH: | 95 | case USB_SPEED_HIGH: |
96 | n = 9; /* 32 ms = 2^(9-1) uframes */ | 96 | /* Many device manufacturers are using full-speed |
97 | * bInterval values in high-speed interrupt endpoint | ||
98 | * descriptors. Try to fix those and fall back to a | ||
99 | * 32 ms default value otherwise. */ | ||
100 | n = fls(d->bInterval*8); | ||
101 | if (n == 0) | ||
102 | n = 9; /* 32 ms = 2^(9-1) uframes */ | ||
97 | j = 16; | 103 | j = 16; |
98 | break; | 104 | break; |
99 | default: /* USB_SPEED_FULL or _LOW */ | 105 | default: /* USB_SPEED_FULL or _LOW */ |