5544c1b
From f9416f401c9eac3f69b4705a999c6ea1ff457016 Mon Sep 17 00:00:00 2001
c8dfc65
From: Gerd Hoffmann <kraxel@redhat.com>
c8dfc65
Date: Fri, 17 Aug 2012 14:05:21 +0200
5544c1b
Subject: [PATCH] xhci: rip out background transfer code
c8dfc65
c8dfc65
original xhci code (the one which used libusb directly) used to use
c8dfc65
'background transfers' for iso streams.  In upstream qemu the iso
c8dfc65
stream buffering is handled by usb-host & usb-redir, so we will
c8dfc65
never ever need this.  It has been left in as reference, but is dead
c8dfc65
code anyway.  Rip it out.
c8dfc65
c8dfc65
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
5544c1b
(cherry picked from commit 331e9406f152b6bae6859a153d36e5076c58901d)
5544c1b
5544c1b
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
c8dfc65
---
c8dfc65
 hw/usb/hcd-xhci.c | 223 +-----------------------------------------------------
c8dfc65
 1 file changed, 4 insertions(+), 219 deletions(-)
c8dfc65
c8dfc65
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
c8dfc65
index 3eb27fa..c0a2476 100644
c8dfc65
--- a/hw/usb/hcd-xhci.c
c8dfc65
+++ b/hw/usb/hcd-xhci.c
c8dfc65
@@ -45,8 +45,6 @@
c8dfc65
 #define MAXPORTS (USB2_PORTS+USB3_PORTS)
c8dfc65
 
c8dfc65
 #define TD_QUEUE 24
c8dfc65
-#define BG_XFERS 8
c8dfc65
-#define BG_PKTS 8
c8dfc65
 
c8dfc65
 /* Very pessimistic, let's hope it's enough for all cases */
c8dfc65
 #define EV_QUEUE (((3*TD_QUEUE)+16)*MAXSLOTS)
c8dfc65
@@ -311,13 +309,11 @@ typedef struct XHCITransfer {
c8dfc65
     bool running_retry;
c8dfc65
     bool cancelled;
c8dfc65
     bool complete;
c8dfc65
-    bool backgrounded;
c8dfc65
     unsigned int iso_pkts;
c8dfc65
     unsigned int slotid;
c8dfc65
     unsigned int epid;
c8dfc65
     bool in_xfer;
c8dfc65
     bool iso_xfer;
c8dfc65
-    bool bg_xfer;
c8dfc65
 
c8dfc65
     unsigned int trb_count;
c8dfc65
     unsigned int trb_alloced;
c8dfc65
@@ -340,14 +336,9 @@ typedef struct XHCIEPContext {
c8dfc65
     unsigned int comp_xfer;
c8dfc65
     XHCITransfer transfers[TD_QUEUE];
c8dfc65
     XHCITransfer *retry;
c8dfc65
-    bool bg_running;
c8dfc65
-    bool bg_updating;
c8dfc65
-    unsigned int next_bg;
c8dfc65
-    XHCITransfer bg_transfers[BG_XFERS];
c8dfc65
     EPType type;
c8dfc65
     dma_addr_t pctx;
c8dfc65
     unsigned int max_psize;
c8dfc65
-    bool has_bg;
c8dfc65
     uint32_t state;
c8dfc65
 } XHCIEPContext;
c8dfc65
 
c8dfc65
@@ -866,10 +857,6 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
c8dfc65
     epctx->pctx = pctx;
c8dfc65
     epctx->max_psize = ctx[1]>>16;
c8dfc65
     epctx->max_psize *= 1+((ctx[1]>>8)&0xff);
c8dfc65
-    epctx->has_bg = false;
c8dfc65
-    if (epctx->type == ET_ISO_IN) {
c8dfc65
-        epctx->has_bg = true;
c8dfc65
-    }
c8dfc65
     DPRINTF("xhci: endpoint %d.%d max transaction (burst) size is %d\n",
c8dfc65
             epid/2, epid%2, epctx->max_psize);
c8dfc65
     for (i = 0; i < ARRAY_SIZE(epctx->transfers); i++) {
c8dfc65
@@ -916,9 +903,6 @@ static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid,
c8dfc65
             t->running_retry = 0;
c8dfc65
             epctx->retry = NULL;
c8dfc65
         }
c8dfc65
-        if (t->backgrounded) {
c8dfc65
-            t->backgrounded = 0;
c8dfc65
-        }
c8dfc65
         if (t->trbs) {
c8dfc65
             g_free(t->trbs);
c8dfc65
         }
c8dfc65
@@ -932,25 +916,6 @@ static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid,
c8dfc65
         t->data_length = t->data_alloced = 0;
c8dfc65
         xferi = (xferi + 1) % TD_QUEUE;
c8dfc65
     }
