PERFORCE change 182116 for review
Hans Petter Selasky
hselasky at skunkworks.freebsd.org
Wed Aug 11 18:25:55 UTC 2010
http://p4web.freebsd.org/@@182116?ac=10
Change 182116 by hselasky at hselasky_laptop001 on 2010/08/08 23:56:18
USB controller (XHCI):
- fix problem with multi enter of USB transfers.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/controller/xhci.c#22 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/controller/xhci.c#22 (text+ko) ====
@@ -1675,6 +1675,8 @@
x = XREAD4(temp.sc, runt, XHCI_MFINDEX);
+ DPRINTF("MFINDEX=0x%08x\n", x);
+
switch (usbd_get_speed(xfer->xroot->udev)) {
case USB_SPEED_FULL:
shift = 3;
@@ -2408,18 +2410,6 @@
return (USB_ERR_NOMEM);
}
- /* check if transfer is not already on interrupt queue */
- if (xfer->wait_queue != &xfer->xroot->bus->intr_q) {
-
- /* remove transfer from pipe queue, if any */
-
- usbd_transfer_dequeue(xfer);
-
- /* add transfer last on interrupt queue */
-
- usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
- }
-
/* check for stopped condition, after putting transfer on interrupt queue */
if (pepext->trb_running == 0) {
struct xhci_softc *sc = XHCI_BUS2SC(xfer->xroot->bus);
@@ -2493,10 +2483,6 @@
xhci_endpoint_doorbell(xfer);
- /* start timeout, if any */
- if (xfer->timeout != 0)
- usbd_transfer_timeout_ms(xfer, &xhci_timeout, xfer->timeout);
-
return (0);
}
@@ -2566,6 +2552,42 @@
}
static void
+xhci_device_generic_multi_enter(struct usb_endpoint *ep,
+ struct usb_xfer *enter_xfer)
+{
+ struct usb_xfer *xfer;
+
+ /* check if there is a current transfer */
+ xfer = ep->endpoint_q.curr;
+ if (xfer == NULL)
+ return;
+
+ /*
+ * Check if the current transfer is started and then pickup
+ * the next one, if any. Else wait for next start event due to
+ * block on failure feature.
+ */
+ if (!xfer->flags_int.bandwidth_reclaimed)
+ return;
+
+ xfer = TAILQ_FIRST(&ep->endpoint_q.head);
+ if (xfer == NULL) {
+ /*
+ * In case of enter we have to consider that the
+ * transfer is queued by the USB core after the enter
+ * method is called.
+ */
+ xfer = enter_xfer;
+
+ if (xfer == NULL)
+ return;
+ }
+
+ /* try to multi buffer */
+ xhci_transfer_insert(xfer);
+}
+
+static void
xhci_device_generic_enter(struct usb_xfer *xfer)
{
DPRINTF("\n");
@@ -2573,8 +2595,7 @@
/* setup TD's and QH */
xhci_setup_generic_chain(xfer);
- /* try to insert xfer on HW queue */
- xhci_transfer_insert(xfer);
+ xhci_device_generic_multi_enter(xfer->endpoint, xfer);
}
static void
@@ -2584,6 +2605,16 @@
/* try to insert xfer on HW queue */
xhci_transfer_insert(xfer);
+
+ /* try to multi buffer */
+ xhci_device_generic_multi_enter(xfer->endpoint, NULL);
+
+ /* add transfer last on interrupt queue */
+ usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
+
+ /* start timeout, if any */
+ if (xfer->timeout != 0)
+ usbd_transfer_timeout_ms(xfer, &xhci_timeout, xfer->timeout);
}
struct usb_pipe_methods xhci_device_generic_methods =
@@ -2594,7 +2625,6 @@
.start = xhci_device_generic_start,
};
-
/*------------------------------------------------------------------------*
* xhci root HUB support
*------------------------------------------------------------------------*
@@ -3429,8 +3459,12 @@
}
TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
- /* try to insert transfer in hardware schedule */
- xhci_transfer_insert(xfer);
+
+ /* try to insert xfer on HW queue */
+ xhci_transfer_insert(xfer);
+
+ /* try to multi buffer */
+ xhci_device_generic_multi_enter(xfer->endpoint, NULL);
}
}
More information about the p4-projects
mailing list