Re: [PATCH 30/37] usb: host: xhci: make a generic TRB tracer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 12/29/2016 07:01 PM, Felipe Balbi wrote:
> instead of having a tracer that can only trace command completions,
> let's promote this tracer so it can trace and decode any TRB.
>
> With that, it will be easier to extrapolate the lifetime of any TRB
> which might help debugging certain issues.
>
> Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx>
> ---
>  drivers/usb/host/xhci-ring.c  |  14 +-
>  drivers/usb/host/xhci-trace.h |  55 +++++---
>  drivers/usb/host/xhci.h       | 311 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 357 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
> index 393c64f8acef..0ee7d358b812 100644
> --- a/drivers/usb/host/xhci-ring.c
> +++ b/drivers/usb/host/xhci-ring.c
> @@ -1346,6 +1346,9 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
>  
>  	cmd_dma = le64_to_cpu(event->cmd_trb);
>  	cmd_trb = xhci->cmd_ring->dequeue;
> +
> +	trace_xhci_handle_command(xhci->cmd_ring, &cmd_trb->generic);
> +

This is duplicated with trace_xhci_handle_event().

>  	cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
>  			cmd_trb);
>  	/*
> @@ -1362,8 +1365,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
>  
>  	del_timer(&xhci->cmd_timer);
>  
> -	trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event);
> -
>  	cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event->status));
>  
>  	/* If CMD ring stopped we own the trbs between enqueue and dequeue */
> @@ -2407,6 +2408,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
>  
>  		ep_trb = &ep_seg->trbs[(ep_trb_dma - ep_seg->dma) /
>  						sizeof(*ep_trb)];
> +
> +		trace_xhci_handle_transfer(ep_ring,
> +				(struct xhci_generic_trb *) ep_trb);
> +

This is duplicated with trace_xhci_handle_event().

