[PATCH 1/6] usb: xhci: add xhci_log_cmd trace events

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

 



This patch creates a new event class called xhci_log_cmd, and
defines the events used for tracing the life cycle of commands
issued for various purposes.

This info can be used, later, to print, in a human readable way,
the life cycle of an xHCI command using the trace-cmd tool and
the appropriate plugin.

Signed-off-by: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx>
---
 drivers/usb/host/xhci-hub.c   |  2 +
 drivers/usb/host/xhci-ring.c  | 13 +++++--
 drivers/usb/host/xhci-trace.h | 90 +++++++++++++++++++++++++++++++++++++++++++
 drivers/usb/host/xhci.c       |  7 ++++
 4 files changed, 108 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 3bddeaa..2c3f77f 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -411,9 +411,11 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
 			}
 			xhci_queue_stop_endpoint(xhci, command, slot_id, i,
 						 suspend);
+			trace_cmd_xhci_stop_device(command);
 		}
 	}
 	xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend);
+	trace_cmd_xhci_stop_device(cmd);
 	xhci_ring_cmd_db(xhci);
 	spin_unlock_irqrestore(&xhci->lock, flags);
 
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index d9936c7..4cdcd71 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1124,6 +1124,7 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
 		xhci_queue_configure_endpoint(xhci, command,
 				xhci->devs[slot_id]->in_ctx->dma, slot_id,
 				false);
+		trace_cmd_xhci_handle_cmd_reset_ep(command);
 		xhci_ring_cmd_db(xhci);
 	} else {
 		/* Clear our internal halted state */
@@ -1231,13 +1232,13 @@ static void xhci_handle_cmd_nec_get_fw(struct xhci_hcd *xhci,
 static void xhci_complete_del_and_free_cmd(struct xhci_command *cmd, u32 status)
 {
 	list_del(&cmd->cmd_list);
+	cmd->status = status;
+	trace_cmd_xhci_complete_del_and_free_cmd(cmd);
 
-	if (cmd->completion) {
-		cmd->status = status;
+	if (cmd->completion)
 		complete(cmd->completion);
-	} else {
+	else
 		kfree(cmd);
-	}
 }
 
 void xhci_cleanup_command_queue(struct xhci_hcd *xhci)
@@ -1268,6 +1269,7 @@ void xhci_handle_command_timeout(struct work_struct *work)
 	}
 	/* mark this command to be cancelled */
 	xhci->current_cmd->status = COMP_COMMAND_ABORTED;
+	trace_cmd_xhci_handle_command_timeout(xhci->current_cmd);
 
 	/* Make sure command ring is running before aborting it */
 	hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
@@ -1432,6 +1434,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
 	}
 
 event_handled:
+	trace_cmd_handle_cmd_completion(cmd);
 	xhci_complete_del_and_free_cmd(cmd, cmd_comp_code);
 
 	inc_deq(xhci, xhci->cmd_ring);
@@ -1773,6 +1776,7 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
 	ep->stopped_stream = stream_id;
 
 	xhci_queue_reset_ep(xhci, command, slot_id, ep_index);
+	trace_cmd_xhci_cleanup_halted_endpoint(command);
 	xhci_cleanup_stalled_ring(xhci, ep_index, td);
 
 	ep->stopped_stream = 0;
@@ -3956,6 +3960,7 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
 		xhci_free_command(xhci, cmd);
 		return;
 	}
