diff options
author | Johan Hovold <johan@kernel.org> | 2017-05-10 12:18:26 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-17 05:53:02 -0400 |
commit | ec963b412a54aac8e527708ecad06a6988a86fb4 (patch) | |
tree | ef5ebb701ffcf5f90b48ab63508e213748c218f9 | |
parent | d81182ce30dbd497a1e7047d7fda2af040347790 (diff) |
USB: usbip: fix nonconforming hub descriptor
Fix up the root-hub descriptor to accommodate the variable-length
DeviceRemovable and PortPwrCtrlMask fields, while marking all ports as
removable (and leaving the reserved bit zero unset).
Also add a build-time constraint on VHCI_HC_PORTS which must never be
greater than USB_MAXCHILDREN (but this was only enforced through a
KConfig constant).
This specifically fixes the descriptor layout whenever VHCI_HC_PORTS is
greater than seven (default is 8).
Fixes: 04679b3489e0 ("Staging: USB/IP: add client driver")
Cc: Takahiro Hirofuchi <hirofuchi@users.sourceforge.net>
Cc: Valentina Manea <valentina.manea.m@gmail.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Acked-by: Shuah Khan <shuahkh@osg.samsung.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/usbip/vhci_hcd.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 5d8b2c261940..0585078638db 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c | |||
@@ -235,14 +235,19 @@ done: | |||
235 | 235 | ||
236 | static inline void hub_descriptor(struct usb_hub_descriptor *desc) | 236 | static inline void hub_descriptor(struct usb_hub_descriptor *desc) |
237 | { | 237 | { |
238 | int width; | ||
239 | |||
238 | memset(desc, 0, sizeof(*desc)); | 240 | memset(desc, 0, sizeof(*desc)); |
239 | desc->bDescriptorType = USB_DT_HUB; | 241 | desc->bDescriptorType = USB_DT_HUB; |
240 | desc->bDescLength = 9; | ||
241 | desc->wHubCharacteristics = cpu_to_le16( | 242 | desc->wHubCharacteristics = cpu_to_le16( |
242 | HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_COMMON_OCPM); | 243 | HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_COMMON_OCPM); |
244 | |||
243 | desc->bNbrPorts = VHCI_HC_PORTS; | 245 | desc->bNbrPorts = VHCI_HC_PORTS; |
244 | desc->u.hs.DeviceRemovable[0] = 0xff; | 246 | BUILD_BUG_ON(VHCI_HC_PORTS > USB_MAXCHILDREN); |
245 | desc->u.hs.DeviceRemovable[1] = 0xff; | 247 | width = desc->bNbrPorts / 8 + 1; |
248 | desc->bDescLength = USB_DT_HUB_NONVAR_SIZE + 2 * width; | ||
249 | memset(&desc->u.hs.DeviceRemovable[0], 0, width); | ||
250 | memset(&desc->u.hs.DeviceRemovable[width], 0xff, width); | ||
246 | } | 251 | } |
247 | 252 | ||
248 | static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | 253 | static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, |