render / rpms / qemu

Forked from rpms/qemu 9 months ago
Clone

Blame 0332-xhci-drop-buffering.patch

Hans de Goede 93b7e3
From ba184fe5a0e63bd40956b456d85a01da13d6183d Mon Sep 17 00:00:00 2001
Hans de Goede c8dfc6
From: Gerd Hoffmann <kraxel@redhat.com>
Hans de Goede c8dfc6
Date: Fri, 17 Aug 2012 11:04:36 +0200
Hans de Goede 93b7e3
Subject: [PATCH 332/369] xhci: drop buffering
Hans de Goede c8dfc6
Hans de Goede c8dfc6
This patch splits the xhci_xfer_data function into three.
Hans de Goede c8dfc6
The xhci_xfer_data function used to do does two things:
Hans de Goede c8dfc6
Hans de Goede c8dfc6
  (1) copy transfer data between guest memory and a temporary buffer.
Hans de Goede c8dfc6
  (2) report transfer results to the guest using events.
Hans de Goede c8dfc6
Hans de Goede c8dfc6
Now we three functions to handle this:
Hans de Goede c8dfc6
Hans de Goede c8dfc6
  (1) xhci_xfer_map creates a scatter list for the transfer and
Hans de Goede c8dfc6
      uses that (instead of the temporary buffer) to build a
Hans de Goede c8dfc6
      USBPacket.
Hans de Goede c8dfc6
  (2) xhci_xfer_unmap undoes the mapping.
Hans de Goede c8dfc6
  (3) xhci_xfer_report sends out events.
Hans de Goede c8dfc6
Hans de Goede c8dfc6
The patch also fixes reporting of transaction errors which must be
Hans de Goede c8dfc6
reported unconditinally, not only in case the guest asks for it
Hans de Goede c8dfc6
using the ISP flag.
Hans de Goede c8dfc6
Hans de Goede 93b7e3
[ v2: fix warning ]
Hans de Goede 93b7e3
Hans de Goede c8dfc6
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Hans de Goede c8dfc6
---
Hans de Goede 93b7e3
 hw/usb/hcd-xhci.c | 185 +++++++++++++++++++++---------------------------------
Hans de Goede c8dfc6
 trace-events      |   2 +-
Hans de Goede 93b7e3
 2 files changed, 72 insertions(+), 115 deletions(-)
