Commit 777aec7ac91b1306d77897aafc8097a87bf4a672
Committed by
Anthony Liguori
1 parent
6e5d97d0
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>
Showing
1 changed file
with
172 additions
and
0 deletions
hw/lsi53c895a.c
... | ... | @@ -10,6 +10,8 @@ |
10 | 10 | /* ??? Need to check if the {read,write}[wl] routines work properly on |
11 | 11 | big-endian targets. */ |
12 | 12 | |
13 | +#include <assert.h> \ | |
14 | + | |
13 | 15 | #include "hw.h" |
14 | 16 | #include "pci.h" |
15 | 17 | #include "scsi-disk.h" |
... | ... | @@ -1981,6 +1983,174 @@ void lsi_scsi_attach(DeviceState *host, BlockDriverState *bd, int id) |
1981 | 1983 | bd->private = &s->pci_dev; |
1982 | 1984 | } |
1983 | 1985 | |
1986 | +static void lsi_scsi_save(QEMUFile *f, void *opaque) | |
1987 | +{ | |
1988 | + LSIState *s = opaque; | |
1989 | + | |
1990 | + assert(s->dma_buf == NULL); | |
1991 | + assert(s->current_dma_len == 0); | |
1992 | + assert(s->active_commands == 0); | |
1993 | + | |
1994 | + pci_device_save(&s->pci_dev, f); | |
1995 | + | |
1996 | + qemu_put_sbe32s(f, &s->carry); | |
1997 | + qemu_put_sbe32s(f, &s->sense); | |
1998 | + qemu_put_sbe32s(f, &s->msg_action); | |
1999 | + qemu_put_sbe32s(f, &s->msg_len); | |
2000 | + qemu_put_buffer(f, s->msg, sizeof (s->msg)); | |
2001 | + qemu_put_sbe32s(f, &s->waiting); | |
2002 | + | |
2003 | + qemu_put_be32s(f, &s->dsa); | |
2004 | + qemu_put_be32s(f, &s->temp); | |
2005 | + qemu_put_be32s(f, &s->dnad); | |
2006 | + qemu_put_be32s(f, &s->dbc); | |
2007 | + qemu_put_8s(f, &s->istat0); | |
2008 | + qemu_put_8s(f, &s->istat1); | |
2009 | + qemu_put_8s(f, &s->dcmd); | |
2010 | + qemu_put_8s(f, &s->dstat); | |
2011 | + qemu_put_8s(f, &s->dien); | |
2012 | + qemu_put_8s(f, &s->sist0); | |
2013 | + qemu_put_8s(f, &s->sist1); | |
2014 | + qemu_put_8s(f, &s->sien0); | |
2015 | + qemu_put_8s(f, &s->sien1); | |
2016 | + qemu_put_8s(f, &s->mbox0); | |
2017 | + qemu_put_8s(f, &s->mbox1); | |
2018 | + qemu_put_8s(f, &s->dfifo); | |
2019 | + qemu_put_8s(f, &s->ctest2); | |
2020 | + qemu_put_8s(f, &s->ctest3); | |
2021 | + qemu_put_8s(f, &s->ctest4); | |
2022 | + qemu_put_8s(f, &s->ctest5); | |
2023 | + qemu_put_8s(f, &s->ccntl0); | |
2024 | + qemu_put_8s(f, &s->ccntl1); | |
2025 | + qemu_put_be32s(f, &s->dsp); | |
2026 | + qemu_put_be32s(f, &s->dsps); | |
2027 | + qemu_put_8s(f, &s->dmode); | |
2028 | + qemu_put_8s(f, &s->dcntl); | |
2029 | + qemu_put_8s(f, &s->scntl0); | |
2030 | + qemu_put_8s(f, &s->scntl1); | |
2031 | + qemu_put_8s(f, &s->scntl2); | |
2032 | + qemu_put_8s(f, &s->scntl3); | |
2033 | + qemu_put_8s(f, &s->sstat0); | |
2034 | + qemu_put_8s(f, &s->sstat1); | |
2035 | + qemu_put_8s(f, &s->scid); | |
2036 | + qemu_put_8s(f, &s->sxfer); | |
2037 | + qemu_put_8s(f, &s->socl); | |
2038 | + qemu_put_8s(f, &s->sdid); | |
2039 | + qemu_put_8s(f, &s->ssid); | |
2040 | + qemu_put_8s(f, &s->sfbr); | |
2041 | + qemu_put_8s(f, &s->stest1); | |
2042 | + qemu_put_8s(f, &s->stest2); | |
2043 | + qemu_put_8s(f, &s->stest3); | |
2044 | + qemu_put_8s(f, &s->sidl); | |
2045 | + qemu_put_8s(f, &s->stime0); | |
2046 | + qemu_put_8s(f, &s->respid0); | |
2047 | + qemu_put_8s(f, &s->respid1); | |
2048 | + qemu_put_be32s(f, &s->mmrs); | |
2049 | + qemu_put_be32s(f, &s->mmws); | |
2050 | + qemu_put_be32s(f, &s->sfs); | |
2051 | + qemu_put_be32s(f, &s->drs); | |
2052 | + qemu_put_be32s(f, &s->sbms); | |
2053 | + qemu_put_be32s(f, &s->dbms); | |
2054 | + qemu_put_be32s(f, &s->dnad64); | |
2055 | + qemu_put_be32s(f, &s->pmjad1); | |
2056 | + qemu_put_be32s(f, &s->pmjad2); | |
2057 | + qemu_put_be32s(f, &s->rbc); | |
2058 | + qemu_put_be32s(f, &s->ua); | |
2059 | + qemu_put_be32s(f, &s->ia); | |
2060 | + qemu_put_be32s(f, &s->sbc); | |
2061 | + qemu_put_be32s(f, &s->csbc); | |
2062 | + qemu_put_buffer(f, (uint8_t *)s->scratch, sizeof (s->scratch)); | |
2063 | + qemu_put_8s(f, &s->sbr); | |
2064 | + | |
2065 | + qemu_put_buffer(f, (uint8_t *)s->script_ram, sizeof (s->script_ram)); | |
2066 | +} | |
2067 | + | |
2068 | +static int lsi_scsi_load(QEMUFile *f, void *opaque, int version_id) | |
2069 | +{ | |
2070 | + LSIState *s = opaque; | |
2071 | + int ret; | |
2072 | + | |
2073 | + if (version_id > 0) { | |
2074 | + return -EINVAL; | |
2075 | + } | |
2076 | + | |
2077 | + if ((ret = pci_device_load(&s->pci_dev, f)) < 0) | |
2078 | + return ret; | |
2079 | + | |
2080 | + qemu_get_sbe32s(f, &s->carry); | |
2081 | + qemu_get_sbe32s(f, &s->sense); | |
2082 | + qemu_get_sbe32s(f, &s->msg_action); | |
2083 | + qemu_get_sbe32s(f, &s->msg_len); | |
2084 | + qemu_get_buffer(f, s->msg, sizeof (s->msg)); | |
2085 | + qemu_get_sbe32s(f, &s->waiting); | |
2086 | + | |
2087 | + qemu_get_be32s(f, &s->dsa); | |
2088 | + qemu_get_be32s(f, &s->temp); | |
2089 | + qemu_get_be32s(f, &s->dnad); | |
2090 | + qemu_get_be32s(f, &s->dbc); | |
2091 | + qemu_get_8s(f, &s->istat0); | |
2092 | + qemu_get_8s(f, &s->istat1); | |
2093 | + qemu_get_8s(f, &s->dcmd); | |
2094 | + qemu_get_8s(f, &s->dstat); | |
2095 | + qemu_get_8s(f, &s->dien); | |
2096 | + qemu_get_8s(f, &s->sist0); | |
2097 | + qemu_get_8s(f, &s->sist1); | |
2098 | + qemu_get_8s(f, &s->sien0); | |
2099 | + qemu_get_8s(f, &s->sien1); | |
2100 | + qemu_get_8s(f, &s->mbox0); | |
2101 | + qemu_get_8s(f, &s->mbox1); | |
2102 | + qemu_get_8s(f, &s->dfifo); | |
2103 | + qemu_get_8s(f, &s->ctest2); | |
2104 | + qemu_get_8s(f, &s->ctest3); | |
2105 | + qemu_get_8s(f, &s->ctest4); | |
2106 | + qemu_get_8s(f, &s->ctest5); | |
2107 | + qemu_get_8s(f, &s->ccntl0); | |
2108 | + qemu_get_8s(f, &s->ccntl1); | |
2109 | + qemu_get_be32s(f, &s->dsp); | |
2110 | + qemu_get_be32s(f, &s->dsps); | |
2111 | + qemu_get_8s(f, &s->dmode); | |
2112 | + qemu_get_8s(f, &s->dcntl); | |
2113 | + qemu_get_8s(f, &s->scntl0); | |
2114 | + qemu_get_8s(f, &s->scntl1); | |
2115 | + qemu_get_8s(f, &s->scntl2); | |
2116 | + qemu_get_8s(f, &s->scntl3); | |
2117 | + qemu_get_8s(f, &s->sstat0); | |
2118 | + qemu_get_8s(f, &s->sstat1); | |
2119 | + qemu_get_8s(f, &s->scid); | |
2120 | + qemu_get_8s(f, &s->sxfer); | |
2121 | + qemu_get_8s(f, &s->socl); | |
2122 | + qemu_get_8s(f, &s->sdid); | |
2123 | + qemu_get_8s(f, &s->ssid); | |
2124 | + qemu_get_8s(f, &s->sfbr); | |
2125 | + qemu_get_8s(f, &s->stest1); | |
2126 | + qemu_get_8s(f, &s->stest2); | |
2127 | + qemu_get_8s(f, &s->stest3); | |
2128 | + qemu_get_8s(f, &s->sidl); | |
2129 | + qemu_get_8s(f, &s->stime0); | |
2130 | + qemu_get_8s(f, &s->respid0); | |
2131 | + qemu_get_8s(f, &s->respid1); | |
2132 | + qemu_get_be32s(f, &s->mmrs); | |
2133 | + qemu_get_be32s(f, &s->mmws); | |
2134 | + qemu_get_be32s(f, &s->sfs); | |
2135 | + qemu_get_be32s(f, &s->drs); | |
2136 | + qemu_get_be32s(f, &s->sbms); | |
2137 | + qemu_get_be32s(f, &s->dbms); | |
2138 | + qemu_get_be32s(f, &s->dnad64); | |
2139 | + qemu_get_be32s(f, &s->pmjad1); | |
2140 | + qemu_get_be32s(f, &s->pmjad2); | |
2141 | + qemu_get_be32s(f, &s->rbc); | |
2142 | + qemu_get_be32s(f, &s->ua); | |
2143 | + qemu_get_be32s(f, &s->ia); | |
2144 | + qemu_get_be32s(f, &s->sbc); | |
2145 | + qemu_get_be32s(f, &s->csbc); | |
2146 | + qemu_get_buffer(f, (uint8_t *)s->scratch, sizeof (s->scratch)); | |
2147 | + qemu_get_8s(f, &s->sbr); | |
2148 | + | |
2149 | + qemu_get_buffer(f, (uint8_t *)s->script_ram, sizeof (s->script_ram)); | |
2150 | + | |
2151 | + return 0; | |
2152 | +} | |
2153 | + | |
1984 | 2154 | static int lsi_scsi_uninit(PCIDevice *d) |
1985 | 2155 | { |
1986 | 2156 | LSIState *s = (LSIState *) d; |
... | ... | @@ -2033,6 +2203,8 @@ static void lsi_scsi_init(PCIDevice *dev) |
2033 | 2203 | lsi_soft_reset(s); |
2034 | 2204 | |
2035 | 2205 | scsi_bus_new(&dev->qdev, lsi_scsi_attach); |
2206 | + | |
2207 | + register_savevm("lsiscsi", -1, 0, lsi_scsi_save, lsi_scsi_load, s); | |
2036 | 2208 | } |
2037 | 2209 | |
2038 | 2210 | static PCIDeviceInfo lsi_info = { | ... | ... |