aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r--drivers/usb/host/xhci-mem.c173
1 files changed, 171 insertions, 2 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 202770676da3..1d0f45f0e7a6 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1045,7 +1045,7 @@ static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci,
1045 if (udev->speed == USB_SPEED_SUPER) 1045 if (udev->speed == USB_SPEED_SUPER)
1046 return ep->ss_ep_comp.wBytesPerInterval; 1046 return ep->ss_ep_comp.wBytesPerInterval;
1047 1047
1048 max_packet = ep->desc.wMaxPacketSize & 0x3ff; 1048 max_packet = GET_MAX_PACKET(ep->desc.wMaxPacketSize);
1049 max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11; 1049 max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11;
1050 /* A 0 in max burst means 1 transfer per ESIT */ 1050 /* A 0 in max burst means 1 transfer per ESIT */
1051 return max_packet * (max_burst + 1); 1051 return max_packet * (max_burst + 1);
@@ -1135,7 +1135,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
1135 /* Fall through */ 1135 /* Fall through */
1136 case USB_SPEED_FULL: 1136 case USB_SPEED_FULL:
1137 case USB_SPEED_LOW: 1137 case USB_SPEED_LOW:
1138 max_packet = ep->desc.wMaxPacketSize & 0x3ff; 1138 max_packet = GET_MAX_PACKET(ep->desc.wMaxPacketSize);
1139 ep_ctx->ep_info2 |= MAX_PACKET(max_packet); 1139 ep_ctx->ep_info2 |= MAX_PACKET(max_packet);
1140 break; 1140 break;
1141 default: 1141 default:
@@ -1443,6 +1443,13 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
1443 xhci->dcbaa = NULL; 1443 xhci->dcbaa = NULL;
1444 1444
1445 scratchpad_free(xhci); 1445 scratchpad_free(xhci);
1446
1447 xhci->num_usb2_ports = 0;
1448 xhci->num_usb3_ports = 0;
1449 kfree(xhci->usb2_ports);
1450 kfree(xhci->usb3_ports);
1451 kfree(xhci->port_array);
1452
1446 xhci->page_size = 0; 1453 xhci->page_size = 0;
1447 xhci->page_shift = 0; 1454 xhci->page_shift = 0;
1448 xhci->bus_suspended = 0; 1455 xhci->bus_suspended = 0;
@@ -1627,6 +1634,166 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci)
1627 &xhci->ir_set->erst_dequeue); 1634 &xhci->ir_set->erst_dequeue);
1628} 1635}
1629 1636
1637static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
1638 u32 __iomem *addr, u8 major_revision)
1639{
1640 u32 temp, port_offset, port_count;
1641 int i;
1642
1643 if (major_revision > 0x03) {
1644 xhci_warn(xhci, "Ignoring unknown port speed, "
1645 "Ext Cap %p, revision = 0x%x\n",
1646 addr, major_revision);
1647 /* Ignoring port protocol we can't understand. FIXME */
1648 return;
1649 }
1650
1651 /* Port offset and count in the third dword, see section 7.2 */
1652 temp = xhci_readl(xhci, addr + 2);
1653 port_offset = XHCI_EXT_PORT_OFF(temp);
1654 port_count = XHCI_EXT_PORT_COUNT(temp);
1655 xhci_dbg(xhci, "Ext Cap %p, port offset = %u, "
1656 "count = %u, revision = 0x%x\n",
1657 addr, port_offset, port_count, major_revision);
1658 /* Port count includes the current port offset */
1659 if (port_offset == 0 || (port_offset + port_count - 1) > num_ports)
1660 /* WTF? "Valid values are ‘1’ to MaxPorts" */
1661 return;
1662 port_offset--;
1663 for (i = port_offset; i < (port_offset + port_count); i++) {
1664 /* Duplicate entry. Ignore the port if the revisions differ. */
1665 if (xhci->port_array[i] != 0) {
1666 xhci_warn(xhci, "Duplicate port entry, Ext Cap %p,"
1667 " port %u\n", addr, i);
1668 xhci_warn(xhci, "Port was marked as USB %u, "
1669 "duplicated as USB %u\n",
1670 xhci->port_array[i], major_revision);
1671 /* Only adjust the roothub port counts if we haven't
1672 * found a similar duplicate.
1673 */
1674 if (xhci->port_array[i] != major_revision &&
1675 xhci->port_array[i] != (u8) -1) {
1676 if (xhci->port_array[i] == 0x03)
1677 xhci->num_usb3_ports--;
1678 else
1679 xhci->num_usb2_ports--;
1680 xhci->port_array[i] = (u8) -1;
1681 }
1682 /* FIXME: Should we disable the port? */
1683 continue;
1684 }
1685 xhci->port_array[i] = major_revision;
1686 if (major_revision == 0x03)
1687 xhci->num_usb3_ports++;
1688 else
1689 xhci->num_usb2_ports++;
1690 }
1691 /* FIXME: Should we disable ports not in the Extended Capabilities? */
1692}
1693
1694/*
1695 * Scan the Extended Capabilities for the "Supported Protocol Capabilities" that
1696 * specify what speeds each port is supposed to be. We can't count on the port
1697 * speed bits in the PORTSC register being correct until a device is connected,
1698 * but we need to set up the two fake roothubs with the correct number of USB
1699 * 3.0 and USB 2.0 ports at host controller initialization time.
1700 */
1701static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
1702{
1703 u32 __iomem *addr;
1704 u32 offset;
1705 unsigned int num_ports;
1706 int i, port_index;
1707
1708 addr = &xhci->cap_regs->hcc_params;
1709 offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr));
1710 if (offset == 0) {
1711 xhci_err(xhci, "No Extended Capability registers, "
1712 "unable to set up roothub.\n");
1713 return -ENODEV;
1714 }
1715
1716 num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
1717 xhci->port_array = kzalloc(sizeof(*xhci->port_array)*num_ports, flags);
1718 if (!xhci->port_array)
1719 return -ENOMEM;
1720
1721 /*
1722 * For whatever reason, the first capability offset is from the
1723 * capability register base, not from the HCCPARAMS register.
1724 * See section 5.3.6 for offset calculation.
1725 */
1726 addr = &xhci->cap_regs->hc_capbase + offset;
1727 while (1) {
1728 u32 cap_id;
1729
1730 cap_id = xhci_readl(xhci, addr);
1731 if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL)
1732 xhci_add_in_port(xhci, num_ports, addr,
1733 (u8) XHCI_EXT_PORT_MAJOR(cap_id));
1734 offset = XHCI_EXT_CAPS_NEXT(cap_id);
1735 if (!offset || (xhci->num_usb2_ports + xhci->num_usb3_ports)
1736 == num_ports)
1737 break;
1738 /*
1739 * Once you're into the Extended Capabilities, the offset is
1740 * always relative to the register holding the offset.
1741 */
1742 addr += offset;
1743 }
1744
1745 if (xhci->num_usb2_ports == 0 && xhci->num_usb3_ports == 0) {
1746 xhci_warn(xhci, "No ports on the roothubs?\n");
1747 return -ENODEV;
1748 }
1749 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);
1751 /*
1752 * 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...
1754 */
1755 if (xhci->num_usb2_ports) {
1756 xhci->usb2_ports = kmalloc(sizeof(*xhci->usb2_ports)*
1757 xhci->num_usb2_ports, flags);
1758 if (!xhci->usb2_ports)
1759 return -ENOMEM;
1760
1761 port_index = 0;
1762 for (i = 0; i < num_ports; i++) {
1763 if (xhci->port_array[i] == 0x03 ||
1764 xhci->port_array[i] == 0 ||
1765 xhci->port_array[i] == -1)
1766 continue;
1767
1768 xhci->usb2_ports[port_index] =
1769 &xhci->op_regs->port_status_base +
1770 NUM_PORT_REGS*i;
1771 xhci_dbg(xhci, "USB 2.0 port at index %u, "
1772 "addr = %p\n", i,
1773 xhci->usb2_ports[port_index]);
1774 port_index++;
1775 }
1776 }
1777 if (xhci->num_usb3_ports) {
1778 xhci->usb3_ports = kmalloc(sizeof(*xhci->usb3_ports)*
1779 xhci->num_usb3_ports, flags);
1780 if (!xhci->usb3_ports)
1781 return -ENOMEM;
1782
1783 port_index = 0;
1784 for (i = 0; i < num_ports; i++)
1785 if (xhci->port_array[i] == 0x03) {
1786 xhci->usb3_ports[port_index] =
1787 &xhci->op_regs->port_status_base +
1788 NUM_PORT_REGS*i;
1789 xhci_dbg(xhci, "USB 3.0 port at index %u, "
1790 "addr = %p\n", i,
1791 xhci->usb3_ports[port_index]);
1792 port_index++;
1793 }
1794 }
1795 return 0;
1796}
1630 1797
1631int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) 1798int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
1632{ 1799{
@@ -1809,6 +1976,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
1809 1976
1810 if (scratchpad_alloc(xhci, flags)) 1977 if (scratchpad_alloc(xhci, flags))
1811 goto fail; 1978 goto fail;
1979 if (xhci_setup_port_arrays(xhci, flags))
1980 goto fail;
1812 1981
1813 return 0; 1982 return 0;
1814 1983