Commit b2d6edbb authored by Lu Baolu's avatar Lu Baolu Committed by Greg Kroah-Hartman

usb: xhci: add xhci_log_ring trace events

This patch creates a new event class called xhci_log_ring, and
defines the events used for tracing the change of all kinds of
rings used by an xhci host. An xHCI ring is basically a memory
block shared between software and hardware. By tracing changes
of rings, it makes the life easier for debugging hardware or
software problems.

This info can be used, later, to print, in a human readable way,
the life cycle of an xHCI ring using the trace-cmd tool and the
appropriate plugin.
Signed-off-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d9f11ba9
...@@ -288,6 +288,8 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring) ...@@ -288,6 +288,8 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring)
if (!ring) if (!ring)
return; return;
trace_xhci_ring_free(ring);
if (ring->first_seg) { if (ring->first_seg) {
if (ring->type == TYPE_STREAM) if (ring->type == TYPE_STREAM)
xhci_remove_stream_mapping(ring); xhci_remove_stream_mapping(ring);
...@@ -400,6 +402,7 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, ...@@ -400,6 +402,7 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
cpu_to_le32(LINK_TOGGLE); cpu_to_le32(LINK_TOGGLE);
} }
xhci_initialize_ring_info(ring, cycle_state); xhci_initialize_ring_info(ring, cycle_state);
trace_xhci_ring_alloc(ring);
return ring; return ring;
fail: fail:
...@@ -504,6 +507,7 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring, ...@@ -504,6 +507,7 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring,
} }
xhci_link_rings(xhci, ring, first, last, num_segs); xhci_link_rings(xhci, ring, first, last, num_segs);
trace_xhci_ring_expansion(ring);
xhci_dbg_trace(xhci, trace_xhci_dbg_ring_expansion, xhci_dbg_trace(xhci, trace_xhci_dbg_ring_expansion,
"ring expansion succeed, now has %d segments", "ring expansion succeed, now has %d segments",
ring->num_segs); ring->num_segs);
......
...@@ -191,6 +191,9 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) ...@@ -191,6 +191,9 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring)
ring->deq_seg = ring->deq_seg->next; ring->deq_seg = ring->deq_seg->next;
ring->dequeue = ring->deq_seg->trbs; ring->dequeue = ring->deq_seg->trbs;
} }
trace_xhci_inc_deq(ring);
return; return;
} }
...@@ -259,6 +262,8 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, ...@@ -259,6 +262,8 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,
ring->enqueue = ring->enq_seg->trbs; ring->enqueue = ring->enq_seg->trbs;
next = ring->enqueue; next = ring->enqueue;
} }
trace_xhci_inc_enq(ring);
} }
/* /*
......
...@@ -388,6 +388,71 @@ DEFINE_EVENT(xhci_log_slot_ctx, xhci_handle_cmd_set_deq, ...@@ -388,6 +388,71 @@ DEFINE_EVENT(xhci_log_slot_ctx, xhci_handle_cmd_set_deq,
TP_ARGS(ctx) TP_ARGS(ctx)
); );
DECLARE_EVENT_CLASS(xhci_log_ring,
TP_PROTO(struct xhci_ring *ring),
TP_ARGS(ring),
TP_STRUCT__entry(
__field(u32, type)
__field(void *, ring)
__field(dma_addr_t, enq)
__field(dma_addr_t, deq)
__field(dma_addr_t, enq_seg)
__field(dma_addr_t, deq_seg)
__field(unsigned int, num_segs)
__field(unsigned int, stream_id)
__field(unsigned int, cycle_state)
__field(unsigned int, num_trbs_free)
__field(unsigned int, bounce_buf_len)
),
TP_fast_assign(
__entry->ring = ring;
__entry->type = ring->type;
__entry->num_segs = ring->num_segs;
__entry->stream_id = ring->stream_id;
__entry->enq_seg = ring->enq_seg->dma;
__entry->deq_seg = ring->deq_seg->dma;
__entry->cycle_state = ring->cycle_state;
__entry->num_trbs_free = ring->num_trbs_free;
__entry->bounce_buf_len = ring->bounce_buf_len;
__entry->enq = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue);
__entry->deq = xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue);
),
TP_printk("%s %p: enq %pad(%pad) deq %pad(%pad) segs %d stream %d free_trbs %d bounce %d cycle %d",
xhci_ring_type_string(__entry->type), __entry->ring,
&__entry->enq, &__entry->enq_seg,
&__entry->deq, &__entry->deq_seg,
__entry->num_segs,
__entry->stream_id,
__entry->num_trbs_free,
__entry->bounce_buf_len,
__entry->cycle_state
)
);
DEFINE_EVENT(xhci_log_ring, xhci_ring_alloc,
TP_PROTO(struct xhci_ring *ring),
TP_ARGS(ring)
);
DEFINE_EVENT(xhci_log_ring, xhci_ring_free,
TP_PROTO(struct xhci_ring *ring),
TP_ARGS(ring)
);
DEFINE_EVENT(xhci_log_ring, xhci_ring_expansion,
TP_PROTO(struct xhci_ring *ring),
TP_ARGS(ring)
);
DEFINE_EVENT(xhci_log_ring, xhci_inc_enq,
TP_PROTO(struct xhci_ring *ring),
TP_ARGS(ring)
);
DEFINE_EVENT(xhci_log_ring, xhci_inc_deq,
TP_PROTO(struct xhci_ring *ring),
TP_ARGS(ring)
);
#endif /* __XHCI_TRACE_H */ #endif /* __XHCI_TRACE_H */
/* this part must be outside header guard */ /* this part must be outside header guard */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment