summaryrefslogtreecommitdiff
path: root/hw/usb
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2012-05-14 13:55:44 +0200
committerGerd Hoffmann <kraxel@redhat.com>2012-06-20 14:46:02 +0200
commit9a77340827cd48c5c9b6daab614009a0594abf38 (patch)
tree814917952be1c64cb8b671380021be8207bebb00 /hw/usb
parent93bfef4c6e4b23caea9d51e1099d06433d8835a4 (diff)
downloadqemu-9a77340827cd48c5c9b6daab614009a0594abf38.zip
ehci: add live migration support
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw/usb')
-rw-r--r--hw/usb/hcd-ehci.c62
1 files changed, 56 insertions, 6 deletions
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 5298204d9d..45b774d8ac 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -414,16 +414,17 @@ struct EHCIState {
*/
QEMUTimer *frame_timer;
QEMUBH *async_bh;
- int astate; // Current state in asynchronous schedule
- int pstate; // Current state in periodic schedule
+ uint32_t astate; /* Current state in asynchronous schedule */
+ uint32_t pstate; /* Current state in periodic schedule */
USBPort ports[NB_PORTS];
USBPort *companion_ports[NB_PORTS];
uint32_t usbsts_pending;
EHCIQueueHead aqueues;
EHCIQueueHead pqueues;
- uint32_t a_fetch_addr; // which address to look at next
- uint32_t p_fetch_addr; // which address to look at next
+ /* which address to look at next */
+ uint32_t a_fetch_addr;
+ uint32_t p_fetch_addr;
USBPacket ipacket;
QEMUSGList isgl;
@@ -2390,9 +2391,58 @@ static USBBusOps ehci_bus_ops = {
.register_companion = ehci_register_companion,
};
+static int usb_ehci_post_load(void *opaque, int version_id)
+{
+ EHCIState *s = opaque;
+ int i;
+
+ for (i = 0; i < NB_PORTS; i++) {
+ USBPort *companion = s->companion_ports[i];
+ if (companion == NULL) {
+ continue;
+ }
+ if (s->portsc[i] & PORTSC_POWNER) {
+ companion->dev = s->ports[i].dev;
+ } else {
+ companion->dev = NULL;
+ }
+ }
+
+ return 0;
+}
+
static const VMStateDescription vmstate_ehci = {
- .name = "ehci",
- .unmigratable = 1,
+ .name = "ehci",
+ .version_id = 1,
+ .post_load = usb_ehci_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_PCI_DEVICE(dev, EHCIState),
+ /* mmio registers */
+ VMSTATE_UINT32(usbcmd, EHCIState),
+ VMSTATE_UINT32(usbsts, EHCIState),
+ VMSTATE_UINT32(usbintr, EHCIState),
+ VMSTATE_UINT32(frindex, EHCIState),
+ VMSTATE_UINT32(ctrldssegment, EHCIState),
+ VMSTATE_UINT32(periodiclistbase, EHCIState),
+ VMSTATE_UINT32(asynclistaddr, EHCIState),
+ VMSTATE_UINT32(configflag, EHCIState),
+ VMSTATE_UINT32(portsc[0], EHCIState),
+ VMSTATE_UINT32(portsc[1], EHCIState),
+ VMSTATE_UINT32(portsc[2], EHCIState),
+ VMSTATE_UINT32(portsc[3], EHCIState),
+ VMSTATE_UINT32(portsc[4], EHCIState),
+ VMSTATE_UINT32(portsc[5], EHCIState),
+ /* frame timer */
+ VMSTATE_TIMER(frame_timer, EHCIState),
+ VMSTATE_UINT64(last_run_ns, EHCIState),
+ VMSTATE_UINT32(async_stepdown, EHCIState),
+ /* schedule state */
+ VMSTATE_UINT32(astate, EHCIState),
+ VMSTATE_UINT32(pstate, EHCIState),
+ VMSTATE_UINT32(a_fetch_addr, EHCIState),
+ VMSTATE_UINT32(p_fetch_addr, EHCIState),
+ VMSTATE_END_OF_LIST()
+ }
};
static Property ehci_properties[] = {