From patchwork Sat Oct 24 15:06:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jaegeuk Kim X-Patchwork-Id: 11854861 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 117BB16C0 for ; Sat, 24 Oct 2020 15:07:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EB6CA222C3 for ; Sat, 24 Oct 2020 15:06:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603552020; bh=azBorIKcYlAPSiV4bkrGq5n2K+2d5lAP8aCRlfP99cU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=MfAID+okNtmxyLy196dwvreZK/Rq6eF4Rfs8wW/gjCkuakhRuyHAg/+hi4dt2lPYk xcZxZdfDXH0x09Lpx7fwmL7ByCEAhaMjZo6+O/kMe1g4K97yPAd/VfkVZbQvII0BKL KrFCbbjMH7yJlp6ZzphWnGFpTVPfrA5RuAhAR9c8= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760497AbgJXPGy (ORCPT ); Sat, 24 Oct 2020 11:06:54 -0400 Received: from mail.kernel.org ([198.145.29.99]:60742 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1760458AbgJXPGw (ORCPT ); Sat, 24 Oct 2020 11:06:52 -0400 Received: from localhost (unknown [104.132.1.66]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 9990022254; Sat, 24 Oct 2020 15:06:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603552011; bh=azBorIKcYlAPSiV4bkrGq5n2K+2d5lAP8aCRlfP99cU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r7Qvz+PNdPue2Q+ElJ+q26/p0/AmE3j+uaDH5MfQiVTXerhC5nbLKW4dO7i52kxLW 1aHI5JUF/xTpbjC7AHshosH9ezAZQ/LsyuKJ18UsryQwyabDtMh3/2J12uVhzuTL95 7/eYJjZP8Bujo7b3OXx7W81/rzWD50u/Z97wmwn0= From: Jaegeuk Kim To: linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, kernel-team@android.com Cc: cang@codeaurora.org, alim.akhtar@samsung.com, avri.altman@wdc.com, bvanassche@acm.org, Jaegeuk Kim Subject: [PATCH v3 2/5] scsi: ufs: clear UAC for FFU and RPMB LUNs Date: Sat, 24 Oct 2020 08:06:43 -0700 Message-Id: <20201024150646.1790529-3-jaegeuk@kernel.org> X-Mailer: git-send-email 2.29.0.rc1.297.gfa9743e501-goog In-Reply-To: <20201024150646.1790529-1-jaegeuk@kernel.org> References: <20201024150646.1790529-1-jaegeuk@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Jaegeuk Kim In order to conduct FFU or RPMB operations, UFS needs to clear UAC. This patch clears it explicitly, so that we could get no failure given early execution. Signed-off-by: Jaegeuk Kim Reported-by: kernel test robot --- drivers/scsi/ufs/ufshcd.c | 70 +++++++++++++++++++++++++++++++++++---- drivers/scsi/ufs/ufshcd.h | 1 + 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index e0b479f9eb8a..011e80a21170 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -7057,7 +7057,6 @@ static inline void ufshcd_blk_pm_runtime_init(struct scsi_device *sdev) static int ufshcd_scsi_add_wlus(struct ufs_hba *hba) { int ret = 0; - struct scsi_device *sdev_rpmb; struct scsi_device *sdev_boot; hba->sdev_ufs_device = __scsi_add_device(hba->host, 0, 0, @@ -7070,14 +7069,14 @@ static int ufshcd_scsi_add_wlus(struct ufs_hba *hba) ufshcd_blk_pm_runtime_init(hba->sdev_ufs_device); scsi_device_put(hba->sdev_ufs_device); - sdev_rpmb = __scsi_add_device(hba->host, 0, 0, + hba->sdev_rpmb = __scsi_add_device(hba->host, 0, 0, ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_RPMB_WLUN), NULL); - if (IS_ERR(sdev_rpmb)) { - ret = PTR_ERR(sdev_rpmb); + if (IS_ERR(hba->sdev_rpmb)) { + ret = PTR_ERR(hba->sdev_rpmb); goto remove_sdev_ufs_device; } - ufshcd_blk_pm_runtime_init(sdev_rpmb); - scsi_device_put(sdev_rpmb); + ufshcd_blk_pm_runtime_init(hba->sdev_rpmb); + scsi_device_put(hba->sdev_rpmb); sdev_boot = __scsi_add_device(hba->host, 0, 0, ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_BOOT_WLUN), NULL); @@ -7601,6 +7600,63 @@ static int ufshcd_add_lus(struct ufs_hba *hba) return ret; } +static int +ufshcd_send_request_sense(struct ufs_hba *hba, struct scsi_device *sdp); + +static int ufshcd_clear_ua_wlun(struct ufs_hba *hba, u8 wlun) +{ + struct scsi_device *sdp; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(hba->host->host_lock, flags); + if (wlun == UFS_UPIU_UFS_DEVICE_WLUN) + sdp = hba->sdev_ufs_device; + else if (wlun == UFS_UPIU_RPMB_WLUN) + sdp = hba->sdev_rpmb; + else + BUG_ON(1); + if (sdp) { + ret = scsi_device_get(sdp); + if (!ret && !scsi_device_online(sdp)) { + ret = -ENODEV; + scsi_device_put(sdp); + } + } else { + ret = -ENODEV; + } + spin_unlock_irqrestore(hba->host->host_lock, flags); + if (ret) + goto out_err; + + ret = ufshcd_send_request_sense(hba, sdp); + scsi_device_put(sdp); +out_err: + if (ret) + dev_err(hba->dev, "%s: UAC clear LU=%x ret = %d\n", + __func__, wlun, ret); + return ret; +} + +static int ufshcd_clear_ua_wluns(struct ufs_hba *hba) +{ + int ret = 0; + + if (!hba->wlun_dev_clr_ua) + goto out; + + ret = ufshcd_clear_ua_wlun(hba, UFS_UPIU_UFS_DEVICE_WLUN); + if (!ret) + ret = ufshcd_clear_ua_wlun(hba, UFS_UPIU_RPMB_WLUN); + if (!ret) + hba->wlun_dev_clr_ua = false; +out: + if (ret) + dev_err(hba->dev, "%s: Failed to clear UAC WLUNS ret = %d\n", + __func__, ret); + return ret; +} + /** * ufshcd_probe_hba - probe hba to detect device and initialize * @hba: per-adapter instance @@ -7720,6 +7776,8 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie) pm_runtime_put_sync(hba->dev); ufshcd_exit_clk_scaling(hba); ufshcd_hba_exit(hba); + } else { + ufshcd_clear_ua_wluns(hba); } } diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 47eb1430274c..718881d038f5 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -681,6 +681,7 @@ struct ufs_hba { * "UFS device" W-LU. */ struct scsi_device *sdev_ufs_device; + struct scsi_device *sdev_rpmb; enum ufs_dev_pwr_mode curr_dev_pwr_mode; enum uic_link_state uic_link_state;