c8dfc65
-    if (epctx->has_bg) {
c8dfc65
-        xferi = epctx->next_bg;
c8dfc65
-        for (i = 0; i < BG_XFERS; i++) {
c8dfc65
-            XHCITransfer *t = &epctx->bg_transfers[xferi];
c8dfc65
-            if (t->running_async) {
c8dfc65
-                usb_cancel_packet(&t->packet);
c8dfc65
-                t->running_async = 0;
c8dfc65
-                t->cancelled = 1;
c8dfc65
-                DPRINTF("xhci: cancelling bg transfer %d, waiting for it to complete...\n", i);
c8dfc65
-                killed++;
c8dfc65
-            }
c8dfc65
-            if (t->data) {
c8dfc65
-                g_free(t->data);
c8dfc65
-            }
c8dfc65
-
c8dfc65
-            t->data = NULL;
c8dfc65
-            xferi = (xferi + 1) % BG_XFERS;
c8dfc65
-        }
c8dfc65
-    }
c8dfc65
     return killed;
c8dfc65
 }
c8dfc65
 
c8dfc65
@@ -1231,160 +1196,6 @@ static void xhci_stall_ep(XHCITransfer *xfer)
c8dfc65
 static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer,
c8dfc65
                        XHCIEPContext *epctx);
c8dfc65
 
