summary refs log tree commit diff stats
path: root/hw/usb/hcd-ohci.c
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2012-11-14 08:50:18 -0600
committerAnthony Liguori <aliguori@us.ibm.com>2012-11-14 08:50:18 -0600
commitce5e5b522e8d3b848b6445c34226b69c77c46403 (patch)
tree9cd13246a20784e657c3d6d686e0282d1da5ffba /hw/usb/hcd-ohci.c
parentbf0dfb69f860a7894958068fba45f5268dddd6be (diff)
parent9d1530470bba5d8bec4796c0b43b874d5f9ef017 (diff)
downloadfocaccia-qemu-ce5e5b522e8d3b848b6445c34226b69c77c46403.tar.gz
focaccia-qemu-ce5e5b522e8d3b848b6445c34226b69c77c46403.zip
Merge remote-tracking branch 'kraxel/usb.70' into staging
* kraxel/usb.70:
  ehci: fix migration
  xhci: Fix some DMA host endian bugs
  usb/combined-packet: Move freeing of combined to usb_combined_packet_remove()
  xhci: Add support for packets with both data and an error status
  ehci: Add support for packets with both data and an error status
  ehci: Get rid of the magical PROC_ERR status
  usb-redir: Allow packets to have both data and an error-status
  usb: split packet result into actual_length + status

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw/usb/hcd-ohci.c')
-rw-r--r--hw/usb/hcd-ohci.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 7571e9e44a..6a39e9697b 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -807,21 +807,24 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
                          DMA_DIRECTION_TO_DEVICE);
     }
 
-    if (completion) {
-        ret = ohci->usb_packet.result;
-    } else {
+    if (!completion) {
         bool int_req = relative_frame_number == frame_count &&
                        OHCI_BM(iso_td.flags, TD_DI) == 0;
         dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA));
         ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN));
         usb_packet_setup(&ohci->usb_packet, pid, ep, addr, false, int_req);
         usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, len);
-        ret = usb_handle_packet(dev, &ohci->usb_packet);
-        if (ret == USB_RET_ASYNC) {
+        usb_handle_packet(dev, &ohci->usb_packet);
+        if (ohci->usb_packet.status == USB_RET_ASYNC) {
             usb_device_flush_ep_queue(dev, ep);
             return 1;
         }
     }
+    if (ohci->usb_packet.status == USB_RET_SUCCESS) {
+        ret = ohci->usb_packet.actual_length;
+    } else {
+        ret = ohci->usb_packet.status;
+    }
 
 #ifdef DEBUG_ISOCH
     printf("so 0x%.8x eo 0x%.8x\nsa 0x%.8x ea 0x%.8x\ndir %s len %zu ret %d\n",
@@ -997,7 +1000,6 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
     }
 #endif
     if (completion) {
-        ret = ohci->usb_packet.result;
         ohci->async_td = 0;
         ohci->async_complete = 0;
     } else {
@@ -1017,16 +1019,22 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
         usb_packet_setup(&ohci->usb_packet, pid, ep, addr, !flag_r,
                          OHCI_BM(td.flags, TD_DI) == 0);
         usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, pktlen);
-        ret = usb_handle_packet(dev, &ohci->usb_packet);
+        usb_handle_packet(dev, &ohci->usb_packet);
 #ifdef DEBUG_PACKET
-        DPRINTF("ret=%d\n", ret);
+        DPRINTF("status=%d\n", ohci->usb_packet.status);
 #endif
-        if (ret == USB_RET_ASYNC) {
+        if (ohci->usb_packet.status == USB_RET_ASYNC) {
             usb_device_flush_ep_queue(dev, ep);
             ohci->async_td = addr;
             return 1;
         }
     }
+    if (ohci->usb_packet.status == USB_RET_SUCCESS) {
+        ret = ohci->usb_packet.actual_length;
+    } else {
+        ret = ohci->usb_packet.status;
+    }
+
     if (ret >= 0) {
         if (dir == OHCI_TD_DIR_IN) {
             ohci_copy_td(ohci, &td, ohci->usb_buf, ret,