|
Hans de Goede |
c8dfc6 |
From ad14386b3f1ccd445afd30d30a343cb9fcf6c0a7 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 |
c8dfc6 |
Subject: [PATCH 332/366] 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 |
c8dfc6 |
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
Hans de Goede |
c8dfc6 |
---
|
|
Hans de Goede |
c8dfc6 |
hw/usb/hcd-xhci.c | 183 +++++++++++++++++++++---------------------------------
|
|
Hans de Goede |
c8dfc6 |
trace-events | 2 +-
|
|
Hans de Goede |
c8dfc6 |
2 files changed, 72 insertions(+), 113 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 |
c8dfc6 |
index c0a2476..c858b6d 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 |
c8dfc6 |
@@ -1279,8 +1280,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 |
c8dfc6 |
@@ -1311,18 +1311,6 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
|
|
Hans de Goede |
c8dfc6 |
bmRequestType = trb_setup->parameter;
|
|
Hans de Goede |
c8dfc6 |
wLength = trb_setup->parameter >> 48;
|
|
Hans de Goede |
c8dfc6 |
|
|
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 |
c8dfc6 |
-
|
|
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 |
c8dfc6 |
if (!dev) {
|
|
Hans de Goede |
c8dfc6 |
@@ -1336,9 +1324,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 |
c8dfc6 |
@@ -1359,16 +1344,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 |
c8dfc6 |
@@ -1402,9 +1377,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 |
c8dfc6 |
@@ -1416,20 +1388,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 |
|