mirror of https://github.com/xemu-project/xemu.git
usb-ohci: Add vmstate descriptor
This adds migration support for OHCI. This defines a descriptor for OHCIState. This changes some OHCIState field types to be migration compatible. This adds a descriptor for OHCIPort. This migrates the EOF timer if the USB was started at the time of migration. Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
fdaad4715a
commit
69e25d26b4
|
@ -80,13 +80,13 @@ typedef struct {
|
||||||
uint32_t bulk_head, bulk_cur;
|
uint32_t bulk_head, bulk_cur;
|
||||||
uint32_t per_cur;
|
uint32_t per_cur;
|
||||||
uint32_t done;
|
uint32_t done;
|
||||||
int done_count;
|
int32_t done_count;
|
||||||
|
|
||||||
/* Frame counter partition */
|
/* Frame counter partition */
|
||||||
uint32_t fsmps:15;
|
uint16_t fsmps;
|
||||||
uint32_t fit:1;
|
uint8_t fit;
|
||||||
uint32_t fi:14;
|
uint16_t fi;
|
||||||
uint32_t frt:1;
|
uint8_t frt;
|
||||||
uint16_t frame_number;
|
uint16_t frame_number;
|
||||||
uint16_t padding;
|
uint16_t padding;
|
||||||
uint32_t pstart;
|
uint32_t pstart;
|
||||||
|
@ -111,7 +111,7 @@ typedef struct {
|
||||||
USBPacket usb_packet;
|
USBPacket usb_packet;
|
||||||
uint8_t usb_buf[8192];
|
uint8_t usb_buf[8192];
|
||||||
uint32_t async_td;
|
uint32_t async_td;
|
||||||
int async_complete;
|
bool async_complete;
|
||||||
|
|
||||||
} OHCIState;
|
} OHCIState;
|
||||||
|
|
||||||
|
@ -693,7 +693,7 @@ static void ohci_async_complete_packet(USBPort *port, USBPacket *packet)
|
||||||
#ifdef DEBUG_PACKET
|
#ifdef DEBUG_PACKET
|
||||||
DPRINTF("Async packet complete\n");
|
DPRINTF("Async packet complete\n");
|
||||||
#endif
|
#endif
|
||||||
ohci->async_complete = 1;
|
ohci->async_complete = true;
|
||||||
ohci_process_lists(ohci, 1);
|
ohci_process_lists(ohci, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1058,7 +1058,7 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
|
||||||
#endif
|
#endif
|
||||||
if (completion) {
|
if (completion) {
|
||||||
ohci->async_td = 0;
|
ohci->async_td = 0;
|
||||||
ohci->async_complete = 0;
|
ohci->async_complete = false;
|
||||||
} else {
|
} else {
|
||||||
if (ohci->async_td) {
|
if (ohci->async_td) {
|
||||||
/* ??? The hardware should allow one active packet per
|
/* ??? The hardware should allow one active packet per
|
||||||
|
@ -1984,6 +1984,108 @@ static Property ohci_pci_properties[] = {
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_ohci_state_port = {
|
||||||
|
.name = "ohci-core/port",
|
||||||
|
.version_id = 1,
|
||||||
|
.minimum_version_id = 1,
|
||||||
|
.minimum_version_id_old = 1,
|
||||||
|
.fields = (VMStateField []) {
|
||||||
|
VMSTATE_UINT32(ctrl, OHCIPort),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool ohci_eof_timer_needed(void *opaque)
|
||||||
|
{
|
||||||
|
OHCIState *ohci = opaque;
|
||||||
|
|
||||||
|
return ohci->eof_timer != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ohci_eof_timer_pre_load(void *opaque)
|
||||||
|
{
|
||||||
|
OHCIState *ohci = opaque;
|
||||||
|
|
||||||
|
ohci_bus_start(ohci);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_ohci_eof_timer = {
|
||||||
|
.name = "ohci-core/eof-timer",
|
||||||
|
.version_id = 1,
|
||||||
|
.minimum_version_id = 1,
|
||||||
|
.minimum_version_id_old = 1,
|
||||||
|
.pre_load = ohci_eof_timer_pre_load,
|
||||||
|
.fields = (VMStateField []) {
|
||||||
|
VMSTATE_TIMER(eof_timer, OHCIState),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const VMStateDescription vmstate_ohci_state = {
|
||||||
|
.name = "ohci-core",
|
||||||
|
.version_id = 1,
|
||||||
|
.minimum_version_id = 1,
|
||||||
|
.fields = (VMStateField[]) {
|
||||||
|
VMSTATE_INT64(sof_time, OHCIState),
|
||||||
|
VMSTATE_UINT32(ctl, OHCIState),
|
||||||
|
VMSTATE_UINT32(status, OHCIState),
|
||||||
|
VMSTATE_UINT32(intr_status, OHCIState),
|
||||||
|
VMSTATE_UINT32(intr, OHCIState),
|
||||||
|
VMSTATE_UINT32(hcca, OHCIState),
|
||||||
|
VMSTATE_UINT32(ctrl_head, OHCIState),
|
||||||
|
VMSTATE_UINT32(ctrl_cur, OHCIState),
|
||||||
|
VMSTATE_UINT32(bulk_head, OHCIState),
|
||||||
|
VMSTATE_UINT32(bulk_cur, OHCIState),
|
||||||
|
VMSTATE_UINT32(per_cur, OHCIState),
|
||||||
|
VMSTATE_UINT32(done, OHCIState),
|
||||||
|
VMSTATE_INT32(done_count, OHCIState),
|
||||||
|
VMSTATE_UINT16(fsmps, OHCIState),
|
||||||
|
VMSTATE_UINT8(fit, OHCIState),
|
||||||
|
VMSTATE_UINT16(fi, OHCIState),
|
||||||
|
VMSTATE_UINT8(frt, OHCIState),
|
||||||
|
VMSTATE_UINT16(frame_number, OHCIState),
|
||||||
|
VMSTATE_UINT16(padding, OHCIState),
|
||||||
|
VMSTATE_UINT32(pstart, OHCIState),
|
||||||
|
VMSTATE_UINT32(lst, OHCIState),
|
||||||
|
VMSTATE_UINT32(rhdesc_a, OHCIState),
|
||||||
|
VMSTATE_UINT32(rhdesc_b, OHCIState),
|
||||||
|
VMSTATE_UINT32(rhstatus, OHCIState),
|
||||||
|
VMSTATE_STRUCT_ARRAY(rhport, OHCIState, OHCI_MAX_PORTS, 0,
|
||||||
|
vmstate_ohci_state_port, OHCIPort),
|
||||||
|
VMSTATE_UINT32(hstatus, OHCIState),
|
||||||
|
VMSTATE_UINT32(hmask, OHCIState),
|
||||||
|
VMSTATE_UINT32(hreset, OHCIState),
|
||||||
|
VMSTATE_UINT32(htest, OHCIState),
|
||||||
|
VMSTATE_UINT32(old_ctl, OHCIState),
|
||||||
|
VMSTATE_UINT8_ARRAY(usb_buf, OHCIState, 8192),
|
||||||
|
VMSTATE_UINT32(async_td, OHCIState),
|
||||||
|
VMSTATE_BOOL(async_complete, OHCIState),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
},
|
||||||
|
.subsections = (VMStateSubsection []) {
|
||||||
|
{
|
||||||
|
.vmsd = &vmstate_ohci_eof_timer,
|
||||||
|
.needed = ohci_eof_timer_needed,
|
||||||
|
} , {
|
||||||
|
/* empty */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_ohci = {
|
||||||
|
.name = "ohci",
|
||||||
|
.version_id = 1,
|
||||||
|
.minimum_version_id = 1,
|
||||||
|
.minimum_version_id_old = 1,
|
||||||
|
.fields = (VMStateField[]) {
|
||||||
|
VMSTATE_PCI_DEVICE(parent_obj, OHCIPCIState),
|
||||||
|
VMSTATE_STRUCT(state, OHCIPCIState, 1, vmstate_ohci_state, OHCIState),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static void ohci_pci_class_init(ObjectClass *klass, void *data)
|
static void ohci_pci_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
|
@ -1997,6 +2099,7 @@ static void ohci_pci_class_init(ObjectClass *klass, void *data)
|
||||||
dc->desc = "Apple USB Controller";
|
dc->desc = "Apple USB Controller";
|
||||||
dc->props = ohci_pci_properties;
|
dc->props = ohci_pci_properties;
|
||||||
dc->hotpluggable = false;
|
dc->hotpluggable = false;
|
||||||
|
dc->vmsd = &vmstate_ohci;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo ohci_pci_info = {
|
static const TypeInfo ohci_pci_info = {
|
||||||
|
|
Loading…
Reference in New Issue