+	trace_cmd_xhci_queue_new_dequeue_state(cmd);
 
 	/* Stop the TD queueing code from ringing the doorbell until
 	 * this command completes.  The HC won't set the dequeue pointer
diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index 1ac2cdf..c31eeaf 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -285,6 +285,96 @@ DEFINE_EVENT(xhci_log_urb, xhci_urb_dequeue,
 	TP_ARGS(urb)
 );
 
+DECLARE_EVENT_CLASS(xhci_log_cmd,
+	TP_PROTO(struct xhci_command *cmd),
+	TP_ARGS(cmd),
+	TP_STRUCT__entry(
+		__field(struct xhci_command *, cmd)
+		__field(struct xhci_container_ctx *, in_ctx)
+		__field(union xhci_trb *, cmd_trb)
+		__field(int, slot_id)
+		__field(int, status)
+		__field(int, type)
+	),
+	TP_fast_assign(
+		__entry->cmd = cmd;
+		__entry->in_ctx = cmd->in_ctx;
+		__entry->cmd_trb = cmd->command_trb;
+		__entry->slot_id = cmd->slot_id;
+		__entry->status = cmd->status;
+		__entry->type = TRB_FIELD_TO_TYPE(le32_to_cpu(cmd->command_trb->generic.field[3]))
+	),
+	TP_printk("cmd @%p: %s: in_ctx=@%p, slot_id=%d, cmd_trb=@%p, status=%d",
+		__entry->cmd, xhci_trb_type_string(__entry->type),
+		__entry->in_ctx, __entry->slot_id, __entry->cmd_trb,
+		__entry->status
+	)
+);
+
+DEFINE_EVENT(xhci_log_cmd, cmd_xhci_stop_device,
+	TP_PROTO(struct xhci_command *cmd),
+	TP_ARGS(cmd)
+);
+
+DEFINE_EVENT(xhci_log_cmd, cmd_xhci_handle_cmd_reset_ep,
+	TP_PROTO(struct xhci_command *cmd),
+	TP_ARGS(cmd)
+);
+
+DEFINE_EVENT(xhci_log_cmd, cmd_xhci_cleanup_halted_endpoint,
+	TP_PROTO(struct xhci_command *cmd),
+	TP_ARGS(cmd)
+);
+
+DEFINE_EVENT(xhci_log_cmd, cmd_xhci_queue_new_dequeue_state,
+	TP_PROTO(struct xhci_command *cmd),
+	TP_ARGS(cmd)
+);
+
+DEFINE_EVENT(xhci_log_cmd, cmd_xhci_urb_dequeue,
+	TP_PROTO(struct xhci_command *cmd),
+	TP_ARGS(cmd)
+);
+
+DEFINE_EVENT(xhci_log_cmd, cmd_xhci_configure_endpoint,
+	TP_PROTO(struct xhci_command *cmd),
+	TP_ARGS(cmd)
+);
+
+DEFINE_EVENT(xhci_log_cmd, cmd_xhci_discover_or_reset_device,
+	TP_PROTO(struct xhci_command *cmd),
+	TP_ARGS(cmd)
+);
+
+DEFINE_EVENT(xhci_log_cmd, cmd_xhci_free_dev,
+	TP_PROTO(struct xhci_command *cmd),
+	TP_ARGS(cmd)
+);
+
+DEFINE_EVENT(xhci_log_cmd, cmd_xhci_alloc_dev,
+	TP_PROTO(struct xhci_command *cmd),
+	TP_ARGS(cmd)
+);
+
+DEFINE_EVENT(xhci_log_cmd, cmd_xhci_setup_device,
+	TP_PROTO(struct xhci_command *cmd),
+	TP_ARGS(cmd)
+);
+
+DEFINE_EVENT(xhci_log_cmd, cmd_handle_cmd_completion,
+	TP_PROTO(struct xhci_command *cmd),
+	TP_ARGS(cmd)
+);
+
+DEFINE_EVENT(xhci_log_cmd, cmd_xhci_handle_command_timeout,
+	TP_PROTO(struct xhci_command *cmd),
+	TP_ARGS(cmd)
+);
+
+DEFINE_EVENT(xhci_log_cmd, cmd_xhci_complete_del_and_free_cmd,
+	TP_PROTO(struct xhci_command *cmd),
+	TP_ARGS(cmd)
+);
 #endif /* __XHCI_TRACE_H */
 
 /* this part must be outside header guard */
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index b3f7766..dff912e 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1549,6 +1549,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 		add_timer(&ep->stop_cmd_timer);
 		xhci_queue_stop_endpoint(xhci, command, urb->dev->slot_id,
 					 ep_index, 0);
+		trace_cmd_xhci_urb_dequeue(command);
 		xhci_ring_cmd_db(xhci);
 	}
 done:
@@ -2631,6 +2632,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
 				"FIXME allocate a new ring segment");
 		return -ENOMEM;
 	}
+	trace_cmd_xhci_configure_endpoint(command);
 	xhci_ring_cmd_db(xhci);
 	spin_unlock_irqrestore(&xhci->lock, flags);
 
@@ -3458,6 +3460,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
 		spin_unlock_irqrestore(&xhci->lock, flags);
 		goto command_cleanup;
 	}
+	trace_cmd_xhci_discover_or_reset_device(reset_device_cmd);
 	xhci_ring_cmd_db(xhci);
 	spin_unlock_irqrestore(&xhci->lock, flags);
 
@@ -3604,6 +3607,7 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
 		xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
 		return;
 	}
+	trace_cmd_xhci_free_dev(command);
 	xhci_ring_cmd_db(xhci);
 	spin_unlock_irqrestore(&xhci->lock, flags);
 
@@ -3662,6 +3666,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
 		xhci_free_command(xhci, command);
 		return 0;
 	}
+	trace_cmd_xhci_alloc_dev(command);
 	xhci_ring_cmd_db(xhci);
 	spin_unlock_irqrestore(&xhci->lock, flags);
 
@@ -3724,6 +3729,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
 	if (!xhci_queue_slot_control(xhci, command, TRB_DISABLE_SLOT,
 				     udev->slot_id))
 		xhci_ring_cmd_db(xhci);
+	trace_cmd_xhci_alloc_dev(command);
 	spin_unlock_irqrestore(&xhci->lock, flags);
 	return 0;
 }
@@ -3826,6 +3832,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
 				"FIXME: allocate a command ring segment");
 		goto out;
 	}
+	trace_cmd_xhci_setup_device(command);
 	xhci_ring_cmd_db(xhci);
 	spin_unlock_irqrestore(&xhci->lock, flags);
 
-- 
2.1.4

--
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