diff options
-rw-r--r-- | drivers/usb/host/xhci-hcd.c | 5 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 48 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 3 |
3 files changed, 55 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c index 1d4a1e3f9533..e478a63488fb 100644 --- a/drivers/usb/host/xhci-hcd.c +++ b/drivers/usb/host/xhci-hcd.c | |||
@@ -727,6 +727,11 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) | |||
727 | ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, | 727 | ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, |
728 | slot_id, ep_index); | 728 | slot_id, ep_index); |
729 | spin_unlock_irqrestore(&xhci->lock, flags); | 729 | spin_unlock_irqrestore(&xhci->lock, flags); |
730 | } else if (usb_endpoint_xfer_int(&urb->ep->desc)) { | ||
731 | spin_lock_irqsave(&xhci->lock, flags); | ||
732 | ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, | ||
733 | slot_id, ep_index); | ||
734 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
730 | } else { | 735 | } else { |
731 | ret = -EINVAL; | 736 | ret = -EINVAL; |
732 | } | 737 | } |
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 | */ | ||
1478 | int 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 | |||
1467 | static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | 1513 | static 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 | { |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index bc64b500feb8..a7728aa91582 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -581,6 +581,7 @@ struct xhci_ep_ctx { | |||
581 | /* bit 15 is Linear Stream Array */ | 581 | /* bit 15 is Linear Stream Array */ |
582 | /* Interval - period between requests to an endpoint - 125u increments. */ | 582 | /* Interval - period between requests to an endpoint - 125u increments. */ |
583 | #define EP_INTERVAL(p) ((p & 0xff) << 16) | 583 | #define EP_INTERVAL(p) ((p & 0xff) << 16) |
584 | #define EP_INTERVAL_TO_UFRAMES(p) (1 << (((p) >> 16) & 0xff)) | ||
584 | 585 | ||
585 | /* ep_info2 bitmasks */ | 586 | /* ep_info2 bitmasks */ |
586 | /* | 587 | /* |
@@ -1223,6 +1224,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, | |||
1223 | int slot_id, unsigned int ep_index); | 1224 | int slot_id, unsigned int ep_index); |
1224 | int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, | 1225 | int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, |
1225 | int slot_id, unsigned int ep_index); | 1226 | int slot_id, unsigned int ep_index); |
1227 | int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, | ||
1228 | int slot_id, unsigned int ep_index); | ||
1226 | int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | 1229 | int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, |
1227 | u32 slot_id); | 1230 | u32 slot_id); |
1228 | int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | 1231 | int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, |