diff options
-rw-r--r-- | drivers/usb/host/xhci-hub.c | 97 | ||||
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 66 | ||||
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 98 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 94 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 62 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 12 |
6 files changed, 341 insertions, 88 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 4c3788c128df..ee4af076a8fe 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -28,13 +28,20 @@ | |||
28 | #define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \ | 28 | #define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \ |
29 | PORT_RC | PORT_PLC | PORT_PE) | 29 | PORT_RC | PORT_PLC | PORT_PE) |
30 | 30 | ||
31 | static void xhci_hub_descriptor(struct xhci_hcd *xhci, | 31 | static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, |
32 | struct usb_hub_descriptor *desc) | 32 | struct usb_hub_descriptor *desc) |
33 | { | 33 | { |
34 | int ports; | 34 | int ports; |
35 | u16 temp; | 35 | u16 temp; |
36 | 36 | ||
37 | ports = HCS_MAX_PORTS(xhci->hcs_params1); | 37 | if (hcd->speed == HCD_USB3) |
38 | ports = xhci->num_usb3_ports; | ||
39 | else | ||
40 | ports = xhci->num_usb2_ports; | ||
41 | |||
42 | /* FIXME: return a USB 3.0 hub descriptor if this request was for the | ||
43 | * USB3 roothub. | ||
44 | */ | ||
38 | 45 | ||
39 | /* USB 3.0 hubs have a different descriptor, but we fake this for now */ | 46 | /* USB 3.0 hubs have a different descriptor, but we fake this for now */ |
40 | desc->bDescriptorType = 0x29; | 47 | desc->bDescriptorType = 0x29; |
@@ -134,18 +141,22 @@ u32 xhci_port_state_to_neutral(u32 state) | |||
134 | 141 | ||
135 | /* | 142 | /* |
136 | * find slot id based on port number. | 143 | * find slot id based on port number. |
144 | * @port: The one-based port number from one of the two split roothubs. | ||
137 | */ | 145 | */ |
138 | int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, | 146 | int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, |
139 | u16 port) | 147 | u16 port) |
140 | { | 148 | { |
141 | int slot_id; | 149 | int slot_id; |
142 | int i; | 150 | int i; |
151 | enum usb_device_speed speed; | ||
143 | 152 | ||
144 | slot_id = 0; | 153 | slot_id = 0; |
145 | for (i = 0; i < MAX_HC_SLOTS; i++) { | 154 | for (i = 0; i < MAX_HC_SLOTS; i++) { |
146 | if (!xhci->devs[i]) | 155 | if (!xhci->devs[i]) |
147 | continue; | 156 | continue; |
148 | if (xhci->devs[i]->port == port) { | 157 | speed = xhci->devs[i]->udev->speed; |
158 | if (((speed == USB_SPEED_SUPER) == (hcd->speed == HCD_USB3)) | ||
159 | && xhci->devs[i]->port == port) { | ||
149 | slot_id = i; | 160 | slot_id = i; |
150 | break; | 161 | break; |
151 | } | 162 | } |
@@ -226,11 +237,11 @@ void xhci_ring_device(struct xhci_hcd *xhci, int slot_id) | |||
226 | return; | 237 | return; |
227 | } | 238 | } |
228 | 239 | ||
229 | static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex, | 240 | static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, |
230 | u32 __iomem *addr, u32 port_status) | 241 | u16 wIndex, u32 __iomem *addr, u32 port_status) |
231 | { | 242 | { |
232 | /* Don't allow the USB core to disable SuperSpeed ports. */ | 243 | /* Don't allow the USB core to disable SuperSpeed ports. */ |
233 | if (xhci->port_array[wIndex] == 0x03) { | 244 | if (hcd->speed == HCD_USB3) { |
234 | xhci_dbg(xhci, "Ignoring request to disable " | 245 | xhci_dbg(xhci, "Ignoring request to disable " |
235 | "SuperSpeed port.\n"); | 246 | "SuperSpeed port.\n"); |
236 | return; | 247 | return; |
@@ -289,18 +300,16 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
289 | unsigned long flags; | 300 | unsigned long flags; |
290 | u32 temp, temp1, status; | 301 | u32 temp, temp1, status; |
291 | int retval = 0; | 302 | int retval = 0; |
292 | u32 __iomem *port_array[15 + USB_MAXCHILDREN]; | 303 | u32 __iomem **port_array; |
293 | int i; | ||
294 | int slot_id; | 304 | int slot_id; |
295 | struct xhci_bus_state *bus_state; | 305 | struct xhci_bus_state *bus_state; |
296 | 306 | ||
297 | ports = HCS_MAX_PORTS(xhci->hcs_params1); | 307 | if (hcd->speed == HCD_USB3) { |
298 | for (i = 0; i < ports; i++) { | 308 | ports = xhci->num_usb3_ports; |
299 | if (i < xhci->num_usb3_ports) | 309 | port_array = xhci->usb3_ports; |
300 | port_array[i] = xhci->usb3_ports[i]; | 310 | } else { |
301 | else | 311 | ports = xhci->num_usb2_ports; |
302 | port_array[i] = | 312 | port_array = xhci->usb2_ports; |
303 | xhci->usb2_ports[i - xhci->num_usb3_ports]; | ||
304 | } | 313 | } |
305 | bus_state = &xhci->bus_state[hcd_index(hcd)]; | 314 | bus_state = &xhci->bus_state[hcd_index(hcd)]; |
306 | 315 | ||
@@ -311,7 +320,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
311 | memset(buf, 0, 4); | 320 | memset(buf, 0, 4); |
312 | break; | 321 | break; |
313 | case GetHubDescriptor: | 322 | case GetHubDescriptor: |
314 | xhci_hub_descriptor(xhci, (struct usb_hub_descriptor *) buf); | 323 | xhci_hub_descriptor(hcd, xhci, |
324 | (struct usb_hub_descriptor *) buf); | ||
315 | break; | 325 | break; |
316 | case GetPortStatus: | 326 | case GetPortStatus: |
317 | if (!wIndex || wIndex > ports) | 327 | if (!wIndex || wIndex > ports) |
@@ -518,7 +528,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
518 | port_array[wIndex], temp); | 528 | port_array[wIndex], temp); |
519 | break; | 529 | break; |
520 | case USB_PORT_FEAT_ENABLE: | 530 | case USB_PORT_FEAT_ENABLE: |
521 | xhci_disable_port(xhci, wIndex, | 531 | xhci_disable_port(hcd, xhci, wIndex, |
522 | port_array[wIndex], temp); | 532 | port_array[wIndex], temp); |
523 | break; | 533 | break; |
524 | default: | 534 | default: |
@@ -550,16 +560,15 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
550 | int i, retval; | 560 | int i, retval; |
551 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 561 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
552 | int ports; | 562 | int ports; |
553 | u32 __iomem *port_array[15 + USB_MAXCHILDREN]; | 563 | u32 __iomem **port_array; |
554 | struct xhci_bus_state *bus_state; | 564 | struct xhci_bus_state *bus_state; |
555 | 565 | ||
556 | ports = HCS_MAX_PORTS(xhci->hcs_params1); | 566 | if (hcd->speed == HCD_USB3) { |
557 | for (i = 0; i < ports; i++) { | 567 | ports = xhci->num_usb3_ports; |
558 | if (i < xhci->num_usb3_ports) | 568 | port_array = xhci->usb3_ports; |
559 | port_array[i] = xhci->usb3_ports[i]; | 569 | } else { |
560 | else | 570 | ports = xhci->num_usb2_ports; |
561 | port_array[i] = | 571 | port_array = xhci->usb2_ports; |
562 | xhci->usb2_ports[i - xhci->num_usb3_ports]; | ||
563 | } | 572 | } |
564 | bus_state = &xhci->bus_state[hcd_index(hcd)]; | 573 | bus_state = &xhci->bus_state[hcd_index(hcd)]; |
565 | 574 | ||
@@ -592,19 +601,18 @@ int xhci_bus_suspend(struct usb_hcd *hcd) | |||
592 | { | 601 | { |
593 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 602 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
594 | int max_ports, port_index; | 603 | int max_ports, port_index; |
595 | u32 __iomem *port_array[15 + USB_MAXCHILDREN]; | 604 | u32 __iomem **port_array; |
596 | int i; | ||
597 | struct xhci_bus_state *bus_state; | 605 | struct xhci_bus_state *bus_state; |
598 | unsigned long flags; | 606 | unsigned long flags; |
599 | 607 | ||
600 | xhci_dbg(xhci, "suspend root hub\n"); | 608 | if (hcd->speed == HCD_USB3) { |
601 | max_ports = HCS_MAX_PORTS(xhci->hcs_params1); | 609 | max_ports = xhci->num_usb3_ports; |
602 | for (i = 0; i < max_ports; i++) { | 610 | port_array = xhci->usb3_ports; |
603 | if (i < xhci->num_usb3_ports) | 611 | xhci_dbg(xhci, "suspend USB 3.0 root hub\n"); |
604 | port_array[i] = xhci->usb3_ports[i]; | 612 | } else { |
605 | else | 613 | max_ports = xhci->num_usb2_ports; |
606 | port_array[i] = | 614 | port_array = xhci->usb2_ports; |
607 | xhci->usb2_ports[i - xhci->num_usb3_ports]; | 615 | xhci_dbg(xhci, "suspend USB 2.0 root hub\n"); |
608 | } | 616 | } |
609 | bus_state = &xhci->bus_state[hcd_index(hcd)]; | 617 | bus_state = &xhci->bus_state[hcd_index(hcd)]; |
610 | 618 | ||
@@ -685,20 +693,19 @@ int xhci_bus_resume(struct usb_hcd *hcd) | |||
685 | { | 693 | { |
686 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 694 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
687 | int max_ports, port_index; | 695 | int max_ports, port_index; |
688 | u32 __iomem *port_array[15 + USB_MAXCHILDREN]; | 696 | u32 __iomem **port_array; |
689 | int i; | ||
690 | struct xhci_bus_state *bus_state; | 697 | struct xhci_bus_state *bus_state; |
691 | u32 temp; | 698 | u32 temp; |
692 | unsigned long flags; | 699 | unsigned long flags; |
693 | 700 | ||
694 | xhci_dbg(xhci, "resume root hub\n"); | 701 | if (hcd->speed == HCD_USB3) { |
695 | max_ports = HCS_MAX_PORTS(xhci->hcs_params1); | 702 | max_ports = xhci->num_usb3_ports; |
696 | for (i = 0; i < max_ports; i++) { | 703 | port_array = xhci->usb3_ports; |
697 | if (i < xhci->num_usb3_ports) | 704 | xhci_dbg(xhci, "resume USB 3.0 root hub\n"); |
698 | port_array[i] = xhci->usb3_ports[i]; | 705 | } else { |
699 | else | 706 | max_ports = xhci->num_usb2_ports; |
700 | port_array[i] = | 707 | port_array = xhci->usb2_ports; |
701 | xhci->usb2_ports[i - xhci->num_usb3_ports]; | 708 | xhci_dbg(xhci, "resume USB 2.0 root hub\n"); |
702 | } | 709 | } |
703 | bus_state = &xhci->bus_state[hcd_index(hcd)]; | 710 | bus_state = &xhci->bus_state[hcd_index(hcd)]; |
704 | 711 | ||
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index bc809cbd570a..180a2abbc868 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -814,14 +814,64 @@ void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci, | |||
814 | ep0_ctx->deq |= ep_ring->cycle_state; | 814 | ep0_ctx->deq |= ep_ring->cycle_state; |
815 | } | 815 | } |
816 | 816 | ||
817 | /* | ||
818 | * The xHCI roothub may have ports of differing speeds in any order in the port | ||
819 | * status registers. xhci->port_array provides an array of the port speed for | ||
820 | * each offset into the port status registers. | ||
821 | * | ||
822 | * The xHCI hardware wants to know the roothub port number that the USB device | ||
823 | * is attached to (or the roothub port its ancestor hub is attached to). All we | ||
824 | * know is the index of that port under either the USB 2.0 or the USB 3.0 | ||
825 | * roothub, but that doesn't give us the real index into the HW port status | ||
826 | * registers. Scan through the xHCI roothub port array, looking for the Nth | ||
827 | * entry of the correct port speed. Return the port number of that entry. | ||
828 | */ | ||
829 | static u32 xhci_find_real_port_number(struct xhci_hcd *xhci, | ||
830 | struct usb_device *udev) | ||
831 | { | ||
832 | struct usb_device *top_dev; | ||
833 | unsigned int num_similar_speed_ports; | ||
834 | unsigned int faked_port_num; | ||
835 | int i; | ||
836 | |||
837 | for (top_dev = udev; top_dev->parent && top_dev->parent->parent; | ||
838 | top_dev = top_dev->parent) | ||
839 | /* Found device below root hub */; | ||
840 | faked_port_num = top_dev->portnum; | ||
841 | for (i = 0, num_similar_speed_ports = 0; | ||
842 | i < HCS_MAX_PORTS(xhci->hcs_params1); i++) { | ||
843 | u8 port_speed = xhci->port_array[i]; | ||
844 | |||
845 | /* | ||
846 | * Skip ports that don't have known speeds, or have duplicate | ||
847 | * Extended Capabilities port speed entries. | ||
848 | */ | ||
849 | if (port_speed == 0 || port_speed == -1) | ||
850 | continue; | ||
851 | |||
852 | /* | ||
853 | * USB 3.0 ports are always under a USB 3.0 hub. USB 2.0 and | ||
854 | * 1.1 ports are under the USB 2.0 hub. If the port speed | ||
855 | * matches the device speed, it's a similar speed port. | ||
856 | */ | ||
857 | if ((port_speed == 0x03) == (udev->speed == USB_SPEED_SUPER)) | ||
858 | num_similar_speed_ports++; | ||
859 | if (num_similar_speed_ports == faked_port_num) | ||
860 | /* Roothub ports are numbered from 1 to N */ | ||
861 | return i+1; | ||
862 | } | ||
863 | return 0; | ||
864 | } | ||
865 | |||
817 | /* Setup an xHCI virtual device for a Set Address command */ | 866 | /* Setup an xHCI virtual device for a Set Address command */ |
818 | int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev) | 867 | int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev) |
819 | { | 868 | { |
820 | struct xhci_virt_device *dev; | 869 | struct xhci_virt_device *dev; |
821 | struct xhci_ep_ctx *ep0_ctx; | 870 | struct xhci_ep_ctx *ep0_ctx; |
822 | struct usb_device *top_dev; | ||
823 | struct xhci_slot_ctx *slot_ctx; | 871 | struct xhci_slot_ctx *slot_ctx; |
824 | struct xhci_input_control_ctx *ctrl_ctx; | 872 | struct xhci_input_control_ctx *ctrl_ctx; |
873 | u32 port_num; | ||
874 | struct usb_device *top_dev; | ||
825 | 875 | ||
826 | dev = xhci->devs[udev->slot_id]; | 876 | dev = xhci->devs[udev->slot_id]; |
827 | /* Slot ID 0 is reserved */ | 877 | /* Slot ID 0 is reserved */ |
@@ -863,12 +913,17 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
863 | BUG(); | 913 | BUG(); |
864 | } | 914 | } |
865 | /* Find the root hub port this device is under */ | 915 | /* Find the root hub port this device is under */ |
916 | port_num = xhci_find_real_port_number(xhci, udev); | ||
917 | if (!port_num) | ||
918 | return -EINVAL; | ||
919 | slot_ctx->dev_info2 |= (u32) ROOT_HUB_PORT(port_num); | ||
920 | /* Set the port number in the virtual_device to the faked port number */ | ||
866 | for (top_dev = udev; top_dev->parent && top_dev->parent->parent; | 921 | for (top_dev = udev; top_dev->parent && top_dev->parent->parent; |
867 | top_dev = top_dev->parent) | 922 | top_dev = top_dev->parent) |
868 | /* Found device below root hub */; | 923 | /* Found device below root hub */; |
869 | slot_ctx->dev_info2 |= (u32) ROOT_HUB_PORT(top_dev->portnum); | ||
870 | dev->port = top_dev->portnum; | 924 | dev->port = top_dev->portnum; |
871 | xhci_dbg(xhci, "Set root hub portnum to %d\n", top_dev->portnum); | 925 | xhci_dbg(xhci, "Set root hub portnum to %d\n", port_num); |
926 | xhci_dbg(xhci, "Set fake root hub portnum to %d\n", dev->port); | ||
872 | 927 | ||
873 | /* Is this a LS/FS device under an external HS hub? */ | 928 | /* Is this a LS/FS device under an external HS hub? */ |
874 | if (udev->tt && udev->tt->hub->parent) { | 929 | if (udev->tt && udev->tt->hub->parent) { |
@@ -1452,6 +1507,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
1452 | xhci->page_size = 0; | 1507 | xhci->page_size = 0; |
1453 | xhci->page_shift = 0; | 1508 | xhci->page_shift = 0; |
1454 | xhci->bus_state[0].bus_suspended = 0; | 1509 | xhci->bus_state[0].bus_suspended = 0; |
1510 | xhci->bus_state[1].bus_suspended = 0; | ||
1455 | } | 1511 | } |
1456 | 1512 | ||
1457 | static int xhci_test_trb_in_td(struct xhci_hcd *xhci, | 1513 | static int xhci_test_trb_in_td(struct xhci_hcd *xhci, |
@@ -1970,8 +2026,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
1970 | init_completion(&xhci->addr_dev); | 2026 | init_completion(&xhci->addr_dev); |
1971 | for (i = 0; i < MAX_HC_SLOTS; ++i) | 2027 | for (i = 0; i < MAX_HC_SLOTS; ++i) |
1972 | xhci->devs[i] = NULL; | 2028 | xhci->devs[i] = NULL; |
1973 | for (i = 0; i < USB_MAXCHILDREN; ++i) | 2029 | for (i = 0; i < USB_MAXCHILDREN; ++i) { |
1974 | xhci->bus_state[0].resume_done[i] = 0; | 2030 | xhci->bus_state[0].resume_done[i] = 0; |
2031 | xhci->bus_state[1].resume_done[i] = 0; | ||
2032 | } | ||
1975 | 2033 | ||
1976 | if (scratchpad_alloc(xhci, flags)) | 2034 | if (scratchpad_alloc(xhci, flags)) |
1977 | goto fail; | 2035 | goto fail; |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 009082829364..4a9d55e80f73 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -50,18 +50,44 @@ static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev) | |||
50 | /* called during probe() after chip reset completes */ | 50 | /* called during probe() after chip reset completes */ |
51 | static int xhci_pci_setup(struct usb_hcd *hcd) | 51 | static int xhci_pci_setup(struct usb_hcd *hcd) |
52 | { | 52 | { |
53 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 53 | struct xhci_hcd *xhci; |
54 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 54 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
55 | int retval; | 55 | int retval; |
56 | u32 temp; | 56 | u32 temp; |
57 | 57 | ||
58 | hcd->self.sg_tablesize = TRBS_PER_SEGMENT - 2; | 58 | hcd->self.sg_tablesize = TRBS_PER_SEGMENT - 2; |
59 | 59 | ||
60 | xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL); | 60 | if (usb_hcd_is_primary_hcd(hcd)) { |
61 | if (!xhci) | 61 | xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL); |
62 | return -ENOMEM; | 62 | if (!xhci) |
63 | *((struct xhci_hcd **) hcd->hcd_priv) = xhci; | 63 | return -ENOMEM; |
64 | xhci->main_hcd = hcd; | 64 | *((struct xhci_hcd **) hcd->hcd_priv) = xhci; |
65 | xhci->main_hcd = hcd; | ||
66 | /* Mark the first roothub as being USB 2.0. | ||
67 | * The xHCI driver will register the USB 3.0 roothub. | ||
68 | */ | ||
69 | hcd->speed = HCD_USB2; | ||
70 | hcd->self.root_hub->speed = USB_SPEED_HIGH; | ||
71 | /* | ||
72 | * USB 2.0 roothub under xHCI has an integrated TT, | ||
73 | * (rate matching hub) as opposed to having an OHCI/UHCI | ||
74 | * companion controller. | ||
75 | */ | ||
76 | hcd->has_tt = 1; | ||
77 | } else { | ||
78 | /* xHCI private pointer was set in xhci_pci_probe for the second | ||
79 | * registered roothub. | ||
80 | */ | ||
81 | xhci = hcd_to_xhci(hcd); | ||
82 | temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params); | ||
83 | if (HCC_64BIT_ADDR(temp)) { | ||
84 | xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n"); | ||
85 | dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)); | ||
86 | } else { | ||
87 | dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32)); | ||
88 | } | ||
89 | return 0; | ||
90 | } | ||
65 | 91 | ||
66 | xhci->cap_regs = hcd->regs; | 92 | xhci->cap_regs = hcd->regs; |
67 | xhci->op_regs = hcd->regs + | 93 | xhci->op_regs = hcd->regs + |
@@ -128,11 +154,67 @@ error: | |||
128 | return retval; | 154 | return retval; |
129 | } | 155 | } |
130 | 156 | ||
157 | /* | ||
158 | * We need to register our own PCI probe function (instead of the USB core's | ||
159 | * function) in order to create a second roothub under xHCI. | ||
160 | */ | ||
161 | static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | ||
162 | { | ||
163 | int retval; | ||
164 | struct xhci_hcd *xhci; | ||
165 | struct hc_driver *driver; | ||
166 | struct usb_hcd *hcd; | ||
167 | |||
168 | driver = (struct hc_driver *)id->driver_data; | ||
169 | /* Register the USB 2.0 roothub. | ||
170 | * FIXME: USB core must know to register the USB 2.0 roothub first. | ||
171 | * This is sort of silly, because we could just set the HCD driver flags | ||
172 | * to say USB 2.0, but I'm not sure what the implications would be in | ||
173 | * the other parts of the HCD code. | ||
174 | */ | ||
175 | retval = usb_hcd_pci_probe(dev, id); | ||
176 | |||
177 | if (retval) | ||
178 | return retval; | ||
179 | |||
180 | /* USB 2.0 roothub is stored in the PCI device now. */ | ||
181 | hcd = dev_get_drvdata(&dev->dev); | ||
182 | xhci = hcd_to_xhci(hcd); | ||
183 | xhci->shared_hcd = usb_create_shared_hcd(driver, &dev->dev, | ||
184 | pci_name(dev), hcd); | ||
185 | if (!xhci->shared_hcd) { | ||
186 | retval = -ENOMEM; | ||
187 | goto dealloc_usb2_hcd; | ||
188 | } | ||
189 | |||
190 | /* Set the xHCI pointer before xhci_pci_setup() (aka hcd_driver.reset) | ||
191 | * is called by usb_add_hcd(). | ||
192 | */ | ||
193 | *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; | ||
194 | |||
195 | retval = usb_add_hcd(xhci->shared_hcd, dev->irq, | ||
196 | IRQF_DISABLED | IRQF_SHARED); | ||
197 | if (retval) | ||
198 | goto put_usb3_hcd; | ||
199 | /* Roothub already marked as USB 3.0 speed */ | ||
200 | return 0; | ||
201 | |||
202 | put_usb3_hcd: | ||
203 | usb_put_hcd(xhci->shared_hcd); | ||
204 | dealloc_usb2_hcd: | ||
205 | usb_hcd_pci_remove(dev); | ||
206 | return retval; | ||
207 | } | ||
208 | |||
131 | static void xhci_pci_remove(struct pci_dev *dev) | 209 | static void xhci_pci_remove(struct pci_dev *dev) |
132 | { | 210 | { |
133 | struct xhci_hcd *xhci; | 211 | struct xhci_hcd *xhci; |
134 | 212 | ||
135 | xhci = hcd_to_xhci(pci_get_drvdata(dev)); | 213 | xhci = hcd_to_xhci(pci_get_drvdata(dev)); |
214 | if (xhci->shared_hcd) { | ||
215 | usb_remove_hcd(xhci->shared_hcd); | ||
216 | usb_put_hcd(xhci->shared_hcd); | ||
217 | } | ||
136 | usb_hcd_pci_remove(dev); | 218 | usb_hcd_pci_remove(dev); |
137 | kfree(xhci); | 219 | kfree(xhci); |
138 | } | 220 | } |
@@ -170,7 +252,7 @@ static const struct hc_driver xhci_pci_hc_driver = { | |||
170 | * generic hardware linkage | 252 | * generic hardware linkage |
171 | */ | 253 | */ |
172 | .irq = xhci_irq, | 254 | .irq = xhci_irq, |
173 | .flags = HCD_MEMORY | HCD_USB3, | 255 | .flags = HCD_MEMORY | HCD_USB3 | HCD_SHARED, |
174 | 256 | ||
175 | /* | 257 | /* |
176 | * basic lifecycle operations | 258 | * basic lifecycle operations |
@@ -231,7 +313,7 @@ static struct pci_driver xhci_pci_driver = { | |||
231 | .name = (char *) hcd_name, | 313 | .name = (char *) hcd_name, |
232 | .id_table = pci_ids, | 314 | .id_table = pci_ids, |
233 | 315 | ||
234 | .probe = usb_hcd_pci_probe, | 316 | .probe = xhci_pci_probe, |
235 | .remove = xhci_pci_remove, | 317 | .remove = xhci_pci_remove, |
236 | /* suspend and resume implemented later */ | 318 | /* suspend and resume implemented later */ |
237 | 319 | ||
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 7fe9aebd3922..3bdf30dd8ce6 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -866,7 +866,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) | |||
866 | } | 866 | } |
867 | spin_unlock(&xhci->lock); | 867 | spin_unlock(&xhci->lock); |
868 | xhci_dbg(xhci, "Calling usb_hc_died()\n"); | 868 | xhci_dbg(xhci, "Calling usb_hc_died()\n"); |
869 | usb_hc_died(xhci_to_hcd(xhci)); | 869 | usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); |
870 | xhci_dbg(xhci, "xHCI host controller is dead.\n"); | 870 | xhci_dbg(xhci, "xHCI host controller is dead.\n"); |
871 | } | 871 | } |
872 | 872 | ||
@@ -1155,20 +1155,56 @@ static void handle_vendor_event(struct xhci_hcd *xhci, | |||
1155 | handle_cmd_completion(xhci, &event->event_cmd); | 1155 | handle_cmd_completion(xhci, &event->event_cmd); |
1156 | } | 1156 | } |
1157 | 1157 | ||
1158 | /* @port_id: the one-based port ID from the hardware (indexed from array of all | ||
1159 | * port registers -- USB 3.0 and USB 2.0). | ||
1160 | * | ||
1161 | * Returns a zero-based port number, which is suitable for indexing into each of | ||
1162 | * the split roothubs' port arrays and bus state arrays. | ||
1163 | */ | ||
1164 | static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd, | ||
1165 | struct xhci_hcd *xhci, u32 port_id) | ||
1166 | { | ||
1167 | unsigned int i; | ||
1168 | unsigned int num_similar_speed_ports = 0; | ||
1169 | |||
1170 | /* port_id from the hardware is 1-based, but port_array[], usb3_ports[], | ||
1171 | * and usb2_ports are 0-based indexes. Count the number of similar | ||
1172 | * speed ports, up to 1 port before this port. | ||
1173 | */ | ||
1174 | for (i = 0; i < (port_id - 1); i++) { | ||
1175 | u8 port_speed = xhci->port_array[i]; | ||
1176 | |||
1177 | /* | ||
1178 | * Skip ports that don't have known speeds, or have duplicate | ||
1179 | * Extended Capabilities port speed entries. | ||
1180 | */ | ||
1181 | if (port_speed == 0 || port_speed == -1) | ||
1182 | continue; | ||
1183 | |||
1184 | /* | ||
1185 | * USB 3.0 ports are always under a USB 3.0 hub. USB 2.0 and | ||
1186 | * 1.1 ports are under the USB 2.0 hub. If the port speed | ||
1187 | * matches the device speed, it's a similar speed port. | ||
1188 | */ | ||
1189 | if ((port_speed == 0x03) == (hcd->speed == HCD_USB3)) | ||
1190 | num_similar_speed_ports++; | ||
1191 | } | ||
1192 | return num_similar_speed_ports; | ||
1193 | } | ||
1194 | |||
1158 | static void handle_port_status(struct xhci_hcd *xhci, | 1195 | static void handle_port_status(struct xhci_hcd *xhci, |
1159 | union xhci_trb *event) | 1196 | union xhci_trb *event) |
1160 | { | 1197 | { |
1161 | struct usb_hcd *hcd = xhci_to_hcd(xhci); | 1198 | struct usb_hcd *hcd; |
1162 | u32 port_id; | 1199 | u32 port_id; |
1163 | u32 temp, temp1; | 1200 | u32 temp, temp1; |
1164 | int max_ports; | 1201 | int max_ports; |
1165 | int slot_id; | 1202 | int slot_id; |
1166 | unsigned int faked_port_index; | 1203 | unsigned int faked_port_index; |
1167 | u32 __iomem *port_array[15 + USB_MAXCHILDREN]; | 1204 | u8 major_revision; |
1168 | int i; | ||
1169 | struct xhci_bus_state *bus_state; | 1205 | struct xhci_bus_state *bus_state; |
1206 | u32 __iomem **port_array; | ||
1170 | 1207 | ||
1171 | bus_state = &xhci->bus_state[0]; | ||
1172 | /* Port status change events always have a successful completion code */ | 1208 | /* Port status change events always have a successful completion code */ |
1173 | if (GET_COMP_CODE(event->generic.field[2]) != COMP_SUCCESS) { | 1209 | if (GET_COMP_CODE(event->generic.field[2]) != COMP_SUCCESS) { |
1174 | xhci_warn(xhci, "WARN: xHC returned failed port status event\n"); | 1210 | xhci_warn(xhci, "WARN: xHC returned failed port status event\n"); |
@@ -1183,15 +1219,43 @@ static void handle_port_status(struct xhci_hcd *xhci, | |||
1183 | goto cleanup; | 1219 | goto cleanup; |
1184 | } | 1220 | } |
1185 | 1221 | ||
1186 | for (i = 0; i < max_ports; i++) { | 1222 | /* Figure out which usb_hcd this port is attached to: |
1187 | if (i < xhci->num_usb3_ports) | 1223 | * is it a USB 3.0 port or a USB 2.0/1.1 port? |
1188 | port_array[i] = xhci->usb3_ports[i]; | 1224 | */ |
1189 | else | 1225 | major_revision = xhci->port_array[port_id - 1]; |
1190 | port_array[i] = | 1226 | if (major_revision == 0) { |
1191 | xhci->usb2_ports[i - xhci->num_usb3_ports]; | 1227 | xhci_warn(xhci, "Event for port %u not in " |
1228 | "Extended Capabilities, ignoring.\n", | ||
1229 | port_id); | ||
1230 | goto cleanup; | ||
1192 | } | 1231 | } |
1232 | if (major_revision == (u8) -1) { | ||
1233 | xhci_warn(xhci, "Event for port %u duplicated in" | ||
1234 | "Extended Capabilities, ignoring.\n", | ||
1235 | port_id); | ||
1236 | goto cleanup; | ||
1237 | } | ||
1238 | |||
1239 | /* | ||
1240 | * Hardware port IDs reported by a Port Status Change Event include USB | ||
1241 | * 3.0 and USB 2.0 ports. We want to check if the port has reported a | ||
1242 | * resume event, but we first need to translate the hardware port ID | ||
1243 | * into the index into the ports on the correct split roothub, and the | ||
1244 | * correct bus_state structure. | ||
1245 | */ | ||
1246 | /* Find the right roothub. */ | ||
1247 | hcd = xhci_to_hcd(xhci); | ||
1248 | if ((major_revision == 0x03) != (hcd->speed == HCD_USB3)) | ||
1249 | hcd = xhci->shared_hcd; | ||
1250 | bus_state = &xhci->bus_state[hcd_index(hcd)]; | ||
1251 | if (hcd->speed == HCD_USB3) | ||
1252 | port_array = xhci->usb3_ports; | ||
1253 | else | ||
1254 | port_array = xhci->usb2_ports; | ||
1255 | /* Find the faked port hub number */ | ||
1256 | faked_port_index = find_faked_portnum_from_hw_portnum(hcd, xhci, | ||
1257 | port_id); | ||
1193 | 1258 | ||
1194 | faked_port_index = port_id; | ||
1195 | temp = xhci_readl(xhci, port_array[faked_port_index]); | 1259 | temp = xhci_readl(xhci, port_array[faked_port_index]); |
1196 | if (hcd->state == HC_STATE_SUSPENDED) { | 1260 | if (hcd->state == HC_STATE_SUSPENDED) { |
1197 | xhci_dbg(xhci, "resume root hub\n"); | 1261 | xhci_dbg(xhci, "resume root hub\n"); |
@@ -1228,10 +1292,10 @@ static void handle_port_status(struct xhci_hcd *xhci, | |||
1228 | xhci_writel(xhci, temp, port_array[faked_port_index]); | 1292 | xhci_writel(xhci, temp, port_array[faked_port_index]); |
1229 | } else { | 1293 | } else { |
1230 | xhci_dbg(xhci, "resume HS port %d\n", port_id); | 1294 | xhci_dbg(xhci, "resume HS port %d\n", port_id); |
1231 | bus_state->resume_done[port_id - 1] = jiffies + | 1295 | bus_state->resume_done[faked_port_index] = jiffies + |
1232 | msecs_to_jiffies(20); | 1296 | msecs_to_jiffies(20); |
1233 | mod_timer(&hcd->rh_timer, | 1297 | mod_timer(&hcd->rh_timer, |
1234 | bus_state->resume_done[port_id - 1]); | 1298 | bus_state->resume_done[faked_port_index]); |
1235 | /* Do the rest in GetPortStatus */ | 1299 | /* Do the rest in GetPortStatus */ |
1236 | } | 1300 | } |
1237 | } | 1301 | } |
@@ -1242,7 +1306,7 @@ cleanup: | |||
1242 | 1306 | ||
1243 | spin_unlock(&xhci->lock); | 1307 | spin_unlock(&xhci->lock); |
1244 | /* Pass this up to the core */ | 1308 | /* Pass this up to the core */ |
1245 | usb_hcd_poll_rh_status(xhci_to_hcd(xhci)); | 1309 | usb_hcd_poll_rh_status(hcd); |
1246 | spin_lock(&xhci->lock); | 1310 | spin_lock(&xhci->lock); |
1247 | } | 1311 | } |
1248 | 1312 | ||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8d45bbde3da4..4549068758f5 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -375,6 +375,21 @@ void xhci_event_ring_work(unsigned long arg) | |||
375 | } | 375 | } |
376 | #endif | 376 | #endif |
377 | 377 | ||
378 | static int xhci_run_finished(struct xhci_hcd *xhci) | ||
379 | { | ||
380 | if (xhci_start(xhci)) { | ||
381 | xhci_halt(xhci); | ||
382 | return -ENODEV; | ||
383 | } | ||
384 | xhci->shared_hcd->state = HC_STATE_RUNNING; | ||
385 | |||
386 | if (xhci->quirks & XHCI_NEC_HOST) | ||
387 | xhci_ring_cmd_db(xhci); | ||
388 | |||
389 | xhci_dbg(xhci, "Finished xhci_run for USB3 roothub\n"); | ||
390 | return 0; | ||
391 | } | ||
392 | |||
378 | /* | 393 | /* |
379 | * Start the HC after it was halted. | 394 | * Start the HC after it was halted. |
380 | * | 395 | * |
@@ -395,7 +410,13 @@ int xhci_run(struct usb_hcd *hcd) | |||
395 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 410 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
396 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); | 411 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); |
397 | 412 | ||
413 | /* Start the xHCI host controller running only after the USB 2.0 roothub | ||
414 | * is setup. | ||
415 | */ | ||
416 | |||
398 | hcd->uses_new_polling = 1; | 417 | hcd->uses_new_polling = 1; |
418 | if (!usb_hcd_is_primary_hcd(hcd)) | ||
419 | return xhci_run_finished(xhci); | ||
399 | 420 | ||
400 | xhci_dbg(xhci, "xhci_run\n"); | 421 | xhci_dbg(xhci, "xhci_run\n"); |
401 | /* unregister the legacy interrupt */ | 422 | /* unregister the legacy interrupt */ |
@@ -469,16 +490,23 @@ int xhci_run(struct usb_hcd *hcd) | |||
469 | xhci_queue_vendor_command(xhci, 0, 0, 0, | 490 | xhci_queue_vendor_command(xhci, 0, 0, 0, |
470 | TRB_TYPE(TRB_NEC_GET_FW)); | 491 | TRB_TYPE(TRB_NEC_GET_FW)); |
471 | 492 | ||
472 | if (xhci_start(xhci)) { | 493 | xhci_dbg(xhci, "Finished xhci_run for USB2 roothub\n"); |
473 | xhci_halt(xhci); | 494 | return 0; |
474 | return -ENODEV; | 495 | } |
475 | } | ||
476 | 496 | ||
477 | if (xhci->quirks & XHCI_NEC_HOST) | 497 | static void xhci_only_stop_hcd(struct usb_hcd *hcd) |
478 | xhci_ring_cmd_db(xhci); | 498 | { |
499 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | ||
479 | 500 | ||
480 | xhci_dbg(xhci, "Finished xhci_run\n"); | 501 | spin_lock_irq(&xhci->lock); |
481 | return 0; | 502 | xhci_halt(xhci); |
503 | |||
504 | /* The shared_hcd is going to be deallocated shortly (the USB core only | ||
505 | * calls this function when allocation fails in usb_add_hcd(), or | ||
506 | * usb_remove_hcd() is called). So we need to unset xHCI's pointer. | ||
507 | */ | ||
508 | xhci->shared_hcd = NULL; | ||
509 | spin_unlock_irq(&xhci->lock); | ||
482 | } | 510 | } |
483 | 511 | ||
484 | /* | 512 | /* |
@@ -495,7 +523,15 @@ void xhci_stop(struct usb_hcd *hcd) | |||
495 | u32 temp; | 523 | u32 temp; |
496 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 524 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
497 | 525 | ||
526 | if (!usb_hcd_is_primary_hcd(hcd)) { | ||
527 | xhci_only_stop_hcd(xhci->shared_hcd); | ||
528 | return; | ||
529 | } | ||
530 | |||
498 | spin_lock_irq(&xhci->lock); | 531 | spin_lock_irq(&xhci->lock); |
532 | /* Make sure the xHC is halted for a USB3 roothub | ||
533 | * (xhci_stop() could be called as part of failed init). | ||
534 | */ | ||
499 | xhci_halt(xhci); | 535 | xhci_halt(xhci); |
500 | xhci_reset(xhci); | 536 | xhci_reset(xhci); |
501 | spin_unlock_irq(&xhci->lock); | 537 | spin_unlock_irq(&xhci->lock); |
@@ -528,6 +564,8 @@ void xhci_stop(struct usb_hcd *hcd) | |||
528 | * This is called when the machine is rebooting or halting. We assume that the | 564 | * This is called when the machine is rebooting or halting. We assume that the |
529 | * machine will be powered off, and the HC's internal state will be reset. | 565 | * machine will be powered off, and the HC's internal state will be reset. |
530 | * Don't bother to free memory. | 566 | * Don't bother to free memory. |
567 | * | ||
568 | * This will only ever be called with the main usb_hcd (the USB3 roothub). | ||
531 | */ | 569 | */ |
532 | void xhci_shutdown(struct usb_hcd *hcd) | 570 | void xhci_shutdown(struct usb_hcd *hcd) |
533 | { | 571 | { |
@@ -694,10 +732,12 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
694 | struct usb_hcd *hcd = xhci_to_hcd(xhci); | 732 | struct usb_hcd *hcd = xhci_to_hcd(xhci); |
695 | int retval; | 733 | int retval; |
696 | 734 | ||
697 | /* Wait a bit if the bus needs to settle from the transistion to | 735 | /* Wait a bit if either of the roothubs need to settle from the |
698 | * suspend. | 736 | * transistion into bus suspend. |
699 | */ | 737 | */ |
700 | if (time_before(jiffies, xhci->bus_state[0].next_statechange)) | 738 | if (time_before(jiffies, xhci->bus_state[0].next_statechange) || |
739 | time_before(jiffies, | ||
740 | xhci->bus_state[1].next_statechange)) | ||
701 | msleep(100); | 741 | msleep(100); |
702 | 742 | ||
703 | spin_lock_irq(&xhci->lock); | 743 | spin_lock_irq(&xhci->lock); |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 443d6333f280..e9217bb288ad 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1174,12 +1174,16 @@ struct xhci_bus_state { | |||
1174 | 1174 | ||
1175 | static inline unsigned int hcd_index(struct usb_hcd *hcd) | 1175 | static inline unsigned int hcd_index(struct usb_hcd *hcd) |
1176 | { | 1176 | { |
1177 | return 0; | 1177 | if (hcd->speed == HCD_USB3) |
1178 | return 0; | ||
1179 | else | ||
1180 | return 1; | ||
1178 | } | 1181 | } |
1179 | 1182 | ||
1180 | /* There is one ehci_hci structure per controller */ | 1183 | /* There is one ehci_hci structure per controller */ |
1181 | struct xhci_hcd { | 1184 | struct xhci_hcd { |
1182 | struct usb_hcd *main_hcd; | 1185 | struct usb_hcd *main_hcd; |
1186 | struct usb_hcd *shared_hcd; | ||
1183 | /* glue to PCI and HCD framework */ | 1187 | /* glue to PCI and HCD framework */ |
1184 | struct xhci_cap_regs __iomem *cap_regs; | 1188 | struct xhci_cap_regs __iomem *cap_regs; |
1185 | struct xhci_op_regs __iomem *op_regs; | 1189 | struct xhci_op_regs __iomem *op_regs; |
@@ -1262,10 +1266,8 @@ struct xhci_hcd { | |||
1262 | #define XHCI_LINK_TRB_QUIRK (1 << 0) | 1266 | #define XHCI_LINK_TRB_QUIRK (1 << 0) |
1263 | #define XHCI_RESET_EP_QUIRK (1 << 1) | 1267 | #define XHCI_RESET_EP_QUIRK (1 << 1) |
1264 | #define XHCI_NEC_HOST (1 << 2) | 1268 | #define XHCI_NEC_HOST (1 << 2) |
1265 | /* There's only one roothub to keep track of bus suspend info for | 1269 | /* There are two roothubs to keep track of bus suspend info for */ |
1266 | * (right now). | 1270 | struct xhci_bus_state bus_state[2]; |
1267 | */ | ||
1268 | struct xhci_bus_state bus_state[1]; | ||
1269 | /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ | 1271 | /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ |
1270 | u8 *port_array; | 1272 | u8 *port_array; |
1271 | /* Array of pointers to USB 3.0 PORTSC registers */ | 1273 | /* Array of pointers to USB 3.0 PORTSC registers */ |