aboutsummaryrefslogtreecommitdiff
path: root/hw/sd/ssi-sd.c
diff options
context:
space:
mode:
authorBin Meng <bin.meng@windriver.com>2021-01-28 14:30:34 +0800
committerPhilippe Mathieu-Daudé <f4bug@amsat.org>2021-02-20 00:17:09 +0100
commit5b45a3666ef77ec65f49b0b074a28f1ef460b9c5 (patch)
treea02ebf876636f8002559c5477b6d642e83fe0113 /hw/sd/ssi-sd.c
parent6ae29af3ed4b24dc733ed4186ebe906b6d1063cd (diff)
downloadqemu-5b45a3666ef77ec65f49b0b074a28f1ef460b9c5.zip
qemu-5b45a3666ef77ec65f49b0b074a28f1ef460b9c5.tar.gz
qemu-5b45a3666ef77ec65f49b0b074a28f1ef460b9c5.tar.bz2
hw/sd: ssi-sd: Fix STOP_TRANSMISSION (CMD12) response
CMD12's response type is R1b, which is basically a R1 plus optional addition of the busy signal token that can be any number of bytes. A zero value indicates card is busy and a non-zero value indicates the card is ready for the next command. Current implementation sends the busy signal token without sending the R1 first. This does not break the U-Boot/Linux mmc_spi driver, but it does not make the VxWorks driver happy. Move the testing logic of s->stopping in the SSI_SD_RESPONSE state a bit later, after the first byte of the card reponse is sent out, to conform with the spec. After the busy signal token is sent, the state should be transferred to SSI_SD_CMD. Fixes: 775616c3ae8c ("Partial SD card SPI mode support") Signed-off-by: Bin Meng <bin.meng@windriver.com> Message-Id: <20210128063035.15674-9-bmeng.cn@gmail.com> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Diffstat (limited to 'hw/sd/ssi-sd.c')
-rw-r--r--hw/sd/ssi-sd.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 84c873b..907d681 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -243,14 +243,15 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val)
s->mode = SSI_SD_RESPONSE;
return SSI_DUMMY;
case SSI_SD_RESPONSE:
- if (s->stopping) {
- s->stopping = 0;
- return SSI_DUMMY;
- }
if (s->response_pos < s->arglen) {
DPRINTF("Response 0x%02x\n", s->response[s->response_pos]);
return s->response[s->response_pos++];
}
+ if (s->stopping) {
+ s->stopping = 0;
+ s->mode = SSI_SD_CMD;
+ return SSI_DUMMY;
+ }
if (sdbus_data_ready(&s->sdbus)) {
DPRINTF("Data read\n");
s->mode = SSI_SD_DATA_START;