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:
Nolan 2009-07-20 14:11:35 -07:00 committed by Anthony Liguori
parent 6e5d97d01d
commit 777aec7ac9
1 changed files with 172 additions and 0 deletions

View File

@ -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 = {