From 968b822c0023861ef6e4e15bb68582b36e89ad29 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 3 Nov 2011 12:03:38 -0400 Subject: USB: Remove the SAW_IRQ hcd flag The HCD_FLAG_SAW_IRQ flag was introduced in order to catch IRQ routing errors: If an URB was unlinked and the host controller hadn't gotten any IRQs, it seemed likely that the IRQs were directed to the wrong vector. This warning hasn't come up in many years, as far as I know; interrupt routing now seems to be well under control. Therefore there's no reason to keep the flag around any more. This patch (as1495) finally removes it. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers/usb/host/xhci-ring.c') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 940321b3ec68..2f8c17381c6c 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2389,17 +2389,7 @@ hw_died: irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd) { - irqreturn_t ret; - struct xhci_hcd *xhci; - - xhci = hcd_to_xhci(hcd); - set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); - if (xhci->shared_hcd) - set_bit(HCD_FLAG_SAW_IRQ, &xhci->shared_hcd->flags); - - ret = xhci_irq(hcd); - - return ret; + return xhci_irq(hcd); } /**** Endpoint Ring Operations ****/ -- cgit v1.2.3 From bc677d5b64644c399cd3db6a905453e611f402ab Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Sat, 3 Dec 2011 23:41:31 +0100 Subject: usb: fix number of mapped SG DMA entries Add a new field num_mapped_sgs to struct urb so that we have a place to store the number of mapped entries and can also retain the original value of entries in num_sgs. Previously, usb_hcd_map_urb_for_dma() would overwrite this with the number of mapped entries, which would break dma_unmap_sg() because it requires the original number of entries. This fixes warnings like the following when using USB storage devices: ------------[ cut here ]------------ WARNING: at lib/dma-debug.c:902 check_unmap+0x4e4/0x695() ehci_hcd 0000:00:12.2: DMA-API: device driver frees DMA sg list with different entry count [map count=4] [unmap count=1] Modules linked in: ohci_hcd ehci_hcd Pid: 0, comm: kworker/0:1 Not tainted 3.2.0-rc2+ #319 Call Trace: [] warn_slowpath_common+0x80/0x98 [] warn_slowpath_fmt+0x41/0x43 [] check_unmap+0x4e4/0x695 [] ? trace_hardirqs_off+0xd/0xf [] ? _raw_spin_unlock_irqrestore+0x33/0x50 [] debug_dma_unmap_sg+0xeb/0x117 [] usb_hcd_unmap_urb_for_dma+0x71/0x188 [] unmap_urb_for_dma+0x20/0x22 [] usb_hcd_giveback_urb+0x5d/0xc0 [] ehci_urb_done+0xf7/0x10c [ehci_hcd] [] qh_completions+0x429/0x4bd [ehci_hcd] [] ehci_work+0x95/0x9c0 [ehci_hcd] ... ---[ end trace f29ac88a5a48c580 ]--- Mapped at: [] debug_dma_map_sg+0x45/0x139 [] usb_hcd_map_urb_for_dma+0x22e/0x478 [] usb_hcd_submit_urb+0x63f/0x6fa [] usb_submit_urb+0x2c7/0x2de [] usb_sg_wait+0x55/0x161 Signed-off-by: Clemens Ladisch Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 5 ++--- drivers/usb/host/ehci-q.c | 2 +- drivers/usb/host/uhci-q.c | 2 +- drivers/usb/host/whci/qset.c | 4 ++-- drivers/usb/host/xhci-ring.c | 4 ++-- include/linux/usb.h | 1 + 6 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/usb/host/xhci-ring.c') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 43a89e4ba928..2cec49d1773d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1398,11 +1398,10 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, ret = -EAGAIN; else urb->transfer_flags |= URB_DMA_MAP_SG; - if (n != urb->num_sgs) { - urb->num_sgs = n; + urb->num_mapped_sgs = n; + if (n != urb->num_sgs) urb->transfer_flags |= URB_DMA_SG_COMBINED; - } } else if (urb->sg) { struct scatterlist *sg = urb->sg; urb->transfer_dma = dma_map_page( diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index f136f7f1c4f4..36ca5077cdf7 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -658,7 +658,7 @@ qh_urb_transaction ( /* * data transfer stage: buffer setup */ - i = urb->num_sgs; + i = urb->num_mapped_sgs; if (len > 0 && i > 0) { sg = urb->sg; buf = sg_dma_address(sg); diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index f6ca80ee4cec..d2c6f5ac4626 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -943,7 +943,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, if (usb_pipein(urb->pipe)) status |= TD_CTRL_SPD; - i = urb->num_sgs; + i = urb->num_mapped_sgs; if (len > 0 && i > 0) { sg = urb->sg; data = sg_dma_address(sg); diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index d6e175428618..a91712c8bff5 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c @@ -443,7 +443,7 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u remaining = urb->transfer_buffer_length; - for_each_sg(urb->sg, sg, urb->num_sgs, i) { + for_each_sg(urb->sg, sg, urb->num_mapped_sgs, i) { dma_addr_t dma_addr; size_t dma_remaining; dma_addr_t sp, ep; @@ -561,7 +561,7 @@ static int qset_add_urb_sg_linearize(struct whc *whc, struct whc_qset *qset, remaining = urb->transfer_buffer_length; - for_each_sg(urb->sg, sg, urb->num_sgs, i) { + for_each_sg(urb->sg, sg, urb->num_mapped_sgs, i) { size_t len; size_t sg_remaining; void *orig; diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 133ce302c860..d030f0b2bfa2 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2551,7 +2551,7 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb) struct scatterlist *sg; sg = NULL; - num_sgs = urb->num_sgs; + num_sgs = urb->num_mapped_sgs; temp = urb->transfer_buffer_length; xhci_dbg(xhci, "count sg list trbs: \n"); @@ -2735,7 +2735,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, return -EINVAL; num_trbs = count_sg_trbs_needed(xhci, urb); - num_sgs = urb->num_sgs; + num_sgs = urb->num_mapped_sgs; total_packet_count = roundup(urb->transfer_buffer_length, usb_endpoint_maxp(&urb->ep->desc)); diff --git a/include/linux/usb.h b/include/linux/usb.h index 2f05a7fa1ecf..4269c3f88148 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1221,6 +1221,7 @@ struct urb { void *transfer_buffer; /* (in) associated data buffer */ dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */ struct scatterlist *sg; /* (in) scatter gather buffer list */ + int num_mapped_sgs; /* (internal) mapped sg entries */ int num_sgs; /* (in) number of entries in the sg list */ u32 transfer_buffer_length; /* (in) data buffer length */ u32 actual_length; /* (return) actual transfer length */ -- cgit v1.2.3 From 2a9227a5eeaeb3f91e3a72ceea4fa59016ca5d20 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Tue, 25 Oct 2011 13:55:30 +0200 Subject: xhci: Remove scary warnings about transfer issues. Getting a short packet or a babble error is usually a recoverable error, so stop scaring users with warnings in dmesg when xHCI debugging is turned off. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ring.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/usb/host/xhci-ring.c') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index d030f0b2bfa2..560b7d7ff0c6 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1643,7 +1643,6 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, } break; case COMP_SHORT_TX: - xhci_warn(xhci, "WARN: short transfer on control ep\n"); if (td->urb->transfer_flags & URB_SHORT_NOT_OK) *status = -EREMOTEIO; else @@ -1985,7 +1984,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, xhci_dbg(xhci, "Stopped on No-op or Link TRB\n"); break; case COMP_STALL: - xhci_warn(xhci, "WARN: Stalled endpoint\n"); + xhci_dbg(xhci, "Stalled endpoint\n"); ep->ep_state |= EP_HALTED; status = -EPIPE; break; @@ -1995,11 +1994,11 @@ static int handle_tx_event(struct xhci_hcd *xhci, break; case COMP_SPLIT_ERR: case COMP_TX_ERR: - xhci_warn(xhci, "WARN: transfer error on endpoint\n"); + xhci_dbg(xhci, "Transfer error on endpoint\n"); status = -EPROTO; break; case COMP_BABBLE: - xhci_warn(xhci, "WARN: babble error on endpoint\n"); + xhci_dbg(xhci, "Babble error on endpoint\n"); status = -EOVERFLOW; break; case COMP_DB_ERR: -- cgit v1.2.3 From c4255f67a869adae49d2ef165bcc9436bb7ec0bb Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Tue, 25 Oct 2011 13:55:30 +0200 Subject: xhci: Remove useless sg-list debugging. Remove verbose debugging about scatter-gather lists, as we haven't had an issue with scatter gather list math for about a year now. The debugging didn't help before, and just clutters up the log file when trying to debug other issues. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ring.c | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'drivers/usb/host/xhci-ring.c') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 560b7d7ff0c6..4e4f587c144b 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2553,10 +2553,8 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb) num_sgs = urb->num_mapped_sgs; temp = urb->transfer_buffer_length; - xhci_dbg(xhci, "count sg list trbs: \n"); num_trbs = 0; for_each_sg(urb->sg, sg, num_sgs, i) { - unsigned int previous_total_trbs = num_trbs; unsigned int len = sg_dma_len(sg); /* Scatter gather list entries may cross 64KB boundaries */ @@ -2571,22 +2569,11 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb) num_trbs++; running_total += TRB_MAX_BUFF_SIZE; } - xhci_dbg(xhci, " sg #%d: dma = %#llx, len = %#x (%d), num_trbs = %d\n", - i, (unsigned long long)sg_dma_address(sg), - len, len, num_trbs - previous_total_trbs); - len = min_t(int, len, temp); temp -= len; if (temp == 0) break; } - xhci_dbg(xhci, "\n"); - if (!in_interrupt()) - xhci_dbg(xhci, "ep %#x - urb len = %d, sglist used, " - "num_trbs = %d\n", - urb->ep->desc.bEndpointAddress, - urb->transfer_buffer_length, - num_trbs); return num_trbs; } @@ -2772,8 +2759,6 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, trb_buff_len = min_t(int, trb_buff_len, this_sg_len); if (trb_buff_len > urb->transfer_buffer_length) trb_buff_len = urb->transfer_buffer_length; - xhci_dbg(xhci, "First length to xfer from 1st sglist entry = %u\n", - trb_buff_len); first_trb = true; /* Queue the first TRB, even if it's zero-length */ @@ -2805,11 +2790,6 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, if (usb_urb_dir_in(urb)) field |= TRB_ISP; - xhci_dbg(xhci, " sg entry: dma = %#x, len = %#x (%d), " - "64KB boundary at %#x, end dma = %#x\n", - (unsigned int) addr, trb_buff_len, trb_buff_len, - (unsigned int) (addr + TRB_MAX_BUFF_SIZE) & ~(TRB_MAX_BUFF_SIZE - 1), - (unsigned int) addr + trb_buff_len); if (TRB_MAX_BUFF_SIZE - (addr & (TRB_MAX_BUFF_SIZE - 1)) < trb_buff_len) { xhci_warn(xhci, "WARN: sg dma xfer crosses 64KB boundaries!\n"); -- cgit v1.2.3 From 3d616f5af2a1cf7acce712993402b0ccbb2ff2cc Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 22 Dec 2011 15:42:25 -0800 Subject: xhci: Remove debugging for individual transfers. Users can trace the submission of URBs through USBmon, so it makes no sense to have duplicate debugging in the xHCI driver. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ring.c | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'drivers/usb/host/xhci-ring.c') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 4e4f587c144b..8638e101b3c1 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1627,7 +1627,6 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index); trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len)); - xhci_debug_trb(xhci, xhci->event_ring->dequeue); switch (trb_comp_code) { case COMP_SUCCESS: if (event_trb == ep_ring->dequeue) { @@ -2895,15 +2894,6 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, } /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */ - if (!in_interrupt()) - xhci_dbg(xhci, "ep %#x - urb len = %#x (%d), " - "addr = %#llx, num_trbs = %d\n", - urb->ep->desc.bEndpointAddress, - urb->transfer_buffer_length, - urb->transfer_buffer_length, - (unsigned long long)urb->transfer_dma, - num_trbs); - ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index, urb->stream_id, num_trbs, urb, 0, false, mem_flags); @@ -3024,9 +3014,6 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, if (!urb->setup_packet) return -EINVAL; - if (!in_interrupt()) - xhci_dbg(xhci, "Queueing ctrl tx for slot id %d, ep %d\n", - slot_id, ep_index); /* 1 TRB for setup, 1 for status */ num_trbs = 2; /* @@ -3218,15 +3205,6 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, return -EINVAL; } - if (!in_interrupt()) - xhci_dbg(xhci, "ep %#x - urb len = %#x (%d)," - " addr = %#llx, num_tds = %d\n", - urb->ep->desc.bEndpointAddress, - urb->transfer_buffer_length, - urb->transfer_buffer_length, - (unsigned long long)urb->transfer_dma, - num_tds); - start_addr = (u64) urb->transfer_dma; start_trb = &ep_ring->enqueue->generic; start_cycle = ep_ring->cycle_state; -- cgit v1.2.3 From b0a465d86af4d1b0b8ce64a413f9b9e1cf5a557e Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 15 Dec 2011 17:30:45 -0800 Subject: xhci: Remove debugging about toggling cycle bits. The code for toggling the cycle bits when the ring wraps around has worked for years. The print statement alone is not enough to indicate there's something wrong with that code. Now that full transfer tracing has been ripped out, the print statement or lack thereof won't help without context of where the enqueue pointer is. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ring.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers/usb/host/xhci-ring.c') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 8638e101b3c1..1fdb7e1cca3f 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -155,10 +155,6 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer while (last_trb(xhci, ring, ring->deq_seg, next)) { if (consumer && last_trb_on_last_seg(xhci, ring, ring->deq_seg, next)) { ring->cycle_state = (ring->cycle_state ? 0 : 1); - if (!in_interrupt()) - xhci_dbg(xhci, "Toggle cycle state for ring %p = %i\n", - ring, - (unsigned int) ring->cycle_state); } ring->deq_seg = ring->deq_seg->next; ring->dequeue = ring->deq_seg->trbs; @@ -231,10 +227,6 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, /* Toggle the cycle bit after the last ring segment. */ if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) { ring->cycle_state = (ring->cycle_state ? 0 : 1); - if (!in_interrupt()) - xhci_dbg(xhci, "Toggle cycle state for ring %p = %i\n", - ring, - (unsigned int) ring->cycle_state); } } ring->enq_seg = ring->enq_seg->next; @@ -2476,11 +2468,6 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, /* Toggle the cycle bit after the last ring segment. */ if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) { ring->cycle_state = (ring->cycle_state ? 0 : 1); - if (!in_interrupt()) { - xhci_dbg(xhci, "queue_trb: Toggle cycle " - "state for ring %p = %i\n", - ring, (unsigned int)ring->cycle_state); - } } ring->enq_seg = ring->enq_seg->next; ring->enqueue = ring->enq_seg->trbs; -- cgit v1.2.3 From 79688acfb5e124fcf586add00af32a2a1a532c64 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 19 Dec 2011 16:56:04 -0800 Subject: xhci: Be less verbose during URB cancellation. With devices that can need up to 128 segments (with 64 TRBs per segment), we can't afford to print out the entire endpoint ring every time an URB is canceled. Instead, print the offset of the TRB, along with device pathname and endpoint number. Only print DMA addresses, since virtual addresses of internal structures are not useful. Change the cancellation code to be more clear about what steps of the cancellation it is in the process of doing (queueing the request, handling the stop endpoint command, turning the TDs into no-ops, or moving the dequeue pointers). Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ring.c | 15 ++++++--------- drivers/usb/host/xhci.c | 19 +++++++++++-------- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers/usb/host/xhci-ring.c') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 1fdb7e1cca3f..f34a268c6ccd 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -552,12 +552,9 @@ 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, "Cancel TRB %p (0x%llx dma) " - "in seg %p (0x%llx dma)\n", - cur_trb, - (unsigned long long)xhci_trb_virt_to_dma(cur_seg, cur_trb), - cur_seg, - (unsigned long long)cur_seg->dma); + xhci_dbg(xhci, "TRB to noop at offset 0x%llx\n", + (unsigned long long) + xhci_trb_virt_to_dma(cur_seg, cur_trb)); } if (cur_trb == cur_td->last_trb) break; @@ -697,9 +694,9 @@ 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, "Cancelling TD starting at %p, 0x%llx (dma).\n", - cur_td->first_trb, - (unsigned long long)xhci_trb_virt_to_dma(cur_td->start_seg, cur_td->first_trb)); + xhci_dbg(xhci, "Removing canceled TD starting at 0x%llx (dma).\n", + (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); if (!ep_ring) { /* This shouldn't happen unless a driver is mucking diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 0968b856ef0a..f3d0b8d96440 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1333,9 +1333,6 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) goto done; } - xhci_dbg(xhci, "Cancel URB %p\n", urb); - xhci_dbg(xhci, "Event ring:\n"); - xhci_debug_ring(xhci, xhci->event_ring); ep_index = xhci_get_endpoint_index(&urb->ep->desc); ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index]; ep_ring = xhci_urb_to_transfer_ring(xhci, urb); @@ -1344,12 +1341,18 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) goto done; } - xhci_dbg(xhci, "Endpoint ring:\n"); - xhci_debug_ring(xhci, ep_ring); - urb_priv = urb->hcpriv; - - for (i = urb_priv->td_cnt; i < urb_priv->length; i++) { + i = urb_priv->td_cnt; + if (i < urb_priv->length) + xhci_dbg(xhci, "Cancel URB %p, dev %s, ep 0x%x, " + "starting at offset 0x%llx\n", + urb, urb->dev->devpath, + urb->ep->desc.bEndpointAddress, + (unsigned long long) xhci_trb_virt_to_dma( + urb_priv->td[i]->start_seg, + urb_priv->td[i]->first_trb)); + + for (; i < urb_priv->length; i++) { td = urb_priv->td[i]; list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list); } -- cgit v1.2.3 From 9258c0b26b7d2e819b157ec394edaf7a5853cebb Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 1 Dec 2011 14:50:30 -0800 Subject: xhci: Better debugging for critical host errors. When a host controller gives a bad event TRB, we should print out the contents of the TRB as a warning so that users don't have to recompile their kernel to get information about what went wrong. Also, print out the event ring if they have xHCI debugging turned on, since previous events can often explain what happened before the bad TRB occurred. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ring.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers/usb/host/xhci-ring.c') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index f34a268c6ccd..b0a85459652e 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1933,6 +1933,15 @@ static int handle_tx_event(struct xhci_hcd *xhci, xdev = xhci->devs[slot_id]; if (!xdev) { xhci_err(xhci, "ERROR Transfer event pointed to bad slot\n"); + xhci_err(xhci, "@%016llx %08x %08x %08x %08x\n", + xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, + xhci->event_ring->dequeue), + lower_32_bits(le64_to_cpu(event->buffer)), + upper_32_bits(le64_to_cpu(event->buffer)), + le32_to_cpu(event->transfer_len), + le32_to_cpu(event->flags)); + xhci_dbg(xhci, "Event ring:\n"); + xhci_debug_segment(xhci, xhci->event_ring->deq_seg); return -ENODEV; } @@ -1946,6 +1955,15 @@ static int handle_tx_event(struct xhci_hcd *xhci, EP_STATE_DISABLED) { xhci_err(xhci, "ERROR Transfer event for disabled endpoint " "or incorrect stream ring\n"); + xhci_err(xhci, "@%016llx %08x %08x %08x %08x\n", + xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, + xhci->event_ring->dequeue), + lower_32_bits(le64_to_cpu(event->buffer)), + upper_32_bits(le64_to_cpu(event->buffer)), + le32_to_cpu(event->transfer_len), + le32_to_cpu(event->flags)); + xhci_dbg(xhci, "Event ring:\n"); + xhci_debug_segment(xhci, xhci->event_ring->deq_seg); return -ENODEV; } -- cgit v1.2.3 From e910b440da9f766f2623479be721032fecff98c3 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 4 Jan 2012 16:54:12 -0800 Subject: xhci: Clean up 32-bit build warnings. Randy Dunlap points out that commit 9258c0b2 "xhci: Better debugging for critical host errors." introduces some new build warnings on 32-bit builds: drivers/usb/host/xhci-ring.c:1936:3: warning: format '%016llx' expects type 'long long unsigned int', but argument 3 has type 'dma_addr_t' drivers/usb/host/xhci-ring.c:1958:3: warning: format '%016llx' expects type 'long long unsigned int', but argument 3 has type 'dma_addr_t' Cast the results of xhci_trb_virt_to_dma() from a dma_addr_t to an unsigned long long. Signed-off-by: Sarah Sharp Reported-by: Randy Dunlap --- drivers/usb/host/xhci-ring.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/usb/host/xhci-ring.c') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index b0a85459652e..b90e1386418b 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1934,7 +1934,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, if (!xdev) { xhci_err(xhci, "ERROR Transfer event pointed to bad slot\n"); xhci_err(xhci, "@%016llx %08x %08x %08x %08x\n", - xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, + (unsigned long long) xhci_trb_virt_to_dma( + xhci->event_ring->deq_seg, xhci->event_ring->dequeue), lower_32_bits(le64_to_cpu(event->buffer)), upper_32_bits(le64_to_cpu(event->buffer)), @@ -1956,7 +1957,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, xhci_err(xhci, "ERROR Transfer event for disabled endpoint " "or incorrect stream ring\n"); xhci_err(xhci, "@%016llx %08x %08x %08x %08x\n", - xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, + (unsigned long long) xhci_trb_virt_to_dma( + xhci->event_ring->deq_seg, xhci->event_ring->dequeue), lower_32_bits(le64_to_cpu(event->buffer)), upper_32_bits(le64_to_cpu(event->buffer)), -- cgit v1.2.3