qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Cc: patches@linaro.org
Subject: [Qemu-devel] [PATCH 09/10] hw/sd.c: Correct handling of APP_CMD status bit
Date: Sun, 18 Dec 2011 20:37:59 +0000	[thread overview]
Message-ID: <1324240680-26905-10-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1324240680-26905-1-git-send-email-peter.maydell@linaro.org>

Fix some bugs in our implementation of the APP_CMD status bit:
 * the response to an ACMD should have APP_CMD set, not cleared
 * if an illegal ACMD is sent then the next command should be
   handled as a normal command

This requires that we split "card is expecting an ACMD" from
the state of the APP_CMD status bit (the latter indicates
both "expecting ACMD" and "that was an ACMD").

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/sd.c |   24 +++++++++++++++++-------
 1 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/hw/sd.c b/hw/sd.c
index e1565b6..6614cbf 100644
--- a/hw/sd.c
+++ b/hw/sd.c
@@ -92,6 +92,10 @@ struct SDState {
 
     int spi;
     int current_cmd;
+    /* True if we will handle the next command as an ACMD. Note that this does
+     * *not* track the APP_CMD status bit!
+     */
+    int expecting_acmd;
     int blk_written;
     uint64_t data_start;
     uint32_t data_offset;
@@ -341,8 +345,8 @@ static int sd_req_crc_validate(SDRequest *req)
 static void sd_response_r1_make(SDState *sd, uint8_t *response)
 {
     uint32_t status = sd->card_status;
-    /* Clear the "clear on read" status bits (except APP_CMD) */
-    sd->card_status &= ~CARD_STATUS_C | APP_CMD;
+    /* Clear the "clear on read" status bits */
+    sd->card_status &= ~CARD_STATUS_C;
 
     response[0] = (status >> 24) & 0xff;
     response[1] = (status >> 16) & 0xff;
@@ -608,6 +612,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
     uint32_t rca = 0x0000;
     uint64_t addr = (sd->ocr & (1 << 30)) ? (uint64_t) req.arg << 9 : req.arg;
 
+    /* Not interpreting this as an app command */
+    sd->card_status &= ~APP_CMD;
+
     if (sd_cmd_type[req.cmd] == sd_ac || sd_cmd_type[req.cmd] == sd_adtc)
         rca = req.arg >> 16;
 
@@ -1116,6 +1123,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
         if (sd->rca != rca)
             return sd_r0;
 
+        sd->expecting_acmd = 1;
         sd->card_status |= APP_CMD;
         return sd_r1;
 
@@ -1155,6 +1163,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
                                     SDRequest req)
 {
     DPRINTF("ACMD%d 0x%08x\n", req.cmd, req.arg);
+    sd->card_status |= APP_CMD;
     switch (req.cmd) {
     case 6:	/* ACMD6:  SET_BUS_WIDTH */
         switch (sd->state) {
@@ -1251,7 +1260,6 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
 
     default:
         /* Fall back to standard commands.  */
-        sd->card_status &= ~APP_CMD;
         return sd_normal_command(sd, req);
     }
 
@@ -1269,7 +1277,7 @@ static int cmd_valid_while_locked(SDState *sd, SDRequest *req)
      * ACMD41 and ACMD42
      * Anything else provokes an "illegal command" response.
      */
-    if (sd->card_status & APP_CMD) {
+    if (sd->expecting_acmd) {
         return req->cmd == 41 || req->cmd == 42;
     }
     if (req->cmd == 16 || req->cmd == 55) {
@@ -1297,6 +1305,7 @@ int sd_do_command(SDState *sd, SDRequest *req,
     if (sd->card_status & CARD_IS_LOCKED) {
         if (!cmd_valid_while_locked(sd, req)) {
             sd->card_status |= ILLEGAL_COMMAND;
+            sd->expecting_acmd = 0;
             fprintf(stderr, "SD: Card is locked\n");
             rtype = sd_illegal;
             goto send_response;
@@ -1306,11 +1315,12 @@ int sd_do_command(SDState *sd, SDRequest *req,
     last_state = sd->state;
     sd_set_mode(sd);
 
-    if (sd->card_status & APP_CMD) {
+    if (sd->expecting_acmd) {
+        sd->expecting_acmd = 0;
         rtype = sd_app_command(sd, *req);
-        sd->card_status &= ~APP_CMD;
-    } else
+    } else {
         rtype = sd_normal_command(sd, *req);
+    }
 
     if (rtype == sd_illegal) {
         sd->card_status |= ILLEGAL_COMMAND;
-- 
1.7.5.4

  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 ` [Qemu-devel] [PATCH 08/10] hw/sd.c: Correct handling of type B SD status bits Peter Maydell
2011-12-18 20:37 ` Peter Maydell [this message]
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-10-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).