|
@@ -3005,26 +3005,20 @@ static void giveback_first_trb(struct xhci_hcd *xhci, int slot_id,
|
|
|
xhci_ring_ep_doorbell(xhci, slot_id, ep_index, stream_id);
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * xHCI uses normal TRBs for both bulk and interrupt. When the interrupt
|
|
|
- * endpoint is to be serviced, the xHC will consume (at most) one TD. A TD
|
|
|
- * (comprised of sg list entries) can take several service intervals to
|
|
|
- * transmit.
|
|
|
- */
|
|
|
-int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|
|
- struct urb *urb, int slot_id, unsigned int ep_index)
|
|
|
+static void check_interval(struct xhci_hcd *xhci, struct urb *urb,
|
|
|
+ struct xhci_ep_ctx *ep_ctx)
|
|
|
{
|
|
|
- struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci,
|
|
|
- xhci->devs[slot_id]->out_ctx, ep_index);
|
|
|
int xhci_interval;
|
|
|
int ep_interval;
|
|
|
|
|
|
xhci_interval = EP_INTERVAL_TO_UFRAMES(le32_to_cpu(ep_ctx->ep_info));
|
|
|
ep_interval = urb->interval;
|
|
|
+
|
|
|
/* Convert to microframes */
|
|
|
if (urb->dev->speed == USB_SPEED_LOW ||
|
|
|
urb->dev->speed == USB_SPEED_FULL)
|
|
|
ep_interval *= 8;
|
|
|
+
|
|
|
/* FIXME change this to a warning and a suggestion to use the new API
|
|
|
* to set the polling interval (once the API is added).
|
|
|
*/
|
|
@@ -3039,6 +3033,22 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|
|
urb->dev->speed == USB_SPEED_FULL)
|
|
|
urb->interval /= 8;
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * xHCI uses normal TRBs for both bulk and interrupt. When the interrupt
|
|
|
+ * endpoint is to be serviced, the xHC will consume (at most) one TD. A TD
|
|
|
+ * (comprised of sg list entries) can take several service intervals to
|
|
|
+ * transmit.
|
|
|
+ */
|
|
|
+int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|
|
+ struct urb *urb, int slot_id, unsigned int ep_index)
|
|
|
+{
|
|
|
+ struct xhci_ep_ctx *ep_ctx;
|
|
|
+
|
|
|
+ ep_ctx = xhci_get_ep_ctx(xhci, xhci->devs[slot_id]->out_ctx, ep_index);
|
|
|
+ check_interval(xhci, urb, ep_ctx);
|
|
|
+
|
|
|
return xhci_queue_bulk_tx(xhci, mem_flags, urb, slot_id, ep_index);
|
|
|
}
|
|
|
|
|
@@ -3720,8 +3730,6 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|
|
struct xhci_ring *ep_ring;
|
|
|
struct xhci_ep_ctx *ep_ctx;
|
|
|
int start_frame;
|
|
|
- int xhci_interval;
|
|
|
- int ep_interval;
|
|
|
int num_tds, num_trbs, i;
|
|
|
int ret;
|
|
|
struct xhci_virt_ep *xep;
|
|
@@ -3749,26 +3757,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|
|
* Check interval value. This should be done before we start to
|
|
|
* calculate the start frame value.
|
|
|
*/
|
|
|
- xhci_interval = EP_INTERVAL_TO_UFRAMES(le32_to_cpu(ep_ctx->ep_info));
|
|
|
- ep_interval = urb->interval;
|
|
|
- /* Convert to microframes */
|
|
|
- if (urb->dev->speed == USB_SPEED_LOW ||
|
|
|
- urb->dev->speed == USB_SPEED_FULL)
|
|
|
- ep_interval *= 8;
|
|
|
- /* FIXME change this to a warning and a suggestion to use the new API
|
|
|
- * to set the polling interval (once the API is added).
|
|
|
- */
|
|
|
- if (xhci_interval != ep_interval) {
|
|
|
- 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 ||
|
|
|
- urb->dev->speed == USB_SPEED_FULL)
|
|
|
- urb->interval /= 8;
|
|
|
- }
|
|
|
+ check_interval(xhci, urb, ep_ctx);
|
|
|
|
|
|
/* Calculate the start frame and put it in urb->start_frame. */
|
|
|
if (HCC_CFC(xhci->hcc_params) && !list_empty(&ep_ring->td_list)) {
|