diff options
Diffstat (limited to 'drivers/usb/host/xhci.h')
-rw-r--r-- | drivers/usb/host/xhci.h | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 652dc36e3012..a450a99e90eb 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -452,6 +452,14 @@ struct xhci_op_regs { */ #define XHCI_DEFAULT_BESL 4 +/* + * USB3 specification define a 360ms tPollingLFPSTiemout for USB3 ports + * to complete link training. usually link trainig completes much faster + * so check status 10 times with 36ms sleep in places we need to wait for + * polling to complete. + */ +#define XHCI_PORT_POLLING_LFPS_TIME 36 + /** * struct xhci_intr_reg - Interrupt Register Set * @irq_pending: IMAN - Interrupt Management Register. Used to enable @@ -1295,6 +1303,8 @@ enum xhci_setup_dev { #define TRB_IOC (1<<5) /* The buffer pointer contains immediate data */ #define TRB_IDT (1<<6) +/* TDs smaller than this might use IDT */ +#define TRB_IDT_MAX_SIZE 8 /* Block Event Interrupt */ #define TRB_BEI (1<<9) @@ -2141,6 +2151,21 @@ static inline struct xhci_ring *xhci_urb_to_transfer_ring(struct xhci_hcd *xhci, urb->stream_id); } +/* + * TODO: As per spec Isochronous IDT transmissions are supported. We bypass + * them anyways as we where unable to find a device that matches the + * constraints. + */ +static inline bool xhci_urb_suitable_for_idt(struct urb *urb) +{ + if (!usb_endpoint_xfer_isoc(&urb->ep->desc) && usb_urb_dir_out(urb) && + usb_endpoint_maxp(&urb->ep->desc) >= TRB_IDT_MAX_SIZE && + urb->transfer_buffer_length <= TRB_IDT_MAX_SIZE) + return true; + + return false; +} + static inline char *xhci_slot_state_string(u32 state) { switch (state) { @@ -2376,6 +2401,35 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, return str; } +static inline const char *xhci_decode_ctrl_ctx(unsigned long drop, + unsigned long add) +{ + static char str[1024]; + unsigned int bit; + int ret = 0; + + if (drop) { + ret = sprintf(str, "Drop:"); + for_each_set_bit(bit, &drop, 32) + ret += sprintf(str + ret, " %d%s", + bit / 2, + bit % 2 ? "in":"out"); + ret += sprintf(str + ret, ", "); + } + + if (add) { + ret += sprintf(str + ret, "Add:%s%s", + (add & SLOT_FLAG) ? " slot":"", + (add & EP0_FLAG) ? " ep0":""); + add &= ~(SLOT_FLAG | EP0_FLAG); + for_each_set_bit(bit, &add, 32) + ret += sprintf(str + ret, " %d%s", + bit / 2, + bit % 2 ? "in":"out"); + } + return str; +} + static inline const char *xhci_decode_slot_context(u32 info, u32 info2, u32 tt_info, u32 state) { |