usb: define USB_SPEED_SUPER_PLUS speed for SuperSpeedPlus USB3.1 devices
Add a new USB_SPEED_SUPER_PLUS device speed, and make sure usb core can handle the new speed. In most cases the behaviour is the same as with USB_SPEED_SUPER SuperSpeed devices. In a few places we add a "Plus" string to inform the user of the new speed. Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
73a02d3245
commit
8a1b2725a6
@ -51,6 +51,7 @@ static const char *const speed_names[] = {
|
||||
[USB_SPEED_HIGH] = "high-speed",
|
||||
[USB_SPEED_WIRELESS] = "wireless",
|
||||
[USB_SPEED_SUPER] = "super-speed",
|
||||
[USB_SPEED_SUPER_PLUS] = "super-speed-plus",
|
||||
};
|
||||
|
||||
const char *usb_speed_string(enum usb_device_speed speed)
|
||||
|
@ -191,6 +191,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
|
||||
if (usb_endpoint_xfer_int(d)) {
|
||||
i = 1;
|
||||
switch (to_usb_device(ddev)->speed) {
|
||||
case USB_SPEED_SUPER_PLUS:
|
||||
case USB_SPEED_SUPER:
|
||||
case USB_SPEED_HIGH:
|
||||
/* Many device manufacturers are using full-speed
|
||||
@ -274,7 +275,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
|
||||
}
|
||||
|
||||
/* Parse a possible SuperSpeed endpoint companion descriptor */
|
||||
if (to_usb_device(ddev)->speed == USB_SPEED_SUPER)
|
||||
if (to_usb_device(ddev)->speed >= USB_SPEED_SUPER)
|
||||
usb_parse_ss_endpoint_companion(ddev, cfgno,
|
||||
inum, asnum, endpoint, buffer, size);
|
||||
|
||||
|
@ -221,7 +221,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,
|
||||
break;
|
||||
case USB_ENDPOINT_XFER_INT:
|
||||
type = "Int.";
|
||||
if (speed == USB_SPEED_HIGH || speed == USB_SPEED_SUPER)
|
||||
if (speed == USB_SPEED_HIGH || speed >= USB_SPEED_SUPER)
|
||||
interval = 1 << (desc->bInterval - 1);
|
||||
else
|
||||
interval = desc->bInterval;
|
||||
@ -230,7 +230,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,
|
||||
return start;
|
||||
}
|
||||
interval *= (speed == USB_SPEED_HIGH ||
|
||||
speed == USB_SPEED_SUPER) ? 125 : 1000;
|
||||
speed >= USB_SPEED_SUPER) ? 125 : 1000;
|
||||
if (interval % 1000)
|
||||
unit = 'u';
|
||||
else {
|
||||
@ -322,7 +322,7 @@ static char *usb_dump_config_descriptor(char *start, char *end,
|
||||
|
||||
if (start > end)
|
||||
return start;
|
||||
if (speed == USB_SPEED_SUPER)
|
||||
if (speed >= USB_SPEED_SUPER)
|
||||
mul = 8;
|
||||
else
|
||||
mul = 2;
|
||||
@ -534,6 +534,8 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
|
||||
speed = "480"; break;
|
||||
case USB_SPEED_SUPER:
|
||||
speed = "5000"; break;
|
||||
case USB_SPEED_SUPER_PLUS:
|
||||
speed = "10000"; break;
|
||||
default:
|
||||
speed = "??";
|
||||
}
|
||||
@ -553,7 +555,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
|
||||
|
||||
/* super/high speed reserves 80%, full/low reserves 90% */
|
||||
if (usbdev->speed == USB_SPEED_HIGH ||
|
||||
usbdev->speed == USB_SPEED_SUPER)
|
||||
usbdev->speed >= USB_SPEED_SUPER)
|
||||
max = 800;
|
||||
else
|
||||
max = FRAME_TIME_MAX_USECS_ALLOC;
|
||||
|
@ -197,7 +197,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
* The xHCI driver has its own irq management
|
||||
* make sure irq setup is not touched for xhci in generic hcd code
|
||||
*/
|
||||
if ((driver->flags & HCD_MASK) != HCD_USB3) {
|
||||
if ((driver->flags & HCD_MASK) < HCD_USB3) {
|
||||
if (!dev->irq) {
|
||||
dev_err(&dev->dev,
|
||||
"Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
|
||||
|
@ -1078,7 +1078,7 @@ static int register_root_hub(struct usb_hcd *hcd)
|
||||
retval = usb_get_bos_descriptor(usb_dev);
|
||||
if (!retval) {
|
||||
usb_dev->lpm_capable = usb_device_supports_lpm(usb_dev);
|
||||
} else if (usb_dev->speed == USB_SPEED_SUPER) {
|
||||
} else if (usb_dev->speed >= USB_SPEED_SUPER) {
|
||||
mutex_unlock(&usb_bus_list_lock);
|
||||
dev_dbg(parent_dev, "can't read %s bos descriptor %d\n",
|
||||
dev_name(&usb_dev->dev), retval);
|
||||
@ -2112,7 +2112,7 @@ int usb_alloc_streams(struct usb_interface *interface,
|
||||
hcd = bus_to_hcd(dev->bus);
|
||||
if (!hcd->driver->alloc_streams || !hcd->driver->free_streams)
|
||||
return -EINVAL;
|
||||
if (dev->speed != USB_SPEED_SUPER)
|
||||
if (dev->speed < USB_SPEED_SUPER)
|
||||
return -EINVAL;
|
||||
if (dev->state < USB_STATE_CONFIGURED)
|
||||
return -ENODEV;
|
||||
@ -2160,7 +2160,7 @@ int usb_free_streams(struct usb_interface *interface,
|
||||
|
||||
dev = interface_to_usbdev(interface);
|
||||
hcd = bus_to_hcd(dev->bus);
|
||||
if (dev->speed != USB_SPEED_SUPER)
|
||||
if (dev->speed < USB_SPEED_SUPER)
|
||||
return -EINVAL;
|
||||
|
||||
/* Double-free is not allowed */
|
||||
|
@ -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
|
||||
|
@ -401,7 +401,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
|
||||
/* SuperSpeed isoc endpoints have up to 16 bursts of up to
|
||||
* 3 packets each
|
||||
*/
|
||||
if (dev->speed == USB_SPEED_SUPER) {
|
||||
if (dev->speed >= USB_SPEED_SUPER) {
|
||||
int burst = 1 + ep->ss_ep_comp.bMaxBurst;
|
||||
int mult = USB_SS_MULT(ep->ss_ep_comp.bmAttributes);
|
||||
max *= burst;
|
||||
@ -499,6 +499,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
|
||||
}
|
||||
/* too big? */
|
||||
switch (dev->speed) {
|
||||
case USB_SPEED_SUPER_PLUS:
|
||||
case USB_SPEED_SUPER: /* units are 125us */
|
||||
/* Handle up to 2^(16-1) microframes */
|
||||
if (urb->interval > (1 << 15))
|
||||
|
@ -45,7 +45,7 @@ static inline unsigned usb_get_max_power(struct usb_device *udev,
|
||||
struct usb_host_config *c)
|
||||
{
|
||||
/* SuperSpeed power is in 8 mA units; others are in 2 mA units */
|
||||
unsigned mul = (udev->speed == USB_SPEED_SUPER ? 8 : 2);
|
||||
unsigned mul = (udev->speed >= USB_SPEED_SUPER ? 8 : 2);
|
||||
|
||||
return c->desc.bMaxPower * mul;
|
||||
}
|
||||
|
@ -954,6 +954,7 @@ enum usb_device_speed {
|
||||
USB_SPEED_HIGH, /* usb 2.0 */
|
||||
USB_SPEED_WIRELESS, /* wireless (usb 2.5) */
|
||||
USB_SPEED_SUPER, /* usb 3.0 */
|
||||
USB_SPEED_SUPER_PLUS, /* usb 3.1 */
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user