From 8865ab79a0a9ce0d55082854fb29cc26535c8722 Mon Sep 17 00:00:00 2001 Message-Id: <8865ab79a0a9ce0d55082854fb29cc26535c8722.1346940159.git.minovotn@redhat.com> In-Reply-To: References: From: Gerd Hoffmann Date: Thu, 16 Aug 2012 11:39:09 +0200 Subject: [PATCH 07/18] ehci: add live migration support RH-Author: Gerd Hoffmann Message-id: <1345117160-21046-8-git-send-email-kraxel@redhat.com> Patchwork-id: 40930 O-Subject: [RHEL-6.4 qemu-kvm PATCH 07/18] ehci: add live migration support Bugzilla: 805172 RH-Acked-by: Paolo Bonzini RH-Acked-by: Hans de Goede RH-Acked-by: Laszlo Ersek [ rhel6: add pre_save & post_load to convert last_run_ns <=> last_run_usec ] Signed-off-by: Gerd Hoffmann (cherry picked from commit 9a77340827cd48c5c9b6daab614009a0594abf38) Conflicts: hw/usb-ehci.c --- hw/usb-ehci.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 69 insertions(+), 6 deletions(-) Signed-off-by: Michal Novotny --- hw/usb-ehci.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c index 46b51ec..aa0afbf 100644 --- a/hw/usb-ehci.c +++ b/hw/usb-ehci.c @@ -403,16 +403,17 @@ struct EHCIState { QEMUTimer *frame_timer; QEMUBH *async_bh; int attach_poll_counter; - 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; uint8_t ibuffer[BUFF_SIZE]; @@ -420,6 +421,10 @@ struct EHCIState { uint32_t last_run_usec; uint32_t frame_end_usec; + + /* for migration compatibility with upstream */ + uint64_t last_run_ns; + uint32_t async_stepdown; }; #define SET_LAST_RUN_CLOCK(s) \ @@ -2215,9 +2220,67 @@ static USBBusOps ehci_bus_ops = { .register_companion = ehci_register_companion, }; +static void usb_ehci_pre_save(void *opaque) +{ + EHCIState *s = opaque; + + s->last_run_ns = (uint64_t)(s->last_run_usec) * 1000; +} + +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; + } + } + + s->last_run_usec = s->last_run_ns / 1000; + return 0; +} + static const VMStateDescription vmstate_ehci = { - .name = "ehci", - .unmigratable = 1, + .name = "ehci", + .version_id = 1, + .pre_save = usb_ehci_pre_save, + .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[] = { -- 1.7.11.4