diff options
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 150 |
1 files changed, 101 insertions, 49 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 5b08cd85f8e7..6bfbd80ec2b9 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -67,6 +67,7 @@ #include <linux/scatterlist.h> #include <linux/slab.h> #include "xhci.h" +#include "xhci-trace.h" static int handle_cmd_in_cmd_wait_list(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, @@ -122,6 +123,16 @@ static int enqueue_is_link_trb(struct xhci_ring *ring) return TRB_TYPE_LINK_LE32(link->control); } +union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring) +{ + /* Enqueue pointer can be left pointing to the link TRB, + * we must handle that + */ + if (TRB_TYPE_LINK_LE32(ring->enqueue->link.control)) + return ring->enq_seg->next->trbs; + return ring->enqueue; +} + /* Updates trb to point to the next TRB in the ring, and updates seg if the next * TRB is in a new segment. This does not skip over link TRBs, and it does not * effect the ring dequeue or enqueue pointers. @@ -555,7 +566,8 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, return; } state->new_cycle_state = 0; - xhci_dbg(xhci, "Finding segment containing stopped TRB.\n"); + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "Finding segment containing stopped TRB."); state->new_deq_seg = find_trb_seg(cur_td->start_seg, dev->eps[ep_index].stopped_trb, &state->new_cycle_state); @@ -565,12 +577,14 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, } /* Dig out the cycle state saved by the xHC during the stop ep cmd */ - xhci_dbg(xhci, "Finding endpoint context\n"); + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "Finding endpoint context"); ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index); state->new_cycle_state = 0x1 & le64_to_cpu(ep_ctx->deq); state->new_deq_ptr = cur_td->last_trb; - xhci_dbg(xhci, "Finding segment containing last TRB in TD.\n"); + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "Finding segment containing last TRB in TD."); state->new_deq_seg = find_trb_seg(state->new_deq_seg, state->new_deq_ptr, &state->new_cycle_state); @@ -597,13 +611,16 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, if (ep_ring->first_seg == ep_ring->first_seg->next && state->new_deq_ptr < dev->eps[ep_index].stopped_trb) state->new_cycle_state ^= 0x1; - xhci_dbg(xhci, "Cycle state = 0x%x\n", state->new_cycle_state); + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "Cycle state = 0x%x", state->new_cycle_state); /* Don't update the ring cycle state for the producer (us). */ - xhci_dbg(xhci, "New dequeue segment = %p (virtual)\n", + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "New dequeue segment = %p (virtual)", state->new_deq_seg); addr = xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr); - xhci_dbg(xhci, "New dequeue pointer = 0x%llx (DMA)\n", + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "New dequeue pointer = 0x%llx (DMA)", (unsigned long long) addr); } @@ -631,9 +648,11 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, if (flip_cycle) cur_trb->generic.field[3] ^= cpu_to_le32(TRB_CYCLE); - xhci_dbg(xhci, "Cancel (unchain) link TRB\n"); - xhci_dbg(xhci, "Address = %p (0x%llx dma); " - "in seg %p (0x%llx dma)\n", + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "Cancel (unchain) link TRB"); + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "Address = %p (0x%llx dma); " + "in seg %p (0x%llx dma)", cur_trb, (unsigned long long)xhci_trb_virt_to_dma(cur_seg, cur_trb), cur_seg, @@ -651,7 +670,8 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, cpu_to_le32(TRB_CYCLE); cur_trb->generic.field[3] |= cpu_to_le32( TRB_TYPE(TRB_TR_NOOP)); - xhci_dbg(xhci, "TRB to noop at offset 0x%llx\n", + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "TRB to noop at offset 0x%llx", (unsigned long long) xhci_trb_virt_to_dma(cur_seg, cur_trb)); } @@ -672,8 +692,9 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, { struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index]; - xhci_dbg(xhci, "Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), " - "new deq ptr = %p (0x%llx dma), new cycle = %u\n", + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), " + "new deq ptr = %p (0x%llx dma), new cycle = %u", deq_state->new_deq_seg, (unsigned long long)deq_state->new_deq_seg->dma, deq_state->new_deq_ptr, @@ -793,7 +814,8 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, */ list_for_each(entry, &ep->cancelled_td_list) { cur_td = list_entry(entry, struct xhci_td, cancelled_td_list); - xhci_dbg(xhci, "Removing canceled TD starting at 0x%llx (dma).\n", + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "Removing canceled TD starting at 0x%llx (dma).", (unsigned long long)xhci_trb_virt_to_dma( cur_td->start_seg, cur_td->first_trb)); ep_ring = xhci_urb_to_transfer_ring(xhci, cur_td->urb); @@ -847,8 +869,12 @@ remove_finished_td: /* Otherwise ring the doorbell(s) to restart queued transfers */ ring_doorbell_for_active_rings(xhci, slot_id, ep_index); } - ep->stopped_td = NULL; - ep->stopped_trb = NULL; + + /* Clear stopped_td and stopped_trb if endpoint is not halted */ + if (!(ep->ep_state & EP_HALTED)) { + ep->stopped_td = NULL; + ep->stopped_trb = NULL; + } /* * Drop the lock and complete the URBs in the cancelled TD list. @@ -913,14 +939,16 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) ep->stop_cmds_pending--; if (xhci->xhc_state & XHCI_STATE_DYING) { - xhci_dbg(xhci, "Stop EP timer ran, but another timer marked " - "xHCI as DYING, exiting.\n"); + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "Stop EP timer ran, but another timer marked " + "xHCI as DYING, exiting."); spin_unlock_irqrestore(&xhci->lock, flags); return; } if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) { - xhci_dbg(xhci, "Stop EP timer ran, but no command pending, " - "exiting.\n"); + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "Stop EP timer ran, but no command pending, " + "exiting."); spin_unlock_irqrestore(&xhci->lock, flags); return; } @@ -962,8 +990,9 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) ring = temp_ep->ring; if (!ring) continue; - xhci_dbg(xhci, "Killing URBs for slot ID %u, " - "ep index %u\n", i, j); + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "Killing URBs for slot ID %u, " + "ep index %u", i, j); while (!list_empty(&ring->td_list)) { cur_td = list_first_entry(&ring->td_list, struct xhci_td, @@ -986,9 +1015,11 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) } } spin_unlock_irqrestore(&xhci->lock, flags); - xhci_dbg(xhci, "Calling usb_hc_died()\n"); + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "Calling usb_hc_died()"); usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); - xhci_dbg(xhci, "xHCI host controller is dead.\n"); + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "xHCI host controller is dead."); } @@ -1092,7 +1123,8 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci, ep_state &= EP_STATE_MASK; slot_state = le32_to_cpu(slot_ctx->dev_state); slot_state = GET_SLOT_STATE(slot_state); - xhci_dbg(xhci, "Slot state = %u, EP state = %u\n", + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "Slot state = %u, EP state = %u", slot_state, ep_state); break; case COMP_EBADSLT: @@ -1112,7 +1144,8 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci, * cancelling URBs, which might not be an error... */ } else { - xhci_dbg(xhci, "Successful Set TR Deq Ptr cmd, deq = @%08llx\n", + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "Successful Set TR Deq Ptr cmd, deq = @%08llx", le64_to_cpu(ep_ctx->deq)); if (xhci_trb_virt_to_dma(dev->eps[ep_index].queued_deq_seg, dev->eps[ep_index].queued_deq_ptr) == @@ -1150,7 +1183,8 @@ static void handle_reset_ep_completion(struct xhci_hcd *xhci, /* This command will only fail if the endpoint wasn't halted, * but we don't care. */ - xhci_dbg(xhci, "Ignoring reset ep completion code of %u\n", + xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep, + "Ignoring reset ep completion code of %u", GET_COMP_CODE(le32_to_cpu(event->status))); /* HW with the reset endpoint quirk needs to have a configure endpoint @@ -1158,7 +1192,8 @@ static void handle_reset_ep_completion(struct xhci_hcd *xhci, * because the HW can't handle two commands being queued in a row. */ if (xhci->quirks & XHCI_RESET_EP_QUIRK) { - xhci_dbg(xhci, "Queueing configure endpoint command\n"); + xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, + "Queueing configure endpoint command"); xhci_queue_configure_endpoint(xhci, xhci->devs[slot_id]->in_ctx->dma, slot_id, false); @@ -1377,6 +1412,9 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, return; } + trace_xhci_cmd_completion(&xhci->cmd_ring->dequeue->generic, + (struct xhci_generic_trb *) event); + if ((GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_CMD_ABORT) || (GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_CMD_STOP)) { /* If the return value is 0, we think the trb pointed by @@ -1390,6 +1428,12 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, inc_deq(xhci, xhci->cmd_ring); return; } + /* There is no command to handle if we get a stop event when the + * command ring is empty, event->cmd_trb points to the next + * unset command + */ + if (xhci->cmd_ring->dequeue == xhci->cmd_ring->enqueue) + return; } switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]) @@ -1444,8 +1488,9 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, ep_state = xhci->devs[slot_id]->eps[ep_index].ep_state; if (!(ep_state & EP_HALTED)) goto bandwidth_change; - xhci_dbg(xhci, "Completed config ep cmd - " - "last ep index = %d, state = %d\n", + xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, + "Completed config ep cmd - " + "last ep index = %d, state = %d", ep_index, ep_state); /* Clear internal halted state and restart ring(s) */ xhci->devs[slot_id]->eps[ep_index].ep_state &= @@ -1454,7 +1499,8 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, break; } bandwidth_change: - xhci_dbg(xhci, "Completed config ep cmd\n"); + xhci_dbg_trace(xhci, trace_xhci_dbg_context_change, + "Completed config ep cmd"); xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(le32_to_cpu(event->status)); complete(&xhci->devs[slot_id]->cmd_completion); @@ -1497,7 +1543,8 @@ bandwidth_change: xhci->error_bitmask |= 1 << 6; break; } - xhci_dbg(xhci, "NEC firmware version %2x.%02x\n", + xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, + "NEC firmware version %2x.%02x", NEC_FW_MAJOR(le32_to_cpu(event->status)), NEC_FW_MINOR(le32_to_cpu(event->status))); break; @@ -1716,6 +1763,19 @@ static void handle_port_status(struct xhci_hcd *xhci, } } + /* + * Check to see if xhci-hub.c is waiting on RExit to U0 transition (or + * RExit to a disconnect state). If so, let the the driver know it's + * out of the RExit state. + */ + if (!DEV_SUPERSPEED(temp) && + test_and_clear_bit(faked_port_index, + &bus_state->rexit_ports)) { + complete(&bus_state->rexit_done[faked_port_index]); + bogus_port_status = true; + goto cleanup; + } + if (hcd->speed != HCD_USB3) xhci_test_and_clear_bit(xhci, port_array, faked_port_index, PORT_PLC); @@ -2877,8 +2937,8 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, return -ENOMEM; } - xhci_dbg(xhci, "ERROR no room on ep ring, " - "try ring expansion\n"); + xhci_dbg_trace(xhci, trace_xhci_dbg_ring_expansion, + "ERROR no room on ep ring, try ring expansion"); num_trbs_needed = num_trbs - ep_ring->num_trbs_free; if (xhci_ring_expansion(xhci, ep_ring, num_trbs_needed, mem_flags)) { @@ -3060,14 +3120,10 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, * to set the polling interval (once the API is added). */ if (xhci_interval != ep_interval) { - if (printk_ratelimit()) - dev_dbg(&urb->dev->dev, "Driver uses different interval" - " (%d microframe%s) than xHCI " - "(%d microframe%s)\n", - ep_interval, - ep_interval == 1 ? "" : "s", - xhci_interval, - xhci_interval == 1 ? "" : "s"); + dev_dbg_ratelimited(&urb->dev->dev, + "Driver uses different interval (%d microframe%s) than xHCI (%d microframe%s)\n", + ep_interval, ep_interval == 1 ? "" : "s", + xhci_interval, xhci_interval == 1 ? "" : "s"); urb->interval = xhci_interval; /* Convert back to frames for LS/FS devices */ if (urb->dev->speed == USB_SPEED_LOW || @@ -3849,14 +3905,10 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags, * to set the polling interval (once the API is added). */ if (xhci_interval != ep_interval) { - if (printk_ratelimit()) - dev_dbg(&urb->dev->dev, "Driver uses different interval" - " (%d microframe%s) than xHCI " - "(%d microframe%s)\n", - ep_interval, - ep_interval == 1 ? "" : "s", - xhci_interval, - xhci_interval == 1 ? "" : "s"); + dev_dbg_ratelimited(&urb->dev->dev, + "Driver uses different interval (%d microframe%s) than xHCI (%d microframe%s)\n", + ep_interval, ep_interval == 1 ? "" : "s", + xhci_interval, xhci_interval == 1 ? "" : "s"); urb->interval = xhci_interval; /* Convert back to frames for LS/FS devices */ if (urb->dev->speed == USB_SPEED_LOW || |