qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] save/restore for LSI SCSI.


From: Nolan
Subject: [Qemu-devel] [PATCH] save/restore for LSI SCSI.
Date: Wed, 14 Jan 2009 13:37:36 -0800

This patch adds save and restore to the LSIlogic SCSI model.

It works fine if the adapter is idle when suspending.  After resume,
subsequent IO operations complete normally.  I have only tested on a
debian etch guest, no windows.

There is a bug if there is IO in flight.  Sometimes it results in the
guest freezing hard, other times in the guest unsuccessfully reseting
the adapter.  Oddly, I saw at least one case where restore failed (with
the "reset the adapter" case), but a second restore from the same
snapshot worked.

I've not much further time to dedicate to this code, so I'm sending it
to the list in the hopes that others might.

Signed-off-by: Nolan Leake <address@hidden>

diff --git a/qemu/hw/lsi53c895a.c b/qemu/hw/lsi53c895a.c
index c65ff90..c44f289 100644
--- a/qemu/hw/lsi53c895a.c
+++ b/qemu/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"
@@ -1973,6 +1975,170 @@ int lsi_scsi_uninit(PCIDevice *d)
     return 0;
 }
 
+static void lsi_scsi_save(QEMUFile *f, void *opaque)
+{
+    LSIState *s = opaque;
+
+    assert(s->active_commands == 0);
+    assert(s->dma_buf == NULL);
+
+#if 0
+    /* XXX Do we need to save any of these? */
+    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);
+#endif
+
+    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_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;
+
+    if (version_id > 0) {
+        return -EINVAL;
+    }
+
+#if 0
+    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);
+#endif
+
+    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_buffer(f, (uint8_t *)s->script_ram, sizeof (s->script_ram));
+
+    return 0;
+}
+
 void *lsi_scsi_init(PCIBus *bus, int devfn)
 {
     LSIState *s;
@@ -2018,5 +2184,7 @@ void *lsi_scsi_init(PCIBus *bus, int devfn)
 
     lsi_soft_reset(s);
 
+    register_savevm("lsiscsi", -1, 0, lsi_scsi_save, lsi_scsi_load, s);
+
     return s;
 }






reply via email to

[Prev in Thread] Current Thread [Next in Thread]