# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Date 1173869096 0
# Node ID 2955b067731093888e7f97e3da93b51dc8b5d255
# Parent 3c38150de7fd4328a1d8e95b70b966d2ac481e12
add usb device save/restore in qemu
Signed-off-by: Zhai Edwin <edwin.zhai@xxxxxxxxx>
---
tools/ioemu/hw/usb-hid.c | 47 +++++++++++++++++++++++++++++++++++++++++++
tools/ioemu/hw/usb-ohci.c | 2 +
tools/ioemu/hw/usb-uhci.c | 50 +++++++++++++++++++++++++++++++++++++++++++++-
tools/ioemu/hw/usb.c | 40 ++++++++++++++++++++++++++++++++++++
tools/ioemu/hw/usb.h | 6 +++++
tools/ioemu/vl.c | 19 +++++++++++++++++
6 files changed, 163 insertions(+), 1 deletion(-)
diff -r 3c38150de7fd -r 2955b0677310 tools/ioemu/hw/usb-hid.c
--- a/tools/ioemu/hw/usb-hid.c Tue Mar 13 15:55:37 2007 +0000
+++ b/tools/ioemu/hw/usb-hid.c Wed Mar 14 10:44:56 2007 +0000
@@ -517,6 +517,49 @@ static void usb_mouse_handle_destroy(USB
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);
+ qemu_put_be32s(f, &s->status_changed);
+
+}
+
+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);
+ qemu_get_be32s(f, &s->status_changed);
+
+ if ( s->kind == USB_TABLET) {
+ fprintf(logfile, "usb_mouse_load:add usb_tablet_event.\n");
+ qemu_add_mouse_event_handler(usb_tablet_event, s, 1);
+ } else if ( s->kind == USB_MOUSE) {
+ fprintf(logfile, "usb_mouse_load:add usb_mouse_event.\n");
+ qemu_add_mouse_event_handler(usb_mouse_event, s, 0);
+ }
+}
+
+
USBDevice *usb_tablet_init(void)
{
USBMouseState *s;
@@ -536,6 +579,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;
}
@@ -558,5 +603,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 -r 3c38150de7fd -r 2955b0677310 tools/ioemu/hw/usb-ohci.c
--- a/tools/ioemu/hw/usb-ohci.c Tue Mar 13 15:55:37 2007 +0000
+++ b/tools/ioemu/hw/usb-ohci.c Wed Mar 14 10:44:56 2007 +0000
@@ -1186,5 +1186,7 @@ void usb_ohci_init(struct PCIBus *bus, i
qemu_register_usb_port(&ohci->rhport[i].port, ohci, i, ohci_attach);
}
+ register_savevm("OHCI USB", 0, 1, generic_pci_save, generic_pci_load,
ohci);
+
ohci_reset(ohci);
}
diff -r 3c38150de7fd -r 2955b0677310 tools/ioemu/hw/usb-uhci.c
--- a/tools/ioemu/hw/usb-uhci.c Tue Mar 13 15:55:37 2007 +0000
+++ b/tools/ioemu/hw/usb-uhci.c Wed Mar 14 10:44:56 2007 +0000
@@ -658,6 +658,50 @@ static void uhci_map(PCIDevice *pci_dev,
register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
}
+void uhci_usb_save(QEMUFile *f, void *opaque)
+{
+ int i;
+ UHCIState *s = (UHCIState*)opaque;
+
+ qemu_put_be16s(f, &s->cmd);
+ qemu_put_be16s(f, &s->status);
+ qemu_put_be16s(f, &s->intr);
+ qemu_put_be16s(f, &s->frnum);
+ qemu_put_be32s(f, &s->fl_base_addr);
+ qemu_put_8s(f, &s->sof_timing);
+ qemu_put_8s(f, &s->status2);
+
+ for(i = 0; i < NB_PORTS; i++) {
+ qemu_put_be16s(f, &s->ports[i].ctrl);
+ }
+
+ qemu_put_timer(f, s->frame_timer);
+}
+
+int uhci_usb_load(QEMUFile *f, void *opaque, int version_id)
+{
+ int i;
+ UHCIState *s = (UHCIState*)opaque;
+
+ if (version_id != 1)
+ return -EINVAL;
+
+ qemu_get_be16s(f, &s->cmd);
+ qemu_get_be16s(f, &s->status);
+ qemu_get_be16s(f, &s->intr);
+ qemu_get_be16s(f, &s->frnum);
+ qemu_get_be32s(f, &s->fl_base_addr);
+ qemu_get_8s(f, &s->sof_timing);
+ qemu_get_8s(f, &s->status2);
+
+ for(i = 0; i < NB_PORTS; i++) {
+ qemu_get_be16s(f, &s->ports[i].ctrl);
+ }
+
+ qemu_get_timer(f, s->frame_timer);
+
+}
+
void usb_uhci_init(PCIBus *bus, int devfn)
{
UHCIState *s;
@@ -693,4 +737,8 @@ void usb_uhci_init(PCIBus *bus, int devf
to rely on this. */
pci_register_io_region(&s->dev, 4, 0x20,
PCI_ADDRESS_SPACE_IO, uhci_map);
-}
+
+ register_savevm("UHCI_usb_pci", 0, 1, generic_pci_save, generic_pci_load,
s);
+
+ register_savevm("UHCI usb controller", 0, 1, uhci_usb_save, uhci_usb_load,
s);
+}
diff -r 3c38150de7fd -r 2955b0677310 tools/ioemu/hw/usb.c
--- a/tools/ioemu/hw/usb.c Tue Mar 13 15:55:37 2007 +0000
+++ b/tools/ioemu/hw/usb.c Wed Mar 14 10:44:56 2007 +0000
@@ -191,3 +191,43 @@ int set_usb_string(uint8_t *buf, const c
}
return q - buf;
}
+
+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 -r 3c38150de7fd -r 2955b0677310 tools/ioemu/hw/usb.h
--- a/tools/ioemu/hw/usb.h Tue Mar 13 15:55:37 2007 +0000
+++ b/tools/ioemu/hw/usb.h Wed Mar 14 10:44:56 2007 +0000
@@ -176,3 +176,9 @@ 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 -r 3c38150de7fd -r 2955b0677310 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Tue Mar 13 15:55:37 2007 +0000
+++ b/tools/ioemu/vl.c Wed Mar 14 10:44:56 2007 +0000
@@ -841,10 +841,22 @@ void qemu_get_timer(QEMUFile *f, QEMUTim
#ifdef CONFIG_DM
static void timer_save(QEMUFile *f, void *opaque)
{
+ /* need timer for save/restoe qemu_timer in usb_uhci */
+ if (cpu_ticks_enabled) {
+ hw_error("cannot save state if virtual timers are running");
+ }
+ qemu_put_be64s(f, &cpu_clock_offset);
}
static int timer_load(QEMUFile *f, void *opaque, int version_id)
{
+ if (version_id != 1)
+ return -EINVAL;
+ if (cpu_ticks_enabled) {
+ return -EINVAL;
+ }
+
+ qemu_get_be64s(f, &cpu_clock_offset);
return 0;
}
#else /* !CONFIG_DM */
@@ -3900,6 +3912,7 @@ static int usb_device_add(const char *de
const char *p;
USBDevice *dev;
USBPort *port;
+ char usb_name[256] = "USB ";
if (!free_usb_ports)
return -1;
@@ -3936,6 +3949,12 @@ static int usb_device_add(const char *de
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;
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|