From 1bb90cf0462c9a07cb428e9dd9665041fe7f9e18 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 19 Jul 2017 14:40:53 +0800 Subject: usb: core: hub: controller driver name may be NULL The controller driver may be NULL if the controller device is the middle device between platform device and roothub. This middle device may not need a device driver due to all hardware control can be at platform device driver, this platform device is usually a dual-role USB controller device. The benefit of using this middle device is we can keep both controller device's private data (known as struct usb_hcd) for USB core use, and platform device's private data for platform driver use. Signed-off-by: Peter Chen Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers/usb/core/hub.c') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 6e6797d145dd..7e3670019aa3 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4342,6 +4342,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, enum usb_device_speed oldspeed = udev->speed; const char *speed; int devnum = udev->devnum; + const char *driver_name; /* root hub ports have a slightly longer reset period * (from USB 2.0 spec, section 7.1.7.5) @@ -4409,11 +4410,23 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, else speed = usb_speed_string(udev->speed); + /* + * The controller driver may be NULL if the controller device + * is the middle device between platform device and roothub. + * This middle device may not need a device driver due to + * all hardware control can be at platform device driver, this + * platform device is usually a dual-role USB controller device. + */ + if (udev->bus->controller->driver) + driver_name = udev->bus->controller->driver->name; + else + driver_name = udev->bus->sysdev->driver->name; + if (udev->speed < USB_SPEED_SUPER) dev_info(&udev->dev, "%s %s USB device number %d using %s\n", (udev->config) ? "reset" : "new", speed, - devnum, udev->bus->controller->driver->name); + devnum, driver_name); /* Set up TT records, if needed */ if (hdev->tt) { @@ -4545,7 +4558,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, "%s SuperSpeed%s USB device number %d using %s\n", (udev->config) ? "reset" : "new", (udev->speed == USB_SPEED_SUPER_PLUS) ? "Plus" : "", - devnum, udev->bus->controller->driver->name); + devnum, driver_name); } /* cope with hardware quirkiness: -- cgit From 74072bae88fb3b0f8b54ec88055abfda758fcba1 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Wed, 16 Aug 2017 14:23:25 +0300 Subject: usb: Increase root hub reset signaling time to prevent retry Save 80ms device enumeration time by increasing root hub port reset time The 50ms reset signaling time is not enough for most root hub ports. Increasing the reset time to 60ms allows host controllers to finish port reset and removes a retry causing an extra 50ms delay. The USB 2 specification requires "at least 50ms" for driving root port reset. The current msleep is exactly 50ms which may not be enough if there are any delays between writing the reset bit to host controller portsc register and phy actually driving reset. On Haswell, Skylake and Kabylake xHC port reset took in average 52-59ms The 80ms improvement comes from (40ms * 2 port resets) save at enumeration for each device connected to a root hub port. more details about root port reset in USB2 section 7.1.7.5:. "Software must ensure that resets issued to the root ports drive reset long enough to overwhelm any concurrent resume attempts by downstream devices. It is required that resets from root ports have a duration of at least 50 ms (TDRSTR). Signed-off-by: Mathias Nyman Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/core/hub.c') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index e53308c558c0..41eaf0b52518 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2614,7 +2614,7 @@ static unsigned hub_is_wusb(struct usb_hub *hub) #define SET_CONFIG_TRIES (2 * (use_both_schemes + 1)) #define USE_NEW_SCHEME(i) ((i) / 2 == (int)old_scheme_first) -#define HUB_ROOT_RESET_TIME 50 /* times are in msec */ +#define HUB_ROOT_RESET_TIME 60 /* times are in msec */ #define HUB_SHORT_RESET_TIME 10 #define HUB_BH_RESET_TIME 50 #define HUB_LONG_RESET_TIME 200 -- cgit