From patchwork Fri Jul 6 13:55:04 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saugata Das X-Patchwork-Id: 9889 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 2FDE123F28 for ; Fri, 6 Jul 2012 13:55:27 +0000 (UTC) Received: from mail-gg0-f180.google.com (mail-gg0-f180.google.com [209.85.161.180]) by fiordland.canonical.com (Postfix) with ESMTP id D6886A1873B for ; Fri, 6 Jul 2012 13:55:26 +0000 (UTC) Received: by ggnf1 with SMTP id f1so9226843ggn.11 for ; Fri, 06 Jul 2012 06:55:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:mime-version:content-type :x-gm-message-state; bh=VaH7iczFDq7ZTLczM5rQwMQCd11W7ybC8YZneiKDsa0=; b=byQQqC8SkaRUsD4i9+tsiwPfX3j5dLZtIZVqYWFHln/43OWgud96lDdQkmCOJ4jdl/ 6/lipatXf4NP23UOkmXhkwkowce883OBjsD6ePqHQv30XwFz8YraHgXE89x2EMZF3kQO fPMkgDKIAhTT/88AwYdvs+e0agOzhEV4NBtuD4soVonoBuJmMltkUVnAlhVBF4osE6F/ bLRQpKVVTJYdhIT8xVhlgzbA+RR0UeHjSLT1VYtsv71W6lv/QNJYro3LTvJ9US9Mf5/M pZP3Ke89vPHw2S7MuWwjD0Gt8X8xOjoEV0UAU62QasJwSu0OYfzugkU6TbmVh5NPysah lu1w== Received: by 10.50.203.39 with SMTP id kn7mr2457985igc.53.1341582926098; Fri, 06 Jul 2012 06:55:26 -0700 (PDT) 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.231.24.148 with SMTP id v20csp10998ibb; Fri, 6 Jul 2012 06:55:25 -0700 (PDT) Received: by 10.14.40.20 with SMTP id e20mr7468763eeb.119.1341582924764; Fri, 06 Jul 2012 06:55:24 -0700 (PDT) Received: from eu1sys200aog111.obsmtp.com (eu1sys200aog111.obsmtp.com. [207.126.144.131]) by mx.google.com with SMTP id p52si13344874eef.119.2012.07.06.06.55.22 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 06 Jul 2012 06:55:24 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.131 is neither permitted nor denied by best guess record for domain of saugata.das@stericsson.com) client-ip=207.126.144.131; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.131 is neither permitted nor denied by best guess record for domain of saugata.das@stericsson.com) smtp.mail=saugata.das@stericsson.com Received: from beta.dmz-eu.st.com ([164.129.1.35]) (using TLSv1) by eu1sys200aob111.postini.com ([207.126.147.11]) with SMTP ID DSNKT/buShE/FUz+jIt0UtpBzpBNIK6NyXyi@postini.com; Fri, 06 Jul 2012 13:55:24 UTC Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 49CED155; Fri, 6 Jul 2012 13:55:17 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 0028549D6; Fri, 6 Jul 2012 13:55:16 +0000 (GMT) Received: from exdcvycastm022.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm022", Issuer "exdcvycastm022" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id 40D5224C2E7; Fri, 6 Jul 2012 15:55:09 +0200 (CEST) Received: from localhost (10.201.54.119) by exdcvycastm022.EQ1STM.local (10.230.100.30) with Microsoft SMTP Server (TLS) id 8.3.83.0; Fri, 6 Jul 2012 15:55:16 +0200 From: Saugata Das To: Cc: , Saugata Das Subject: [PATCH v2] Fix for checking block numbers in disable emulation mode Date: Fri, 6 Jul 2012 19:25:04 +0530 Message-ID: <1341582904-31896-1-git-send-email-saugata.das@stericsson.com> X-Mailer: git-send-email 1.7.4.3 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQmxL7f3JbHE10t583l+Jegwhn5e8/7cBPwny5mTcx4X8Hm72Xdyt4Hq/SE50QhMAsX7G6EL From: Saugata Das In 512B disable emulation patch, a check is done to ensure that size of the data is multiple of 4KB within mmc_blk_issue_rw_rq. However, the check is done with brq->data.blocks, which is not initialized at the point of check. This is now changed to blk_rq_sectors. In addition, when retrying read transfers, the current code retries with single block. This has been changed to 8 blocks if disable emulation is enabled. For hosts which are not capable to handle transfer of multiple of 4KB, a check has been added in mmc_read_ext_csd. A check has been added for reliable write with EN_REL_WR=0, which is not allowed. Signed-off-by: Saugata Das Changes in v2 : - Added check in mmc_read_ext_csd --- drivers/mmc/card/block.c | 19 +++++++++++++------ drivers/mmc/core/mmc.c | 9 +++++++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index d628c5d..69b7b03 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1114,7 +1114,10 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, bool do_rel_wr = ((req->cmd_flags & REQ_FUA) || (req->cmd_flags & REQ_META)) && (rq_data_dir(req) == WRITE) && - (md->flags & MMC_BLK_REL_WR); + (md->flags & MMC_BLK_REL_WR) && + ((card->ext_csd.data_sector_size == 512) || + ((card->ext_csd.data_sector_size == 4096) && + (card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN))); memset(brq, 0, sizeof(struct mmc_blk_request)); brq->mrq.cmd = &brq->cmd; @@ -1145,7 +1148,9 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, * sectors can be read successfully. */ if (disable_multi) - brq->data.blocks = 1; + brq->data.blocks = + (card->ext_csd.data_sector_size == 4096) ? + 8 : 1; /* Some controllers can't do multiblock reads due to hw bugs */ if (card->host->caps2 & MMC_CAP2_NO_MULTI_READ && @@ -1296,10 +1301,11 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) * When 4KB native sector is enabled, only 8 blocks * multiple read or write is allowed */ - if ((brq->data.blocks & 0x07) && + if ((blk_rq_sectors(req) & 0x07) && (card->ext_csd.data_sector_size == 4096)) { - pr_err("%s: Transfer size is not 4KB sector size aligned\n", - req->rq_disk->disk_name); + pr_err("%s: Transfer size [%d] is not 4KB sector size aligned\n", + req->rq_disk->disk_name, + blk_rq_sectors(req)); goto cmd_abort; } mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); @@ -1364,7 +1370,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) /* Fall through */ } case MMC_BLK_ECC_ERR: - if (brq->data.blocks > 1) { + if (brq->data.blocks > + (card->ext_csd.data_sector_size >> 9)) { /* Redo read one sector at a time */ pr_warning("%s: retrying using single block read\n", req->rq_disk->disk_name); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 28fbd77..fb68f17 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -503,9 +503,14 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 | ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24; - if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1) + if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1) { + if ((card->host->caps2 & MMC_CAP2_NO_MULTI_READ) || + (card->host->max_blk_count & 0x07)) { + err = -EINVAL; + goto out; + } card->ext_csd.data_sector_size = 4096; - else + } else card->ext_csd.data_sector_size = 512; if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) &&