|
@@ -298,7 +298,7 @@ static void usb_set_lpm_parameters(struct usb_device *udev)
|
|
|
unsigned int hub_u1_del;
|
|
|
unsigned int hub_u2_del;
|
|
|
|
|
|
- if (!udev->lpm_capable || udev->speed != USB_SPEED_SUPER)
|
|
|
+ if (!udev->lpm_capable || udev->speed < USB_SPEED_SUPER)
|
|
|
return;
|
|
|
|
|
|
hub = usb_hub_to_struct_hub(udev->parent);
|
|
@@ -2645,7 +2645,7 @@ static unsigned hub_is_wusb(struct usb_hub *hub)
|
|
|
*/
|
|
|
static bool use_new_scheme(struct usb_device *udev, int retry)
|
|
|
{
|
|
|
- if (udev->speed == USB_SPEED_SUPER)
|
|
|
+ if (udev->speed >= USB_SPEED_SUPER)
|
|
|
return false;
|
|
|
|
|
|
return USE_NEW_SCHEME(retry);
|
|
@@ -3989,7 +3989,7 @@ int usb_disable_lpm(struct usb_device *udev)
|
|
|
struct usb_hcd *hcd;
|
|
|
|
|
|
if (!udev || !udev->parent ||
|
|
|
- udev->speed != USB_SPEED_SUPER ||
|
|
|
+ udev->speed < USB_SPEED_SUPER ||
|
|
|
!udev->lpm_capable ||
|
|
|
udev->state < USB_STATE_DEFAULT)
|
|
|
return 0;
|
|
@@ -4048,7 +4048,7 @@ void usb_enable_lpm(struct usb_device *udev)
|
|
|
struct usb_port *port_dev;
|
|
|
|
|
|
if (!udev || !udev->parent ||
|
|
|
- udev->speed != USB_SPEED_SUPER ||
|
|
|
+ udev->speed < USB_SPEED_SUPER ||
|
|
|
!udev->lpm_capable ||
|
|
|
udev->state < USB_STATE_DEFAULT)
|
|
|
return;
|
|
@@ -4323,7 +4323,9 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
|
|
|
|
|
|
retval = -ENODEV;
|
|
|
|
|
|
- if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) {
|
|
|
+ /* Don't allow speed changes at reset, except usb 3.0 to faster */
|
|
|
+ if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed &&
|
|
|
+ !(oldspeed == USB_SPEED_SUPER && udev->speed > oldspeed)) {
|
|
|
dev_dbg(&udev->dev, "device reset changed speed!\n");
|
|
|
goto fail;
|
|
|
}
|
|
@@ -4335,6 +4337,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
|
|
|
* reported as 0xff in the device descriptor). WUSB1.0[4.8.1].
|
|
|
*/
|
|
|
switch (udev->speed) {
|
|
|
+ case USB_SPEED_SUPER_PLUS:
|
|
|
case USB_SPEED_SUPER:
|
|
|
case USB_SPEED_WIRELESS: /* fixed at 512 */
|
|
|
udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
|
|
@@ -4361,7 +4364,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
|
|
|
else
|
|
|
speed = usb_speed_string(udev->speed);
|
|
|
|
|
|
- if (udev->speed != USB_SPEED_SUPER)
|
|
|
+ if (udev->speed < USB_SPEED_SUPER)
|
|
|
dev_info(&udev->dev,
|
|
|
"%s %s USB device number %d using %s\n",
|
|
|
(udev->config) ? "reset" : "new", speed,
|
|
@@ -4485,11 +4488,12 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
|
|
|
devnum, retval);
|
|
|
goto fail;
|
|
|
}
|
|
|
- if (udev->speed == USB_SPEED_SUPER) {
|
|
|
+ if (udev->speed >= USB_SPEED_SUPER) {
|
|
|
devnum = udev->devnum;
|
|
|
dev_info(&udev->dev,
|
|
|
- "%s SuperSpeed USB device number %d using %s\n",
|
|
|
+ "%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);
|
|
|
}
|
|
|
|
|
@@ -4528,7 +4532,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
|
|
|
* got from those devices show they aren't superspeed devices. Warm
|
|
|
* reset the port attached by the devices can fix them.
|
|
|
*/
|
|
|
- if ((udev->speed == USB_SPEED_SUPER) &&
|
|
|
+ if ((udev->speed >= USB_SPEED_SUPER) &&
|
|
|
(le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) {
|
|
|
dev_err(&udev->dev, "got a wrong device descriptor, "
|
|
|
"warm reset device\n");
|
|
@@ -4539,7 +4543,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
|
|
|
}
|
|
|
|
|
|
if (udev->descriptor.bMaxPacketSize0 == 0xff ||
|
|
|
- udev->speed == USB_SPEED_SUPER)
|
|
|
+ udev->speed >= USB_SPEED_SUPER)
|
|
|
i = 512;
|
|
|
else
|
|
|
i = udev->descriptor.bMaxPacketSize0;
|
|
@@ -4749,7 +4753,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
|
|
|
udev->level = hdev->level + 1;
|
|
|
udev->wusb = hub_is_wusb(hub);
|
|
|
|
|
|
- /* Only USB 3.0 devices are connected to SuperSpeed hubs. */
|
|
|
+ /* Devices connected to SuperSpeed hubs are USB 3.0 or later */
|
|
|
if (hub_is_superspeed(hub->hdev))
|
|
|
udev->speed = USB_SPEED_SUPER;
|
|
|
else
|