]> xenbits.xensource.com Git - qemu-xen.git/commitdiff
ehci: Handle USB_RET_PROCERR in ehci_fill_queue
authorHans de Goede <hdegoede@redhat.com>
Mon, 3 Sep 2012 09:35:58 +0000 (11:35 +0200)
committerGerd Hoffmann <kraxel@redhat.com>
Tue, 11 Sep 2012 05:42:59 +0000 (07:42 +0200)
USB_RET_PROCERR can be triggered by the guest (by for example requesting more
then BUFFSIZE bytes), so don't assert on it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
hw/usb/hcd-ehci.c

index d87aca83310cb8f19a264353f3487a73e7e956b0..25343942024acbe8d409fe3dbe41d49cc59c75ae 100644 (file)
@@ -2076,7 +2076,7 @@ static int ehci_state_horizqh(EHCIQueue *q)
     return again;
 }
 
-static void ehci_fill_queue(EHCIPacket *p)
+static int ehci_fill_queue(EHCIPacket *p)
 {
     EHCIQueue *q = p->queue;
     EHCIqtd qtd = p->qtd;
@@ -2100,9 +2100,13 @@ static void ehci_fill_queue(EHCIPacket *p)
         p->qtdaddr = qtdaddr;
         p->qtd = qtd;
         p->usb_status = ehci_execute(p, "queue");
+        if (p->usb_status == USB_RET_PROCERR) {
+            break;
+        }
         assert(p->usb_status == USB_RET_ASYNC);
         p->async = EHCI_ASYNC_INFLIGHT;
     }
+    return p->usb_status;
 }
 
 static int ehci_state_execute(EHCIQueue *q)
@@ -2144,8 +2148,7 @@ static int ehci_state_execute(EHCIQueue *q)
         trace_usb_ehci_packet_action(p->queue, p, "async");
         p->async = EHCI_ASYNC_INFLIGHT;
         ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
-        again = 1;
-        ehci_fill_queue(p);
+        again = (ehci_fill_queue(p) == USB_RET_PROCERR) ? -1 : 1;
         goto out;
     }