From patchwork Sun Dec 18 20:37:51 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 5843 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 0040B23E2D for ; Sun, 18 Dec 2011 20:38:14 +0000 (UTC) Received: from mail-ey0-f180.google.com (mail-ey0-f180.google.com [209.85.215.180]) by fiordland.canonical.com (Postfix) with ESMTP id E5227A18281 for ; Sun, 18 Dec 2011 20:38:13 +0000 (UTC) Received: by mail-ey0-f180.google.com with SMTP id c11so1269913eaa.11 for ; Sun, 18 Dec 2011 12:38:13 -0800 (PST) Received: by 10.205.120.14 with SMTP id fw14mr750314bkc.53.1324240693769; Sun, 18 Dec 2011 12:38:13 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.204.40.4 with SMTP id i4cs108683bke; Sun, 18 Dec 2011 12:38:13 -0800 (PST) Received: by 10.216.139.94 with SMTP id b72mr5871086wej.38.1324240692329; Sun, 18 Dec 2011 12:38:12 -0800 (PST) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [81.2.115.146]) by mx.google.com with ESMTPS id j10si9186500wij.61.2011.12.18.12.38.12 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 18 Dec 2011 12:38:12 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 81.2.115.146 as permitted sender) client-ip=81.2.115.146; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 81.2.115.146 as permitted sender) smtp.mail=pm215@archaic.org.uk Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1RcNUe-00070Q-Mi; Sun, 18 Dec 2011 20:38:00 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 01/10] hw/sd.c: Fix the set of commands which are failed when card is locked Date: Sun, 18 Dec 2011 20:37:51 +0000 Message-Id: <1324240680-26905-2-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1324240680-26905-1-git-send-email-peter.maydell@linaro.org> References: <1324240680-26905-1-git-send-email-peter.maydell@linaro.org> Fix bugs in the code determining whether to accept a card when the SD card is locked. Most notably, we had the condition completely reversed, so we would accept all the commands we should refuse and refuse all the commands we should accept. Correct this by refactoring the enormous if () clause into a separate function. We had also missed ACMD42 off the list of commands which are accepted in locked state: add it. This is one of the two problems reported in LP:597641. Signed-off-by: Peter Maydell --- hw/sd.c | 29 ++++++++++++++++++++++------- 1 files changed, 22 insertions(+), 7 deletions(-) diff --git a/hw/sd.c b/hw/sd.c index 10e26ad..a1c98c0 100644 --- a/hw/sd.c +++ b/hw/sd.c @@ -1265,6 +1265,25 @@ static sd_rsp_type_t sd_app_command(SDState *sd, return sd_r0; } +static int cmd_valid_while_locked(SDState *sd, SDRequest *req) +{ + /* Valid commands in locked state: + * basic class (0) + * lock card class (7) + * CMD16 + * implicitly, the ACMD prefix CMD55 + * ACMD41 and ACMD42 + * Anything else provokes an "illegal command" response. + */ + if (sd->card_status & APP_CMD) { + return req->cmd == 41 || req->cmd == 42; + } + if (req->cmd == 16 || req->cmd == 55) { + return 1; + } + return sd_cmd_class[req->cmd] == 0 || sd_cmd_class[req->cmd] == 7; +} + int sd_do_command(SDState *sd, SDRequest *req, uint8_t *response) { uint32_t last_status = sd->card_status; @@ -1283,17 +1302,13 @@ int sd_do_command(SDState *sd, SDRequest *req, sd->card_status &= ~CARD_STATUS_B; sd_set_status(sd); - if (last_status & CARD_IS_LOCKED) - if (((last_status & APP_CMD) && - req->cmd == 41) || - (!(last_status & APP_CMD) && - (sd_cmd_class[req->cmd] == 0 || - sd_cmd_class[req->cmd] == 7 || - req->cmd == 16 || req->cmd == 55))) { + if (last_status & CARD_IS_LOCKED) { + if (!cmd_valid_while_locked(sd, req)) { sd->card_status |= ILLEGAL_COMMAND; fprintf(stderr, "SD: Card is locked\n"); return 0; } + } if (last_status & APP_CMD) { rtype = sd_app_command(sd, *req);