On 08/18/11 20:04, Daniel P. Berrange wrote:
I've been experimenting with multiple USB2 buses, and device physical port
addressing. It seems if you have 2 devices of the same type on the same
port, but in different buses, you get a bogus VMState assertion failure

     qemu-system-x86_64: savevm.c:1260: vmstate_register_with_alias_id: Assertion 
`!se->compat || se->instance_id == 0' failed.
     Aborted

AFAICT, the problem is that the 'se->idstr' field in the SaveStateEntry
struct is not getting a unique enough value.

Both the USB devices get idstr named   "1/usb-ccid", which IIUC is a
combination of the device type and the port number.

Indeed.

IMHO, it needs to have the USB bus name in there too eg. in this
example it should have been

     ehci0.0/1/usb-ccid
     ehci1.0/1/usb-ccid

I assumed the savevm code walks up the device path and creates a unique name by prefixing the string with the parents pci address, but it doesn't :-(

We can do that outself though, see attached patch.
That gives us IDs like this:

  0000:00:01.2/uhci              (hcd, unchanged)
  0000:00:01.2/1/usb-ptr         (usb devs, now with hcd pci addr)

Juan?  Does that look sane?

cheers,
  Gerd
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index c0bbc7c..477d57f 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -342,7 +342,20 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState 
*qdev, int indent)
 static char *usb_get_dev_path(DeviceState *qdev)
 {
     USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
-    return g_strdup(dev->port->path);
+    DeviceState *hcd = qdev->parent_bus->parent;
+    char *id = NULL;
+
+    if (hcd && hcd->parent_bus && hcd->parent_bus->info->get_dev_path) {
+        id = hcd->parent_bus->info->get_dev_path(hcd);
+    }
+    if (id) {
+        int len = strlen(id)+strlen(dev->port->path)+2;
+        char *ret = g_malloc(len);
+        snprintf(ret, len, "%s/%s", id, dev->port->path);
+        return ret;
+    } else {
+        return g_strdup(dev->port->path);
+    }
 }
 
 static char *usb_get_fw_dev_path(DeviceState *qdev)

Reply via email to