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: 8886481 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id BF0B19F39A for ; Wed, 20 Apr 2016 07:12:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9F1FE20211 for ; Wed, 20 Apr 2016 07:12:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 67A3A201C0 for ; Wed, 20 Apr 2016 07:12:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932393AbcDTHMG (ORCPT ); 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 X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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(-) 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;