summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-ring.c
diff options
context:
space:
mode:
authorFelipe Balbi <felipe.balbi@linux.intel.com>2017-04-07 16:56:57 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-08 12:17:41 +0200
commit19a7d0d65c4a813069f4bc4ca701d6a163c337e9 (patch)
treec41b437121a032eac950270e040238e2ee4e81c6 /drivers/usb/host/xhci-ring.c
parentusb: host: xhci: extract xhci_slot_state_string() (diff)
downloadlinux-19a7d0d65c4a813069f4bc4ca701d6a163c337e9.tar.xz
linux-19a7d0d65c4a813069f4bc4ca701d6a163c337e9.zip
usb: host: xhci: add Slot and EP Context tracers
With these, we can track what's happening with the HW while executing each and every command. It will give us visibility into how the different contexts are being modified by xHC which can bring insight into problems while debugging. Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r--drivers/usb/host/xhci-ring.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index a3309aa02993..2f700c9893bd 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -689,6 +689,8 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
struct xhci_virt_ep *ep;
struct xhci_td *cur_td = NULL;
struct xhci_td *last_unlinked_td;
+ struct xhci_ep_ctx *ep_ctx;
+ struct xhci_virt_device *vdev;
struct xhci_dequeue_state deq_state;
@@ -702,6 +704,11 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
memset(&deq_state, 0, sizeof(deq_state));
ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
+
+ vdev = xhci->devs[slot_id];
+ ep_ctx = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index);
+ trace_xhci_handle_cmd_stop_ep(ep_ctx);
+
ep = &xhci->devs[slot_id]->eps[ep_index];
last_unlinked_td = list_last_entry(&ep->cancelled_td_list,
struct xhci_td, cancelled_td_list);
@@ -1029,6 +1036,8 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx);
+ trace_xhci_handle_cmd_set_deq(slot_ctx);
+ trace_xhci_handle_cmd_set_deq_ep(ep_ctx);
if (cmd_comp_code != COMP_SUCCESS) {
unsigned int ep_state;
@@ -1099,9 +1108,15 @@ cleanup:
static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
union xhci_trb *trb, u32 cmd_comp_code)
{
+ struct xhci_virt_device *vdev;
+ struct xhci_ep_ctx *ep_ctx;
unsigned int ep_index;
ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
+ vdev = xhci->devs[slot_id];
+ ep_ctx = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index);
+ trace_xhci_handle_cmd_reset_ep(ep_ctx);
+
/* This command will only fail if the endpoint wasn't halted,
* but we don't care.
*/
@@ -1143,10 +1158,15 @@ static void xhci_handle_cmd_enable_slot(struct xhci_hcd *xhci, int slot_id,
static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id)
{
struct xhci_virt_device *virt_dev;
+ struct xhci_slot_ctx *slot_ctx;
virt_dev = xhci->devs[slot_id];
if (!virt_dev)
return;
+
+ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx);
+ trace_xhci_handle_cmd_disable_slot(slot_ctx);
+
if (xhci->quirks & XHCI_EP_LIMIT_QUIRK)
/* Delete default control endpoint resources */
xhci_free_device_endpoint_resources(xhci, virt_dev, true);
@@ -1158,6 +1178,7 @@ static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id,
{
struct xhci_virt_device *virt_dev;
struct xhci_input_control_ctx *ctrl_ctx;
+ struct xhci_ep_ctx *ep_ctx;
unsigned int ep_index;
unsigned int ep_state;
u32 add_flags, drop_flags;
@@ -1182,6 +1203,9 @@ static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id,
/* Input ctx add_flags are the endpoint index plus one */
ep_index = xhci_last_valid_endpoint(add_flags) - 1;
+ ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->out_ctx, ep_index);
+ trace_xhci_handle_cmd_config_ep(ep_ctx);
+
/* A usb_set_interface() call directly after clearing a halted
* condition may race on this quirky hardware. Not worth
* worrying about, since this is prototype hardware. Not sure
@@ -1206,9 +1230,26 @@ static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id,
return;
}
+static void xhci_handle_cmd_addr_dev(struct xhci_hcd *xhci, int slot_id)
+{
+ struct xhci_virt_device *vdev;
+ struct xhci_slot_ctx *slot_ctx;
+
+ vdev = xhci->devs[slot_id];
+ slot_ctx = xhci_get_slot_ctx(xhci, vdev->out_ctx);
+ trace_xhci_handle_cmd_addr_dev(slot_ctx);
+}
+
static void xhci_handle_cmd_reset_dev(struct xhci_hcd *xhci, int slot_id,
struct xhci_event_cmd *event)
{
+ struct xhci_virt_device *vdev;
+ struct xhci_slot_ctx *slot_ctx;
+
+ vdev = xhci->devs[slot_id];
+ slot_ctx = xhci_get_slot_ctx(xhci, vdev->out_ctx);
+ trace_xhci_handle_cmd_reset_dev(slot_ctx);
+
xhci_dbg(xhci, "Completed reset device command.\n");
if (!xhci->devs[slot_id])
xhci_warn(xhci, "Reset device command completion "
@@ -1384,6 +1425,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
case TRB_EVAL_CONTEXT:
break;
case TRB_ADDR_DEV:
+ xhci_handle_cmd_addr_dev(xhci, slot_id);
break;
case TRB_STOP_RING:
WARN_ON(slot_id != TRB_TO_SLOT_ID(