From 1c9de5bf428612458427943b724bea51abde520a Mon Sep 17 00:00:00 2001 From: Yuyang Du Date: Thu, 8 Jun 2017 13:04:10 +0800 Subject: usbip: vhci-hcd: Add USB3 SuperSpeed support This patch adds a USB3 HCD to an existing USB2 HCD and provides the support of SuperSpeed, in case the device can only be enumerated with SuperSpeed. The bulk of the added code in usb3_bos_desc and hub_control to support SuperSpeed is borrowed from the commit 1cd8fd2887e162ad ("usb: gadget: dummy_hcd: add SuperSpeed support"). With this patch, each vhci will have VHCI_HC_PORTS HighSpeed ports and VHCI_HC_PORTS SuperSpeed ports. Suggested-by: Krzysztof Opasiak Signed-off-by: Yuyang Du Acked-by: Shuah Khan Signed-off-by: Greg Kroah-Hartman --- tools/usb/usbip/libsrc/vhci_driver.c | 23 ++++++++++++++++------- tools/usb/usbip/libsrc/vhci_driver.h | 8 +++++++- tools/usb/usbip/src/usbip_attach.c | 3 ++- 3 files changed, 25 insertions(+), 9 deletions(-) (limited to 'tools/usb') diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 3d8189b4f539..9bd2cd71645d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -52,9 +52,10 @@ static int parse_status(const char *value) unsigned long socket; char lbusid[SYSFS_BUS_ID_SIZE]; struct usbip_imported_device *idev; + char hub[3]; - ret = sscanf(c, "%d %d %d %x %lx %31s\n", - &port, &status, &speed, + ret = sscanf(c, "%2s %d %d %d %x %lx %31s\n", + hub, &port, &status, &speed, &devid, &socket, lbusid); if (ret < 5) { @@ -62,15 +63,19 @@ static int parse_status(const char *value) BUG(); } - dbg("port %d status %d speed %d devid %x", - port, status, speed, devid); + dbg("hub %s port %d status %d speed %d devid %x", + hub, port, status, speed, devid); dbg("socket %lx lbusid %s", socket, lbusid); /* if a device is connected, look at it */ idev = &vhci_driver->idev[port]; - memset(idev, 0, sizeof(*idev)); + if (strncmp("hs", hub, 2) == 0) + idev->hub = HUB_SPEED_HIGH; + else /* strncmp("ss", hub, 2) == 0 */ + idev->hub = HUB_SPEED_SUPER; + idev->port = port; idev->status = status; @@ -320,11 +325,15 @@ err: } -int usbip_vhci_get_free_port(void) +int usbip_vhci_get_free_port(uint32_t speed) { for (int i = 0; i < vhci_driver->nports; i++) { + if (speed == USB_SPEED_SUPER && + vhci_driver->idev[i].hub != HUB_SPEED_SUPER) + continue; + if (vhci_driver->idev[i].status == VDEV_ST_NULL) - return i; + return vhci_driver->idev[i].port; } return -1; diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index dfe19c1c0245..4898d3bafb10 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -14,7 +14,13 @@ #define USBIP_VHCI_DEVICE_NAME "vhci_hcd.0" #define MAXNPORT 128 +enum hub_speed { + HUB_SPEED_HIGH = 0, + HUB_SPEED_SUPER, +}; + struct usbip_imported_device { + enum hub_speed hub; uint8_t port; uint32_t status; @@ -46,7 +52,7 @@ void usbip_vhci_driver_close(void); int usbip_vhci_refresh_device_list(void); -int usbip_vhci_get_free_port(void); +int usbip_vhci_get_free_port(uint32_t speed); int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, uint32_t speed); diff --git a/tools/usb/usbip/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c index 62a297ff647a..6e89768ffe30 100644 --- a/tools/usb/usbip/src/usbip_attach.c +++ b/tools/usb/usbip/src/usbip_attach.c @@ -94,6 +94,7 @@ static int import_device(int sockfd, struct usbip_usb_device *udev) { int rc; int port; + uint32_t speed = udev->speed; rc = usbip_vhci_driver_open(); if (rc < 0) { @@ -101,7 +102,7 @@ static int import_device(int sockfd, struct usbip_usb_device *udev) return -1; } - port = usbip_vhci_get_free_port(); + port = usbip_vhci_get_free_port(speed); if (port < 0) { err("no free port"); usbip_vhci_driver_close(); -- cgit v1.2.3-58-ga151