aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-mem.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-16 18:04:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-16 18:04:26 -0400
commit971f115a50afbe409825c9f3399d5a3b9aca4381 (patch)
treecb42dc07a032e325f22b64d961587c081225c6d6 /drivers/usb/host/xhci-mem.c
parent2e270d84223262a38d4755c61d55f5c73ea89e56 (diff)
parent500132a0f26ad7d9916102193cbc6c1b1becb373 (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.c93
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 */
829static 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 */
818int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev) 867int 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
1458static int xhci_test_trb_in_td(struct xhci_hcd *xhci, 1513static 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;