Received: by 2002:a05:7412:3784:b0:e2:908c:2ebd with SMTP id jk4csp1915044rdb; Tue, 3 Oct 2023 05:16:19 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHLX8ry5k1ce8GuVreAwoI8By0FcftUdlaP+rEPb7w7p1M1JxhqdxXai83Fngn9QoFyJy8U X-Received: by 2002:a05:6e02:1c25:b0:351:4dcd:7655 with SMTP id m5-20020a056e021c2500b003514dcd7655mr17445859ilh.31.1696335378626; Tue, 03 Oct 2023 05:16:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1696335378; cv=none; d=google.com; s=arc-20160816; b=zozh5LGE/3fpNcyBnpR8l7hh2o8BpL2+XfLhYgmnryYRBXwEBSAsn7nJSt/fG4hf/7 hfdnRwGVfl9n5oAzsanKTyxzLB1huXykZxgjfAbIj/4Jp9ghkzhmfe6Y+YiyN68VXNif V04Qzua6Xj6LMBKRdOmTna5ZAwV+tVKNPIOzES8WX+QD4iVDro9aw01fb2LosGNipMwX lj7bcqjartS7BkSpwwJ5T5fs4TCcKVhjFmpeSNNtJ3QteZniiIynUV3dDI+SqWIW1llo GtI25Mr65IoiIVc2U6cmWKNj83tEjTq/ynic71ZmnPRdHYElNtEV/qXb15QUcJDiv/ou v7YQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=VDVpSksuWR7AsHnYKiy6VQr580Esn9Zomwi8qvkWS/g=; fh=vBnKFefFPFrDyJU1mppZP0jQUnKYIcYzbFz/qeRKvVo=; b=FYHu+4sG+iHpc9l91pD7R+rGMWz9pLtD2bl+GiU8SUQBLFHwyEGVWXw/BUl/bhVBN/ Gv8zp0Im1Bk0LEg2JU5/ccI9fHXj7JE8BZfJsP0uVyT3Ee7PuIkNZfaGWNr617zePLse aM0p2YMdpXbucLXwIQfL5LHosdja9dSPnTcZUbl9gS9Fst1YRalnqBJoRRMaecyPS/MC +0AFc5bJG9gRE8BsBCU5corqPfiMS9uwdrL/Q0Qo4sRzQTWmAYxrESx9g21GE44eCyPA KkN2NmRVB2qPa0C1psczZWmLGwSVWhZaLwmdHl4d8Q7qd3aqDG9j8z+nU1axhx+CV42Y pmcA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="zvADul/5"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id a21-20020a63e855000000b005859d13f276si1227361pgk.569.2023.10.03.05.16.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Oct 2023 05:16:18 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="zvADul/5"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id B2A3680732B3; Tue, 3 Oct 2023 05:15:49 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232195AbjJCMPr (ORCPT + 99 others); Tue, 3 Oct 2023 08:15:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43794 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231960AbjJCMPq (ORCPT ); Tue, 3 Oct 2023 08:15:46 -0400 Received: from mail-yw1-x1130.google.com (mail-yw1-x1130.google.com [IPv6:2607:f8b0:4864:20::1130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4D9B0AF for ; Tue, 3 Oct 2023 05:15:42 -0700 (PDT) Received: by mail-yw1-x1130.google.com with SMTP id 00721157ae682-5a2536adaf3so10268577b3.2 for ; Tue, 03 Oct 2023 05:15:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1696335341; x=1696940141; darn=vger.kernel.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=VDVpSksuWR7AsHnYKiy6VQr580Esn9Zomwi8qvkWS/g=; b=zvADul/5c5pG0m1/UEIS9V7tCT4o0Kyk847/6YYGqzfCJFNdAMZ3uKhD6WP5nFV57x /uuvL8YM3jsOEIcyaxu9YaFI2VNFV5I7jVuixG3jyzF3wneheoiRGfatZuWxeojZH9TF n8blcBsZZrDAdApnTXj+DL+CltQSXaa8SwK5/G8uVwxdH/rTezREC8501zwPjik524Ui 5N66RSWueAM+AP8zIRlecRKBVewULMLWuz0wgZUtcLU3rVZbXHnkF01+c8dBbmLDBqAx Y67H+nHNo8z9oMOH3aanVGy+qUTpy5OGnsYt/TLS+EBlltbFG1uTlgWNlGbfoF1YisVS obzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696335341; x=1696940141; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=VDVpSksuWR7AsHnYKiy6VQr580Esn9Zomwi8qvkWS/g=; b=g1hlsd6fUTGTLbLby4i+VQwXcCc03XjyK4dJjMAW1xceusjOlinP4EWs2JJZyuxJGV h3pui2vXkB4r2ZwT9U0eMKp9BlSilCU53Pjn9U634fgv7r4EcIH8YzYzSDHlG1xJw6LA Pols/4dZbDecA9OEbLP6ysMQzObDuPsTH9sBRHYWF9jLJ7AYYxCTkEcwj3MBcldfnNVG ifPTL012EFCivFBmPOHm+NTrUG5dL+9aelSd0+i8YZ+axBY2Cm/UjLPDUTxnZciioydR iTY2Z7CSSa2ECAvYLCyLCpbBtgiLiiA5DDYdLLOeW2ghzU/VM5xPvagpe5ORJJ+gy2lP 89SQ== X-Gm-Message-State: AOJu0YxgpDc6RvLGRF7JHYSvsW0KEJDChnPcfOS6gCUkhtNDt3NctAGD HPvtF48lwsFLLtD6KPh6WYw7oKggJ1uHi9/xm8HTUA== X-Received: by 2002:a25:aa93:0:b0:d78:ef4:76ae with SMTP id t19-20020a25aa93000000b00d780ef476aemr13144936ybi.33.1696335341408; Tue, 03 Oct 2023 05:15:41 -0700 (PDT) MIME-Version: 1.0 References: <20230915094351.11120-1-victorshihgli@gmail.com> <20230915094351.11120-19-victorshihgli@gmail.com> In-Reply-To: <20230915094351.11120-19-victorshihgli@gmail.com> From: Ulf Hansson Date: Tue, 3 Oct 2023 14:15:05 +0200 Message-ID: Subject: Re: [PATCH V12 18/23] mmc: sdhci-uhs2: add request() and others To: Victor Shih Cc: adrian.hunter@intel.com, linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, benchuanggli@gmail.com, HL.Liu@genesyslogic.com.tw, Greg.tu@genesyslogic.com.tw, takahiro.akashi@linaro.org, dlunev@chromium.org, Ben Chuang , Victor Shih Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Tue, 03 Oct 2023 05:15:50 -0700 (PDT) On Fri, 15 Sept 2023 at 11:44, Victor Shih wrote: > > From: Victor Shih > > This is a sdhci version of mmc's request operation. > It covers both UHS-I and UHS-II. Okay, but again, please elaborate on why we need/want this. > > Signed-off-by: Ben Chuang > Signed-off-by: AKASHI Takahiro > Signed-off-by: Victor Shih > --- > > Updates in V11: > - Drop the check mmc_card_uhs2_hd_mode(host->mmc) > in sdhci_uhs2_set_transfer_mode(). > > Updates in V10: > - Use tmode_half_duplex to instead of uhs2_tmode0_flag > in sdhci_uhs2_set_transfer_mode(). > > Updates in V9: > - Modify the annotations in __sdhci_uhs2_send_command(). > > Updates in V8: > - Adjust the position of matching brackets in > sdhci_uhs2_send_command_retry(). > - Modify CameCase definition in __sdhci_uhs2_finish_command(). > - Modify error message in __sdhci_uhs2_finish_command(). > - sdhci_uhs2_send_command_retry() to instead of sdhci_uhs2_send_command() > in sdhci_uhs2_request(). > - Use sdhci_uhs2_mode() to simplify code in sdhci_uhs2_request_atomic(). > - Add forward declaration for sdhci_send_command(). > > Updates in V7: > - Cancel export state of some functions. > - Remove unnecessary whitespace changes. > > Updates in V6: > - Add uhs2_dev_cmd() to simplify code. > - Remove unnecessary functions. > - Cancel export state of some functions. > - Drop use CONFIG_MMC_DEBUG(). > - Wrap at 100 columns in some functions. > > --- > > drivers/mmc/host/sdhci-uhs2.c | 412 ++++++++++++++++++++++++++++++++++ > drivers/mmc/host/sdhci.c | 49 ++-- > drivers/mmc/host/sdhci.h | 8 + > 3 files changed, 454 insertions(+), 15 deletions(-) > > diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c > index 09b86fec9f7b..1f8d527424fd 100644 > --- a/drivers/mmc/host/sdhci-uhs2.c > +++ b/drivers/mmc/host/sdhci-uhs2.c [...] > + > +static void __sdhci_uhs2_send_command(struct sdhci_host *host, struct mmc_command *cmd) > +{ > + int i, j; > + int cmd_reg; > + > + i = 0; > + sdhci_writel(host, > + ((u32)cmd->uhs2_cmd->arg << 16) | > + (u32)cmd->uhs2_cmd->header, > + SDHCI_UHS2_CMD_PACKET + i); > + i += 4; > + > + /* > + * Per spec, payload (config) should be MSB before sending out. > + * But we don't need convert here because had set payload as > + * MSB when preparing config read/write commands. > + */ > + for (j = 0; j < cmd->uhs2_cmd->payload_len / sizeof(u32); j++) { > + sdhci_writel(host, *(cmd->uhs2_cmd->payload + j), SDHCI_UHS2_CMD_PACKET + i); > + i += 4; > + } > + > + for ( ; i < SDHCI_UHS2_CMD_PACK_MAX_LEN; i += 4) > + sdhci_writel(host, 0, SDHCI_UHS2_CMD_PACKET + i); > + > + DBG("UHS2 CMD packet_len = %d.\n", cmd->uhs2_cmd->packet_len); > + for (i = 0; i < cmd->uhs2_cmd->packet_len; i++) > + DBG("UHS2 CMD_PACKET[%d] = 0x%x.\n", i, > + sdhci_readb(host, SDHCI_UHS2_CMD_PACKET + i)); We are ignoring what we just read. Isn't there something we need to verify? Moreover, the whole thing with i,j and the +4 thing above looks a bit odd to me. I am not sure whether the above can be simplified, but I leave that for you to have a second look at. > + > + cmd_reg = FIELD_PREP(SDHCI_UHS2_CMD_PACK_LEN_MASK, cmd->uhs2_cmd->packet_len); > + if ((cmd->flags & MMC_CMD_MASK) == MMC_CMD_ADTC) > + cmd_reg |= SDHCI_UHS2_CMD_DATA; > + if (cmd->opcode == MMC_STOP_TRANSMISSION) > + cmd_reg |= SDHCI_UHS2_CMD_CMD12; > + > + /* UHS2 Native ABORT */ > + if ((cmd->uhs2_cmd->header & UHS2_NATIVE_PACKET) && > + (uhs2_dev_cmd(cmd) == UHS2_DEV_CMD_TRANS_ABORT)) > + cmd_reg |= SDHCI_UHS2_CMD_TRNS_ABORT; > + > + /* UHS2 Native DORMANT */ > + if ((cmd->uhs2_cmd->header & UHS2_NATIVE_PACKET) && > + (uhs2_dev_cmd(cmd) == UHS2_DEV_CMD_GO_DORMANT_STATE)) > + cmd_reg |= SDHCI_UHS2_CMD_DORMANT; > + > + DBG("0x%x is set to UHS2 CMD register.\n", cmd_reg); > + > + sdhci_writew(host, cmd_reg, SDHCI_UHS2_CMD); > +} [...] > +static bool sdhci_uhs2_send_command_retry(struct sdhci_host *host, > + struct mmc_command *cmd, > + unsigned long flags) > + __releases(host->lock) > + __acquires(host->lock) > +{ > + struct mmc_command *deferred_cmd = host->deferred_cmd; > + int timeout = 10; /* Approx. 10 ms */ > + bool present; Why do we need a retry mechanism at this level? The mmc core sometimes retries commands when it seems reasonable, why isn't that sufficient? > + > + while (!sdhci_uhs2_send_command(host, cmd)) { > + if (!timeout--) { > + pr_err("%s: Controller never released inhibit bit(s).\n", > + mmc_hostname(host->mmc)); > + sdhci_dumpregs(host); > + cmd->error = -EIO; > + return false; > + } > + > + spin_unlock_irqrestore(&host->lock, flags); > + > + usleep_range(1000, 1250); > + > + present = host->mmc->ops->get_cd(host->mmc); > + > + spin_lock_irqsave(&host->lock, flags); > + > + /* A deferred command might disappear, handle that */ > + if (cmd == deferred_cmd && cmd != host->deferred_cmd) > + return true; > + > + if (sdhci_present_error(host, cmd, present)) > + return false; > + } If the retry is needed, would it be possible to convert into using read_poll_timeout() for the above while loop instead? If so, please make that conversion. > + > + if (cmd == host->deferred_cmd) > + host->deferred_cmd = NULL; > + > + return true; > +} > + > +static void __sdhci_uhs2_finish_command(struct sdhci_host *host) > +{ > + struct mmc_command *cmd = host->cmd; > + u8 resp; > + u8 ecode; > + bool breada0 = 0; Nitpick: Maybe find some better variable names. Like error_code... > + int i; > + > + if (host->mmc->flags & MMC_UHS2_SD_TRAN) { > + resp = sdhci_readb(host, SDHCI_UHS2_RESPONSE + 2); > + if (resp & UHS2_RES_NACK_MASK) { > + ecode = (resp >> UHS2_RES_ECODE_POS) & UHS2_RES_ECODE_MASK; > + pr_err("%s: NACK response, ECODE=0x%x.\n", mmc_hostname(host->mmc), ecode); > + } > + breada0 = 1; > + } > + > + if (cmd->uhs2_resp && > + cmd->uhs2_resp_len && cmd->uhs2_resp_len <= 20) { > + /* Get whole response of some native CCMD, like > + * DEVICE_INIT, ENUMERATE. > + */ > + for (i = 0; i < cmd->uhs2_resp_len; i++) > + cmd->uhs2_resp[i] = sdhci_readb(host, SDHCI_UHS2_RESPONSE + i); > + } else { > + /* Get SD CMD response and Payload for some read > + * CCMD, like INQUIRY_CFG. > + */ > + /* Per spec (p136), payload field is divided into > + * a unit of DWORD and transmission order within > + * a DWORD is big endian. > + */ > + if (!breada0) > + sdhci_readl(host, SDHCI_UHS2_RESPONSE); > + for (i = 4; i < 20; i += 4) { Again we do sdhci_readl above but just ignore the data. I assume that's deliberate, as we are probably just interested in the remaining pieces. Moreover, the whole thing with +4 things continues to look a bit odd to me. I am not sure whether it can be simplified, but I leave that for you to have a second look at. > + cmd->resp[i / 4 - 1] = > + (sdhci_readb(host, > + SDHCI_UHS2_RESPONSE + i) << 24) | > + (sdhci_readb(host, > + SDHCI_UHS2_RESPONSE + i + 1) > + << 16) | > + (sdhci_readb(host, > + SDHCI_UHS2_RESPONSE + i + 2) > + << 8) | > + sdhci_readb(host, SDHCI_UHS2_RESPONSE + i + 3); > + } > + } > +} [...] > + > +void sdhci_uhs2_request(struct mmc_host *mmc, struct mmc_request *mrq) static void > +{ > + struct sdhci_host *host = mmc_priv(mmc); > + struct mmc_command *cmd; > + unsigned long flags; > + bool present; > + > + if (!(sdhci_uhs2_mode(host))) { > + sdhci_request(mmc, mrq); > + return; > + } > + > + mrq->stop = NULL; > + mrq->sbc = NULL; > + if (mrq->data) > + mrq->data->stop = NULL; > + > + /* Firstly check card presence */ > + present = mmc->ops->get_cd(mmc); > + > + spin_lock_irqsave(&host->lock, flags); > + > + if (sdhci_present_error(host, mrq->cmd, present)) > + goto out_finish; > + > + cmd = mrq->cmd; > + > + if (!sdhci_uhs2_send_command_retry(host, cmd, flags)) > + goto out_finish; > + > + spin_unlock_irqrestore(&host->lock, flags); > + > + return; > + > +out_finish: > + sdhci_finish_mrq(host, mrq); > + spin_unlock_irqrestore(&host->lock, flags); > +} > +EXPORT_SYMBOL_GPL(sdhci_uhs2_request); Drop this, it's not used outside this module. > + > +int sdhci_uhs2_request_atomic(struct mmc_host *mmc, struct mmc_request *mrq) This function is entirely unused. Did you actually test this with an hsq enabled host? Or perhaps you have just added this for completeness? > +{ > + struct sdhci_host *host = mmc_priv(mmc); > + struct mmc_command *cmd; > + unsigned long flags; > + int ret = 0; > + > + if (!sdhci_uhs2_mode(host)) > + return sdhci_request_atomic(mmc, mrq); > + > + spin_lock_irqsave(&host->lock, flags); > + > + if (sdhci_present_error(host, mrq->cmd, true)) { > + sdhci_finish_mrq(host, mrq); > + goto out_finish; > + } > + > + cmd = mrq->cmd; > + > + /* > + * The HSQ may send a command in interrupt context without polling > + * the busy signaling, which means we should return BUSY if controller > + * has not released inhibit bits to allow HSQ trying to send request > + * again in non-atomic context. So we should not finish this request > + * here. > + */ > + if (!sdhci_uhs2_send_command(host, cmd)) > + ret = -EBUSY; > + > +out_finish: > + spin_unlock_irqrestore(&host->lock, flags); > + return ret; > +} > +EXPORT_SYMBOL_GPL(sdhci_uhs2_request_atomic); > + [...] Kind regards Uffe