Hans de Goede c8dfc6
Hans de Goede c8dfc6
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
Hans de Goede 93b7e3
index c0a2476..446d692 100644
Hans de Goede c8dfc6
--- a/hw/usb/hcd-xhci.c
Hans de Goede c8dfc6
+++ b/hw/usb/hcd-xhci.c
Hans de Goede c8dfc6
@@ -305,6 +305,7 @@ typedef struct XHCIState XHCIState;
Hans de Goede c8dfc6
 typedef struct XHCITransfer {
Hans de Goede c8dfc6
     XHCIState *xhci;
Hans de Goede c8dfc6
     USBPacket packet;
Hans de Goede c8dfc6
+    QEMUSGList sgl;
Hans de Goede c8dfc6
     bool running_async;
Hans de Goede c8dfc6
     bool running_retry;
Hans de Goede c8dfc6
     bool cancelled;
Hans de Goede c8dfc6
@@ -319,10 +320,6 @@ typedef struct XHCITransfer {
Hans de Goede c8dfc6
     unsigned int trb_alloced;
Hans de Goede c8dfc6
     XHCITRB *trbs;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    unsigned int data_length;
Hans de Goede c8dfc6
-    unsigned int data_alloced;
Hans de Goede c8dfc6
-    uint8_t *data;
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
     TRBCCode status;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     unsigned int pkts;
Hans de Goede c8dfc6
@@ -906,14 +903,9 @@ static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid,
Hans de Goede c8dfc6
         if (t->trbs) {
Hans de Goede c8dfc6
             g_free(t->trbs);
Hans de Goede c8dfc6
         }
Hans de Goede c8dfc6
-        if (t->data) {
Hans de Goede c8dfc6
-            g_free(t->data);
Hans de Goede c8dfc6
-        }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
         t->trbs = NULL;
Hans de Goede c8dfc6
-        t->data = NULL;
Hans de Goede c8dfc6
         t->trb_count = t->trb_alloced = 0;
Hans de Goede c8dfc6
-        t->data_length = t->data_alloced = 0;
Hans de Goede c8dfc6
         xferi = (xferi + 1) % TD_QUEUE;
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
     return killed;
Hans de Goede c8dfc6
@@ -1072,24 +1064,13 @@ static TRBCCode xhci_set_ep_dequeue(XHCIState *xhci, unsigned int slotid,
Hans de Goede c8dfc6
     return CC_SUCCESS;
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-static int xhci_xfer_data(XHCITransfer *xfer, uint8_t *data,
Hans de Goede c8dfc6
-                          unsigned int length, bool in_xfer, bool out_xfer,
Hans de Goede c8dfc6
-                          bool report)
Hans de Goede c8dfc6
+static int xhci_xfer_map(XHCITransfer *xfer)
Hans de Goede c8dfc6
 {
Hans de Goede c8dfc6
-    int i;
Hans de Goede c8dfc6
-    uint32_t edtla = 0;
Hans de Goede c8dfc6
-    unsigned int transferred = 0;
Hans de Goede c8dfc6
-    unsigned int left = length;
Hans de Goede c8dfc6
-    bool reported = 0;
Hans de Goede c8dfc6
-    bool shortpkt = 0;
Hans de Goede c8dfc6
-    XHCIEvent event = {ER_TRANSFER, CC_SUCCESS};
Hans de Goede c8dfc6
+    int in_xfer = (xfer->packet.pid == USB_TOKEN_IN);
Hans de Goede c8dfc6
     XHCIState *xhci = xfer->xhci;
Hans de Goede c8dfc6
+    int i;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    DPRINTF("xhci_xfer_data(len=%d, in_xfer=%d, out_xfer=%d, report=%d)\n",
Hans de Goede c8dfc6
-            length, in_xfer, out_xfer, report);
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
-    assert(!(in_xfer && out_xfer));
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
+    pci_dma_sglist_init(&xfer->sgl, &xhci->pci_dev, xfer->trb_count);
Hans de Goede c8dfc6
     for (i = 0; i < xfer->trb_count; i++) {
Hans de Goede c8dfc6
         XHCITRB *trb = &xfer->trbs[i];
Hans de Goede c8dfc6
         dma_addr_t addr;
Hans de Goede c8dfc6
@@ -1099,54 +1080,70 @@ static int xhci_xfer_data(XHCITransfer *xfer, uint8_t *data,
Hans de Goede c8dfc6
         case TR_DATA:
Hans de Goede c8dfc6
             if ((!(trb->control & TRB_TR_DIR)) != (!in_xfer)) {
Hans de Goede c8dfc6
                 fprintf(stderr, "xhci: data direction mismatch for TR_DATA\n");
Hans de Goede c8dfc6
-                xhci_die(xhci);
Hans de Goede c8dfc6
-                return transferred;
Hans de Goede c8dfc6
+                goto err;
Hans de Goede c8dfc6
             }
Hans de Goede c8dfc6
             /* fallthrough */
Hans de Goede c8dfc6
         case TR_NORMAL:
Hans de Goede c8dfc6
         case TR_ISOCH:
Hans de Goede c8dfc6
             addr = xhci_mask64(trb->parameter);
Hans de Goede c8dfc6
             chunk = trb->status & 0x1ffff;
Hans de Goede c8dfc6
+            if (trb->control & TRB_TR_IDT) {
Hans de Goede c8dfc6
+                if (chunk > 8 || in_xfer) {
Hans de Goede c8dfc6
+                    fprintf(stderr, "xhci: invalid immediate data TRB\n");
Hans de Goede c8dfc6
+                    goto err;
Hans de Goede c8dfc6
+                }
Hans de Goede c8dfc6
+                qemu_sglist_add(&xfer->sgl, trb->addr, chunk);
Hans de Goede c8dfc6
+            } else {
Hans de Goede c8dfc6
+                qemu_sglist_add(&xfer->sgl, addr, chunk);
Hans de Goede c8dfc6
+            }
Hans de Goede c8dfc6
+            break;
Hans de Goede c8dfc6
+        }
Hans de Goede c8dfc6
+    }
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
+    usb_packet_map(&xfer->packet, &xfer->sgl);
Hans de Goede c8dfc6
+    return 0;
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
+err:
Hans de Goede c8dfc6
+    qemu_sglist_destroy(&xfer->sgl);
Hans de Goede c8dfc6
+    xhci_die(xhci);
Hans de Goede c8dfc6
+    return -1;
Hans de Goede c8dfc6
+}
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
+static void xhci_xfer_unmap(XHCITransfer *xfer)
Hans de Goede c8dfc6
+{
Hans de Goede c8dfc6
+    usb_packet_unmap(&xfer->packet, &xfer->sgl);
Hans de Goede c8dfc6
+    qemu_sglist_destroy(&xfer->sgl);
Hans de Goede c8dfc6
+}
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
+static void xhci_xfer_report(XHCITransfer *xfer)
Hans de Goede c8dfc6
+{
Hans de Goede c8dfc6
+    uint32_t edtla = 0;
Hans de Goede c8dfc6
+    unsigned int left;
Hans de Goede c8dfc6
+    bool reported = 0;
Hans de Goede c8dfc6
+    bool shortpkt = 0;
Hans de Goede c8dfc6
+    XHCIEvent event = {ER_TRANSFER, CC_SUCCESS};
Hans de Goede c8dfc6
+    XHCIState *xhci = xfer->xhci;
Hans de Goede c8dfc6
+    int i;
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
+    left = xfer->packet.result < 0 ? 0 : xfer->packet.result;
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
+    for (i = 0; i < xfer->trb_count; i++) {
Hans de Goede c8dfc6
+        XHCITRB *trb = &xfer->trbs[i];
Hans de Goede c8dfc6
+        unsigned int chunk = 0;
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
+        switch (TRB_TYPE(*trb)) {
Hans de Goede c8dfc6
+        case TR_DATA:
Hans de Goede c8dfc6
+        case TR_NORMAL:
Hans de Goede c8dfc6
+        case TR_ISOCH:
Hans de Goede c8dfc6
+            chunk = trb->status & 0x1ffff;
Hans de Goede c8dfc6
             if (chunk > left) {
Hans de Goede c8dfc6
                 chunk = left;
Hans de Goede c8dfc6
-                shortpkt = 1;
Hans de Goede c8dfc6
-            }
Hans de Goede c8dfc6
-            if (in_xfer || out_xfer) {
Hans de Goede c8dfc6
-                if (trb->control & TRB_TR_IDT) {
Hans de Goede c8dfc6
-                    uint64_t idata;
Hans de Goede c8dfc6
-                    if (chunk > 8 || in_xfer) {
Hans de Goede c8dfc6
-                        fprintf(stderr, "xhci: invalid immediate data TRB\n");
Hans de Goede c8dfc6
-                        xhci_die(xhci);
Hans de Goede c8dfc6
-                        return transferred;
Hans de Goede c8dfc6
-                    }
Hans de Goede c8dfc6
-                    idata = le64_to_cpu(trb->parameter);
Hans de Goede c8dfc6
-                    memcpy(data, &idata, chunk);
Hans de Goede c8dfc6
-                } else {
Hans de Goede c8dfc6
-                    DPRINTF("xhci_xfer_data: r/w(%d) %d bytes at "
Hans de Goede c8dfc6
-                            DMA_ADDR_FMT "\n", in_xfer, chunk, addr);
Hans de Goede c8dfc6
-                    if (in_xfer) {
Hans de Goede c8dfc6
-                        pci_dma_write(&xhci->pci_dev, addr, data, chunk);
Hans de Goede c8dfc6
-                    } else {
Hans de Goede c8dfc6
-                        pci_dma_read(&xhci->pci_dev, addr, data, chunk);
Hans de Goede c8dfc6
-                    }
Hans de Goede c8dfc6
-#ifdef DEBUG_DATA
Hans de Goede c8dfc6
-                    unsigned int count = chunk;
Hans de Goede c8dfc6
-                    int i;
Hans de Goede c8dfc6
-                    if (count > 16) {
Hans de Goede c8dfc6
-                        count = 16;
Hans de Goede c8dfc6
-                    }
Hans de Goede c8dfc6
-                    DPRINTF(" ::");
Hans de Goede c8dfc6
-                    for (i = 0; i < count; i++) {
Hans de Goede c8dfc6
-                        DPRINTF(" %02x", data[i]);
Hans de Goede c8dfc6
-                    }
Hans de Goede c8dfc6
-                    DPRINTF("\n");
Hans de Goede c8dfc6
-#endif
Hans de Goede c8dfc6
+                if (xfer->status == CC_SUCCESS) {
Hans de Goede c8dfc6
+                    shortpkt = 1;
Hans de Goede c8dfc6
                 }
Hans de Goede c8dfc6
             }
Hans de Goede c8dfc6
             left -= chunk;
Hans de Goede c8dfc6
-            data += chunk;
Hans de Goede c8dfc6
             edtla += chunk;
Hans de Goede c8dfc6
-            transferred += chunk;
Hans de Goede c8dfc6
             break;
Hans de Goede c8dfc6
         case TR_STATUS:
Hans de Goede c8dfc6
             reported = 0;
Hans de Goede c8dfc6
@@ -1154,8 +1151,9 @@ static int xhci_xfer_data(XHCITransfer *xfer, uint8_t *data,
Hans de Goede c8dfc6
             break;
Hans de Goede c8dfc6
         }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-        if (report && !reported && (trb->control & TRB_TR_IOC ||
Hans de Goede c8dfc6
-            (shortpkt && (trb->control & TRB_TR_ISP)))) {
Hans de Goede c8dfc6
+        if (!reported && ((trb->control & TRB_TR_IOC) ||
Hans de Goede c8dfc6
+                          (shortpkt && (trb->control & TRB_TR_ISP)) ||
Hans de Goede c8dfc6
+                          (xfer->status != CC_SUCCESS))) {
Hans de Goede c8dfc6
             event.slotid = xfer->slotid;
Hans de Goede c8dfc6
             event.epid = xfer->epid;
Hans de Goede c8dfc6
             event.length = (trb->status & 0x1ffff) - chunk;
Hans de Goede c8dfc6
@@ -1175,9 +1173,11 @@ static int xhci_xfer_data(XHCITransfer *xfer, uint8_t *data,
Hans de Goede c8dfc6
             }
Hans de Goede c8dfc6
             xhci_event(xhci, &event);
Hans de Goede c8dfc6
             reported = 1;
Hans de Goede c8dfc6
+            if (xfer->status != CC_SUCCESS) {
Hans de Goede c8dfc6
+                return;
Hans de Goede c8dfc6
+            }
Hans de Goede c8dfc6
         }
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
-    return transferred;
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
 static void xhci_stall_ep(XHCITransfer *xfer)
Hans de Goede c8dfc6
@@ -1204,7 +1204,7 @@ static int xhci_setup_packet(XHCITransfer *xfer, USBDevice *dev)
Hans de Goede c8dfc6
     dir = xfer->in_xfer ? USB_TOKEN_IN : USB_TOKEN_OUT;
Hans de Goede c8dfc6
     ep = usb_ep_get(dev, dir, xfer->epid >> 1);
Hans de Goede c8dfc6
     usb_packet_setup(&xfer->packet, dir, ep, xfer->trbs[0].addr);
Hans de Goede c8dfc6
-    usb_packet_addbuf(&xfer->packet, xfer->data, xfer->data_length);
Hans de Goede c8dfc6
+    xhci_xfer_map(xfer);
Hans de Goede c8dfc6
     DPRINTF("xhci: setup packet pid 0x%x addr %d ep %d\n",
Hans de Goede c8dfc6
             xfer->packet.pid, dev->addr, ep->nr);
Hans de Goede c8dfc6
     return 0;
Hans de Goede c8dfc6
@@ -1230,12 +1230,13 @@ static int xhci_complete_packet(XHCITransfer *xfer, int ret)
Hans de Goede c8dfc6
         xfer->running_async = 0;
Hans de Goede c8dfc6
         xfer->running_retry = 0;
Hans de Goede c8dfc6
         xfer->complete = 1;
Hans de Goede c8dfc6
+        xhci_xfer_unmap(xfer);
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     if (ret >= 0) {
Hans de Goede c8dfc6
-        xfer->status = CC_SUCCESS;
Hans de Goede c8dfc6
-        xhci_xfer_data(xfer, xfer->data, ret, xfer->in_xfer, 0, 1);
Hans de Goede c8dfc6
         trace_usb_xhci_xfer_success(xfer, ret);
Hans de Goede c8dfc6
+        xfer->status = CC_SUCCESS;
Hans de Goede c8dfc6
+        xhci_xfer_report(xfer);
Hans de Goede c8dfc6
         return 0;
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
@@ -1244,12 +1245,12 @@ static int xhci_complete_packet(XHCITransfer *xfer, int ret)
Hans de Goede c8dfc6
     switch (ret) {
Hans de Goede c8dfc6
     case USB_RET_NODEV:
Hans de Goede c8dfc6
         xfer->status = CC_USB_TRANSACTION_ERROR;
Hans de Goede c8dfc6
-        xhci_xfer_data(xfer, xfer->data, 0, xfer->in_xfer, 0, 1);
Hans de Goede c8dfc6
+        xhci_xfer_report(xfer);
Hans de Goede c8dfc6
         xhci_stall_ep(xfer);
Hans de Goede c8dfc6
         break;
Hans de Goede c8dfc6
     case USB_RET_STALL:
Hans de Goede c8dfc6
         xfer->status = CC_STALL_ERROR;
Hans de Goede c8dfc6
-        xhci_xfer_data(xfer, xfer->data, 0, xfer->in_xfer, 0, 1);
Hans de Goede c8dfc6
+        xhci_xfer_report(xfer);
Hans de Goede c8dfc6
         xhci_stall_ep(xfer);
Hans de Goede c8dfc6
         break;
Hans de Goede c8dfc6
     default:
Hans de Goede 93b7e3
@@ -1271,7 +1272,6 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
Hans de Goede 93b7e3
 {
Hans de Goede 93b7e3
     XHCITRB *trb_setup, *trb_status;
Hans de Goede 93b7e3
     uint8_t bmRequestType;
Hans de Goede 93b7e3
-    uint16_t wLength;
Hans de Goede 93b7e3
     XHCIPort *port;
Hans de Goede 93b7e3
     USBDevice *dev;
Hans de Goede 93b7e3
     int ret;
Hans de Goede 93b7e3
@@ -1279,8 +1279,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
Hans de Goede c8dfc6
     trb_setup = &xfer->trbs[0];
Hans de Goede c8dfc6
     trb_status = &xfer->trbs[xfer->trb_count-1];
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    trace_usb_xhci_xfer_start(xfer, xfer->slotid, xfer->epid,
Hans de Goede c8dfc6
-                              trb_setup->parameter >> 48);
Hans de Goede c8dfc6
+    trace_usb_xhci_xfer_start(xfer, xfer->slotid, xfer->epid);
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     /* at most one Event Data TRB allowed after STATUS */
Hans de Goede c8dfc6
     if (TRB_TYPE(*trb_status) == TR_EVDATA && xfer->trb_count > 2) {
Hans de Goede 93b7e3
@@ -1309,19 +1308,6 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
Hans de Goede 93b7e3
     }
Hans de Goede c8dfc6
 
Hans de Goede 93b7e3
     bmRequestType = trb_setup->parameter;
Hans de Goede 93b7e3
-    wLength = trb_setup->parameter >> 48;
Hans de Goede 93b7e3
-
Hans de Goede c8dfc6
-    if (xfer->data && xfer->data_alloced < wLength) {
Hans de Goede c8dfc6
-        xfer->data_alloced = 0;
Hans de Goede c8dfc6
-        g_free(xfer->data);
Hans de Goede c8dfc6
-        xfer->data = NULL;
Hans de Goede c8dfc6
-    }
Hans de Goede c8dfc6
-    if (!xfer->data) {
Hans de Goede c8dfc6
-        DPRINTF("xhci: alloc %d bytes data\n", wLength);
Hans de Goede c8dfc6
-        xfer->data = g_malloc(wLength+1);
Hans de Goede c8dfc6
-        xfer->data_alloced = wLength;
Hans de Goede c8dfc6
-    }
Hans de Goede c8dfc6
-    xfer->data_length = wLength;
Hans de Goede 93b7e3
 
Hans de Goede c8dfc6
     port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1];
Hans de Goede c8dfc6
     dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr);
Hans de Goede 93b7e3
@@ -1336,9 +1322,6 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     xhci_setup_packet(xfer, dev);
Hans de Goede c8dfc6
     xfer->packet.parameter = trb_setup->parameter;
Hans de Goede c8dfc6
-    if (!xfer->in_xfer) {
Hans de Goede c8dfc6
-        xhci_xfer_data(xfer, xfer->data, wLength, 0, 1, 0);
Hans de Goede c8dfc6
-    }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     ret = usb_handle_packet(dev, &xfer->packet);
Hans de Goede c8dfc6
 
Hans de Goede 93b7e3
@@ -1359,16 +1342,6 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     xfer->in_xfer = epctx->type>>2;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    if (xfer->data && xfer->data_alloced < xfer->data_length) {
Hans de Goede c8dfc6
-        xfer->data_alloced = 0;
Hans de Goede c8dfc6
-        g_free(xfer->data);
Hans de Goede c8dfc6
-        xfer->data = NULL;
Hans de Goede c8dfc6
-    }
Hans de Goede c8dfc6
-    if (!xfer->data && xfer->data_length) {
Hans de Goede c8dfc6
-        DPRINTF("xhci: alloc %d bytes data\n", xfer->data_length);
Hans de Goede c8dfc6
-        xfer->data = g_malloc(xfer->data_length);
Hans de Goede c8dfc6
-        xfer->data_alloced = xfer->data_length;
Hans de Goede c8dfc6
-    }
Hans de Goede c8dfc6
     if (epctx->type == ET_ISO_IN || epctx->type == ET_ISO_OUT) {
Hans de Goede c8dfc6
         xfer->pkts = 1;
Hans de Goede c8dfc6
     } else {
Hans de Goede 93b7e3
@@ -1402,9 +1375,6 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
Hans de Goede c8dfc6
         return -1;
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    if (!xfer->in_xfer) {
Hans de Goede c8dfc6
-        xhci_xfer_data(xfer, xfer->data, xfer->data_length, 0, 1, 0);
Hans de Goede c8dfc6
-    }
Hans de Goede c8dfc6
     ret = usb_handle_packet(dev, &xfer->packet);
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     xhci_complete_packet(xfer, ret);
Hans de Goede 93b7e3
@@ -1416,20 +1386,7 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
 static int xhci_fire_transfer(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx)
Hans de Goede c8dfc6
 {
Hans de Goede c8dfc6
-    int i;
Hans de Goede c8dfc6
-    unsigned int length = 0;
Hans de Goede c8dfc6
-    XHCITRB *trb;
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
-    for (i = 0; i < xfer->trb_count; i++) {
Hans de Goede c8dfc6
-        trb = &xfer->trbs[i];
Hans de Goede c8dfc6
-        if (TRB_TYPE(*trb) == TR_NORMAL || TRB_TYPE(*trb) == TR_ISOCH) {
Hans de Goede c8dfc6
-            length += trb->status & 0x1ffff;
Hans de Goede c8dfc6
-        }
Hans de Goede c8dfc6
-    }
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
-    trace_usb_xhci_xfer_start(xfer, xfer->slotid, xfer->epid, length);
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
-    xfer->data_length = length;
Hans de Goede c8dfc6
+    trace_usb_xhci_xfer_start(xfer, xfer->slotid, xfer->epid);
Hans de Goede c8dfc6
     return xhci_submit(xhci, xfer, epctx);
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
diff --git a/trace-events b/trace-events
Hans de Goede c8dfc6
index 10bc04e..c83d65e 100644
Hans de Goede c8dfc6
--- a/trace-events
Hans de Goede c8dfc6
+++ b/trace-events
Hans de Goede c8dfc6
@@ -326,7 +326,7 @@ usb_xhci_ep_disable(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
Hans de Goede c8dfc6
 usb_xhci_ep_kick(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
Hans de Goede c8dfc6
 usb_xhci_ep_stop(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
Hans de Goede c8dfc6
 usb_xhci_ep_reset(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
Hans de Goede c8dfc6
-usb_xhci_xfer_start(void *xfer, uint32_t slotid, uint32_t epid, uint32_t length) "%p: slotid %d, epid %d, length %d"
Hans de Goede c8dfc6
+usb_xhci_xfer_start(void *xfer, uint32_t slotid, uint32_t epid) "%p: slotid %d, epid %d"
Hans de Goede c8dfc6
 usb_xhci_xfer_async(void *xfer) "%p"
Hans de Goede c8dfc6
 usb_xhci_xfer_nak(void *xfer) "%p"
Hans de Goede c8dfc6
 usb_xhci_xfer_retry(void *xfer) "%p"
Hans de Goede c8dfc6
-- 
Hans de Goede c8dfc6
1.7.12
Hans de Goede c8dfc6