c8dfc65
-static void xhci_bg_update(XHCIState *xhci, XHCIEPContext *epctx)
c8dfc65
-{
c8dfc65
-    if (epctx->bg_updating) {
c8dfc65
-        return;
c8dfc65
-    }
c8dfc65
-    DPRINTF("xhci_bg_update(%p, %p)\n", xhci, epctx);
c8dfc65
-    assert(epctx->has_bg);
c8dfc65
-    DPRINTF("xhci: fg=%d bg=%d\n", epctx->comp_xfer, epctx->next_bg);
c8dfc65
-    epctx->bg_updating = 1;
c8dfc65
-    while (epctx->transfers[epctx->comp_xfer].backgrounded &&
c8dfc65
-           epctx->bg_transfers[epctx->next_bg].complete) {
c8dfc65
-        XHCITransfer *fg = &epctx->transfers[epctx->comp_xfer];
c8dfc65
-        XHCITransfer *bg = &epctx->bg_transfers[epctx->next_bg];
c8dfc65
-#if 0
c8dfc65
-        DPRINTF("xhci: completing fg %d from bg %d.%d (stat: %d)\n",
c8dfc65
-                epctx->comp_xfer, epctx->next_bg, bg->cur_pkt,
c8dfc65
-                bg->usbxfer->iso_packet_desc[bg->cur_pkt].status
c8dfc65
-               );
c8dfc65
-#endif
c8dfc65
-        assert(epctx->type == ET_ISO_IN);
c8dfc65
-        assert(bg->iso_xfer);
c8dfc65
-        assert(bg->in_xfer);
c8dfc65
-        uint8_t *p = bg->data + bg->cur_pkt * bg->pktsize;
c8dfc65
-#if 0
c8dfc65
-        int len = bg->usbxfer->iso_packet_desc[bg->cur_pkt].actual_length;
c8dfc65
-        fg->status = libusb_to_ccode(bg->usbxfer->iso_packet_desc[bg->cur_pkt].status);
c8dfc65
-#else
c8dfc65
-        int len = 0;
c8dfc65
-        FIXME();
c8dfc65
-#endif
c8dfc65
-        fg->complete = 1;
c8dfc65
-        fg->backgrounded = 0;
c8dfc65
-
c8dfc65
-        if (fg->status == CC_STALL_ERROR) {
c8dfc65
-            xhci_stall_ep(fg);
c8dfc65
-        }
c8dfc65
-
c8dfc65
-        xhci_xfer_data(fg, p, len, 1, 0, 1);
c8dfc65
-
c8dfc65
-        epctx->comp_xfer++;
c8dfc65
-        if (epctx->comp_xfer == TD_QUEUE) {
c8dfc65
-            epctx->comp_xfer = 0;
c8dfc65
-        }
c8dfc65
-        DPRINTF("next fg xfer: %d\n", epctx->comp_xfer);
c8dfc65
-        bg->cur_pkt++;
c8dfc65
-        if (bg->cur_pkt == bg->pkts) {
c8dfc65
-            bg->complete = 0;
c8dfc65
-            if (xhci_submit(xhci, bg, epctx) < 0) {
c8dfc65
-                fprintf(stderr, "xhci: bg resubmit failed\n");
c8dfc65
-            }
c8dfc65
-            epctx->next_bg++;
c8dfc65
-            if (epctx->next_bg == BG_XFERS) {
c8dfc65
-                epctx->next_bg = 0;
c8dfc65
-            }
c8dfc65
-            DPRINTF("next bg xfer: %d\n", epctx->next_bg);
c8dfc65
-
c8dfc65
-        xhci_kick_ep(xhci, fg->slotid, fg->epid);
c8dfc65
-        }
c8dfc65
-    }
c8dfc65
-    epctx->bg_updating = 0;
c8dfc65
-}
c8dfc65
-
c8dfc65
-#if 0
c8dfc65
-static void xhci_xfer_cb(struct libusb_transfer *transfer)
c8dfc65
-{
c8dfc65
-    XHCIState *xhci;
c8dfc65
-    XHCITransfer *xfer;
c8dfc65
-
c8dfc65
-    xfer = (XHCITransfer *)transfer->user_data;
c8dfc65
-    xhci = xfer->xhci;
c8dfc65
-
c8dfc65
-    DPRINTF("xhci_xfer_cb(slot=%d, ep=%d, status=%d)\n", xfer->slotid,
c8dfc65
-            xfer->epid, transfer->status);
c8dfc65
-
c8dfc65
-    assert(xfer->slotid >= 1 && xfer->slotid <= MAXSLOTS);
c8dfc65
-    assert(xfer->epid >= 1 && xfer->epid <= 31);
c8dfc65
-
c8dfc65
-    if (xfer->cancelled) {
c8dfc65
-        DPRINTF("xhci: transfer cancelled, not reporting anything\n");
c8dfc65
-        xfer->running = 0;
c8dfc65
-        return;
c8dfc65
-    }
c8dfc65
-
c8dfc65
-    XHCIEPContext *epctx;
c8dfc65
-    XHCISlot *slot;
c8dfc65
-    slot = &xhci->slots[xfer->slotid-1];
c8dfc65
-    assert(slot->eps[xfer->epid-1]);
c8dfc65
-    epctx = slot->eps[xfer->epid-1];
c8dfc65
-
c8dfc65
-    if (xfer->bg_xfer) {
c8dfc65
-        DPRINTF("xhci: background transfer, updating\n");
c8dfc65
-        xfer->complete = 1;
c8dfc65
-        xfer->running = 0;
c8dfc65
-        xhci_bg_update(xhci, epctx);
c8dfc65
-        return;
c8dfc65
-    }
c8dfc65
-
c8dfc65
-    if (xfer->iso_xfer) {
c8dfc65
-        transfer->status = transfer->iso_packet_desc[0].status;
c8dfc65
-        transfer->actual_length = transfer->iso_packet_desc[0].actual_length;
c8dfc65
-    }
c8dfc65
-
c8dfc65
-    xfer->status = libusb_to_ccode(transfer->status);
c8dfc65
-
c8dfc65
-    xfer->complete = 1;
c8dfc65
-    xfer->running = 0;
c8dfc65
-
c8dfc65
-    if (transfer->status == LIBUSB_TRANSFER_STALL)
c8dfc65
-        xhci_stall_ep(xhci, epctx, xfer);
c8dfc65
-
c8dfc65
-    DPRINTF("xhci: transfer actual length = %d\n", transfer->actual_length);
c8dfc65
-
c8dfc65
-    if (xfer->in_xfer) {
c8dfc65
-        if (xfer->epid == 1) {
c8dfc65
-            xhci_xfer_data(xhci, xfer, xfer->data + 8,
c8dfc65
-                           transfer->actual_length, 1, 0, 1);
c8dfc65
-        } else {
c8dfc65
-            xhci_xfer_data(xhci, xfer, xfer->data,
c8dfc65
-                           transfer->actual_length, 1, 0, 1);
c8dfc65
-        }
c8dfc65
-    } else {
c8dfc65
-        xhci_xfer_data(xhci, xfer, NULL, transfer->actual_length, 0, 0, 1);
c8dfc65
-    }
c8dfc65
-
c8dfc65
-    xhci_kick_ep(xhci, xfer->slotid, xfer->epid);
c8dfc65
-}
c8dfc65
-
c8dfc65
-static int xhci_hle_control(XHCIState *xhci, XHCITransfer *xfer,
c8dfc65
-                            uint8_t bmRequestType, uint8_t bRequest,
c8dfc65
-                            uint16_t wValue, uint16_t wIndex, uint16_t wLength)
c8dfc65
-{
c8dfc65
-    uint16_t type_req = (bmRequestType << 8) | bRequest;
c8dfc65
-
c8dfc65
-    switch (type_req) {
c8dfc65
-        case 0x0000 | USB_REQ_SET_CONFIGURATION:
c8dfc65
-            DPRINTF("xhci: HLE switch configuration\n");
c8dfc65
-            return xhci_switch_config(xhci, xfer->slotid, wValue) == 0;
c8dfc65
-        case 0x0100 | USB_REQ_SET_INTERFACE:
c8dfc65
-            DPRINTF("xhci: HLE set interface altsetting\n");
c8dfc65
-            return xhci_set_iface_alt(xhci, xfer->slotid, wIndex, wValue) == 0;
c8dfc65
-        case 0x0200 | USB_REQ_CLEAR_FEATURE:
c8dfc65
-            if (wValue == 0) { // endpoint halt
c8dfc65
-                DPRINTF("xhci: HLE clear halt\n");
c8dfc65
-                return xhci_clear_halt(xhci, xfer->slotid, wIndex);
c8dfc65
-            }
c8dfc65
-        case 0x0000 | USB_REQ_SET_ADDRESS:
c8dfc65
-            fprintf(stderr, "xhci: warn: illegal SET_ADDRESS request\n");
c8dfc65
-            return 0;
c8dfc65
-        default:
c8dfc65
-            return 0;
c8dfc65
-    }
c8dfc65
-}
c8dfc65
-#endif
c8dfc65
-
c8dfc65
 static int xhci_setup_packet(XHCITransfer *xfer, USBDevice *dev)
