diff options
author | Johan Hovold <johan@kernel.org> | 2017-05-10 18:18:26 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-06-29 12:48:52 +0200 |
commit | 800d7454e50fea1af3801adf4debf249922b2c88 (patch) | |
tree | 32f4fa28f8a3815c8d8bb60d53c4fce5998040bd /drivers/usb | |
parent | 525e496a9722a6189f7ece9236a76f00cb8abef0 (diff) |
USB: usbip: fix nonconforming hub descriptor
commit ec963b412a54aac8e527708ecad06a6988a86fb4 upstream.
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>
[ johan: backport to v4.4, which uses VHCI_NPORTS ]
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-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 7fbe19d5279e..81b2b9f808b5 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -215,14 +215,19 @@ done: static inline void hub_descriptor(struct usb_hub_descriptor *desc) { + int width; + memset(desc, 0, sizeof(*desc)); desc->bDescriptorType = USB_DT_HUB; - desc->bDescLength = 9; desc->wHubCharacteristics = cpu_to_le16( HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_COMMON_OCPM); + desc->bNbrPorts = VHCI_NPORTS; - desc->u.hs.DeviceRemovable[0] = 0xff; - desc->u.hs.DeviceRemovable[1] = 0xff; + BUILD_BUG_ON(VHCI_NPORTS > USB_MAXCHILDREN); + width = desc->bNbrPorts / 8 + 1; + desc->bDescLength = USB_DT_HUB_NONVAR_SIZE + 2 * width; + memset(&desc->u.hs.DeviceRemovable[0], 0, width); + memset(&desc->u.hs.DeviceRemovable[width], 0xff, width); } static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, |