>  		/*
>  		 * No-op TRB should not trigger interrupts.
>  		 * If ep_trb is a no-op TRB, it means the
> @@ -2475,6 +2480,8 @@ static int xhci_handle_event(struct xhci_hcd *xhci)
>  	    xhci->event_ring->cycle_state)
>  		return 0;
>  
> +	trace_xhci_handle_event(xhci->event_ring, &event->generic);
> +
>  	/*
>  	 * Barrier between reading the TRB_CYCLE (valid) flag above and any
>  	 * speculative reads of the event's flags/data below.
> @@ -2642,6 +2649,9 @@ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring,
>  	trb->field[1] = cpu_to_le32(field2);
>  	trb->field[2] = cpu_to_le32(field3);
>  	trb->field[3] = cpu_to_le32(field4);
> +
> +	trace_xhci_queue_trb(ring, trb);
> +
>  	inc_enq(xhci, ring, more_trbs_coming);
>  }
>  
> diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
> index 59c05653b2ea..d01524b9fb14 100644
> --- a/drivers/usb/host/xhci-trace.h
> +++ b/drivers/usb/host/xhci-trace.h
> @@ -115,34 +115,47 @@ DEFINE_EVENT(xhci_log_ctx, xhci_address_ctx,
>  	TP_ARGS(xhci, ctx, ep_num)
>  );
>  
> -DECLARE_EVENT_CLASS(xhci_log_event,
> -	TP_PROTO(void *trb_va, struct xhci_generic_trb *ev),
> -	TP_ARGS(trb_va, ev),
> +DECLARE_EVENT_CLASS(xhci_log_trb,
> +	TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb),
> +	TP_ARGS(ring, trb),
>  	TP_STRUCT__entry(
> -		__field(void *, va)
> -		__field(u64, dma)
> -		__field(u32, status)
> -		__field(u32, flags)
> -		__dynamic_array(u8, trb, sizeof(struct xhci_generic_trb))
> +		__field(u32, type)
> +		__field(u32, field0)
> +		__field(u32, field1)
> +		__field(u32, field2)
> +		__field(u32, field3)
>  	),
>  	TP_fast_assign(
> -		__entry->va = trb_va;
> -		__entry->dma = ((u64)le32_to_cpu(ev->field[1])) << 32 |
> -					le32_to_cpu(ev->field[0]);
> -		__entry->status = le32_to_cpu(ev->field[2]);
> -		__entry->flags = le32_to_cpu(ev->field[3]);
> -		memcpy(__get_dynamic_array(trb), trb_va,
> -			sizeof(struct xhci_generic_trb));
> +		__entry->type = ring->type;
> +		__entry->field0 = le32_to_cpu(trb->field[0]);
> +		__entry->field1 = le32_to_cpu(trb->field[1]);
> +		__entry->field2 = le32_to_cpu(trb->field[2]);
> +		__entry->field3 = le32_to_cpu(trb->field[3]);
>  	),
> -	TP_printk("\ntrb_dma=@%llx, trb_va=@%p, status=%08x, flags=%08x",
> -			(unsigned long long) __entry->dma, __entry->va,
> -			__entry->status, __entry->flags
> +	TP_printk("%s: %s", xhci_ring_type_string(__entry->type),

How about moving the common fields of a TRB (like TRB type and
the cycle bit) to the place between ring type and trb decoding string?
And remove type and cycle decoding in xhci_decode_trb() as well.

Something like:

diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index d01524b..f8ef7b8 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -132,9 +132,11 @@ DECLARE_EVENT_CLASS(xhci_log_trb,
                __entry->field2 = le32_to_cpu(trb->field[2]);
                __entry->field3 = le32_to_cpu(trb->field[3]);
        ),
-       TP_printk("%s: %s", xhci_ring_type_string(__entry->type),
-                       xhci_decode_trb(__entry->field0, __entry->field1,
-                                       __entry->field2, __entry->field3)
+       TP_printk("%s: %s: %c: %s", xhci_ring_type_string(__entry->type),
+                 xhci_trb_type_string(TRB_FIELD_TO_TYPE(__entry->field3)),
+                 __entry->field3 & TRB_CYCLE ? 'C' : 'c',
+                 xhci_decode_trb(__entry->field0, __entry->field1,
+                                 __entry->field2, __entry->field3)
        )
 );


> +			xhci_decode_trb(__entry->field0, __entry->field1,
> +					__entry->field2, __entry->field3)
>  	)
>  );
>  
> -DEFINE_EVENT(xhci_log_event, xhci_cmd_completion,
> -	TP_PROTO(void *trb_va, struct xhci_generic_trb *ev),
> -	TP_ARGS(trb_va, ev)
> +DEFINE_EVENT(xhci_log_trb, xhci_handle_event,
> +	TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb),
> +	TP_ARGS(ring, trb)
> +);
> +
> +DEFINE_EVENT(xhci_log_trb, xhci_handle_command,
> +	TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb),
> +	TP_ARGS(ring, trb)
> +);
> +
> +DEFINE_EVENT(xhci_log_trb, xhci_handle_transfer,
> +	TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb),
> +	TP_ARGS(ring, trb)
> +);
> +
> +DEFINE_EVENT(xhci_log_trb, xhci_queue_trb,
> +	TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb),
> +	TP_ARGS(ring, trb)
>  );

xhci_handle_command and xhci_handle_transfer are duplications
of xhci_handle_event. I suggest to remove them.

How about adding an event for the link TRBs. Something like,

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 4bad432..6dc8efb 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -173,6 +173,7 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring)
                ring->num_trbs_free++;
        }
        while (trb_is_link(ring->dequeue)) {
+               trace_xhci_link_trb(ring, ring->dequeue);
                ring->deq_seg = ring->deq_seg->next;
                ring->dequeue = ring->deq_seg->trbs;
        }
@@ -211,6 +212,7 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,
        ring->enq_updates++;
        /* Update the dequeue pointer further if that was a link TRB */
        while (trb_is_link(next)) {
+               trace_xhci_link_trb(ring, next);
 
                /*
                 * If the caller doesn't plan on enqueueing more TDs before
diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index d01524b..f1a06b5 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -158,6 +158,10 @@ DEFINE_EVENT(xhci_log_trb, xhci_queue_trb,
        TP_ARGS(ring, trb)
 );
 
+DEFINE_EVENT(xhci_log_trb, xhci_link_trb,
+       TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb),
+       TP_ARGS(ring, trb)
+);
 #endif /* __XHCI_TRACE_H */
 
 /* this part must be outside header guard */


>  
>  #endif /* __XHCI_TRACE_H */
> diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
> index c7e95a6e39a7..eb72ad4c0d72 100644
> --- a/drivers/usb/host/xhci.h
> +++ b/drivers/usb/host/xhci.h
> @@ -1200,6 +1200,27 @@ struct xhci_event_cmd {
>  
>  /* Address device - disable SetAddress */
>  #define TRB_BSR		(1<<9)
> +
> +/* Configure Endpoint - Deconfigure */
> +#define TRB_DC		(1<<9)
> +
> +/* Stop Ring - Transfer State Preserve */
> +#define TRB_TSP		(1<<9)
> +
> +/* Force Event */
> +#define TRB_TO_VF_INTR_TARGET(p)	(((p) & (0x3ff << 22)) >> 22)
> +#define TRB_TO_VF_ID(p)			(((p) & (0xff << 16)) >> 16)
> +
> +/* Set Latency Tolerance Value */
> +#define TRB_TO_BELT(p)			(((p) & (0xfff << 16)) >> 16)
> +
> +/* Get Port Bandwidth */
> +#define TRB_TO_DEV_SPEED(p)		(((p) & (0xf << 16)) >> 16)
> +
> +/* Force Header */
> +#define TRB_TO_PACKET_TYPE(p)		((p) & 0x1f)
> +#define TRB_TO_ROOTHUB_PORT(p)		(((p) & (0xff << 24)) >> 24)
> +
>  enum xhci_setup_dev {
>  	SETUP_CONTEXT_ONLY,
>  	SETUP_CONTEXT_ADDRESS,
> @@ -1223,16 +1244,21 @@ enum xhci_setup_dev {
>  #define STREAM_ID_FOR_TRB(p)		((((p)) & 0xffff) << 16)
>  #define SCT_FOR_TRB(p)			(((p) << 1) & 0x7)
>  
> +/* Link TRB specific fields */
> +#define TRB_TC			(1<<1)
>  
>  /* Port Status Change Event TRB fields */
>  /* Port ID - bits 31:24 */
>  #define GET_PORT_ID(p)		(((p) & (0xff << 24)) >> 24)
>  
> +#define EVENT_DATA		(1 << 2)
> +
>  /* Normal TRB fields */
>  /* transfer_len bitmasks - bits 0:16 */
>  #define	TRB_LEN(p)		((p) & 0x1ffff)
>  /* TD Size, packets remaining in this TD, bits 21:17 (5 bits, so max 31) */
>  #define TRB_TD_SIZE(p)          (min((p), (u32)31) << 17)
> +#define GET_TD_SIZE(p)		(((p) & 0x3e0000) >> 17)
>  /* xhci 1.1 uses the TD_SIZE field for TBC if Extended TBC is enabled (ETE) */
>  #define TRB_TD_SIZE_TBC(p)      (min((p), (u32)31) << 17)
>  /* Interrupter Target - which MSI-X vector to target the completion event at */
> @@ -1360,6 +1386,80 @@ union xhci_trb {
>  /* Get NEC firmware revision. */
>  #define	TRB_NEC_GET_FW		49
>  
> +static inline const char *xhci_trb_type_string(u8 type)
> +{
> +	switch (type) {
> +	case TRB_NORMAL:
> +		return "Normal";
> +	case TRB_SETUP:
> +		return "Setup Stage";
> +	case TRB_DATA:
> +		return "Data Stage";
> +	case TRB_STATUS:
> +		return "Status Stage";
> +	case TRB_ISOC:
> +		return "Isoch";
> +	case TRB_LINK:
> +		return "Link";
> +	case TRB_EVENT_DATA:
> +		return "Event Data";
> +	case TRB_TR_NOOP:
> +		return "No-Op";
> +	case TRB_ENABLE_SLOT:
> +		return "Enable Slot Command";
> +	case TRB_DISABLE_SLOT:
> +		return "Disable Slot Command";
> +	case TRB_ADDR_DEV:
> +		return "Address Device Command";
> +	case TRB_CONFIG_EP:
> +		return "Configure Endpoint Command";
> +	case TRB_EVAL_CONTEXT:
> +		return "Evaluate Context Command";
> +	case TRB_RESET_EP:
> +		return "Reset Endpoint Command";
> +	case TRB_STOP_RING:
> +		return "Stop Ring Command";
> +	case TRB_SET_DEQ:
> +		return "Set TR Dequeue Pointer Command";
> +	case TRB_RESET_DEV:
> +		return "Reset Device Command";
> +	case TRB_FORCE_EVENT:
> +		return "Force Event Command";
> +	case TRB_NEG_BANDWIDTH:
> +		return "Negotiate Bandwidth Command";
> +	case TRB_SET_LT:
> +		return "Set Latency Tolerance Value Command";
> +	case TRB_GET_BW:
> +		return "Get Port Bandwidth Command";
> +	case TRB_FORCE_HEADER:
> +		return "Force Header Command";
> +	case TRB_CMD_NOOP:
> +		return "No-Op Command";
> +	case TRB_TRANSFER:
> +		return "Transfer Event";
> +	case TRB_COMPLETION:
> +		return "Command Completion Event";
> +	case TRB_PORT_STATUS:
> +		return "Port Status Change Event";
> +	case TRB_BANDWIDTH_EVENT:
> +		return "Bandwidth Request Event";
> +	case TRB_DOORBELL:
> +		return "Doorbell Event";
> +	case TRB_HC_EVENT:
> +		return "Host Controller Event";
> +	case TRB_DEV_NOTE:
> +		return "Device Notification Event";
> +	case TRB_MFINDEX_WRAP:
> +		return "MFINDEX Wrap Event";
> +	case TRB_NEC_CMD_COMP:
> +		return "NEC Command Completion Event";
> +	case TRB_NEC_GET_FW:
> +		return "NET Get Firmware Revision Command";
> +	default:
> +		return "UNKNOWN";
> +	}
> +}
> +
>  #define TRB_TYPE_LINK(x)	(((x) & TRB_TYPE_BITMASK) == TRB_TYPE(TRB_LINK))
>  /* Above, but for __le32 types -- can avoid work by swapping constants: */
>  #define TRB_TYPE_LINK_LE32(x)	(((x) & cpu_to_le32(TRB_TYPE_BITMASK)) == \
> @@ -1436,6 +1536,28 @@ enum xhci_ring_type {
>  	TYPE_EVENT,
>  };
>  
> +static inline const char *xhci_ring_type_string(enum xhci_ring_type type)
> +{
> +	switch (type) {
> +	case TYPE_CTRL:
> +		return "CTRL";
> +	case TYPE_ISOC:
> +		return "ISOC";
> +	case TYPE_BULK:
> +		return "BULK";
> +	case TYPE_INTR:
> +		return "INTR";
> +	case TYPE_STREAM:
> +		return "STREAM";
> +	case TYPE_COMMAND:
> +		return "CMD";
> +	case TYPE_EVENT:
> +		return "EVENT";
> +	}
> +
> +	return "UNKNOWN";
> +}
> +
>  struct xhci_ring {
>  	struct xhci_segment	*first_seg;
>  	struct xhci_segment	*last_seg;
> @@ -2026,4 +2148,193 @@ static inline struct xhci_ring *xhci_urb_to_transfer_ring(struct xhci_hcd *xhci,
>  					urb->stream_id);
>  }
>  
> +static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
> +		u32 field3)
> +{
> +	static char str[256];
> +	int type = TRB_FIELD_TO_TYPE(field3);
> +
> +	switch (type) {
> +	case TRB_LINK:
> +		sprintf(str, "TRB %08x%08x status '%s' len %d slot %d ep %d type '%s' flags %c:%c",

How about using snprintf() to avoid buffer over flow?

> +				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)),

"TRB_FIELD_TO_TYPE(field3)" could be replaced with "type". The same for other
places in this function.


> +				field3 & EVENT_DATA ? 'E' : 'e',
> +				field3 & TRB_CYCLE ? 'C' : 'c');

This decoding seems not for a link trb, but an event one. :-)

> +		break;
> +	case TRB_TRANSFER:
> +	case TRB_COMPLETION:
> +	case TRB_PORT_STATUS:
> +	case TRB_BANDWIDTH_EVENT:
> +	case TRB_DOORBELL:
> +	case TRB_HC_EVENT:
> +	case TRB_DEV_NOTE:
> +	case TRB_MFINDEX_WRAP:
> +		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?!? */

I think it should. This field is defined as an index in the Device Context.

> +				TRB_TO_EP_INDEX(field3) + 1,
> +				xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
> +				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');
> +		break;
> +	case TRB_NORMAL:
> +	case TRB_DATA:
> +	case TRB_STATUS:
> +	case TRB_ISOC:
> +	case TRB_EVENT_DATA:
> +	case TRB_TR_NOOP:
> +		sprintf(str, "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)),
> +				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');
> +		break;
> +
> +	case TRB_CMD_NOOP:
> +	case TRB_ENABLE_SLOT:
> +		sprintf(str, "%s: flags %c",
> +				xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
> +				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)),
> +				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)),
> +				field1, field0,
> +				TRB_TO_SLOT_ID(field3),
> +				field3 & TRB_BSR ? 'B' : 'b',
> +				field3 & TRB_CYCLE ? 'C' : 'c');
> +		break;
> +	case TRB_CONFIG_EP:
> +		sprintf(str, "%s: ctx %08x%08x slot %d flags %c:%c",
> +				xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
> +				field1, field0,
> +				TRB_TO_SLOT_ID(field3),
> +				field3 & TRB_DC ? 'D' : 'd',
> +				field3 & TRB_CYCLE ? 'C' : 'c');
> +		break;
> +	case TRB_EVAL_CONTEXT:
> +		sprintf(str, "%s: ctx %08x%08x slot %d flags %c",
> +				xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
> +				field1, field0,
> +				TRB_TO_SLOT_ID(field3),
> +				field3 & TRB_CYCLE ? 'C' : 'c');
> +		break;
> +	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)),
> +				field1, field0,
> +				TRB_TO_SLOT_ID(field3),
> +				/* Macro decrements 1, maybe it shouldn't?!? */
> +				TRB_TO_EP_INDEX(field3) + 1,
> +				field3 & TRB_CYCLE ? 'C' : 'c');
> +		break;
> +	case TRB_STOP_RING:
> +		sprintf(str, "%s: slot %d sp %d ep %d flags %c",
> +				xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
> +				TRB_TO_SLOT_ID(field3),
> +				TRB_TO_SUSPEND_PORT(field3),
> +				/* Macro decrements 1, maybe it shouldn't?!? */
> +				TRB_TO_EP_INDEX(field3) + 1,
> +				field3 & TRB_CYCLE ? 'C' : 'c');
> +		break;
> +	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)),
> +				field1, field0,
> +				TRB_TO_STREAM_ID(field2),
> +				TRB_TO_SLOT_ID(field3),
> +				/* Macro decrements 1, maybe it shouldn't?!? */
> +				TRB_TO_EP_INDEX(field3) + 1,
> +				field3 & TRB_CYCLE ? 'C' : 'c');
> +		break;
> +	case TRB_RESET_DEV:
> +		sprintf(str, "%s: slot %d flags %c",
> +				xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
> +				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)),
> +				field1, field0,
> +				TRB_TO_VF_INTR_TARGET(field2),
> +				TRB_TO_VF_ID(field3),
> +				field3 & TRB_CYCLE ? 'C' : 'c');
> +		break;
> +	case TRB_SET_LT:
> +		sprintf(str, "%s: belt %d flags %c",
> +				xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
> +				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)),
> +				field1, field0,
> +				TRB_TO_SLOT_ID(field3),
> +				TRB_TO_DEV_SPEED(field3),
> +				field3 & TRB_CYCLE ? 'C' : 'c');
> +		break;
> +	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)),
> +				field2, field1, field0 & 0xffffffe0,
> +				TRB_TO_PACKET_TYPE(field0),
> +				TRB_TO_ROOTHUB_PORT(field3),
> +				field3 & TRB_CYCLE ? 'C' : 'c');
> +		break;
> +	default:
> +		sprintf(str, "type '%s' -> raw %08x %08x %08x %08x",
> +				xhci_trb_type_string(TRB_FIELD_TO_TYPE(field3)),
> +				field0, field1, field2, field3);
> +	}
> +
> +	return str;
> +}
> +
> +
>  #endif /* __LINUX_XHCI_HCD_H */

Best regards,
Lu Baolu
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux