Revision a229c053

b/hw/usb/host-linux.c
111 111
    uint32_t  iso_urb_count;
112 112
    uint32_t  options;
113 113
    Notifier  exit;
114
    QEMUBH    *bh;
114 115

  
115 116
    struct endp_data ep_in[USB_MAX_ENDPOINTS];
116 117
    struct endp_data ep_out[USB_MAX_ENDPOINTS];
......
1421 1422
    }
1422 1423
}
1423 1424

  
1425
/*
1426
 * This is *NOT* about restoring state.  We have absolutely no idea
1427
 * what state the host device is in at the moment and whenever it is
1428
 * still present in the first place.  Attemping to contine where we
1429
 * left off is impossible.
1430
 *
1431
 * What we are going to to to here is emulate a surprise removal of
1432
 * the usb device passed through, then kick host scan so the device
1433
 * will get re-attached (and re-initialized by the guest) in case it
1434
 * is still present.
1435
 *
1436
 * As the device removal will change the state of other devices (usb
1437
 * host controller, most likely interrupt controller too) we have to
1438
 * wait with it until *all* vmstate is loaded.  Thus post_load just
1439
 * kicks a bottom half which then does the actual work.
1440
 */
1441
static void usb_host_post_load_bh(void *opaque)
1442
{
1443
    USBHostDevice *dev = opaque;
1444

  
1445
    if (dev->fd != -1) {
1446
        usb_host_close(dev);
1447
    }
1448
    if (dev->dev.attached) {
1449
        usb_device_detach(&dev->dev);
1450
    }
1451
    usb_host_auto_check(NULL);
1452
}
1453

  
1454
static int usb_host_post_load(void *opaque, int version_id)
1455
{
1456
    USBHostDevice *dev = opaque;
1457

  
1458
    qemu_bh_schedule(dev->bh);
1459
    return 0;
1460
}
1461

  
1424 1462
static int usb_host_initfn(USBDevice *dev)
1425 1463
{
1426 1464
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
......
1432 1470
    QTAILQ_INSERT_TAIL(&hostdevs, s, next);
1433 1471
    s->exit.notify = usb_host_exit_notifier;
1434 1472
    qemu_add_exit_notifier(&s->exit);
1473
    s->bh = qemu_bh_new(usb_host_post_load_bh, s);
1435 1474
    usb_host_auto_check(NULL);
1436 1475

  
1437 1476
    if (s->match.bus_num != 0 && s->match.port != NULL) {
......
1443 1482

  
1444 1483
static const VMStateDescription vmstate_usb_host = {
1445 1484
    .name = "usb-host",
1446
    .unmigratable = 1,
1485
    .version_id = 1,
1486
    .minimum_version_id = 1,
1487
    .post_load = usb_host_post_load,
1488
    .fields = (VMStateField[]) {
1489
        VMSTATE_USB_DEVICE(dev, USBHostDevice),
1490
        VMSTATE_END_OF_LIST()
1491
    }
1447 1492
};
1448 1493

  
1449 1494
static Property usb_host_dev_properties[] = {

Also available in: Unified diff