aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/usb/host/xhci.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci.h')
-rw-r--r--drivers/usb/host/xhci.h333
1 files changed, 228 insertions, 105 deletions
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index da3eb695fe54..73a28a986d5e 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -425,6 +425,7 @@ struct xhci_op_regs {
#define PORT_L1DS_MASK (0xff << 8)
#define PORT_L1DS(p) (((p) & 0xff) << 8)
#define PORT_HLE (1 << 16)
+#define PORT_TEST_MODE_SHIFT 28
/* USB3 Protocol PORTLI Port Link Information */
#define PORT_RX_LANES(p) (((p) >> 16) & 0xf)
@@ -617,6 +618,7 @@ struct xhci_slot_ctx {
#define ROUTE_STRING_MASK (0xfffff)
/* Device speed - values defined by PORTSC Device Speed field - 20:23 */
#define DEV_SPEED (0xf << 20)
+#define GET_DEV_SPEED(n) (((n) & DEV_SPEED) >> 20)
/* bit 24 reserved */
/* Is this LS/FS device connected through a HS hub? - bit 25 */
#define DEV_MTT (0x1 << 25)
@@ -637,6 +639,7 @@ struct xhci_slot_ctx {
#define DEVINFO_TO_ROOT_HUB_PORT(p) (((p) >> 16) & 0xff)
/* Maximum number of ports under a hub device */
#define XHCI_MAX_PORTS(p) (((p) & 0xff) << 24)
+#define DEVINFO_TO_MAX_PORTS(p) (((p) & (0xff << 24)) >> 24)
/* tt_info bitmasks */
/*
@@ -651,6 +654,7 @@ struct xhci_slot_ctx {
*/
#define TT_PORT (0xff << 8)
#define TT_THINK_TIME(p) (((p) & 0x3) << 16)
+#define GET_TT_THINK_TIME(p) (((p) & (0x3 << 16)) >> 16)
/* dev_state bitmasks */
/* USB device address - assigned by the HC */
@@ -1562,10 +1566,8 @@ struct xhci_ring {
struct xhci_segment *last_seg;
union xhci_trb *enqueue;
struct xhci_segment *enq_seg;
- unsigned int enq_updates;
union xhci_trb *dequeue;
struct xhci_segment *deq_seg;
- unsigned int deq_updates;
struct list_head td_list;
/*
* Write the cycle state into the TRB cycle field to give ownership of
@@ -1604,7 +1606,6 @@ struct xhci_scratchpad {
u64 *sp_array;
dma_addr_t sp_dma;
void **sp_buffers;
- dma_addr_t *sp_dma_buffers;
};
struct urb_priv {
@@ -1722,7 +1723,6 @@ struct xhci_hcd {
int page_shift;
/* msi-x vectors */
int msix_count;
- struct msix_entry *msix_entries;
/* optional clock */
struct clk *clk;
/* data structures */
@@ -1818,6 +1818,7 @@ struct xhci_hcd {
#define XHCI_MISSING_CAS (1 << 24)
/* For controller with a broken Port Disable implementation */
#define XHCI_BROKEN_PORT_PED (1 << 25)
+#define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26)
unsigned int num_active_eps;
unsigned int limit_active_eps;
@@ -1843,6 +1844,7 @@ struct xhci_hcd {
/* Compliance Mode Recovery Data */
struct timer_list comp_mode_recovery_timer;
u32 port_status_u0;
+ u16 test_mode;
/* Compliance Mode Timer Triggered every 2 seconds */
#define COMP_MODE_RCVRY_MSECS 2000
@@ -1918,19 +1920,10 @@ void xhci_print_ir_set(struct xhci_hcd *xhci, int set_num);
void xhci_print_registers(struct xhci_hcd *xhci);
void xhci_dbg_regs(struct xhci_hcd *xhci);
void xhci_print_run_regs(struct xhci_hcd *xhci);
-void xhci_print_trb_offsets(struct xhci_hcd *xhci, union xhci_trb *trb);
-void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb);
-void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg);
-void xhci_debug_ring(struct xhci_hcd *xhci, struct xhci_ring *ring);
void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst);
void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci);
-void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring);
-void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int last_ep);
char *xhci_get_slot_state(struct xhci_hcd *xhci,
struct xhci_container_ctx *ctx);
-void xhci_dbg_ep_rings(struct xhci_hcd *xhci,
- unsigned int slot_id, unsigned int ep_index,
- struct xhci_virt_ep *ep);
void xhci_dbg_trace(struct xhci_hcd *xhci, void (*trace)(struct va_format *),
const char *fmt, ...);
@@ -1944,16 +1937,8 @@ void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci,
struct usb_device *udev);
unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc);
unsigned int xhci_get_endpoint_address(unsigned int ep_index);
-unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc);
-unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index);
unsigned int xhci_last_valid_endpoint(u32 added_ctxs);
void xhci_endpoint_zero(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_host_endpoint *ep);
-void xhci_drop_ep_from_interval_table(struct xhci_hcd *xhci,
- struct xhci_bw_info *ep_bw,
- struct xhci_interval_bw_table *bw_table,
- struct usb_device *udev,
- struct xhci_virt_ep *virt_ep,
- struct xhci_tt_bw_info *tt_info);
void xhci_update_tt_active_eps(struct xhci_hcd *xhci,
struct xhci_virt_device *virt_dev,
int old_active_eps);
@@ -2010,53 +1995,25 @@ typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *);
int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec);
void xhci_quiesce(struct xhci_hcd *xhci);
int xhci_halt(struct xhci_hcd *xhci);
+int xhci_start(struct xhci_hcd *xhci);
int xhci_reset(struct xhci_hcd *xhci);
-int xhci_init(struct usb_hcd *hcd);
int xhci_run(struct usb_hcd *hcd);
-void xhci_stop(struct usb_hcd *hcd);
-void xhci_shutdown(struct usb_hcd *hcd);
int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks);
void xhci_init_driver(struct hc_driver *drv,
const struct xhci_driver_overrides *over);
+int xhci_disable_slot(struct xhci_hcd *xhci,
+ struct xhci_command *command, u32 slot_id);
-#ifdef CONFIG_PM
int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup);
int xhci_resume(struct xhci_hcd *xhci, bool hibernated);
-#else
-#define xhci_suspend NULL
-#define xhci_resume NULL
-#endif
-int xhci_get_frame(struct usb_hcd *hcd);
irqreturn_t xhci_irq(struct usb_hcd *hcd);
irqreturn_t xhci_msi_irq(int irq, void *hcd);
int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev);
-void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev);
int xhci_alloc_tt_info(struct xhci_hcd *xhci,
struct xhci_virt_device *virt_dev,
struct usb_device *hdev,
struct usb_tt *tt, gfp_t mem_flags);
-int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev,
- struct usb_host_endpoint **eps, unsigned int num_eps,
- unsigned int num_streams, gfp_t mem_flags);
-int xhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev,
- struct usb_host_endpoint **eps, unsigned int num_eps,
- gfp_t mem_flags);
-int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev);
-int xhci_enable_device(struct usb_hcd *hcd, struct usb_device *udev);
-int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev);
-int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
- struct usb_device *udev, int enable);
-int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
- struct usb_tt *tt, gfp_t mem_flags);
-int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags);
-int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
-int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep);
-int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep);
-void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
-int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev);
-int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
-void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
/* xHCI ring, segment, TRB, and TD functions */
dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb);
@@ -2100,9 +2057,6 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
struct xhci_dequeue_state *deq_state);
void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
unsigned int ep_index, struct xhci_td *td);
-void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci,
- unsigned int slot_id, unsigned int ep_index,
- struct xhci_dequeue_state *deq_state);
void xhci_stop_endpoint_command_watchdog(unsigned long arg);
void xhci_handle_command_timeout(struct work_struct *work);
@@ -2113,16 +2067,13 @@ void xhci_cleanup_command_queue(struct xhci_hcd *xhci);
/* xHCI roothub code */
void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array,
int port_id, u32 link_state);
-int xhci_enable_usb3_lpm_timeout(struct usb_hcd *hcd,
- struct usb_device *udev, enum usb3_link_state state);
-int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
- struct usb_device *udev, enum usb3_link_state state);
void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array,
int port_id, u32 port_bit);
int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,
char *buf, u16 wLength);
int xhci_hub_status_data(struct usb_hcd *hcd, char *buf);
int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1);
+void xhci_hc_died(struct xhci_hcd *xhci);
#ifdef CONFIG_PM
int xhci_bus_suspend(struct usb_hcd *hcd);
@@ -2153,6 +2104,22 @@ static inline struct xhci_ring *xhci_urb_to_transfer_ring(struct xhci_hcd *xhci,
urb->stream_id);
}
+static inline char *xhci_slot_state_string(u32 state)
+{
+ switch (state) {
+ case SLOT_STATE_ENABLED:
+ return "enabled/disabled";
+ case SLOT_STATE_DEFAULT:
+ return "default";
+ case SLOT_STATE_ADDRESSED:
+ return "addressed";
+ case SLOT_STATE_CONFIGURED:
+ return "configured";
+ default:
+ return "reserved";
+ }
+}
+
static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
u32 field3)
{
@@ -2162,14 +2129,12 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
switch (type) {
case TRB_LINK:
sprintf(str,
- "TRB %08x%08x status '%s' len %d slot %d ep %d type '%s' flags %c:%c",
- field1, field0,
- xhci_trb_comp_code_string(GET_COMP_CODE(field2)),
- EVENT_TRB_LEN(field2), TRB_TO_SLOT_ID(field3),
- /* Macro decrements 1, maybe it shouldn't?!? */
- TRB_TO_EP_INDEX(field3) + 1,
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
- field3 & EVENT_DATA ? 'E' : 'e',
+ "LINK %08x%08x intr %d type '%s' flags %c:%c:%c:%c",
+ field1, field0, GET_INTR_TARGET(field2),
+ xhci_trb_type_string(type),
+ field3 & TRB_IOC ? 'I' : 'i',
+ field3 & TRB_CHAIN ? 'C' : 'c',
+ field3 & TRB_TC ? 'T' : 't',
field3 & TRB_CYCLE ? 'C' : 'c');
break;
case TRB_TRANSFER:
@@ -2187,37 +2152,52 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
EVENT_TRB_LEN(field2), TRB_TO_SLOT_ID(field3),
/* Macro decrements 1, maybe it shouldn't?!? */
TRB_TO_EP_INDEX(field3) + 1,
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
field3 & EVENT_DATA ? 'E' : 'e',
field3 & TRB_CYCLE ? 'C' : 'c');
break;
case TRB_SETUP:
- 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:%c:%c:%c:%c:%c",
- field0 & 0xff,
- (field0 & 0xff00) >> 8,
- (field0 & 0xff000000) >> 24,
- (field0 & 0xff0000) >> 16,
- (field1 & 0xff00) >> 8,
- field1 & 0xff,
- (field1 & 0xff000000) >> 16 |
- (field1 & 0xff0000) >> 16,
- TRB_LEN(field2), GET_TD_SIZE(field2),
- GET_INTR_TARGET(field2),
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
- field3 & TRB_BEI ? 'B' : 'b',
- field3 & TRB_IDT ? 'I' : 'i',
- field3 & TRB_IOC ? 'I' : 'i',
- field3 & TRB_CHAIN ? 'C' : 'c',
- field3 & TRB_NO_SNOOP ? 'S' : 's',
- field3 & TRB_ISP ? 'I' : 'i',
- field3 & TRB_ENT ? 'E' : 'e',
- field3 & TRB_CYCLE ? 'C' : 'c');
+ 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",
+ field0 & 0xff,
+ (field0 & 0xff00) >> 8,
+ (field0 & 0xff000000) >> 24,
+ (field0 & 0xff0000) >> 16,
+ (field1 & 0xff00) >> 8,
+ field1 & 0xff,
+ (field1 & 0xff000000) >> 16 |
+ (field1 & 0xff0000) >> 16,
+ TRB_LEN(field2), GET_TD_SIZE(field2),
+ GET_INTR_TARGET(field2),
+ xhci_trb_type_string(type),
+ field3 & TRB_IDT ? 'I' : 'i',
+ field3 & TRB_IOC ? 'I' : 'i',
+ field3 & TRB_CYCLE ? 'C' : 'c');
break;
- case TRB_NORMAL:
case TRB_DATA:
+ sprintf(str, "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c:%c:%c:%c",
+ field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2),
+ GET_INTR_TARGET(field2),
+ xhci_trb_type_string(type),
+ field3 & TRB_IDT ? 'I' : 'i',
+ field3 & TRB_IOC ? 'I' : 'i',
+ field3 & TRB_CHAIN ? 'C' : 'c',
+ field3 & TRB_NO_SNOOP ? 'S' : 's',
+ field3 & TRB_ISP ? 'I' : 'i',
+ field3 & TRB_ENT ? 'E' : 'e',
+ field3 & TRB_CYCLE ? 'C' : 'c');
+ break;
case TRB_STATUS:
+ sprintf(str, "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c",
+ field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2),
+ GET_INTR_TARGET(field2),
+ xhci_trb_type_string(type),
+ field3 & TRB_IOC ? 'I' : 'i',
+ field3 & TRB_CHAIN ? 'C' : 'c',
+ field3 & TRB_ENT ? 'E' : 'e',
+ field3 & TRB_CYCLE ? 'C' : 'c');
+ break;
+ case TRB_NORMAL:
case TRB_ISOC:
case TRB_EVENT_DATA:
case TRB_TR_NOOP:
@@ -2225,7 +2205,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
"Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c:%c:%c:%c:%c",
field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2),
GET_INTR_TARGET(field2),
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
field3 & TRB_BEI ? 'B' : 'b',
field3 & TRB_IDT ? 'I' : 'i',
field3 & TRB_IOC ? 'I' : 'i',
@@ -2240,21 +2220,21 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
case TRB_ENABLE_SLOT:
sprintf(str,
"%s: flags %c",
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
field3 & TRB_CYCLE ? 'C' : 'c');
break;
case TRB_DISABLE_SLOT:
case TRB_NEG_BANDWIDTH:
sprintf(str,
"%s: slot %d flags %c",
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
TRB_TO_SLOT_ID(field3),
field3 & TRB_CYCLE ? 'C' : 'c');
break;
case TRB_ADDR_DEV:
sprintf(str,
"%s: ctx %08x%08x slot %d flags %c:%c",
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
field1, field0,
TRB_TO_SLOT_ID(field3),
field3 & TRB_BSR ? 'B' : 'b',
@@ -2263,7 +2243,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
case TRB_CONFIG_EP:
sprintf(str,
"%s: ctx %08x%08x slot %d flags %c:%c",
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
field1, field0,
TRB_TO_SLOT_ID(field3),
field3 & TRB_DC ? 'D' : 'd',
@@ -2272,7 +2252,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
case TRB_EVAL_CONTEXT:
sprintf(str,
"%s: ctx %08x%08x slot %d flags %c",
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
field1, field0,
TRB_TO_SLOT_ID(field3),
field3 & TRB_CYCLE ? 'C' : 'c');
@@ -2280,7 +2260,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
case TRB_RESET_EP:
sprintf(str,
"%s: ctx %08x%08x slot %d ep %d flags %c",
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
field1, field0,
TRB_TO_SLOT_ID(field3),
/* Macro decrements 1, maybe it shouldn't?!? */
@@ -2290,7 +2270,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
case TRB_STOP_RING:
sprintf(str,
"%s: slot %d sp %d ep %d flags %c",
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
TRB_TO_SLOT_ID(field3),
TRB_TO_SUSPEND_PORT(field3),
/* Macro decrements 1, maybe it shouldn't?!? */
@@ -2300,7 +2280,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
case TRB_SET_DEQ:
sprintf(str,
"%s: deq %08x%08x stream %d slot %d ep %d flags %c",
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
field1, field0,
TRB_TO_STREAM_ID(field2),
TRB_TO_SLOT_ID(field3),
@@ -2311,14 +2291,14 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
case TRB_RESET_DEV:
sprintf(str,
"%s: slot %d flags %c",
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
TRB_TO_SLOT_ID(field3),
field3 & TRB_CYCLE ? 'C' : 'c');
break;
case TRB_FORCE_EVENT:
sprintf(str,
"%s: event %08x%08x vf intr %d vf id %d flags %c",
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
field1, field0,
TRB_TO_VF_INTR_TARGET(field2),
TRB_TO_VF_ID(field3),
@@ -2327,14 +2307,14 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
case TRB_SET_LT:
sprintf(str,
"%s: belt %d flags %c",
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
TRB_TO_BELT(field3),
field3 & TRB_CYCLE ? 'C' : 'c');
break;
case TRB_GET_BW:
sprintf(str,
"%s: ctx %08x%08x slot %d speed %d flags %c",
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
field1, field0,
TRB_TO_SLOT_ID(field3),
TRB_TO_DEV_SPEED(field3),
@@ -2343,7 +2323,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
case TRB_FORCE_HEADER:
sprintf(str,
"%s: info %08x%08x%08x pkt type %d roothub port %d flags %c",
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
field2, field1, field0 & 0xffffffe0,
TRB_TO_PACKET_TYPE(field0),
TRB_TO_ROOTHUB_PORT(field3),
@@ -2352,12 +2332,155 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
default:
sprintf(str,
"type '%s' -> raw %08x %08x %08x %08x",
- xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
+ xhci_trb_type_string(type),
field0, field1, field2, field3);
}
return str;
}
+static inline const char *xhci_decode_slot_context(u32 info, u32 info2,
+ u32 tt_info, u32 state)
+{
+ static char str[1024];
+ u32 speed;
+ u32 hub;
+ u32 mtt;
+ int ret = 0;
+
+ speed = info & DEV_SPEED;
+ hub = info & DEV_HUB;
+ mtt = info & DEV_MTT;
+
+ ret = sprintf(str, "RS %05x %s%s%s Ctx Entries %d MEL %d us Port# %d/%d",
+ info & ROUTE_STRING_MASK,
+ ({ char *s;
+ switch (speed) {
+ case SLOT_SPEED_FS:
+ s = "full-speed";
+ break;
+ case SLOT_SPEED_LS:
+ s = "low-speed";
+ break;
+ case SLOT_SPEED_HS:
+ s = "high-speed";
+ break;
+ case SLOT_SPEED_SS:
+ s = "super-speed";
+ break;
+ case SLOT_SPEED_SSP:
+ s = "super-speed plus";
+ break;
+ default:
+ s = "UNKNOWN speed";
+ } s; }),
+ mtt ? " multi-TT" : "",
+ hub ? " Hub" : "",
+ (info & LAST_CTX_MASK) >> 27,
+ info2 & MAX_EXIT,
+ DEVINFO_TO_ROOT_HUB_PORT(info2),
+ DEVINFO_TO_MAX_PORTS(info2));
+
+ ret += sprintf(str + ret, " [TT Slot %d Port# %d TTT %d Intr %d] Addr %d State %s",
+ tt_info & TT_SLOT, (tt_info & TT_PORT) >> 8,
+ GET_TT_THINK_TIME(tt_info), GET_INTR_TARGET(tt_info),
+ state & DEV_ADDR_MASK,
+ xhci_slot_state_string(GET_SLOT_STATE(state)));
+
+ return str;
+}
+
+static inline const char *xhci_ep_state_string(u8 state)
+{
+ switch (state) {
+ case EP_STATE_DISABLED:
+ return "disabled";
+ case EP_STATE_RUNNING:
+ return "running";
+ case EP_STATE_HALTED:
+ return "halted";
+ case EP_STATE_STOPPED:
+ return "stopped";
+ case EP_STATE_ERROR:
+ return "error";
+ default:
+ return "INVALID";
+ }
+}
+
+static inline const char *xhci_ep_type_string(u8 type)
+{
+ switch (type) {
+ case ISOC_OUT_EP:
+ return "Isoc OUT";
+ case BULK_OUT_EP:
+ return "Bulk OUT";
+ case INT_OUT_EP:
+ return "Int OUT";
+ case CTRL_EP:
+ return "Ctrl";
+ case ISOC_IN_EP:
+ return "Isoc IN";
+ case BULK_IN_EP:
+ return "Bulk IN";
+ case INT_IN_EP:
+ return "Int IN";
+ default:
+ return "INVALID";
+ }
+}
+
+static inline const char *xhci_decode_ep_context(u32 info, u32 info2, u64 deq,
+ u32 tx_info)
+{
+ static char str[1024];
+ int ret;
+
+ u32 esit;
+ u16 maxp;
+ u16 avg;
+
+ u8 max_pstr;
+ u8 ep_state;
+ u8 interval;
+ u8 ep_type;
+ u8 burst;
+ u8 cerr;
+ u8 mult;
+ u8 lsa;
+ u8 hid;
+
+ esit = EP_MAX_ESIT_PAYLOAD_HI(info) << 16 |
+ EP_MAX_ESIT_PAYLOAD_LO(tx_info);
+
+ ep_state = info & EP_STATE_MASK;
+ max_pstr = info & EP_MAXPSTREAMS_MASK;
+ interval = CTX_TO_EP_INTERVAL(info);
+ mult = CTX_TO_EP_MULT(info) + 1;
+ lsa = info & EP_HAS_LSA;
+
+ cerr = (info2 & (3 << 1)) >> 1;
+ ep_type = CTX_TO_EP_TYPE(info2);
+ hid = info2 & (1 << 7);
+ burst = CTX_TO_MAX_BURST(info2);
+ maxp = MAX_PACKET_DECODED(info2);
+
+ avg = EP_AVG_TRB_LENGTH(tx_info);
+
+ ret = sprintf(str, "State %s mult %d max P. Streams %d %s",
+ xhci_ep_state_string(ep_state), mult,
+ max_pstr, lsa ? "LSA " : "");
+
+ ret += sprintf(str + ret, "interval %d us max ESIT payload %d CErr %d ",
+ (1 << interval) * 125, esit, cerr);
+
+ ret += sprintf(str + ret, "Type %s %sburst %d maxp %d deq %016llx ",
+ xhci_ep_type_string(ep_type), hid ? "HID" : "",
+ burst, maxp, deq);
+
+ ret += sprintf(str + ret, "avg trb len %d", avg);
+
+ return str;
+}
#endif /* __LINUX_XHCI_HCD_H */