diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 18:04:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 18:04:26 -0400 |
commit | 971f115a50afbe409825c9f3399d5a3b9aca4381 (patch) | |
tree | cb42dc07a032e325f22b64d961587c081225c6d6 /drivers/usb/host/xhci-mem.c | |
parent | 2e270d84223262a38d4755c61d55f5c73ea89e56 (diff) | |
parent | 500132a0f26ad7d9916102193cbc6c1b1becb373 (diff) |
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (172 commits)
USB: Add support for SuperSpeed isoc endpoints
xhci: Clean up cycle bit math used during stalls.
xhci: Fix cycle bit calculation during stall handling.
xhci: Update internal dequeue pointers after stalls.
USB: Disable auto-suspend for USB 3.0 hubs.
USB: Remove bogus USB_PORT_STAT_SUPER_SPEED symbol.
xhci: Return canceled URBs immediately when host is halted.
xhci: Fixes for suspend/resume of shared HCDs.
xhci: Fix re-init on power loss after resume.
xhci: Make roothub functions deal with device removal.
xhci: Limit roothub ports to 15 USB3 & 31 USB2 ports.
xhci: Return a USB 3.0 hub descriptor for USB3 roothub.
xhci: Register second xHCI roothub.
xhci: Change xhci_find_slot_id_by_port() API.
xhci: Refactor bus suspend state into a struct.
xhci: Index with a port array instead of PORTSC addresses.
USB: Set usb_hcd->state and flags for shared roothubs.
usb: Make core allocate resources per PCI-device.
usb: Store bus type in usb_hcd, not in driver flags.
usb: Change usb_hcd->bandwidth_mutex to a pointer.
...
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 93 |
1 files changed, 84 insertions, 9 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index a9534396e85b..a003e79aacdc 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,16 +913,20 @@ 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 a HS hub? */ | 928 | /* Is this a LS/FS device under an external HS hub? */ |
874 | if ((udev->speed == USB_SPEED_LOW || udev->speed == USB_SPEED_FULL) && | 929 | if (udev->tt && udev->tt->hub->parent) { |
875 | udev->tt) { | ||
876 | slot_ctx->tt_info = udev->tt->hub->slot_id; | 930 | slot_ctx->tt_info = udev->tt->hub->slot_id; |
877 | slot_ctx->tt_info |= udev->ttport << 8; | 931 | slot_ctx->tt_info |= udev->ttport << 8; |
878 | if (udev->tt->multi) | 932 | if (udev->tt->multi) |
@@ -1452,7 +1506,8 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
1452 | 1506 | ||
1453 | xhci->page_size = 0; | 1507 | xhci->page_size = 0; |
1454 | xhci->page_shift = 0; | 1508 | xhci->page_shift = 0; |
1455 | xhci->bus_suspended = 0; | 1509 | xhci->bus_state[0].bus_suspended = 0; |
1510 | xhci->bus_state[1].bus_suspended = 0; | ||
1456 | } | 1511 | } |
1457 | 1512 | ||
1458 | static int xhci_test_trb_in_td(struct xhci_hcd *xhci, | 1513 | static int xhci_test_trb_in_td(struct xhci_hcd *xhci, |
@@ -1748,6 +1803,20 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) | |||
1748 | } | 1803 | } |
1749 | xhci_dbg(xhci, "Found %u USB 2.0 ports and %u USB 3.0 ports.\n", | 1804 | xhci_dbg(xhci, "Found %u USB 2.0 ports and %u USB 3.0 ports.\n", |
1750 | xhci->num_usb2_ports, xhci->num_usb3_ports); | 1805 | xhci->num_usb2_ports, xhci->num_usb3_ports); |
1806 | |||
1807 | /* Place limits on the number of roothub ports so that the hub | ||
1808 | * descriptors aren't longer than the USB core will allocate. | ||
1809 | */ | ||
1810 | if (xhci->num_usb3_ports > 15) { | ||
1811 | xhci_dbg(xhci, "Limiting USB 3.0 roothub ports to 15.\n"); | ||
1812 | xhci->num_usb3_ports = 15; | ||
1813 | } | ||
1814 | if (xhci->num_usb2_ports > USB_MAXCHILDREN) { | ||
1815 | xhci_dbg(xhci, "Limiting USB 2.0 roothub ports to %u.\n", | ||
1816 | USB_MAXCHILDREN); | ||
1817 | xhci->num_usb2_ports = USB_MAXCHILDREN; | ||
1818 | } | ||
1819 | |||
1751 | /* | 1820 | /* |
1752 | * Note we could have all USB 3.0 ports, or all USB 2.0 ports. | 1821 | * Note we could have all USB 3.0 ports, or all USB 2.0 ports. |
1753 | * Not sure how the USB core will handle a hub with no ports... | 1822 | * Not sure how the USB core will handle a hub with no ports... |
@@ -1772,6 +1841,8 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) | |||
1772 | "addr = %p\n", i, | 1841 | "addr = %p\n", i, |
1773 | xhci->usb2_ports[port_index]); | 1842 | xhci->usb2_ports[port_index]); |
1774 | port_index++; | 1843 | port_index++; |
1844 | if (port_index == xhci->num_usb2_ports) | ||
1845 | break; | ||
1775 | } | 1846 | } |
1776 | } | 1847 | } |
1777 | if (xhci->num_usb3_ports) { | 1848 | if (xhci->num_usb3_ports) { |
@@ -1790,6 +1861,8 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) | |||
1790 | "addr = %p\n", i, | 1861 | "addr = %p\n", i, |
1791 | xhci->usb3_ports[port_index]); | 1862 | xhci->usb3_ports[port_index]); |
1792 | port_index++; | 1863 | port_index++; |
1864 | if (port_index == xhci->num_usb3_ports) | ||
1865 | break; | ||
1793 | } | 1866 | } |
1794 | } | 1867 | } |
1795 | return 0; | 1868 | return 0; |
@@ -1971,8 +2044,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
1971 | init_completion(&xhci->addr_dev); | 2044 | init_completion(&xhci->addr_dev); |
1972 | for (i = 0; i < MAX_HC_SLOTS; ++i) | 2045 | for (i = 0; i < MAX_HC_SLOTS; ++i) |
1973 | xhci->devs[i] = NULL; | 2046 | xhci->devs[i] = NULL; |
1974 | for (i = 0; i < MAX_HC_PORTS; ++i) | 2047 | for (i = 0; i < USB_MAXCHILDREN; ++i) { |
1975 | xhci->resume_done[i] = 0; | 2048 | xhci->bus_state[0].resume_done[i] = 0; |
2049 | xhci->bus_state[1].resume_done[i] = 0; | ||
2050 | } | ||
1976 | 2051 | ||
1977 | if (scratchpad_alloc(xhci, flags)) | 2052 | if (scratchpad_alloc(xhci, flags)) |
1978 | goto fail; | 2053 | goto fail; |