diff options
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 36 |
1 files changed, 8 insertions, 28 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 35616ffbe3ae..6dc238c592bc 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -1022,44 +1022,24 @@ void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci, | |||
1022 | * is attached to (or the roothub port its ancestor hub is attached to). All we | 1022 | * is attached to (or the roothub port its ancestor hub is attached to). All we |
1023 | * know is the index of that port under either the USB 2.0 or the USB 3.0 | 1023 | * know is the index of that port under either the USB 2.0 or the USB 3.0 |
1024 | * roothub, but that doesn't give us the real index into the HW port status | 1024 | * roothub, but that doesn't give us the real index into the HW port status |
1025 | * registers. Scan through the xHCI roothub port array, looking for the Nth | 1025 | * registers. Call xhci_find_raw_port_number() to get real index. |
1026 | * entry of the correct port speed. Return the port number of that entry. | ||
1027 | */ | 1026 | */ |
1028 | static u32 xhci_find_real_port_number(struct xhci_hcd *xhci, | 1027 | static u32 xhci_find_real_port_number(struct xhci_hcd *xhci, |
1029 | struct usb_device *udev) | 1028 | struct usb_device *udev) |
1030 | { | 1029 | { |
1031 | struct usb_device *top_dev; | 1030 | struct usb_device *top_dev; |
1032 | unsigned int num_similar_speed_ports; | 1031 | struct usb_hcd *hcd; |
1033 | unsigned int faked_port_num; | 1032 | |
1034 | int i; | 1033 | if (udev->speed == USB_SPEED_SUPER) |
1034 | hcd = xhci->shared_hcd; | ||
1035 | else | ||
1036 | hcd = xhci->main_hcd; | ||
1035 | 1037 | ||
1036 | for (top_dev = udev; top_dev->parent && top_dev->parent->parent; | 1038 | for (top_dev = udev; top_dev->parent && top_dev->parent->parent; |
1037 | top_dev = top_dev->parent) | 1039 | top_dev = top_dev->parent) |
1038 | /* Found device below root hub */; | 1040 | /* Found device below root hub */; |
1039 | faked_port_num = top_dev->portnum; | ||
1040 | for (i = 0, num_similar_speed_ports = 0; | ||
1041 | i < HCS_MAX_PORTS(xhci->hcs_params1); i++) { | ||
1042 | u8 port_speed = xhci->port_array[i]; | ||
1043 | |||
1044 | /* | ||
1045 | * Skip ports that don't have known speeds, or have duplicate | ||
1046 | * Extended Capabilities port speed entries. | ||
1047 | */ | ||
1048 | if (port_speed == 0 || port_speed == DUPLICATE_ENTRY) | ||
1049 | continue; | ||
1050 | 1041 | ||
1051 | /* | 1042 | return xhci_find_raw_port_number(hcd, top_dev->portnum); |
1052 | * USB 3.0 ports are always under a USB 3.0 hub. USB 2.0 and | ||
1053 | * 1.1 ports are under the USB 2.0 hub. If the port speed | ||
1054 | * matches the device speed, it's a similar speed port. | ||
1055 | */ | ||
1056 | if ((port_speed == 0x03) == (udev->speed == USB_SPEED_SUPER)) | ||
1057 | num_similar_speed_ports++; | ||
1058 | if (num_similar_speed_ports == faked_port_num) | ||
1059 | /* Roothub ports are numbered from 1 to N */ | ||
1060 | return i+1; | ||
1061 | } | ||
1062 | return 0; | ||
1063 | } | 1043 | } |
1064 | 1044 | ||
1065 | /* Setup an xHCI virtual device for a Set Address command */ | 1045 | /* Setup an xHCI virtual device for a Set Address command */ |