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[] = {