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