aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/hcd.c
diff options
context:
space:
mode:
authorinaky@linux.intel.com <inaky@linux.intel.com>2006-10-11 23:05:59 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-12-01 17:23:26 -0500
commit88fafff9d73c0a506c0b08e7cd637c89d8b604e1 (patch)
tree238af08cc3639f32943890535e0f036a9606752c /drivers/usb/core/hcd.c
parent437052516779fea608261a50682b124315f48f01 (diff)
usb hub: fix root hub code so it takes more than 15 devices per root hub
Wireless USB Host Controllers accept a large number of devices per host, which shows up as a large number of ports in its root hub. When the number of ports in a hub device goes over 16, the activation of the hub fails with the cryptic message in klogd. hub 2-0:1.0: activate --> -22 Following this further, it was seen that: hub_probe() hub_configure() generates pipe number pseudo allocates buffer 'maxp' bytes in size using usb_maxpacket() The endpoint descriptor for a root hub interrupt endpoint is declared in drivers/usb/core/hcd.c:hs_rh_config_descriptor and declares it to be size two (supporting 15 devices max). hub_activate() usb_hcd_submit_urb() rh_urb_enqueue() urb->pipe is neither int nor ctl, so it errors out rh_queue_status() Returns -EINVAL because the buffer length is smaller than the minimum needed to report all the hub port bits as in accordance with USB2.0[11.12.3]. There has to be trunc((PORTS + 1 + 7) / 8) bytes of space at least. Alan Stern confirmed that the reason for reading maxpktsize and not the right amount is because some hubs are known to return more data and thus cause overflow. So this patch simply changes the code to make the interrupt endpoint's max packet size be at least the minimum required by USB_MAXCHILDREN (instead of a fixed magic number) and add documentation for that. This way we are always ahead of the limit. Signed-off-by: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/hcd.c')
-rw-r--r--drivers/usb/core/hcd.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index afa2dd20332..10064af65d1 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -256,7 +256,9 @@ static const u8 hs_rh_config_descriptor [] = {
256 0x05, /* __u8 ep_bDescriptorType; Endpoint */ 256 0x05, /* __u8 ep_bDescriptorType; Endpoint */
257 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ 257 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
258 0x03, /* __u8 ep_bmAttributes; Interrupt */ 258 0x03, /* __u8 ep_bmAttributes; Interrupt */
259 0x02, 0x00, /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ 259 /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8)
260 * see hub.c:hub_configure() for details. */
261 (USB_MAXCHILDREN + 1 + 7) / 8, 0x00,
260 0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */ 262 0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */
261}; 263};
262 264