usb_packet_complete assert(p->owner != NULL)

Message ID
State New
Headers show

Commit Message

Stefan Hajnoczi Oct. 8, 2011, 9:02 a.m.
I hit an assertion in hw/usb.c when passing through a host USB device
on qemu.git/master (e4fc8781db7c49b0c5ac5d24762e17c59dfe0871).  This
device has never worked before and I was curious to see how
qemu.git/master would do.

The assertion is:
void usb_packet_complete(USBDevice *dev, USBPacket *p)
    /* Note: p->owner != dev is possible in case dev is a hub */
    assert(p->owner != NULL);

The problem seems to be that usb_packet_complete() is called on the
hub device and the hub calls usb_packet_complete() again on the actual
leaf device.  Since usb_packet_complete() sets packet->owner to NULL
we hit the assertion immediately when trying to invoke the leaf device

I don't understand how USB emulation hangs together, so I added this quick hack:

 static void usb_hub_handle_reset(USBDevice *dev)

The hub is now directly invoking .complete() and not messing with
packet->owner (which is already NULL).  We don't hit the assertion
anymore.  Unfortunately the device does not work in my Windows guest -
it must be another problem though.

I'm not sending it as a patch because there's probably a better way of
fixing this.  Any ideas?



diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index 286e3ad..277cb47 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -210,7 +210,7 @@  static void usb_hub_complete(USBPort *port,
USBPacket *packet)
      * If we ever inplement usb 2.0 split transactions this will
      * become a little more complicated ...
-    usb_packet_complete(&s->dev, packet);
+    s->dev.port->ops->complete(s->dev.port, packet);