usb-host: live migration support
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
		
							parent
							
								
									a844ed842d
								
							
						
					
					
						commit
						a229c0535b
					
				| @ -111,6 +111,7 @@ typedef struct USBHostDevice { | ||||
|     uint32_t  iso_urb_count; | ||||
|     uint32_t  options; | ||||
|     Notifier  exit; | ||||
|     QEMUBH    *bh; | ||||
| 
 | ||||
|     struct endp_data ep_in[USB_MAX_ENDPOINTS]; | ||||
|     struct endp_data ep_out[USB_MAX_ENDPOINTS]; | ||||
| @ -1421,6 +1422,43 @@ static void usb_host_exit_notifier(struct Notifier *n, void *data) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * This is *NOT* about restoring state.  We have absolutely no idea | ||||
|  * what state the host device is in at the moment and whenever it is | ||||
|  * still present in the first place.  Attemping to contine where we | ||||
|  * left off is impossible. | ||||
|  * | ||||
|  * What we are going to to to here is emulate a surprise removal of | ||||
|  * the usb device passed through, then kick host scan so the device | ||||
|  * will get re-attached (and re-initialized by the guest) in case it | ||||
|  * is still present. | ||||
|  * | ||||
|  * As the device removal will change the state of other devices (usb | ||||
|  * host controller, most likely interrupt controller too) we have to | ||||
|  * wait with it until *all* vmstate is loaded.  Thus post_load just | ||||
|  * kicks a bottom half which then does the actual work. | ||||
|  */ | ||||
| static void usb_host_post_load_bh(void *opaque) | ||||
| { | ||||
|     USBHostDevice *dev = opaque; | ||||
| 
 | ||||
|     if (dev->fd != -1) { | ||||
|         usb_host_close(dev); | ||||
|     } | ||||
|     if (dev->dev.attached) { | ||||
|         usb_device_detach(&dev->dev); | ||||
|     } | ||||
|     usb_host_auto_check(NULL); | ||||
| } | ||||
| 
 | ||||
| static int usb_host_post_load(void *opaque, int version_id) | ||||
| { | ||||
|     USBHostDevice *dev = opaque; | ||||
| 
 | ||||
|     qemu_bh_schedule(dev->bh); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static int usb_host_initfn(USBDevice *dev) | ||||
| { | ||||
|     USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev); | ||||
| @ -1432,6 +1470,7 @@ static int usb_host_initfn(USBDevice *dev) | ||||
|     QTAILQ_INSERT_TAIL(&hostdevs, s, next); | ||||
|     s->exit.notify = usb_host_exit_notifier; | ||||
|     qemu_add_exit_notifier(&s->exit); | ||||
|     s->bh = qemu_bh_new(usb_host_post_load_bh, s); | ||||
|     usb_host_auto_check(NULL); | ||||
| 
 | ||||
|     if (s->match.bus_num != 0 && s->match.port != NULL) { | ||||
| @ -1443,7 +1482,13 @@ static int usb_host_initfn(USBDevice *dev) | ||||
| 
 | ||||
| static const VMStateDescription vmstate_usb_host = { | ||||
|     .name = "usb-host", | ||||
|     .unmigratable = 1, | ||||
|     .version_id = 1, | ||||
|     .minimum_version_id = 1, | ||||
|     .post_load = usb_host_post_load, | ||||
|     .fields = (VMStateField[]) { | ||||
|         VMSTATE_USB_DEVICE(dev, USBHostDevice), | ||||
|         VMSTATE_END_OF_LIST() | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| static Property usb_host_dev_properties[] = { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Gerd Hoffmann
						Gerd Hoffmann