From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Cc: patches@linaro.org
Subject: [Qemu-devel] [PATCH 08/10] hw/sd.c: Correct handling of type B SD status bits
Date: Sun, 18 Dec 2011 20:37:58 +0000 [thread overview]
Message-ID: <1324240680-26905-9-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1324240680-26905-1-git-send-email-peter.maydell@linaro.org>
Correct how we handle the type B ("cleared on valid command")
status bits. In particular, the CURRENT_STATE bits in a response
should be the state of the card when it received that command,
not the state when it received the preceding command. (This is
one of the issues noted in LP:597641.)
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/sd.c | 44 +++++++++++++++++++++++++-------------------
1 files changed, 25 insertions(+), 19 deletions(-)
diff --git a/hw/sd.c b/hw/sd.c
index 9eebfac..e1565b6 100644
--- a/hw/sd.c
+++ b/hw/sd.c
@@ -104,7 +104,7 @@ struct SDState {
int enable;
};
-static void sd_set_status(SDState *sd)
+static void sd_set_mode(SDState *sd)
{
switch (sd->state) {
case sd_inactive_state:
@@ -126,9 +126,6 @@ static void sd_set_status(SDState *sd)
sd->mode = sd_data_transfer_mode;
break;
}
-
- sd->card_status &= ~CURRENT_STATE;
- sd->card_status |= sd->state << 9;
}
static const sd_cmd_type_t sd_cmd_type[64] = {
@@ -341,13 +338,10 @@ static int sd_req_crc_validate(SDRequest *req)
return sd_crc7(buffer, 5) != req->crc; /* TODO */
}
-static void sd_response_r1_make(SDState *sd,
- uint8_t *response, uint32_t last_status)
+static void sd_response_r1_make(SDState *sd, uint8_t *response)
{
- uint32_t mask = CARD_STATUS_B ^ ILLEGAL_COMMAND;
- uint32_t status;
-
- status = (sd->card_status & ~mask) | (last_status & mask);
+ uint32_t status = sd->card_status;
+ /* Clear the "clear on read" status bits (except APP_CMD) */
sd->card_status &= ~CARD_STATUS_C | APP_CMD;
response[0] = (status >> 24) & 0xff;
@@ -1286,7 +1280,7 @@ static int cmd_valid_while_locked(SDState *sd, SDRequest *req)
int sd_do_command(SDState *sd, SDRequest *req,
uint8_t *response) {
- uint32_t last_status = sd->card_status;
+ int last_state;
sd_rsp_type_t rtype;
int rsplen;
@@ -1300,10 +1294,7 @@ int sd_do_command(SDState *sd, SDRequest *req,
goto send_response;
}
- sd->card_status &= ~CARD_STATUS_B;
- sd_set_status(sd);
-
- if (last_status & CARD_IS_LOCKED) {
+ if (sd->card_status & CARD_IS_LOCKED) {
if (!cmd_valid_while_locked(sd, req)) {
sd->card_status |= ILLEGAL_COMMAND;
fprintf(stderr, "SD: Card is locked\n");
@@ -1312,7 +1303,10 @@ int sd_do_command(SDState *sd, SDRequest *req,
}
}
- if (last_status & APP_CMD) {
+ last_state = sd->state;
+ sd_set_mode(sd);
+
+ if (sd->card_status & APP_CMD) {
rtype = sd_app_command(sd, *req);
sd->card_status &= ~APP_CMD;
} else
@@ -1320,15 +1314,20 @@ int sd_do_command(SDState *sd, SDRequest *req,
if (rtype == sd_illegal) {
sd->card_status |= ILLEGAL_COMMAND;
+ } else {
+ /* Valid command, we can update the 'state before command' bits.
+ * (Do this now so they appear in r1 responses.)
+ */
+ sd->current_cmd = req->cmd;
+ sd->card_status &= ~CURRENT_STATE;
+ sd->card_status |= (last_state << 9);
}
- sd->current_cmd = req->cmd;
-
send_response:
switch (rtype) {
case sd_r1:
case sd_r1b:
- sd_response_r1_make(sd, response, last_status);
+ sd_response_r1_make(sd, response);
rsplen = 4;
break;
@@ -1364,6 +1363,13 @@ send_response:
break;
}
+ if (rtype != sd_illegal) {
+ /* Clear the "clear on valid command" status bits now we've
+ * sent any response
+ */
+ sd->card_status &= ~CARD_STATUS_B;
+ }
+
#ifdef DEBUG_SD
if (rsplen) {
int i;
--
1.7.5.4
next prev parent reply other threads:[~2011-12-18 20:38 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-18 20:37 [Qemu-devel] [PATCH 00/10] hw/sd.c: Fix various status related bugs Peter Maydell
2011-12-18 20:37 ` [Qemu-devel] [PATCH 01/10] hw/sd.c: Fix the set of commands which are failed when card is locked Peter Maydell
2011-12-18 20:37 ` [Qemu-devel] [PATCH 02/10] hw/sd.c: Add comment regarding CARD_STATUS_* defines Peter Maydell
2011-12-18 20:37 ` [Qemu-devel] [PATCH 03/10] hw/sd.c: On CRC error, set CRC error status bit rather than clearing it Peter Maydell
2011-12-18 20:37 ` [Qemu-devel] [PATCH 04/10] hw/sd.c: When setting ADDRESS_ERROR bit, don't clear everything else Peter Maydell
2011-12-18 20:37 ` [Qemu-devel] [PATCH 05/10] hw/sd.c: Handle illegal commands in sd_do_command Peter Maydell
2011-12-18 20:37 ` [Qemu-devel] [PATCH 06/10] hw/sd.c: Handle CRC and locked-card errors in normal code path Peter Maydell
2011-12-18 20:37 ` [Qemu-devel] [PATCH 07/10] hw/sd.c: Set ILLEGAL_COMMAND for ACMDs in invalid state Peter Maydell
2011-12-18 20:37 ` Peter Maydell [this message]
2011-12-18 20:37 ` [Qemu-devel] [PATCH 09/10] hw/sd.c: Correct handling of APP_CMD status bit Peter Maydell
2011-12-18 20:38 ` [Qemu-devel] [PATCH 10/10] hw/sd.c: Clear status bits when read via response r6 Peter Maydell
2011-12-21 3:54 ` [Qemu-devel] [PATCH 00/10] hw/sd.c: Fix various status related bugs andrzej zaborowski
2011-12-21 11:13 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1324240680-26905-9-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=patches@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).