summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-12-14 14:35:22 +0100
committerGerd Hoffmann <kraxel@redhat.com>2013-01-07 12:57:23 +0100
commitf881c8d36b5c524348bc337b46baf34636079cf6 (patch)
tree865dcf8832f2dca177d0b19c86a12ddd29014427
parent8e4a424b305e29dc0e454f52df3b35577f342975 (diff)
downloadqemu-f881c8d36b5c524348bc337b46baf34636079cf6.tar.gz
qemu-f881c8d36b5c524348bc337b46baf34636079cf6.tar.bz2
qemu-f881c8d36b5c524348bc337b46baf34636079cf6.zip
ehci: Add a ehci_writeback_async_complete_packet helper function
Also drop the warning printf, which was there mainly because this was an untested code path (as the previous bug fixes to it show), but that no longer is the case now :) Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r--hw/usb/hcd-ehci.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 7536837fb2..218b1d7efe 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -438,6 +438,22 @@ static inline bool ehci_periodic_enabled(EHCIState *s)
return ehci_enabled(s) && (s->usbcmd & USBCMD_PSE);
}
+/* Finish executing and writeback a packet outside of the regular
+ fetchqh -> fetchqtd -> execute -> writeback cycle */
+static void ehci_writeback_async_complete_packet(EHCIPacket *p)
+{
+ EHCIQueue *q = p->queue;
+ int state;
+
+ state = ehci_get_state(q->ehci, q->async);
+ ehci_state_executing(q);
+ ehci_state_writeback(q); /* Frees the packet! */
+ if (!(q->qh.token & QTD_TOKEN_HALT)) {
+ ehci_state_advqueue(q);
+ }
+ ehci_set_state(q->ehci, q->async, state);
+}
+
/* packet management */
static EHCIPacket *ehci_alloc_packet(EHCIQueue *q)
@@ -455,17 +471,7 @@ static EHCIPacket *ehci_alloc_packet(EHCIQueue *q)
static void ehci_free_packet(EHCIPacket *p)
{
if (p->async == EHCI_ASYNC_FINISHED) {
- EHCIQueue *q = p->queue;
- int state = ehci_get_state(q->ehci, q->async);
- /* This is a normal, but rare condition (cancel racing completion) */
- fprintf(stderr, "EHCI: Warning packet completed but not processed\n");
- ehci_state_executing(q);
- ehci_state_writeback(q);
- if (!(q->qh.token & QTD_TOKEN_HALT)) {
- ehci_state_advqueue(q);
- }
- ehci_set_state(q->ehci, q->async, state);
- /* state_writeback recurses into us with async == EHCI_ASYNC_NONE!! */
+ ehci_writeback_async_complete_packet(p);
return;
}
trace_usb_ehci_packet_action(p->queue, p, "free");