| .. | .. |
|---|
| 1 | | -// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ |
|---|
| 2 | 2 | |
|---|
| 3 | 3 | /* |
|---|
| 4 | 4 | * xHCI host controller driver |
|---|
| .. | .. |
|---|
| 17 | 17 | #include <linux/kernel.h> |
|---|
| 18 | 18 | #include <linux/usb/hcd.h> |
|---|
| 19 | 19 | #include <linux/io-64-nonatomic-lo-hi.h> |
|---|
| 20 | +#include <linux/android_kabi.h> |
|---|
| 20 | 21 | |
|---|
| 21 | 22 | /* Code sharing between pci-quirks and xhci hcd */ |
|---|
| 22 | 23 | #include "xhci-ext-caps.h" |
|---|
| 23 | 24 | #include "pci-quirks.h" |
|---|
| 25 | + |
|---|
| 26 | +/* max buffer size for trace and debug messages */ |
|---|
| 27 | +#define XHCI_MSG_MAX 500 |
|---|
| 24 | 28 | |
|---|
| 25 | 29 | /* xHCI PCI Configuration Registers */ |
|---|
| 26 | 30 | #define XHCI_SBRN_OFFSET (0x60) |
|---|
| .. | .. |
|---|
| 225 | 229 | /* bit 14 Extended TBC Enable, changes Isoc TRB fields to support larger TBC */ |
|---|
| 226 | 230 | #define CMD_ETE (1 << 14) |
|---|
| 227 | 231 | /* bits 15:31 are reserved (and should be preserved on writes). */ |
|---|
| 232 | + |
|---|
| 233 | +#define XHCI_RESET_LONG_USEC (10 * 1000 * 1000) |
|---|
| 234 | +#define XHCI_RESET_SHORT_USEC (250 * 1000) |
|---|
| 228 | 235 | |
|---|
| 229 | 236 | /* IMAN - Interrupt Management Register */ |
|---|
| 230 | 237 | #define IMAN_IE (1 << 1) |
|---|
| .. | .. |
|---|
| 809 | 816 | struct completion *completion; |
|---|
| 810 | 817 | union xhci_trb *command_trb; |
|---|
| 811 | 818 | struct list_head cmd_list; |
|---|
| 819 | + |
|---|
| 820 | + ANDROID_KABI_RESERVE(1); |
|---|
| 821 | + ANDROID_KABI_RESERVE(2); |
|---|
| 812 | 822 | }; |
|---|
| 813 | 823 | |
|---|
| 814 | 824 | /* drop context bitmasks */ |
|---|
| .. | .. |
|---|
| 918 | 928 | #define SS_BW_RESERVED 10 |
|---|
| 919 | 929 | |
|---|
| 920 | 930 | struct xhci_virt_ep { |
|---|
| 931 | + struct xhci_virt_device *vdev; /* parent */ |
|---|
| 932 | + unsigned int ep_index; |
|---|
| 921 | 933 | struct xhci_ring *ring; |
|---|
| 922 | 934 | /* Related to endpoints that are configured to use stream IDs only */ |
|---|
| 923 | 935 | struct xhci_stream_info *stream_info; |
|---|
| .. | .. |
|---|
| 936 | 948 | #define EP_GETTING_NO_STREAMS (1 << 5) |
|---|
| 937 | 949 | #define EP_HARD_CLEAR_TOGGLE (1 << 6) |
|---|
| 938 | 950 | #define EP_SOFT_CLEAR_TOGGLE (1 << 7) |
|---|
| 951 | +/* usb_hub_clear_tt_buffer is in progress */ |
|---|
| 952 | +#define EP_CLEARING_TT (1 << 8) |
|---|
| 939 | 953 | /* ---- Related to URB cancellation ---- */ |
|---|
| 940 | 954 | struct list_head cancelled_td_list; |
|---|
| 941 | 955 | /* Watchdog timer for stop endpoint command to cancel URBs */ |
|---|
| .. | .. |
|---|
| 994 | 1008 | #define EP_CTX_PER_DEV 31 |
|---|
| 995 | 1009 | |
|---|
| 996 | 1010 | struct xhci_virt_device { |
|---|
| 1011 | + int slot_id; |
|---|
| 997 | 1012 | struct usb_device *udev; |
|---|
| 998 | 1013 | /* |
|---|
| 999 | 1014 | * Commands to the hardware are passed an "input context" that |
|---|
| .. | .. |
|---|
| 1313 | 1328 | #define TRB_IOC (1<<5) |
|---|
| 1314 | 1329 | /* The buffer pointer contains immediate data */ |
|---|
| 1315 | 1330 | #define TRB_IDT (1<<6) |
|---|
| 1331 | +/* TDs smaller than this might use IDT */ |
|---|
| 1332 | +#define TRB_IDT_MAX_SIZE 8 |
|---|
| 1316 | 1333 | |
|---|
| 1317 | 1334 | /* Block Event Interrupt */ |
|---|
| 1318 | 1335 | #define TRB_BEI (1<<9) |
|---|
| .. | .. |
|---|
| 1408 | 1425 | /* MFINDEX Wrap Event - microframe counter wrapped */ |
|---|
| 1409 | 1426 | #define TRB_MFINDEX_WRAP 39 |
|---|
| 1410 | 1427 | /* TRB IDs 40-47 reserved, 48-63 is vendor-defined */ |
|---|
| 1411 | | - |
|---|
| 1428 | +#define TRB_VENDOR_DEFINED_LOW 48 |
|---|
| 1412 | 1429 | /* Nec vendor-specific command completion event. */ |
|---|
| 1413 | 1430 | #define TRB_NEC_CMD_COMP 48 |
|---|
| 1414 | 1431 | /* Get NEC firmware revision. */ |
|---|
| .. | .. |
|---|
| 1509 | 1526 | #define TRB_SEGMENT_SIZE (TRBS_PER_SEGMENT*16) |
|---|
| 1510 | 1527 | #define TRB_SEGMENT_SHIFT (ilog2(TRB_SEGMENT_SIZE)) |
|---|
| 1511 | 1528 | /* TRB buffer pointers can't cross 64KB boundaries */ |
|---|
| 1512 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 1513 | | -#define TRB_MAX_BUFF_SHIFT 12 |
|---|
| 1514 | | -#else |
|---|
| 1515 | 1529 | #define TRB_MAX_BUFF_SHIFT 16 |
|---|
| 1516 | | -#endif |
|---|
| 1517 | 1530 | #define TRB_MAX_BUFF_SIZE (1 << TRB_MAX_BUFF_SHIFT) |
|---|
| 1518 | 1531 | /* How much data is left before the 64KB boundary? */ |
|---|
| 1519 | 1532 | #define TRB_BUFF_LEN_UP_TO_BOUNDARY(addr) (TRB_MAX_BUFF_SIZE - \ |
|---|
| 1520 | 1533 | (addr & (TRB_MAX_BUFF_SIZE - 1))) |
|---|
| 1534 | +#define MAX_SOFT_RETRY 3 |
|---|
| 1521 | 1535 | |
|---|
| 1522 | 1536 | struct xhci_segment { |
|---|
| 1523 | 1537 | union xhci_trb *trbs; |
|---|
| .. | .. |
|---|
| 1529 | 1543 | void *bounce_buf; |
|---|
| 1530 | 1544 | unsigned int bounce_offs; |
|---|
| 1531 | 1545 | unsigned int bounce_len; |
|---|
| 1546 | + |
|---|
| 1547 | + ANDROID_KABI_RESERVE(1); |
|---|
| 1548 | +}; |
|---|
| 1549 | + |
|---|
| 1550 | +enum xhci_cancelled_td_status { |
|---|
| 1551 | + TD_DIRTY = 0, |
|---|
| 1552 | + TD_HALTED, |
|---|
| 1553 | + TD_CLEARING_CACHE, |
|---|
| 1554 | + TD_CLEARED, |
|---|
| 1532 | 1555 | }; |
|---|
| 1533 | 1556 | |
|---|
| 1534 | 1557 | struct xhci_td { |
|---|
| 1535 | 1558 | struct list_head td_list; |
|---|
| 1536 | 1559 | struct list_head cancelled_td_list; |
|---|
| 1560 | + int status; |
|---|
| 1561 | + enum xhci_cancelled_td_status cancel_status; |
|---|
| 1537 | 1562 | struct urb *urb; |
|---|
| 1538 | 1563 | struct xhci_segment *start_seg; |
|---|
| 1539 | 1564 | union xhci_trb *first_trb; |
|---|
| 1540 | 1565 | union xhci_trb *last_trb; |
|---|
| 1566 | + struct xhci_segment *last_trb_seg; |
|---|
| 1541 | 1567 | struct xhci_segment *bounce_seg; |
|---|
| 1542 | 1568 | /* actual_length of the URB has already been set */ |
|---|
| 1543 | 1569 | bool urb_length_set; |
|---|
| 1570 | + unsigned int num_trbs; |
|---|
| 1544 | 1571 | }; |
|---|
| 1545 | 1572 | |
|---|
| 1546 | 1573 | /* xHCI command default timeout value */ |
|---|
| .. | .. |
|---|
| 1550 | 1577 | struct xhci_cd { |
|---|
| 1551 | 1578 | struct xhci_command *command; |
|---|
| 1552 | 1579 | union xhci_trb *cmd_trb; |
|---|
| 1553 | | -}; |
|---|
| 1554 | | - |
|---|
| 1555 | | -struct xhci_dequeue_state { |
|---|
| 1556 | | - struct xhci_segment *new_deq_seg; |
|---|
| 1557 | | - union xhci_trb *new_deq_ptr; |
|---|
| 1558 | | - int new_cycle_state; |
|---|
| 1559 | | - unsigned int stream_id; |
|---|
| 1560 | 1580 | }; |
|---|
| 1561 | 1581 | |
|---|
| 1562 | 1582 | enum xhci_ring_type { |
|---|
| .. | .. |
|---|
| 1605 | 1625 | * if we own the TRB (if we are the consumer). See section 4.9.1. |
|---|
| 1606 | 1626 | */ |
|---|
| 1607 | 1627 | u32 cycle_state; |
|---|
| 1628 | + unsigned int err_count; |
|---|
| 1608 | 1629 | unsigned int stream_id; |
|---|
| 1609 | 1630 | unsigned int num_segs; |
|---|
| 1610 | 1631 | unsigned int num_trbs_free; |
|---|
| .. | .. |
|---|
| 1613 | 1634 | enum xhci_ring_type type; |
|---|
| 1614 | 1635 | bool last_td_was_short; |
|---|
| 1615 | 1636 | struct radix_tree_root *trb_address_map; |
|---|
| 1637 | + |
|---|
| 1638 | + ANDROID_KABI_RESERVE(1); |
|---|
| 1639 | + ANDROID_KABI_RESERVE(2); |
|---|
| 1616 | 1640 | }; |
|---|
| 1617 | 1641 | |
|---|
| 1618 | 1642 | struct xhci_erst_entry { |
|---|
| .. | .. |
|---|
| 1630 | 1654 | dma_addr_t erst_dma_addr; |
|---|
| 1631 | 1655 | /* Num entries the ERST can contain */ |
|---|
| 1632 | 1656 | unsigned int erst_size; |
|---|
| 1657 | + |
|---|
| 1658 | + ANDROID_KABI_RESERVE(1); |
|---|
| 1633 | 1659 | }; |
|---|
| 1634 | 1660 | |
|---|
| 1635 | 1661 | struct xhci_scratchpad { |
|---|
| .. | .. |
|---|
| 1641 | 1667 | struct urb_priv { |
|---|
| 1642 | 1668 | int num_tds; |
|---|
| 1643 | 1669 | int num_tds_done; |
|---|
| 1644 | | - struct xhci_td td[0]; |
|---|
| 1670 | + struct xhci_td td[]; |
|---|
| 1645 | 1671 | }; |
|---|
| 1646 | 1672 | |
|---|
| 1647 | 1673 | /* |
|---|
| .. | .. |
|---|
| 1693 | 1719 | /* Which ports are waiting on RExit to U0 transition. */ |
|---|
| 1694 | 1720 | unsigned long rexit_ports; |
|---|
| 1695 | 1721 | struct completion rexit_done[USB_MAXCHILDREN]; |
|---|
| 1722 | + struct completion u3exit_done[USB_MAXCHILDREN]; |
|---|
| 1696 | 1723 | }; |
|---|
| 1697 | 1724 | |
|---|
| 1698 | 1725 | |
|---|
| .. | .. |
|---|
| 1701 | 1728 | * Intel Lynx Point LP xHCI host. |
|---|
| 1702 | 1729 | */ |
|---|
| 1703 | 1730 | #define XHCI_MAX_REXIT_TIMEOUT_MS 20 |
|---|
| 1704 | | - |
|---|
| 1705 | | -static inline unsigned int hcd_index(struct usb_hcd *hcd) |
|---|
| 1706 | | -{ |
|---|
| 1707 | | - if (hcd->speed >= HCD_USB3) |
|---|
| 1708 | | - return 0; |
|---|
| 1709 | | - else |
|---|
| 1710 | | - return 1; |
|---|
| 1711 | | -} |
|---|
| 1712 | | - |
|---|
| 1713 | 1731 | struct xhci_port_cap { |
|---|
| 1714 | 1732 | u32 *psi; /* array of protocol speed ID entries */ |
|---|
| 1715 | 1733 | u8 psi_count; |
|---|
| .. | .. |
|---|
| 1730 | 1748 | struct xhci_port **ports; |
|---|
| 1731 | 1749 | unsigned int num_ports; |
|---|
| 1732 | 1750 | struct usb_hcd *hcd; |
|---|
| 1751 | + /* keep track of bus suspend info */ |
|---|
| 1752 | + struct xhci_bus_state bus_state; |
|---|
| 1733 | 1753 | /* supported prococol extended capabiliy values */ |
|---|
| 1734 | 1754 | u8 maj_rev; |
|---|
| 1735 | 1755 | u8 min_rev; |
|---|
| .. | .. |
|---|
| 1746 | 1766 | struct xhci_doorbell_array __iomem *dba; |
|---|
| 1747 | 1767 | /* Our HCD's current interrupter register set */ |
|---|
| 1748 | 1768 | struct xhci_intr_reg __iomem *ir_set; |
|---|
| 1749 | | - /* secondary interrupter */ |
|---|
| 1750 | | - struct xhci_intr_reg __iomem **sec_ir_set; |
|---|
| 1751 | | - |
|---|
| 1752 | | - int core_id; |
|---|
| 1753 | 1769 | |
|---|
| 1754 | 1770 | /* Cached register copies of read-only HC data */ |
|---|
| 1755 | 1771 | __u32 hcs_params1; |
|---|
| .. | .. |
|---|
| 1779 | 1795 | /* optional clocks */ |
|---|
| 1780 | 1796 | struct clk *clk; |
|---|
| 1781 | 1797 | struct clk *reg_clk; |
|---|
| 1798 | + /* optional reset controller */ |
|---|
| 1799 | + struct reset_control *reset; |
|---|
| 1782 | 1800 | /* data structures */ |
|---|
| 1783 | 1801 | struct xhci_device_context_array *dcbaa; |
|---|
| 1784 | 1802 | struct xhci_ring *cmd_ring; |
|---|
| .. | .. |
|---|
| 1793 | 1811 | struct xhci_command *current_cmd; |
|---|
| 1794 | 1812 | struct xhci_ring *event_ring; |
|---|
| 1795 | 1813 | struct xhci_erst erst; |
|---|
| 1796 | | - |
|---|
| 1797 | | - /* secondary event ring and erst */ |
|---|
| 1798 | | - struct xhci_ring **sec_event_ring; |
|---|
| 1799 | | - struct xhci_erst *sec_erst; |
|---|
| 1800 | | - |
|---|
| 1801 | 1814 | /* Scratchpad */ |
|---|
| 1802 | 1815 | struct xhci_scratchpad *scratchpad; |
|---|
| 1803 | 1816 | /* Store LPM test failed devices' information */ |
|---|
| .. | .. |
|---|
| 1884 | 1897 | #define XHCI_SUSPEND_DELAY BIT_ULL(30) |
|---|
| 1885 | 1898 | #define XHCI_INTEL_USB_ROLE_SW BIT_ULL(31) |
|---|
| 1886 | 1899 | #define XHCI_ZERO_64B_REGS BIT_ULL(32) |
|---|
| 1900 | +#define XHCI_DEFAULT_PM_RUNTIME_ALLOW BIT_ULL(33) |
|---|
| 1887 | 1901 | #define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34) |
|---|
| 1888 | 1902 | #define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35) |
|---|
| 1889 | | -#define XHCI_TRB_ENT_QUIRK BIT_ULL(36) |
|---|
| 1890 | | -#define XHCI_DIS_AUTOSUSPEND BIT_ULL(37) |
|---|
| 1903 | +#define XHCI_RENESAS_FW_QUIRK BIT_ULL(36) |
|---|
| 1904 | +#define XHCI_SKIP_PHY_INIT BIT_ULL(37) |
|---|
| 1891 | 1905 | #define XHCI_DISABLE_SPARSE BIT_ULL(38) |
|---|
| 1892 | | -#define XHCI_WARM_RESET_ON_SUSPEND BIT_ULL(39) |
|---|
| 1893 | | -#define XHCI_U2_BROKEN_SUSPEND BIT_ULL(40) |
|---|
| 1894 | | -#define XHCI_SKIP_PHY_INIT BIT_ULL(41) |
|---|
| 1906 | +#define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39) |
|---|
| 1907 | +#define XHCI_NO_SOFT_RETRY BIT_ULL(40) |
|---|
| 1908 | +#define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(42) |
|---|
| 1909 | +#define XHCI_SUSPEND_RESUME_CLKS BIT_ULL(43) |
|---|
| 1910 | +#define XHCI_RESET_TO_DEFAULT BIT_ULL(44) |
|---|
| 1911 | +#define XHCI_U2_BROKEN_SUSPEND BIT_ULL(45) |
|---|
| 1895 | 1912 | |
|---|
| 1896 | 1913 | unsigned int num_active_eps; |
|---|
| 1897 | 1914 | unsigned int limit_active_eps; |
|---|
| 1898 | | - /* There are two roothubs to keep track of bus suspend info for */ |
|---|
| 1899 | | - struct xhci_bus_state bus_state[2]; |
|---|
| 1900 | 1915 | struct xhci_port *hw_ports; |
|---|
| 1901 | 1916 | struct xhci_hub usb2_rhub; |
|---|
| 1902 | 1917 | struct xhci_hub usb3_rhub; |
|---|
| 1903 | | - /* support xHCI 0.96 spec USB2 software LPM */ |
|---|
| 1904 | | - unsigned sw_lpm_support:1; |
|---|
| 1905 | 1918 | /* support xHCI 1.0 spec USB2 hardware LPM */ |
|---|
| 1906 | 1919 | unsigned hw_lpm_support:1; |
|---|
| 1907 | 1920 | /* Broken Suspend flag for SNPS Suspend resume issue */ |
|---|
| .. | .. |
|---|
| 1924 | 1937 | struct list_head regset_list; |
|---|
| 1925 | 1938 | |
|---|
| 1926 | 1939 | void *dbc; |
|---|
| 1940 | + |
|---|
| 1941 | + /* Used for bug 194461020 */ |
|---|
| 1942 | + ANDROID_KABI_USE(1, struct xhci_vendor_ops *vendor_ops); |
|---|
| 1943 | + |
|---|
| 1944 | + ANDROID_KABI_RESERVE(2); |
|---|
| 1945 | + ANDROID_KABI_RESERVE(3); |
|---|
| 1946 | + ANDROID_KABI_RESERVE(4); |
|---|
| 1947 | + |
|---|
| 1927 | 1948 | /* platform-specific data -- must come last */ |
|---|
| 1928 | | - unsigned long priv[0] __aligned(sizeof(s64)); |
|---|
| 1949 | + unsigned long priv[] __aligned(sizeof(s64)); |
|---|
| 1929 | 1950 | }; |
|---|
| 1930 | 1951 | |
|---|
| 1931 | 1952 | /* Platform specific overrides to generic XHCI hc_driver ops */ |
|---|
| .. | .. |
|---|
| 1933 | 1954 | size_t extra_priv_size; |
|---|
| 1934 | 1955 | int (*reset)(struct usb_hcd *hcd); |
|---|
| 1935 | 1956 | int (*start)(struct usb_hcd *hcd); |
|---|
| 1957 | + int (*add_endpoint)(struct usb_hcd *hcd, struct usb_device *udev, |
|---|
| 1958 | + struct usb_host_endpoint *ep); |
|---|
| 1959 | + int (*drop_endpoint)(struct usb_hcd *hcd, struct usb_device *udev, |
|---|
| 1960 | + struct usb_host_endpoint *ep); |
|---|
| 1961 | + int (*check_bandwidth)(struct usb_hcd *, struct usb_device *); |
|---|
| 1962 | + void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *); |
|---|
| 1963 | + int (*address_device)(struct usb_hcd *hcd, struct usb_device *udev); |
|---|
| 1964 | + int (*bus_suspend)(struct usb_hcd *hcd); |
|---|
| 1965 | + int (*bus_resume)(struct usb_hcd *hcd); |
|---|
| 1936 | 1966 | }; |
|---|
| 1937 | 1967 | |
|---|
| 1938 | 1968 | #define XHCI_CFC_DELAY 10 |
|---|
| .. | .. |
|---|
| 2037 | 2067 | struct xhci_ring *evt_ring, |
|---|
| 2038 | 2068 | struct xhci_erst *erst, |
|---|
| 2039 | 2069 | gfp_t flags); |
|---|
| 2070 | +void xhci_initialize_ring_info(struct xhci_ring *ring, |
|---|
| 2071 | + unsigned int cycle_state); |
|---|
| 2040 | 2072 | void xhci_free_erst(struct xhci_hcd *xhci, struct xhci_erst *erst); |
|---|
| 2041 | 2073 | void xhci_free_endpoint_ring(struct xhci_hcd *xhci, |
|---|
| 2042 | 2074 | struct xhci_virt_device *virt_dev, |
|---|
| .. | .. |
|---|
| 2057 | 2089 | struct xhci_ring *xhci_dma_to_transfer_ring( |
|---|
| 2058 | 2090 | struct xhci_virt_ep *ep, |
|---|
| 2059 | 2091 | u64 address); |
|---|
| 2060 | | -struct xhci_ring *xhci_stream_id_to_ring( |
|---|
| 2061 | | - struct xhci_virt_device *dev, |
|---|
| 2062 | | - unsigned int ep_index, |
|---|
| 2063 | | - unsigned int stream_id); |
|---|
| 2064 | 2092 | struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, |
|---|
| 2065 | 2093 | bool allocate_completion, gfp_t mem_flags); |
|---|
| 2066 | 2094 | struct xhci_command *xhci_alloc_command_with_ctx(struct xhci_hcd *xhci, |
|---|
| .. | .. |
|---|
| 2072 | 2100 | int type, gfp_t flags); |
|---|
| 2073 | 2101 | void xhci_free_container_ctx(struct xhci_hcd *xhci, |
|---|
| 2074 | 2102 | struct xhci_container_ctx *ctx); |
|---|
| 2075 | | -int xhci_sec_event_ring_setup(struct usb_hcd *hcd, unsigned int intr_num); |
|---|
| 2076 | | -int xhci_sec_event_ring_cleanup(struct usb_hcd *hcd, unsigned int intr_num); |
|---|
| 2077 | 2103 | |
|---|
| 2078 | 2104 | /* xHCI host controller glue */ |
|---|
| 2079 | 2105 | typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *); |
|---|
| 2080 | | -int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec); |
|---|
| 2106 | +int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, u64 timeout_us); |
|---|
| 2081 | 2107 | void xhci_quiesce(struct xhci_hcd *xhci); |
|---|
| 2082 | 2108 | int xhci_halt(struct xhci_hcd *xhci); |
|---|
| 2083 | 2109 | int xhci_start(struct xhci_hcd *xhci); |
|---|
| 2084 | | -int xhci_reset(struct xhci_hcd *xhci); |
|---|
| 2110 | +int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us); |
|---|
| 2085 | 2111 | int xhci_run(struct usb_hcd *hcd); |
|---|
| 2086 | 2112 | int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); |
|---|
| 2087 | 2113 | void xhci_shutdown(struct usb_hcd *hcd); |
|---|
| 2088 | 2114 | void xhci_init_driver(struct hc_driver *drv, |
|---|
| 2089 | 2115 | const struct xhci_driver_overrides *over); |
|---|
| 2116 | +int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, |
|---|
| 2117 | + struct usb_host_endpoint *ep); |
|---|
| 2118 | +int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, |
|---|
| 2119 | + struct usb_host_endpoint *ep); |
|---|
| 2120 | +int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); |
|---|
| 2121 | +void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); |
|---|
| 2122 | +int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev); |
|---|
| 2090 | 2123 | int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id); |
|---|
| 2091 | 2124 | int xhci_ext_cap_init(struct xhci_hcd *xhci); |
|---|
| 2092 | 2125 | |
|---|
| .. | .. |
|---|
| 2134 | 2167 | enum xhci_ep_reset_type reset_type); |
|---|
| 2135 | 2168 | int xhci_queue_reset_device(struct xhci_hcd *xhci, struct xhci_command *cmd, |
|---|
| 2136 | 2169 | u32 slot_id); |
|---|
| 2137 | | -void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, |
|---|
| 2138 | | - unsigned int slot_id, unsigned int ep_index, |
|---|
| 2139 | | - unsigned int stream_id, struct xhci_td *cur_td, |
|---|
| 2140 | | - struct xhci_dequeue_state *state); |
|---|
| 2141 | | -void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, |
|---|
| 2142 | | - unsigned int slot_id, unsigned int ep_index, |
|---|
| 2143 | | - struct xhci_dequeue_state *deq_state); |
|---|
| 2144 | | -void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index, |
|---|
| 2145 | | - unsigned int stream_id, struct xhci_td *td); |
|---|
| 2170 | +void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int slot_id, |
|---|
| 2171 | + unsigned int ep_index, unsigned int stream_id, |
|---|
| 2172 | + struct xhci_td *td); |
|---|
| 2146 | 2173 | void xhci_stop_endpoint_command_watchdog(struct timer_list *t); |
|---|
| 2147 | 2174 | void xhci_handle_command_timeout(struct work_struct *work); |
|---|
| 2148 | 2175 | |
|---|
| 2149 | 2176 | void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, |
|---|
| 2150 | 2177 | unsigned int ep_index, unsigned int stream_id); |
|---|
| 2178 | +void xhci_ring_doorbell_for_active_rings(struct xhci_hcd *xhci, |
|---|
| 2179 | + unsigned int slot_id, |
|---|
| 2180 | + unsigned int ep_index); |
|---|
| 2151 | 2181 | void xhci_cleanup_command_queue(struct xhci_hcd *xhci); |
|---|
| 2152 | 2182 | void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring); |
|---|
| 2153 | 2183 | unsigned int count_trbs(u64 addr, u64 len); |
|---|
| .. | .. |
|---|
| 2197 | 2227 | urb->stream_id); |
|---|
| 2198 | 2228 | } |
|---|
| 2199 | 2229 | |
|---|
| 2230 | +/** |
|---|
| 2231 | + * struct xhci_vendor_ops - function callbacks for vendor specific operations |
|---|
| 2232 | + * @vendor_init: called for vendor init process |
|---|
| 2233 | + * @vendor_cleanup: called for vendor cleanup process |
|---|
| 2234 | + * @is_usb_offload_enabled: called to check if usb offload enabled |
|---|
| 2235 | + * @queue_irq_work: called to queue vendor specific irq work |
|---|
| 2236 | + * @alloc_dcbaa: called when allocating vendor specific dcbaa |
|---|
| 2237 | + * @free_dcbaa: called to free vendor specific dcbaa |
|---|
| 2238 | + * @alloc_transfer_ring: called when remote transfer ring allocation is required |
|---|
| 2239 | + * @free_transfer_ring: called to free vendor specific transfer ring |
|---|
| 2240 | + * @sync_dev_ctx: called when synchronization for device context is required |
|---|
| 2241 | + * @alloc_container_ctx: called when allocating vendor specific container context |
|---|
| 2242 | + * @free_container_ctx: called to free vendor specific container context |
|---|
| 2243 | + */ |
|---|
| 2244 | +struct xhci_vendor_ops { |
|---|
| 2245 | + int (*vendor_init)(struct xhci_hcd *xhci); |
|---|
| 2246 | + void (*vendor_cleanup)(struct xhci_hcd *xhci); |
|---|
| 2247 | + bool (*is_usb_offload_enabled)(struct xhci_hcd *xhci, |
|---|
| 2248 | + struct xhci_virt_device *vdev, |
|---|
| 2249 | + unsigned int ep_index); |
|---|
| 2250 | + irqreturn_t (*queue_irq_work)(struct xhci_hcd *xhci); |
|---|
| 2251 | + |
|---|
| 2252 | + struct xhci_device_context_array *(*alloc_dcbaa)(struct xhci_hcd *xhci, |
|---|
| 2253 | + gfp_t flags); |
|---|
| 2254 | + void (*free_dcbaa)(struct xhci_hcd *xhci); |
|---|
| 2255 | + |
|---|
| 2256 | + struct xhci_ring *(*alloc_transfer_ring)(struct xhci_hcd *xhci, |
|---|
| 2257 | + u32 endpoint_type, enum xhci_ring_type ring_type, |
|---|
| 2258 | + unsigned int max_packet, gfp_t mem_flags); |
|---|
| 2259 | + void (*free_transfer_ring)(struct xhci_hcd *xhci, |
|---|
| 2260 | + struct xhci_virt_device *virt_dev, unsigned int ep_index); |
|---|
| 2261 | + int (*sync_dev_ctx)(struct xhci_hcd *xhci, unsigned int slot_id); |
|---|
| 2262 | + bool (*usb_offload_skip_urb)(struct xhci_hcd *xhci, struct urb *urb); |
|---|
| 2263 | + void (*alloc_container_ctx)(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, |
|---|
| 2264 | + int type, gfp_t flags); |
|---|
| 2265 | + void (*free_container_ctx)(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); |
|---|
| 2266 | +}; |
|---|
| 2267 | + |
|---|
| 2268 | +struct xhci_vendor_ops *xhci_vendor_get_ops(struct xhci_hcd *xhci); |
|---|
| 2269 | + |
|---|
| 2270 | +int xhci_vendor_sync_dev_ctx(struct xhci_hcd *xhci, unsigned int slot_id); |
|---|
| 2271 | +bool xhci_vendor_usb_offload_skip_urb(struct xhci_hcd *xhci, struct urb *urb); |
|---|
| 2272 | +void xhci_vendor_free_transfer_ring(struct xhci_hcd *xhci, |
|---|
| 2273 | + struct xhci_virt_device *virt_dev, unsigned int ep_index); |
|---|
| 2274 | +bool xhci_vendor_is_usb_offload_enabled(struct xhci_hcd *xhci, |
|---|
| 2275 | + struct xhci_virt_device *virt_dev, unsigned int ep_index); |
|---|
| 2276 | + |
|---|
| 2277 | +/* |
|---|
| 2278 | + * TODO: As per spec Isochronous IDT transmissions are supported. We bypass |
|---|
| 2279 | + * them anyways as we where unable to find a device that matches the |
|---|
| 2280 | + * constraints. |
|---|
| 2281 | + */ |
|---|
| 2282 | +static inline bool xhci_urb_suitable_for_idt(struct urb *urb) |
|---|
| 2283 | +{ |
|---|
| 2284 | + if (!usb_endpoint_xfer_isoc(&urb->ep->desc) && usb_urb_dir_out(urb) && |
|---|
| 2285 | + usb_endpoint_maxp(&urb->ep->desc) >= TRB_IDT_MAX_SIZE && |
|---|
| 2286 | + urb->transfer_buffer_length <= TRB_IDT_MAX_SIZE && |
|---|
| 2287 | + !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) && |
|---|
| 2288 | + !urb->num_sgs) |
|---|
| 2289 | + return true; |
|---|
| 2290 | + |
|---|
| 2291 | + return false; |
|---|
| 2292 | +} |
|---|
| 2293 | + |
|---|
| 2200 | 2294 | static inline char *xhci_slot_state_string(u32 state) |
|---|
| 2201 | 2295 | { |
|---|
| 2202 | 2296 | switch (state) { |
|---|
| .. | .. |
|---|
| 2213 | 2307 | } |
|---|
| 2214 | 2308 | } |
|---|
| 2215 | 2309 | |
|---|
| 2216 | | -static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
|---|
| 2217 | | - u32 field3) |
|---|
| 2310 | +static inline const char *xhci_decode_trb(char *str, size_t size, |
|---|
| 2311 | + u32 field0, u32 field1, u32 field2, u32 field3) |
|---|
| 2218 | 2312 | { |
|---|
| 2219 | | - static char str[256]; |
|---|
| 2220 | 2313 | int type = TRB_FIELD_TO_TYPE(field3); |
|---|
| 2221 | 2314 | |
|---|
| 2222 | 2315 | switch (type) { |
|---|
| 2223 | 2316 | case TRB_LINK: |
|---|
| 2224 | | - sprintf(str, |
|---|
| 2317 | + snprintf(str, size, |
|---|
| 2225 | 2318 | "LINK %08x%08x intr %d type '%s' flags %c:%c:%c:%c", |
|---|
| 2226 | 2319 | field1, field0, GET_INTR_TARGET(field2), |
|---|
| 2227 | 2320 | xhci_trb_type_string(type), |
|---|
| .. | .. |
|---|
| 2238 | 2331 | case TRB_HC_EVENT: |
|---|
| 2239 | 2332 | case TRB_DEV_NOTE: |
|---|
| 2240 | 2333 | case TRB_MFINDEX_WRAP: |
|---|
| 2241 | | - sprintf(str, |
|---|
| 2334 | + snprintf(str, size, |
|---|
| 2242 | 2335 | "TRB %08x%08x status '%s' len %d slot %d ep %d type '%s' flags %c:%c", |
|---|
| 2243 | 2336 | field1, field0, |
|---|
| 2244 | 2337 | xhci_trb_comp_code_string(GET_COMP_CODE(field2)), |
|---|
| .. | .. |
|---|
| 2251 | 2344 | |
|---|
| 2252 | 2345 | break; |
|---|
| 2253 | 2346 | case TRB_SETUP: |
|---|
| 2254 | | - sprintf(str, "bRequestType %02x bRequest %02x wValue %02x%02x wIndex %02x%02x wLength %d length %d TD size %d intr %d type '%s' flags %c:%c:%c", |
|---|
| 2347 | + snprintf(str, size, |
|---|
| 2348 | + "bRequestType %02x bRequest %02x wValue %02x%02x wIndex %02x%02x wLength %d length %d TD size %d intr %d type '%s' flags %c:%c:%c", |
|---|
| 2255 | 2349 | field0 & 0xff, |
|---|
| 2256 | 2350 | (field0 & 0xff00) >> 8, |
|---|
| 2257 | 2351 | (field0 & 0xff000000) >> 24, |
|---|
| .. | .. |
|---|
| 2268 | 2362 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2269 | 2363 | break; |
|---|
| 2270 | 2364 | case TRB_DATA: |
|---|
| 2271 | | - sprintf(str, "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c:%c:%c:%c", |
|---|
| 2365 | + snprintf(str, size, |
|---|
| 2366 | + "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c:%c:%c:%c", |
|---|
| 2272 | 2367 | field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2), |
|---|
| 2273 | 2368 | GET_INTR_TARGET(field2), |
|---|
| 2274 | 2369 | xhci_trb_type_string(type), |
|---|
| .. | .. |
|---|
| 2281 | 2376 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2282 | 2377 | break; |
|---|
| 2283 | 2378 | case TRB_STATUS: |
|---|
| 2284 | | - sprintf(str, "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c", |
|---|
| 2379 | + snprintf(str, size, |
|---|
| 2380 | + "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c", |
|---|
| 2285 | 2381 | field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2), |
|---|
| 2286 | 2382 | GET_INTR_TARGET(field2), |
|---|
| 2287 | 2383 | xhci_trb_type_string(type), |
|---|
| .. | .. |
|---|
| 2294 | 2390 | case TRB_ISOC: |
|---|
| 2295 | 2391 | case TRB_EVENT_DATA: |
|---|
| 2296 | 2392 | case TRB_TR_NOOP: |
|---|
| 2297 | | - sprintf(str, |
|---|
| 2393 | + snprintf(str, size, |
|---|
| 2298 | 2394 | "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c:%c:%c:%c:%c", |
|---|
| 2299 | 2395 | field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2), |
|---|
| 2300 | 2396 | GET_INTR_TARGET(field2), |
|---|
| .. | .. |
|---|
| 2311 | 2407 | |
|---|
| 2312 | 2408 | case TRB_CMD_NOOP: |
|---|
| 2313 | 2409 | case TRB_ENABLE_SLOT: |
|---|
| 2314 | | - sprintf(str, |
|---|
| 2410 | + snprintf(str, size, |
|---|
| 2315 | 2411 | "%s: flags %c", |
|---|
| 2316 | 2412 | xhci_trb_type_string(type), |
|---|
| 2317 | 2413 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2318 | 2414 | break; |
|---|
| 2319 | 2415 | case TRB_DISABLE_SLOT: |
|---|
| 2320 | 2416 | case TRB_NEG_BANDWIDTH: |
|---|
| 2321 | | - sprintf(str, |
|---|
| 2417 | + snprintf(str, size, |
|---|
| 2322 | 2418 | "%s: slot %d flags %c", |
|---|
| 2323 | 2419 | xhci_trb_type_string(type), |
|---|
| 2324 | 2420 | TRB_TO_SLOT_ID(field3), |
|---|
| 2325 | 2421 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2326 | 2422 | break; |
|---|
| 2327 | 2423 | case TRB_ADDR_DEV: |
|---|
| 2328 | | - sprintf(str, |
|---|
| 2424 | + snprintf(str, size, |
|---|
| 2329 | 2425 | "%s: ctx %08x%08x slot %d flags %c:%c", |
|---|
| 2330 | 2426 | xhci_trb_type_string(type), |
|---|
| 2331 | 2427 | field1, field0, |
|---|
| .. | .. |
|---|
| 2334 | 2430 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2335 | 2431 | break; |
|---|
| 2336 | 2432 | case TRB_CONFIG_EP: |
|---|
| 2337 | | - sprintf(str, |
|---|
| 2433 | + snprintf(str, size, |
|---|
| 2338 | 2434 | "%s: ctx %08x%08x slot %d flags %c:%c", |
|---|
| 2339 | 2435 | xhci_trb_type_string(type), |
|---|
| 2340 | 2436 | field1, field0, |
|---|
| .. | .. |
|---|
| 2343 | 2439 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2344 | 2440 | break; |
|---|
| 2345 | 2441 | case TRB_EVAL_CONTEXT: |
|---|
| 2346 | | - sprintf(str, |
|---|
| 2442 | + snprintf(str, size, |
|---|
| 2347 | 2443 | "%s: ctx %08x%08x slot %d flags %c", |
|---|
| 2348 | 2444 | xhci_trb_type_string(type), |
|---|
| 2349 | 2445 | field1, field0, |
|---|
| .. | .. |
|---|
| 2351 | 2447 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2352 | 2448 | break; |
|---|
| 2353 | 2449 | case TRB_RESET_EP: |
|---|
| 2354 | | - sprintf(str, |
|---|
| 2355 | | - "%s: ctx %08x%08x slot %d ep %d flags %c", |
|---|
| 2450 | + snprintf(str, size, |
|---|
| 2451 | + "%s: ctx %08x%08x slot %d ep %d flags %c:%c", |
|---|
| 2356 | 2452 | xhci_trb_type_string(type), |
|---|
| 2357 | 2453 | field1, field0, |
|---|
| 2358 | 2454 | TRB_TO_SLOT_ID(field3), |
|---|
| 2359 | 2455 | /* Macro decrements 1, maybe it shouldn't?!? */ |
|---|
| 2360 | 2456 | TRB_TO_EP_INDEX(field3) + 1, |
|---|
| 2457 | + field3 & TRB_TSP ? 'T' : 't', |
|---|
| 2361 | 2458 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2362 | 2459 | break; |
|---|
| 2363 | 2460 | case TRB_STOP_RING: |
|---|
| 2364 | | - sprintf(str, |
|---|
| 2461 | + snprintf(str, size, |
|---|
| 2365 | 2462 | "%s: slot %d sp %d ep %d flags %c", |
|---|
| 2366 | 2463 | xhci_trb_type_string(type), |
|---|
| 2367 | 2464 | TRB_TO_SLOT_ID(field3), |
|---|
| .. | .. |
|---|
| 2371 | 2468 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2372 | 2469 | break; |
|---|
| 2373 | 2470 | case TRB_SET_DEQ: |
|---|
| 2374 | | - sprintf(str, |
|---|
| 2471 | + snprintf(str, size, |
|---|
| 2375 | 2472 | "%s: deq %08x%08x stream %d slot %d ep %d flags %c", |
|---|
| 2376 | 2473 | xhci_trb_type_string(type), |
|---|
| 2377 | 2474 | field1, field0, |
|---|
| .. | .. |
|---|
| 2382 | 2479 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2383 | 2480 | break; |
|---|
| 2384 | 2481 | case TRB_RESET_DEV: |
|---|
| 2385 | | - sprintf(str, |
|---|
| 2482 | + snprintf(str, size, |
|---|
| 2386 | 2483 | "%s: slot %d flags %c", |
|---|
| 2387 | 2484 | xhci_trb_type_string(type), |
|---|
| 2388 | 2485 | TRB_TO_SLOT_ID(field3), |
|---|
| 2389 | 2486 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2390 | 2487 | break; |
|---|
| 2391 | 2488 | case TRB_FORCE_EVENT: |
|---|
| 2392 | | - sprintf(str, |
|---|
| 2489 | + snprintf(str, size, |
|---|
| 2393 | 2490 | "%s: event %08x%08x vf intr %d vf id %d flags %c", |
|---|
| 2394 | 2491 | xhci_trb_type_string(type), |
|---|
| 2395 | 2492 | field1, field0, |
|---|
| .. | .. |
|---|
| 2398 | 2495 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2399 | 2496 | break; |
|---|
| 2400 | 2497 | case TRB_SET_LT: |
|---|
| 2401 | | - sprintf(str, |
|---|
| 2498 | + snprintf(str, size, |
|---|
| 2402 | 2499 | "%s: belt %d flags %c", |
|---|
| 2403 | 2500 | xhci_trb_type_string(type), |
|---|
| 2404 | 2501 | TRB_TO_BELT(field3), |
|---|
| 2405 | 2502 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2406 | 2503 | break; |
|---|
| 2407 | 2504 | case TRB_GET_BW: |
|---|
| 2408 | | - sprintf(str, |
|---|
| 2505 | + snprintf(str, size, |
|---|
| 2409 | 2506 | "%s: ctx %08x%08x slot %d speed %d flags %c", |
|---|
| 2410 | 2507 | xhci_trb_type_string(type), |
|---|
| 2411 | 2508 | field1, field0, |
|---|
| .. | .. |
|---|
| 2414 | 2511 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2415 | 2512 | break; |
|---|
| 2416 | 2513 | case TRB_FORCE_HEADER: |
|---|
| 2417 | | - sprintf(str, |
|---|
| 2514 | + snprintf(str, size, |
|---|
| 2418 | 2515 | "%s: info %08x%08x%08x pkt type %d roothub port %d flags %c", |
|---|
| 2419 | 2516 | xhci_trb_type_string(type), |
|---|
| 2420 | 2517 | field2, field1, field0 & 0xffffffe0, |
|---|
| .. | .. |
|---|
| 2423 | 2520 | field3 & TRB_CYCLE ? 'C' : 'c'); |
|---|
| 2424 | 2521 | break; |
|---|
| 2425 | 2522 | default: |
|---|
| 2426 | | - sprintf(str, |
|---|
| 2523 | + snprintf(str, size, |
|---|
| 2427 | 2524 | "type '%s' -> raw %08x %08x %08x %08x", |
|---|
| 2428 | 2525 | xhci_trb_type_string(type), |
|---|
| 2429 | 2526 | field0, field1, field2, field3); |
|---|
| .. | .. |
|---|
| 2432 | 2529 | return str; |
|---|
| 2433 | 2530 | } |
|---|
| 2434 | 2531 | |
|---|
| 2435 | | -static inline const char *xhci_decode_slot_context(u32 info, u32 info2, |
|---|
| 2436 | | - u32 tt_info, u32 state) |
|---|
| 2532 | +static inline const char *xhci_decode_ctrl_ctx(char *str, |
|---|
| 2533 | + unsigned long drop, unsigned long add) |
|---|
| 2437 | 2534 | { |
|---|
| 2438 | | - static char str[1024]; |
|---|
| 2535 | + unsigned int bit; |
|---|
| 2536 | + int ret = 0; |
|---|
| 2537 | + |
|---|
| 2538 | + str[0] = '\0'; |
|---|
| 2539 | + |
|---|
| 2540 | + if (drop) { |
|---|
| 2541 | + ret = sprintf(str, "Drop:"); |
|---|
| 2542 | + for_each_set_bit(bit, &drop, 32) |
|---|
| 2543 | + ret += sprintf(str + ret, " %d%s", |
|---|
| 2544 | + bit / 2, |
|---|
| 2545 | + bit % 2 ? "in":"out"); |
|---|
| 2546 | + ret += sprintf(str + ret, ", "); |
|---|
| 2547 | + } |
|---|
| 2548 | + |
|---|
| 2549 | + if (add) { |
|---|
| 2550 | + ret += sprintf(str + ret, "Add:%s%s", |
|---|
| 2551 | + (add & SLOT_FLAG) ? " slot":"", |
|---|
| 2552 | + (add & EP0_FLAG) ? " ep0":""); |
|---|
| 2553 | + add &= ~(SLOT_FLAG | EP0_FLAG); |
|---|
| 2554 | + for_each_set_bit(bit, &add, 32) |
|---|
| 2555 | + ret += sprintf(str + ret, " %d%s", |
|---|
| 2556 | + bit / 2, |
|---|
| 2557 | + bit % 2 ? "in":"out"); |
|---|
| 2558 | + } |
|---|
| 2559 | + return str; |
|---|
| 2560 | +} |
|---|
| 2561 | + |
|---|
| 2562 | +static inline const char *xhci_decode_slot_context(char *str, |
|---|
| 2563 | + u32 info, u32 info2, u32 tt_info, u32 state) |
|---|
| 2564 | +{ |
|---|
| 2439 | 2565 | u32 speed; |
|---|
| 2440 | 2566 | u32 hub; |
|---|
| 2441 | 2567 | u32 mtt; |
|---|
| .. | .. |
|---|
| 2519 | 2645 | return "Unknown"; |
|---|
| 2520 | 2646 | } |
|---|
| 2521 | 2647 | |
|---|
| 2522 | | -static inline const char *xhci_decode_portsc(u32 portsc) |
|---|
| 2648 | +static inline const char *xhci_decode_portsc(char *str, u32 portsc) |
|---|
| 2523 | 2649 | { |
|---|
| 2524 | | - static char str[256]; |
|---|
| 2525 | 2650 | int ret; |
|---|
| 2526 | 2651 | |
|---|
| 2527 | 2652 | ret = sprintf(str, "%s %s %s Link:%s PortSpeed:%d ", |
|---|
| .. | .. |
|---|
| 2561 | 2686 | ret += sprintf(str + ret, "WDE "); |
|---|
| 2562 | 2687 | if (portsc & PORT_WKOC_E) |
|---|
| 2563 | 2688 | ret += sprintf(str + ret, "WOE "); |
|---|
| 2689 | + |
|---|
| 2690 | + return str; |
|---|
| 2691 | +} |
|---|
| 2692 | + |
|---|
| 2693 | +static inline const char *xhci_decode_usbsts(char *str, u32 usbsts) |
|---|
| 2694 | +{ |
|---|
| 2695 | + int ret = 0; |
|---|
| 2696 | + |
|---|
| 2697 | + ret = sprintf(str, " 0x%08x", usbsts); |
|---|
| 2698 | + |
|---|
| 2699 | + if (usbsts == ~(u32)0) |
|---|
| 2700 | + return str; |
|---|
| 2701 | + |
|---|
| 2702 | + if (usbsts & STS_HALT) |
|---|
| 2703 | + ret += sprintf(str + ret, " HCHalted"); |
|---|
| 2704 | + if (usbsts & STS_FATAL) |
|---|
| 2705 | + ret += sprintf(str + ret, " HSE"); |
|---|
| 2706 | + if (usbsts & STS_EINT) |
|---|
| 2707 | + ret += sprintf(str + ret, " EINT"); |
|---|
| 2708 | + if (usbsts & STS_PORT) |
|---|
| 2709 | + ret += sprintf(str + ret, " PCD"); |
|---|
| 2710 | + if (usbsts & STS_SAVE) |
|---|
| 2711 | + ret += sprintf(str + ret, " SSS"); |
|---|
| 2712 | + if (usbsts & STS_RESTORE) |
|---|
| 2713 | + ret += sprintf(str + ret, " RSS"); |
|---|
| 2714 | + if (usbsts & STS_SRE) |
|---|
| 2715 | + ret += sprintf(str + ret, " SRE"); |
|---|
| 2716 | + if (usbsts & STS_CNR) |
|---|
| 2717 | + ret += sprintf(str + ret, " CNR"); |
|---|
| 2718 | + if (usbsts & STS_HCE) |
|---|
| 2719 | + ret += sprintf(str + ret, " HCE"); |
|---|
| 2720 | + |
|---|
| 2721 | + return str; |
|---|
| 2722 | +} |
|---|
| 2723 | + |
|---|
| 2724 | +static inline const char *xhci_decode_doorbell(char *str, u32 slot, u32 doorbell) |
|---|
| 2725 | +{ |
|---|
| 2726 | + u8 ep; |
|---|
| 2727 | + u16 stream; |
|---|
| 2728 | + int ret; |
|---|
| 2729 | + |
|---|
| 2730 | + ep = (doorbell & 0xff); |
|---|
| 2731 | + stream = doorbell >> 16; |
|---|
| 2732 | + |
|---|
| 2733 | + if (slot == 0) { |
|---|
| 2734 | + sprintf(str, "Command Ring %d", doorbell); |
|---|
| 2735 | + return str; |
|---|
| 2736 | + } |
|---|
| 2737 | + ret = sprintf(str, "Slot %d ", slot); |
|---|
| 2738 | + if (ep > 0 && ep < 32) |
|---|
| 2739 | + ret = sprintf(str + ret, "ep%d%s", |
|---|
| 2740 | + ep / 2, |
|---|
| 2741 | + ep % 2 ? "in" : "out"); |
|---|
| 2742 | + else if (ep == 0 || ep < 248) |
|---|
| 2743 | + ret = sprintf(str + ret, "Reserved %d", ep); |
|---|
| 2744 | + else |
|---|
| 2745 | + ret = sprintf(str + ret, "Vendor Defined %d", ep); |
|---|
| 2746 | + if (stream) |
|---|
| 2747 | + ret = sprintf(str + ret, " Stream %d", stream); |
|---|
| 2564 | 2748 | |
|---|
| 2565 | 2749 | return str; |
|---|
| 2566 | 2750 | } |
|---|
| .. | .. |
|---|
| 2605 | 2789 | } |
|---|
| 2606 | 2790 | } |
|---|
| 2607 | 2791 | |
|---|
| 2608 | | -static inline const char *xhci_decode_ep_context(u32 info, u32 info2, u64 deq, |
|---|
| 2609 | | - u32 tx_info) |
|---|
| 2792 | +static inline const char *xhci_decode_ep_context(char *str, u32 info, |
|---|
| 2793 | + u32 info2, u64 deq, u32 tx_info) |
|---|
| 2610 | 2794 | { |
|---|
| 2611 | | - static char str[1024]; |
|---|
| 2612 | 2795 | int ret; |
|---|
| 2613 | 2796 | |
|---|
| 2614 | 2797 | u32 esit; |
|---|