Commit 0caf6b33 authored by Mathias Nyman's avatar Mathias Nyman Committed by Greg Kroah-Hartman

xhci: Make sure xhci handles USB_SPEED_SUPER_PLUS devices.

In most cases the devices with the speed set to USB_SPEED_SUPER_PLUS
are handled like regular SuperSpeed devices.
Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8df0d77d
...@@ -1070,7 +1070,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd *xhci, ...@@ -1070,7 +1070,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd *xhci,
struct usb_device *top_dev; struct usb_device *top_dev;
struct usb_hcd *hcd; struct usb_hcd *hcd;
if (udev->speed == USB_SPEED_SUPER) if (udev->speed >= USB_SPEED_SUPER)
hcd = xhci->shared_hcd; hcd = xhci->shared_hcd;
else else
hcd = xhci->main_hcd; hcd = xhci->main_hcd;
...@@ -1105,6 +1105,7 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud ...@@ -1105,6 +1105,7 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
/* 3) Only the control endpoint is valid - one endpoint context */ /* 3) Only the control endpoint is valid - one endpoint context */
slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | udev->route); slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | udev->route);
switch (udev->speed) { switch (udev->speed) {
case USB_SPEED_SUPER_PLUS:
case USB_SPEED_SUPER: case USB_SPEED_SUPER:
slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SS); slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SS);
max_packets = MAX_PACKET(512); max_packets = MAX_PACKET(512);
...@@ -1292,6 +1293,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev, ...@@ -1292,6 +1293,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
} }
/* Fall through - SS and HS isoc/int have same decoding */ /* Fall through - SS and HS isoc/int have same decoding */
case USB_SPEED_SUPER_PLUS:
case USB_SPEED_SUPER: case USB_SPEED_SUPER:
if (usb_endpoint_xfer_int(&ep->desc) || if (usb_endpoint_xfer_int(&ep->desc) ||
usb_endpoint_xfer_isoc(&ep->desc)) { usb_endpoint_xfer_isoc(&ep->desc)) {
...@@ -1332,7 +1334,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev, ...@@ -1332,7 +1334,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
static u32 xhci_get_endpoint_mult(struct usb_device *udev, static u32 xhci_get_endpoint_mult(struct usb_device *udev,
struct usb_host_endpoint *ep) struct usb_host_endpoint *ep)
{ {
if (udev->speed != USB_SPEED_SUPER || if (udev->speed < USB_SPEED_SUPER ||
!usb_endpoint_xfer_isoc(&ep->desc)) !usb_endpoint_xfer_isoc(&ep->desc))
return 0; return 0;
return ep->ss_ep_comp.bmAttributes; return ep->ss_ep_comp.bmAttributes;
...@@ -1382,7 +1384,7 @@ static u32 xhci_get_max_esit_payload(struct usb_device *udev, ...@@ -1382,7 +1384,7 @@ static u32 xhci_get_max_esit_payload(struct usb_device *udev,
usb_endpoint_xfer_bulk(&ep->desc)) usb_endpoint_xfer_bulk(&ep->desc))
return 0; return 0;
if (udev->speed == USB_SPEED_SUPER) if (udev->speed >= USB_SPEED_SUPER)
return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval); return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)); max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
...@@ -1453,6 +1455,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, ...@@ -1453,6 +1455,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)); max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
max_burst = 0; max_burst = 0;
switch (udev->speed) { switch (udev->speed) {
case USB_SPEED_SUPER_PLUS:
case USB_SPEED_SUPER: case USB_SPEED_SUPER:
/* dig out max burst from ep companion desc */ /* dig out max burst from ep companion desc */
max_burst = ep->ss_ep_comp.bMaxBurst; max_burst = ep->ss_ep_comp.bMaxBurst;
......
...@@ -3573,7 +3573,7 @@ static unsigned int xhci_get_burst_count(struct xhci_hcd *xhci, ...@@ -3573,7 +3573,7 @@ static unsigned int xhci_get_burst_count(struct xhci_hcd *xhci,
{ {
unsigned int max_burst; unsigned int max_burst;
if (xhci->hci_version < 0x100 || udev->speed != USB_SPEED_SUPER) if (xhci->hci_version < 0x100 || udev->speed < USB_SPEED_SUPER)
return 0; return 0;
max_burst = urb->ep->ss_ep_comp.bMaxBurst; max_burst = urb->ep->ss_ep_comp.bMaxBurst;
...@@ -3599,6 +3599,7 @@ static unsigned int xhci_get_last_burst_packet_count(struct xhci_hcd *xhci, ...@@ -3599,6 +3599,7 @@ static unsigned int xhci_get_last_burst_packet_count(struct xhci_hcd *xhci,
return 0; return 0;
switch (udev->speed) { switch (udev->speed) {
case USB_SPEED_SUPER_PLUS:
case USB_SPEED_SUPER: case USB_SPEED_SUPER:
/* bMaxBurst is zero based: 0 means 1 packet per burst */ /* bMaxBurst is zero based: 0 means 1 packet per burst */
max_burst = urb->ep->ss_ep_comp.bMaxBurst; max_burst = urb->ep->ss_ep_comp.bMaxBurst;
......
...@@ -2084,6 +2084,7 @@ static unsigned int xhci_get_block_size(struct usb_device *udev) ...@@ -2084,6 +2084,7 @@ static unsigned int xhci_get_block_size(struct usb_device *udev)
case USB_SPEED_HIGH: case USB_SPEED_HIGH:
return HS_BLOCK; return HS_BLOCK;
case USB_SPEED_SUPER: case USB_SPEED_SUPER:
case USB_SPEED_SUPER_PLUS:
return SS_BLOCK; return SS_BLOCK;
case USB_SPEED_UNKNOWN: case USB_SPEED_UNKNOWN:
case USB_SPEED_WIRELESS: case USB_SPEED_WIRELESS:
...@@ -2209,7 +2210,7 @@ static int xhci_check_bw_table(struct xhci_hcd *xhci, ...@@ -2209,7 +2210,7 @@ static int xhci_check_bw_table(struct xhci_hcd *xhci,
unsigned int packets_remaining = 0; unsigned int packets_remaining = 0;
unsigned int i; unsigned int i;
if (virt_dev->udev->speed == USB_SPEED_SUPER) if (virt_dev->udev->speed >= USB_SPEED_SUPER)
return xhci_check_ss_bw(xhci, virt_dev); return xhci_check_ss_bw(xhci, virt_dev);
if (virt_dev->udev->speed == USB_SPEED_HIGH) { if (virt_dev->udev->speed == USB_SPEED_HIGH) {
...@@ -2410,7 +2411,7 @@ void xhci_drop_ep_from_interval_table(struct xhci_hcd *xhci, ...@@ -2410,7 +2411,7 @@ void xhci_drop_ep_from_interval_table(struct xhci_hcd *xhci,
if (xhci_is_async_ep(ep_bw->type)) if (xhci_is_async_ep(ep_bw->type))
return; return;
if (udev->speed == USB_SPEED_SUPER) { if (udev->speed >= USB_SPEED_SUPER) {
if (xhci_is_sync_in_ep(ep_bw->type)) if (xhci_is_sync_in_ep(ep_bw->type))
xhci->devs[udev->slot_id]->bw_table->ss_bw_in -= xhci->devs[udev->slot_id]->bw_table->ss_bw_in -=
xhci_get_ss_bw_consumed(ep_bw); xhci_get_ss_bw_consumed(ep_bw);
...@@ -2448,6 +2449,7 @@ void xhci_drop_ep_from_interval_table(struct xhci_hcd *xhci, ...@@ -2448,6 +2449,7 @@ void xhci_drop_ep_from_interval_table(struct xhci_hcd *xhci,
interval_bw->overhead[HS_OVERHEAD_TYPE] -= 1; interval_bw->overhead[HS_OVERHEAD_TYPE] -= 1;
break; break;
case USB_SPEED_SUPER: case USB_SPEED_SUPER:
case USB_SPEED_SUPER_PLUS:
case USB_SPEED_UNKNOWN: case USB_SPEED_UNKNOWN:
case USB_SPEED_WIRELESS: case USB_SPEED_WIRELESS:
/* Should never happen because only LS/FS/HS endpoints will get /* Should never happen because only LS/FS/HS endpoints will get
...@@ -2507,6 +2509,7 @@ static void xhci_add_ep_to_interval_table(struct xhci_hcd *xhci, ...@@ -2507,6 +2509,7 @@ static void xhci_add_ep_to_interval_table(struct xhci_hcd *xhci,
interval_bw->overhead[HS_OVERHEAD_TYPE] += 1; interval_bw->overhead[HS_OVERHEAD_TYPE] += 1;
break; break;
case USB_SPEED_SUPER: case USB_SPEED_SUPER:
case USB_SPEED_SUPER_PLUS:
case USB_SPEED_UNKNOWN: case USB_SPEED_UNKNOWN:
case USB_SPEED_WIRELESS: case USB_SPEED_WIRELESS:
/* Should never happen because only LS/FS/HS endpoints will get /* Should never happen because only LS/FS/HS endpoints will get
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment