summary refs log tree commit diff stats
path: root/hw/usb/libhw.c
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2012-10-04 19:49:15 -0500
committerAnthony Liguori <aliguori@us.ibm.com>2012-10-04 19:49:15 -0500
commit938406dfb11d8a40d9228b3596d49a583d7218ff (patch)
treee573870cfe8fa52868b4442b9f0bae799e44e537 /hw/usb/libhw.c
parent4be403c8158e1b6be743f0fef004310cea4e3975 (diff)
parent39c138c8420f51a7da7b35233a8d7400a0b589ac (diff)
downloadfocaccia-qemu-938406dfb11d8a40d9228b3596d49a583d7218ff.tar.gz
focaccia-qemu-938406dfb11d8a40d9228b3596d49a583d7218ff.zip
Merge remote-tracking branch 'kraxel/usb.66' into staging
* kraxel/usb.66:
  usb: Fix usb_packet_map() in the presence of IOMMUs
  usb-redir: Adjust pkg-config check for usbredirparser .pc file rename (v2)
  ehci: Fix interrupt packet MULT handling
  xhci: create a memory region for each port
  xhci: route string & usb hub support
  xhci: tweak limits
  compat: turn off msi/msix on xhci for old machine types
  add pc-1.3 machine type

Conflicts:
	hw/pc_piix.c

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw/usb/libhw.c')
-rw-r--r--hw/usb/libhw.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/hw/usb/libhw.c b/hw/usb/libhw.c
index c0de30ea88..703e2d213b 100644
--- a/hw/usb/libhw.c
+++ b/hw/usb/libhw.c
@@ -28,19 +28,25 @@ int usb_packet_map(USBPacket *p, QEMUSGList *sgl)
 {
     DMADirection dir = (p->pid == USB_TOKEN_IN) ?
         DMA_DIRECTION_FROM_DEVICE : DMA_DIRECTION_TO_DEVICE;
-    dma_addr_t len;
     void *mem;
     int i;
 
     for (i = 0; i < sgl->nsg; i++) {
-        len = sgl->sg[i].len;
-        mem = dma_memory_map(sgl->dma, sgl->sg[i].base, &len, dir);
-        if (!mem) {
-            goto err;
-        }
-        qemu_iovec_add(&p->iov, mem, len);
-        if (len != sgl->sg[i].len) {
-            goto err;
+        dma_addr_t base = sgl->sg[i].base;
+        dma_addr_t len = sgl->sg[i].len;
+
+        while (len) {
+            dma_addr_t xlen = len;
+            mem = dma_memory_map(sgl->dma, sgl->sg[i].base, &xlen, dir);
+            if (!mem) {
+                goto err;
+            }
+            if (xlen > len) {
+                xlen = len;
+            }
+            qemu_iovec_add(&p->iov, mem, xlen);
+            len -= xlen;
+            base += xlen;
         }
     }
     return 0;