commit 93f590514fa96dedc02274183fd1c57fcbba6fdc Author: Uri Lublin Date: Mon Jul 23 11:57:33 2007 +0300 migration: save/load usb devices (specifically mouse/tablet) Taken (slightly modified) from xen (hg 14366:2955b0677310 Tim Deegan) Signed-off-by: Uri Lublin diff --git a/qemu/hw/usb-hid.c b/qemu/hw/usb-hid.c index bde3a7c..d24a959 100644 --- a/qemu/hw/usb-hid.c +++ b/qemu/hw/usb-hid.c @@ -510,6 +510,45 @@ static void usb_mouse_handle_destroy(USBDevice *dev) qemu_free(s); } +void usb_mouse_save(QEMUFile *f, void *opaque) +{ + USBMouseState *s = (USBMouseState*)opaque; + + qemu_put_be32s(f, &s->dx); + qemu_put_be32s(f, &s->dy); + qemu_put_be32s(f, &s->dz); + qemu_put_be32s(f, &s->buttons_state); + qemu_put_be32s(f, &s->x); + qemu_put_be32s(f, &s->y); + qemu_put_be32s(f, &s->kind); + qemu_put_be32s(f, &s->mouse_grabbed); + +} + +int usb_mouse_load(QEMUFile *f, void *opaque, int version_id) +{ + USBMouseState *s = (USBMouseState*)opaque; + + if (version_id != 1) + return -EINVAL; + + qemu_get_be32s(f, &s->dx); + qemu_get_be32s(f, &s->dy); + qemu_get_be32s(f, &s->dz); + qemu_get_be32s(f, &s->buttons_state); + qemu_get_be32s(f, &s->x); + qemu_get_be32s(f, &s->y); + qemu_get_be32s(f, &s->kind); + qemu_get_be32s(f, &s->mouse_grabbed); + + if ( s->kind == USB_TABLET) + qemu_add_mouse_event_handler(usb_tablet_event, s, 1, "QEMU USB Tablet"); + else if ( s->kind == USB_MOUSE) + qemu_add_mouse_event_handler(usb_mouse_event, s, 0, "QEMU USB Mouse"); + return 0; +} + + USBDevice *usb_tablet_init(void) { USBMouseState *s; @@ -528,6 +567,8 @@ USBDevice *usb_tablet_init(void) pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet"); + register_savevm("USB tablet dev", 0, 1, usb_mouse_save, usb_mouse_load, s); + return (USBDevice *)s; } @@ -549,5 +590,7 @@ USBDevice *usb_mouse_init(void) pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse"); + register_savevm("USB mouse dev", 0, 1, usb_mouse_save, usb_mouse_load, s); + return (USBDevice *)s; } diff --git a/qemu/hw/usb.c b/qemu/hw/usb.c index efbc6db..04d9233 100644 --- a/qemu/hw/usb.c +++ b/qemu/hw/usb.c @@ -201,3 +201,43 @@ void usb_send_msg(USBDevice *dev, int msg) dev->handle_packet(dev, &p); } +void generic_usb_save(QEMUFile* f, void *opaque) +{ + USBDevice *s = (USBDevice*)opaque; + + qemu_put_be32s(f, &s->speed); + qemu_put_8s(f, &s->addr); + qemu_put_be32s(f, &s->state); + + qemu_put_buffer(f, s->setup_buf, 8); + qemu_put_buffer(f, s->data_buf, 1024); + + qemu_put_be32s(f, &s->remote_wakeup); + qemu_put_be32s(f, &s->setup_state); + qemu_put_be32s(f, &s->setup_len); + qemu_put_be32s(f, &s->setup_index); + +} + +int generic_usb_load(QEMUFile* f, void *opaque, int version_id) +{ + USBDevice *s = (USBDevice*)opaque; + + if (version_id != 1) + return -EINVAL; + + qemu_get_be32s(f, &s->speed); + qemu_get_8s(f, &s->addr); + qemu_get_be32s(f, &s->state); + + qemu_get_buffer(f, s->setup_buf, 8); + qemu_get_buffer(f, s->data_buf, 1024); + + qemu_get_be32s(f, &s->remote_wakeup); + qemu_get_be32s(f, &s->setup_state); + qemu_get_be32s(f, &s->setup_len); + qemu_get_be32s(f, &s->setup_index); + + return 0; +} + diff --git a/qemu/hw/usb.h b/qemu/hw/usb.h index ed8890e..f2e6d3f 100644 --- a/qemu/hw/usb.h +++ b/qemu/hw/usb.h @@ -218,3 +218,8 @@ USBDevice *usb_tablet_init(void); /* usb-msd.c */ USBDevice *usb_msd_init(const char *filename); + +/* usb.c */ +void generic_usb_save(QEMUFile* f, void *opaque); +int generic_usb_load(QEMUFile* f, void *opaque, int version_id); + diff --git a/qemu/vl.c b/qemu/vl.c index c795af2..f166b92 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -4023,6 +4023,7 @@ static int usb_device_add(const char *devname) const char *p; USBDevice *dev; USBPort *port; + char usb_name[256] = "USB "; if (!free_usb_ports) return -1; @@ -4059,6 +4060,12 @@ static int usb_device_add(const char *devname) free_usb_ports = port->next; port->next = used_usb_ports; used_usb_ports = port; + + pstrcpy(usb_name + strlen(usb_name), + sizeof(usb_name) - strlen(usb_name), + devname); + register_savevm(usb_name, 0, 1, generic_usb_save, generic_usb_load, dev); + usb_attach(port, dev); return 0; }