Add save/restore support to the LSI logic SCSI device model.
This patch requires "Handle BH's queued by AIO completions in qemu_aio_flush()" to work reliably. The combination of those two patches survived 300+ migrations with heavy IO load running in the guest. Signed-off-by: Nolan Leake <nolan <at> sigbus.net> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
6e5d97d01d
commit
777aec7ac9
172
hw/lsi53c895a.c
172
hw/lsi53c895a.c
@ -10,6 +10,8 @@
|
||||
/* ??? Need to check if the {read,write}[wl] routines work properly on
|
||||
big-endian targets. */
|
||||
|
||||
#include <assert.h> \
|
||||
|
||||
#include "hw.h"
|
||||
#include "pci.h"
|
||||
#include "scsi-disk.h"
|
||||
@ -1981,6 +1983,174 @@ void lsi_scsi_attach(DeviceState *host, BlockDriverState *bd, int id)
|
||||
bd->private = &s->pci_dev;
|
||||
}
|
||||
|
||||
static void lsi_scsi_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
LSIState *s = opaque;
|
||||
|
||||
assert(s->dma_buf == NULL);
|
||||
assert(s->current_dma_len == 0);
|
||||
assert(s->active_commands == 0);
|
||||
|
||||
pci_device_save(&s->pci_dev, f);
|
||||
|
||||
qemu_put_sbe32s(f, &s->carry);
|
||||
qemu_put_sbe32s(f, &s->sense);
|
||||
qemu_put_sbe32s(f, &s->msg_action);
|
||||
qemu_put_sbe32s(f, &s->msg_len);
|
||||
qemu_put_buffer(f, s->msg, sizeof (s->msg));
|
||||
qemu_put_sbe32s(f, &s->waiting);
|
||||
|
||||
qemu_put_be32s(f, &s->dsa);
|
||||
qemu_put_be32s(f, &s->temp);
|
||||
qemu_put_be32s(f, &s->dnad);
|
||||
qemu_put_be32s(f, &s->dbc);
|
||||
qemu_put_8s(f, &s->istat0);
|
||||
qemu_put_8s(f, &s->istat1);
|
||||
qemu_put_8s(f, &s->dcmd);
|
||||
qemu_put_8s(f, &s->dstat);
|
||||
qemu_put_8s(f, &s->dien);
|
||||
qemu_put_8s(f, &s->sist0);
|
||||
qemu_put_8s(f, &s->sist1);
|
||||
qemu_put_8s(f, &s->sien0);
|
||||
qemu_put_8s(f, &s->sien1);
|
||||
qemu_put_8s(f, &s->mbox0);
|
||||
qemu_put_8s(f, &s->mbox1);
|
||||
qemu_put_8s(f, &s->dfifo);
|
||||
qemu_put_8s(f, &s->ctest2);
|
||||
qemu_put_8s(f, &s->ctest3);
|
||||
qemu_put_8s(f, &s->ctest4);
|
||||
qemu_put_8s(f, &s->ctest5);
|
||||
qemu_put_8s(f, &s->ccntl0);
|
||||
qemu_put_8s(f, &s->ccntl1);
|
||||
qemu_put_be32s(f, &s->dsp);
|
||||
qemu_put_be32s(f, &s->dsps);
|
||||
qemu_put_8s(f, &s->dmode);
|
||||
qemu_put_8s(f, &s->dcntl);
|
||||
qemu_put_8s(f, &s->scntl0);
|
||||
qemu_put_8s(f, &s->scntl1);
|
||||
qemu_put_8s(f, &s->scntl2);
|
||||
qemu_put_8s(f, &s->scntl3);
|
||||
qemu_put_8s(f, &s->sstat0);
|
||||
qemu_put_8s(f, &s->sstat1);
|
||||
qemu_put_8s(f, &s->scid);
|
||||
qemu_put_8s(f, &s->sxfer);
|
||||
qemu_put_8s(f, &s->socl);
|
||||
qemu_put_8s(f, &s->sdid);
|
||||
qemu_put_8s(f, &s->ssid);
|
||||
qemu_put_8s(f, &s->sfbr);
|
||||
qemu_put_8s(f, &s->stest1);
|
||||
qemu_put_8s(f, &s->stest2);
|
||||
qemu_put_8s(f, &s->stest3);
|
||||
qemu_put_8s(f, &s->sidl);
|
||||
qemu_put_8s(f, &s->stime0);
|
||||
qemu_put_8s(f, &s->respid0);
|
||||
qemu_put_8s(f, &s->respid1);
|
||||
qemu_put_be32s(f, &s->mmrs);
|
||||
qemu_put_be32s(f, &s->mmws);
|
||||
qemu_put_be32s(f, &s->sfs);
|
||||
qemu_put_be32s(f, &s->drs);
|
||||
qemu_put_be32s(f, &s->sbms);
|
||||
qemu_put_be32s(f, &s->dbms);
|
||||
qemu_put_be32s(f, &s->dnad64);
|
||||
qemu_put_be32s(f, &s->pmjad1);
|
||||
qemu_put_be32s(f, &s->pmjad2);
|
||||
qemu_put_be32s(f, &s->rbc);
|
||||
qemu_put_be32s(f, &s->ua);
|
||||
qemu_put_be32s(f, &s->ia);
|
||||
qemu_put_be32s(f, &s->sbc);
|
||||
qemu_put_be32s(f, &s->csbc);
|
||||
qemu_put_buffer(f, (uint8_t *)s->scratch, sizeof (s->scratch));
|
||||
qemu_put_8s(f, &s->sbr);
|
||||
|
||||
qemu_put_buffer(f, (uint8_t *)s->script_ram, sizeof (s->script_ram));
|
||||
}
|
||||
|
||||
static int lsi_scsi_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
LSIState *s = opaque;
|
||||
int ret;
|
||||
|
||||
if (version_id > 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((ret = pci_device_load(&s->pci_dev, f)) < 0)
|
||||
return ret;
|
||||
|
||||
qemu_get_sbe32s(f, &s->carry);
|
||||
qemu_get_sbe32s(f, &s->sense);
|
||||
qemu_get_sbe32s(f, &s->msg_action);
|
||||
qemu_get_sbe32s(f, &s->msg_len);
|
||||
qemu_get_buffer(f, s->msg, sizeof (s->msg));
|
||||
qemu_get_sbe32s(f, &s->waiting);
|
||||
|
||||
qemu_get_be32s(f, &s->dsa);
|
||||
qemu_get_be32s(f, &s->temp);
|
||||
qemu_get_be32s(f, &s->dnad);
|
||||
qemu_get_be32s(f, &s->dbc);
|
||||
qemu_get_8s(f, &s->istat0);
|
||||
qemu_get_8s(f, &s->istat1);
|
||||
qemu_get_8s(f, &s->dcmd);
|
||||
qemu_get_8s(f, &s->dstat);
|
||||
qemu_get_8s(f, &s->dien);
|
||||
qemu_get_8s(f, &s->sist0);
|
||||
qemu_get_8s(f, &s->sist1);
|
||||
qemu_get_8s(f, &s->sien0);
|
||||
qemu_get_8s(f, &s->sien1);
|
||||
qemu_get_8s(f, &s->mbox0);
|
||||
qemu_get_8s(f, &s->mbox1);
|
||||
qemu_get_8s(f, &s->dfifo);
|
||||
qemu_get_8s(f, &s->ctest2);
|
||||
qemu_get_8s(f, &s->ctest3);
|
||||
qemu_get_8s(f, &s->ctest4);
|
||||
qemu_get_8s(f, &s->ctest5);
|
||||
qemu_get_8s(f, &s->ccntl0);
|
||||
qemu_get_8s(f, &s->ccntl1);
|
||||
qemu_get_be32s(f, &s->dsp);
|
||||
qemu_get_be32s(f, &s->dsps);
|
||||
qemu_get_8s(f, &s->dmode);
|
||||
qemu_get_8s(f, &s->dcntl);
|
||||
qemu_get_8s(f, &s->scntl0);
|
||||
qemu_get_8s(f, &s->scntl1);
|
||||
qemu_get_8s(f, &s->scntl2);
|
||||
qemu_get_8s(f, &s->scntl3);
|
||||
qemu_get_8s(f, &s->sstat0);
|
||||
qemu_get_8s(f, &s->sstat1);
|
||||
qemu_get_8s(f, &s->scid);
|
||||
qemu_get_8s(f, &s->sxfer);
|
||||
qemu_get_8s(f, &s->socl);
|
||||
qemu_get_8s(f, &s->sdid);
|
||||
qemu_get_8s(f, &s->ssid);
|
||||
qemu_get_8s(f, &s->sfbr);
|
||||
qemu_get_8s(f, &s->stest1);
|
||||
qemu_get_8s(f, &s->stest2);
|
||||
qemu_get_8s(f, &s->stest3);
|
||||
qemu_get_8s(f, &s->sidl);
|
||||
qemu_get_8s(f, &s->stime0);
|
||||
qemu_get_8s(f, &s->respid0);
|
||||
qemu_get_8s(f, &s->respid1);
|
||||
qemu_get_be32s(f, &s->mmrs);
|
||||
qemu_get_be32s(f, &s->mmws);
|
||||
qemu_get_be32s(f, &s->sfs);
|
||||
qemu_get_be32s(f, &s->drs);
|
||||
qemu_get_be32s(f, &s->sbms);
|
||||
qemu_get_be32s(f, &s->dbms);
|
||||
qemu_get_be32s(f, &s->dnad64);
|
||||
qemu_get_be32s(f, &s->pmjad1);
|
||||
qemu_get_be32s(f, &s->pmjad2);
|
||||
qemu_get_be32s(f, &s->rbc);
|
||||
qemu_get_be32s(f, &s->ua);
|
||||
qemu_get_be32s(f, &s->ia);
|
||||
qemu_get_be32s(f, &s->sbc);
|
||||
qemu_get_be32s(f, &s->csbc);
|
||||
qemu_get_buffer(f, (uint8_t *)s->scratch, sizeof (s->scratch));
|
||||
qemu_get_8s(f, &s->sbr);
|
||||
|
||||
qemu_get_buffer(f, (uint8_t *)s->script_ram, sizeof (s->script_ram));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lsi_scsi_uninit(PCIDevice *d)
|
||||
{
|
||||
LSIState *s = (LSIState *) d;
|
||||
@ -2033,6 +2203,8 @@ static void lsi_scsi_init(PCIDevice *dev)
|
||||
lsi_soft_reset(s);
|
||||
|
||||
scsi_bus_new(&dev->qdev, lsi_scsi_attach);
|
||||
|
||||
register_savevm("lsiscsi", -1, 0, lsi_scsi_save, lsi_scsi_load, s);
|
||||
}
|
||||
|
||||
static PCIDeviceInfo lsi_info = {
|
||||
|
Loading…
Reference in New Issue
Block a user