From patchwork Wed Apr 20 07:11:41 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "\(Exiting\) Baolin Wang" X-Patchwork-Id: 66180 Delivered-To: patch@linaro.org Received: by 10.140.93.198 with SMTP id d64csp2287848qge; Wed, 20 Apr 2016 00:12:08 -0700 (PDT) X-Received: by 10.98.17.78 with SMTP id z75mr10279203pfi.40.1461136328629; Wed, 20 Apr 2016 00:12:08 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 21si16347537pfv.71.2016.04.20.00.12.08; Wed, 20 Apr 2016 00:12:08 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932393AbcDTHMG (ORCPT + 2 others); Wed, 20 Apr 2016 03:12:06 -0400 Received: from mail-pf0-f171.google.com ([209.85.192.171]:33764 "EHLO mail-pf0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932385AbcDTHMF (ORCPT ); Wed, 20 Apr 2016 03:12:05 -0400 Received: by mail-pf0-f171.google.com with SMTP id 184so15485295pff.0 for ; Wed, 20 Apr 2016 00:12:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=gwZvZ2aKCvR8rZrysOq4N04mYPrbZRW1sQVGNXgCyog=; b=Hes0r9kUw4Xh27FRVkum0vFXVG67k0f45+dOaQxuQp9n3FwUV+ksUFzTW2QnQW4dI6 ZnST1fQPga6KwHUmq2G9H7K/khhswoSHmeEu5e5mSZ+aQmlUia/gwSC45rkFnrYX4h4B 6lrKo59vLqM6ikhZRyId3iSvF5pcFLPvYRTTI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=gwZvZ2aKCvR8rZrysOq4N04mYPrbZRW1sQVGNXgCyog=; b=YjxJPEurT5vhHhZnyhsXOiu7ENn+4ISMvdrg3KPQzE/zXnVZZGVrPMc8uYbbm7cDSL 9gzM6eicJA0bQ3qbuhaxqVj4RU7BzlSiYGn8p6JnUlfVzXCg68sjuwkNSR3n+EEmm5nw 15kxiCxS8k43aSnGSmOIqNLpTDR1h165chvhU6zsIz4fzOPVa6glwR/SZL2IGviFBKoA LeczT0z0GlEkPJeS/YYH9qwV08gSOPxLNtzZUwd8kfpVSBPuBDKZxfw3Aq6o6wMSkGCV vl1MLBkx1vLWc2N2HsuhE+vYnnKjw8aoN/NbL7jVorrIFr45XTR+Tg1dRtmVo7OkHQlT oMhg== X-Gm-Message-State: AOPr4FUfuK5KQNUJQRtHVAcqAky03wTVtRAO84jJCVq4BE9ZWzc+8R+td2tb+2SDbcpX2WVK X-Received: by 10.98.83.65 with SMTP id h62mr10088285pfb.130.1461136324620; Wed, 20 Apr 2016 00:12:04 -0700 (PDT) Received: from baolinwangubtpc.spreadtrum.com ([175.111.195.49]) by smtp.gmail.com with ESMTPSA id f17sm16693502pfj.60.2016.04.20.00.12.01 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Apr 2016 00:12:04 -0700 (PDT) From: Baolin Wang To: ulf.hansson@linaro.org Cc: adrian.hunter@intel.com, rmk+kernel@arm.linux.org.uk, shawn.lin@rock-chips.com, dianders@chromium.org, heiko@sntech.de, linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, broonie@kernel.org, linus.walleij@linaro.org, baolin.wang@linaro.org Subject: [RFC] mmc: Change the max discard sectors and erase response if mmc host supports busy signalling Date: Wed, 20 Apr 2016 15:11:41 +0800 Message-Id: <52b204074e197e9bb58b5c56d5e2ebb71942b4b7.1461135976.git.baolin.wang@linaro.org> X-Mailer: git-send-email 1.7.9.5 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org When mmc host HW supports busy signalling (using R1B as response), We shouldn't use 'host->max_busy_timeout' as the limitation when deciding the max discard sectors that we tell the generic BLOCK layer about. Instead, we should pick one preferred erase size as the max discard sectors. If the host controller supports busy signalling and the timeout for the erase operation exceeds the max_busy_timeout, we should use R1B response. Or we need to prevent the host from doing hw busy detection, which is done by converting to a R1 response instead. Signed-off-by: Baolin Wang --- drivers/mmc/core/core.c | 50 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 3f1362a..8164c01 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2008,7 +2008,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, unsigned int to, unsigned int arg) { struct mmc_command cmd = {0}; - unsigned int qty = 0; + unsigned int qty = 0, busy_timeout = 0; unsigned long timeout; int err; @@ -2076,8 +2076,21 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, memset(&cmd, 0, sizeof(struct mmc_command)); cmd.opcode = MMC_ERASE; cmd.arg = arg; - cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; - cmd.busy_timeout = mmc_erase_timeout(card, arg, qty); + busy_timeout = mmc_erase_timeout(card, arg, qty); + /* + * If the host controller supports busy signalling and the timeout for + * the erase operation exceeds the max_busy_timeout, we should use R1B + * response. Or we need to prevent the host from doing hw busy + * detection, which is done by converting to a R1 response instead. + */ + if (card->host->caps & MMC_CAP_WAIT_WHILE_BUSY && + busy_timeout > card->host->max_busy_timeout) { + cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; + cmd.busy_timeout = busy_timeout; + } else { + cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; + } + err = mmc_wait_for_cmd(card->host, &cmd, 0); if (err) { pr_err("mmc_erase: erase error %d, status %#x\n", @@ -2269,23 +2282,42 @@ static unsigned int mmc_do_calc_max_discard(struct mmc_card *card, unsigned int arg) { struct mmc_host *host = card->host; - unsigned int max_discard, x, y, qty = 0, max_qty, timeout; + unsigned int max_discard, x, y, qty = 0, max_qty, min_qty, timeout; unsigned int last_timeout = 0; - if (card->erase_shift) + if (card->erase_shift) { max_qty = UINT_MAX >> card->erase_shift; - else if (mmc_card_sd(card)) + min_qty = card->pref_erase >> card->erase_shift; + } else if (mmc_card_sd(card)) { max_qty = UINT_MAX; - else + min_qty = card->pref_erase; + } else { max_qty = UINT_MAX / card->erase_size; + min_qty = card->pref_erase / card->erase_size; + } /* Find the largest qty with an OK timeout */ do { y = 0; for (x = 1; x && x <= max_qty && max_qty - x >= qty; x <<= 1) { timeout = mmc_erase_timeout(card, arg, qty + x); - if (timeout > host->max_busy_timeout) - break; + /* + * If the host can support busy signalling, then it is + * no need to use 'host->max_busy_timeout' as the + * limitation when deciding the max discards sectors. + * We should set a balance value to improve the erase + * speed, and it can not get too long timeout at the + * same time. + */ + if (host->caps & MMC_CAP_WAIT_WHILE_BUSY) { + if (qty + x > min_qty && + timeout > host->max_busy_timeout) + break; + } else { + if (timeout > host->max_busy_timeout) + break; + } + if (timeout < last_timeout) break; last_timeout = timeout;