aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-ring.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r--drivers/usb/host/xhci-ring.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index aac379e1c883..ff5e6bc2299d 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1072,7 +1072,12 @@ static int handle_tx_event(struct xhci_hcd *xhci,
1072 else 1072 else
1073 status = 0; 1073 status = 0;
1074 } else { 1074 } else {
1075 xhci_dbg(xhci, "Successful bulk transfer!\n"); 1075 if (usb_endpoint_xfer_bulk(&td->urb->ep->desc))
1076 xhci_dbg(xhci, "Successful bulk "
1077 "transfer!\n");
1078 else
1079 xhci_dbg(xhci, "Successful interrupt "
1080 "transfer!\n");
1076 status = 0; 1081 status = 0;
1077 } 1082 }
1078 break; 1083 break;
@@ -1464,6 +1469,47 @@ static void giveback_first_trb(struct xhci_hcd *xhci, int slot_id,
1464 ring_ep_doorbell(xhci, slot_id, ep_index); 1469 ring_ep_doorbell(xhci, slot_id, ep_index);
1465} 1470}
1466 1471
1472/*
1473 * xHCI uses normal TRBs for both bulk and interrupt. When the interrupt
1474 * endpoint is to be serviced, the xHC will consume (at most) one TD. A TD
1475 * (comprised of sg list entries) can take several service intervals to
1476 * transmit.
1477 */
1478int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
1479 struct urb *urb, int slot_id, unsigned int ep_index)
1480{
1481 struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci,
1482 xhci->devs[slot_id]->out_ctx, ep_index);
1483 int xhci_interval;
1484 int ep_interval;
1485
1486 xhci_interval = EP_INTERVAL_TO_UFRAMES(ep_ctx->ep_info);
1487 ep_interval = urb->interval;
1488 /* Convert to microframes */
1489 if (urb->dev->speed == USB_SPEED_LOW ||
1490 urb->dev->speed == USB_SPEED_FULL)
1491 ep_interval *= 8;
1492 /* FIXME change this to a warning and a suggestion to use the new API
1493 * to set the polling interval (once the API is added).
1494 */
1495 if (xhci_interval != ep_interval) {
1496 if (!printk_ratelimit())
1497 dev_dbg(&urb->dev->dev, "Driver uses different interval"
1498 " (%d microframe%s) than xHCI "
1499 "(%d microframe%s)\n",
1500 ep_interval,
1501 ep_interval == 1 ? "" : "s",
1502 xhci_interval,
1503 xhci_interval == 1 ? "" : "s");
1504 urb->interval = xhci_interval;
1505 /* Convert back to frames for LS/FS devices */
1506 if (urb->dev->speed == USB_SPEED_LOW ||
1507 urb->dev->speed == USB_SPEED_FULL)
1508 urb->interval /= 8;
1509 }
1510 return xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index);
1511}
1512
1467static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, 1513static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
1468 struct urb *urb, int slot_id, unsigned int ep_index) 1514 struct urb *urb, int slot_id, unsigned int ep_index)
1469{ 1515{