@@ -44,9 +44,6 @@
#define DPRINTF(...)
#endif
-/* internal processing - reset HC to try and recover */
-#define USB_RET_PROCERR (-99)
-
#define MMIO_SIZE 0x1000
/* Capability Registers Base Address - section 2.2 */
@@ -1407,7 +1404,7 @@ static int ehci_init_transfer(EHCIPacket *p)
while (bytes > 0) {
if (cpage > 4) {
fprintf(stderr, "cpage out of range (%d)\n", cpage);
- return USB_RET_PROCERR;
+ return -1;
}
page = p->qtd.bufptr[cpage] & QTD_BUFPTR_MASK;
@@ -1544,8 +1541,7 @@ static void ehci_execute_complete(EHCIQueue *q)
}
}
-// 4.10.3
-
+/* 4.10.3 returns "again" */
static int ehci_execute(EHCIPacket *p, const char *action)
{
USBEndpoint *ep;
@@ -1557,13 +1553,13 @@ static int ehci_execute(EHCIPacket *p, const char *action)
if (!(p->qtd.token & QTD_TOKEN_ACTIVE)) {
fprintf(stderr, "Attempting to execute inactive qtd\n");
- return USB_RET_PROCERR;
+ return -1;
}
if (get_field(p->qtd.token, QTD_TOKEN_TBYTES) > BUFF_SIZE) {
ehci_trace_guest_bug(p->queue->ehci,
"guest requested more bytes than allowed");
- return USB_RET_PROCERR;
+ return -1;
}
p->pid = (p->qtd.token & QTD_TOKEN_PID_MASK) >> QTD_TOKEN_PID_SH;
@@ -1587,7 +1583,7 @@ static int ehci_execute(EHCIPacket *p, const char *action)
if (p->async == EHCI_ASYNC_NONE) {
if (ehci_init_transfer(p) != 0) {
- return USB_RET_PROCERR;
+ return -1;
}
spd = (p->pid == USB_TOKEN_IN && NLPTR_TBIT(p->qtd.altnext) == 0);
@@ -1606,14 +1602,10 @@ static int ehci_execute(EHCIPacket *p, const char *action)
if (p->packet.actual_length > BUFF_SIZE) {
fprintf(stderr, "ret from usb_handle_packet > BUFF_SIZE\n");
- return USB_RET_PROCERR;
+ return -1;
}
- if (p->packet.status == USB_RET_SUCCESS) {
- return p->packet.actual_length;
- } else {
- return p->packet.status;
- }
+ return 1;
}
/* 4.7.2
@@ -1648,7 +1640,7 @@ static int ehci_process_itd(EHCIState *ehci,
}
if (len > BUFF_SIZE) {
- return USB_RET_PROCERR;
+ return -1;
}
pci_dma_sglist_init(&ehci->isgl, &ehci->dev, 2);
@@ -2048,8 +2040,7 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
break;
case EHCI_ASYNC_INFLIGHT:
/* Check if the guest has added new tds to the queue */
- again = (ehci_fill_queue(QTAILQ_LAST(&q->packets, pkts_head)) ==
- USB_RET_PROCERR) ? -1 : 1;
+ again = ehci_fill_queue(QTAILQ_LAST(&q->packets, pkts_head));
/* Unfinished async handled packet, go horizontal */
ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
break;
@@ -2086,6 +2077,7 @@ static int ehci_state_horizqh(EHCIQueue *q)
return again;
}
+/* Returns "again" */
static int ehci_fill_queue(EHCIPacket *p)
{
USBEndpoint *ep = p->packet.ep;
@@ -2114,17 +2106,14 @@ static int ehci_fill_queue(EHCIPacket *p)
p = ehci_alloc_packet(q);
p->qtdaddr = qtdaddr;
p->qtd = qtd;
- p->usb_status = ehci_execute(p, "queue");
- if (p->usb_status == USB_RET_PROCERR) {
- break;
+ if (ehci_execute(p, "queue") == -1) {
+ return -1;
}
- assert(p->usb_status == USB_RET_ASYNC);
+ assert(p->packet.status == USB_RET_ASYNC);
p->async = EHCI_ASYNC_INFLIGHT;
}
- if (p->usb_status != USB_RET_PROCERR) {
- usb_device_flush_ep_queue(ep->dev, ep);
- }
- return p->usb_status;
+ usb_device_flush_ep_queue(ep->dev, ep);
+ return 1;
}
static int ehci_state_execute(EHCIQueue *q)
@@ -2153,23 +2142,27 @@ static int ehci_state_execute(EHCIQueue *q)
ehci_set_usbsts(q->ehci, USBSTS_REC);
}
- p->usb_status = ehci_execute(p, "process");
- if (p->usb_status == USB_RET_PROCERR) {
- again = -1;
+ again = ehci_execute(p, "process");
+ if (again == -1) {
goto out;
}
- if (p->usb_status == USB_RET_ASYNC) {
+ if (p->packet.status == USB_RET_ASYNC) {
ehci_flush_qh(q);
trace_usb_ehci_packet_action(p->queue, p, "async");
p->async = EHCI_ASYNC_INFLIGHT;
ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
if (q->async) {
- again = (ehci_fill_queue(p) == USB_RET_PROCERR) ? -1 : 1;
+ again = ehci_fill_queue(p);
} else {
again = 1;
}
goto out;
}
+ if (p->packet.status == USB_RET_SUCCESS) {
+ p->usb_status = p->packet.actual_length;
+ } else {
+ p->usb_status = p->packet.status;
+ }
ehci_set_state(q->ehci, q->async, EST_EXECUTING);
again = 1;
Instead make ehci_execute and ehci_fill_queue return the again value. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- hw/usb/hcd-ehci.c | 55 ++++++++++++++++++++++++------------------------------- 1 file changed, 24 insertions(+), 31 deletions(-)