c8dfc65
 {
c8dfc65
     USBEndpoint *ep;
c8dfc65
@@ -1559,9 +1370,7 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
c8dfc65
         xfer->data_alloced = xfer->data_length;
c8dfc65
     }
c8dfc65
     if (epctx->type == ET_ISO_IN || epctx->type == ET_ISO_OUT) {
c8dfc65
-        if (!xfer->bg_xfer) {
c8dfc65
-            xfer->pkts = 1;
c8dfc65
-        }
c8dfc65
+        xfer->pkts = 1;
c8dfc65
     } else {
c8dfc65
         xfer->pkts = 0;
c8dfc65
     }
c8dfc65
@@ -1620,32 +1429,8 @@ static int xhci_fire_transfer(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext
c8dfc65
 
c8dfc65
     trace_usb_xhci_xfer_start(xfer, xfer->slotid, xfer->epid, length);
c8dfc65
 
c8dfc65
-    if (!epctx->has_bg) {
c8dfc65
-        xfer->data_length = length;
c8dfc65
-        xfer->backgrounded = 0;
c8dfc65
-        return xhci_submit(xhci, xfer, epctx);
c8dfc65
-    } else {
c8dfc65
-        if (!epctx->bg_running) {
c8dfc65
-            for (i = 0; i < BG_XFERS; i++) {
c8dfc65
-                XHCITransfer *t = &epctx->bg_transfers[i];
c8dfc65
-                t->xhci = xhci;
c8dfc65
-                t->epid = xfer->epid;
c8dfc65
-                t->slotid = xfer->slotid;
c8dfc65
-                t->pkts = BG_PKTS;
c8dfc65
-                t->pktsize = epctx->max_psize;
c8dfc65
-                t->data_length = t->pkts * t->pktsize;
c8dfc65
-                t->bg_xfer = 1;
c8dfc65
-                if (xhci_submit(xhci, t, epctx) < 0) {
c8dfc65
-                    fprintf(stderr, "xhci: bg submit failed\n");
c8dfc65
-                    return -1;
c8dfc65
-                }
c8dfc65
-            }
c8dfc65
-            epctx->bg_running = 1;
c8dfc65
-        }
c8dfc65
-        xfer->backgrounded = 1;
c8dfc65
-        xhci_bg_update(xhci, epctx);
c8dfc65
-        return 0;
c8dfc65
-    }
c8dfc65
+    xfer->data_length = length;
c8dfc65
+    return xhci_submit(xhci, xfer, epctx);
c8dfc65
 }
c8dfc65
 
c8dfc65
 static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid)
c8dfc65
@@ -1695,7 +1480,7 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid
c8dfc65
 
c8dfc65
     while (1) {
c8dfc65
         XHCITransfer *xfer = &epctx->transfers[epctx->next_xfer];
c8dfc65
-        if (xfer->running_async || xfer->running_retry || xfer->backgrounded) {
c8dfc65
+        if (xfer->running_async || xfer->running_retry) {
c8dfc65
             break;
c8dfc65
         }
c8dfc65
         length = xhci_ring_chain_length(xhci, &epctx->ring);