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
(cherry picked from commit 8046d44f3c
)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
stable-2.11
parent
a22b8096b6
commit
1e14820884
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue