~ubuntu-branches/ubuntu/quantal/linux-linaro-mx51/quantal

« back to all changes in this revision

Viewing changes to drivers/usb/host/xhci-mem.c

  • Committer: Bazaar Package Importer
  • Author(s): John Rigby, John Rigby
  • Date: 2011-01-08 18:34:41 UTC
  • Revision ID: james.westby@ubuntu.com-20110108183441-002wttt2gz2sah4b
Tags: 2.6.37-1002.5
[ John Rigby ]

* rebase to new upstreams: 
  v2.6.37 final
  Ubuntu-2.6.37-12.28
* Clean up lintian errors and warnings
  - LP: #697317

Show diffs side-by-side

added added

removed removed

Lines of Context:
1443
1443
        xhci->dcbaa = NULL;
1444
1444
 
1445
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
1453
        xhci->page_size = 0;
1447
1454
        xhci->page_shift = 0;
1448
1455
        xhci->bus_suspended = 0;
1627
1634
                        &xhci->ir_set->erst_dequeue);
1628
1635
}
1629
1636
 
 
1637
static 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
 */
 
1701
static 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
 
1631
1798
int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
1632
1799
{
1809
1976
 
1810
1977
        if (scratchpad_alloc(xhci, flags))
1811
1978
                goto fail;
 
1979
        if (xhci_setup_port_arrays(xhci, flags))
 
1980
                goto fail;
1812
1981
 
1813
1982
        return 0;
1814
1983