summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-01-16 13:28:12 +0000
committerPeter Maydell <peter.maydell@linaro.org>2018-01-16 13:28:12 +0000
commit8046d44f3c9f67828d3368797d4d314433ee75e9 (patch)
tree213747cf2f522d79f9d06ed8cf367e32326d402e /hw
parent16bf0e0e7aaa8efc0b8ee7e2aecb2fa235f82d38 (diff)
hw/sd/ssi-sd: Reset SD card on controller reset
Since ssi-sd is still using the legacy SD card API, the SD card created by sd_init() is not plugged into any bus. This means that the controller has to reset it manually. Failing to do this mostly didn't affect the guest since the guest typically does a programmed SD card reset as part of its SD controller driver initialization, but meant that migration failed because it's only in sd_reset() that we set up the wpgrps_size field. In the case of sd-ssi, we have to implement an entire reset function since there wasn't one previously, and that requires a QOM cast macro that got omitted when this device was QOMified. Cc: qemu-stable@nongnu.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 1515506513-31961-4-git-send-email-peter.maydell@linaro.org
Diffstat (limited to 'hw')
-rw-r--r--hw/sd/ssi-sd.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 24001dc3e6..f88f509e0a 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -50,6 +50,9 @@ typedef struct {
SDState *sd;
} ssi_sd_state;
+#define TYPE_SSI_SD "ssi-sd"
+#define SSI_SD(obj) OBJECT_CHECK(ssi_sd_state, (obj), TYPE_SSI_SD)
+
/* State word bits. */
#define SSI_SDR_LOCKED 0x0001
#define SSI_SDR_WP_ERASE 0x0002
@@ -241,7 +244,6 @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, d);
DriveInfo *dinfo;
- s->mode = SSI_SD_CMD;
/* FIXME use a qdev drive property instead of drive_get_next() */
dinfo = drive_get_next(IF_SD);
s->sd = sd_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, true);
@@ -251,6 +253,24 @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
}
}
+static void ssi_sd_reset(DeviceState *dev)
+{
+ ssi_sd_state *s = SSI_SD(dev);
+
+ s->mode = SSI_SD_CMD;
+ s->cmd = 0;
+ memset(s->cmdarg, 0, sizeof(s->cmdarg));
+ memset(s->response, 0, sizeof(s->response));
+ s->arglen = 0;
+ s->response_pos = 0;
+ s->stopping = 0;
+
+ /* Since we're still using the legacy SD API the card is not plugged
+ * into any bus, and we must reset it manually.
+ */
+ device_reset(DEVICE(s->sd));
+}
+
static void ssi_sd_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -260,10 +280,11 @@ static void ssi_sd_class_init(ObjectClass *klass, void *data)
k->transfer = ssi_sd_transfer;
k->cs_polarity = SSI_CS_LOW;
dc->vmsd = &vmstate_ssi_sd;
+ dc->reset = ssi_sd_reset;
}
static const TypeInfo ssi_sd_info = {
- .name = "ssi-sd",
+ .name = TYPE_SSI_SD,
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(ssi_sd_state),
.class_init = ssi_sd_class_init,