All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/21] UFS patches for kernel v5.15
@ 2021-07-01 21:12 Bart Van Assche
  2021-07-01 21:12 ` [PATCH 01/21] Fix the documentation of the scsi_execute() time parameter Bart Van Assche
                   ` (20 more replies)
  0 siblings, 21 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen; +Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche

Hi Martin,

Please consider the patches in this series for kernel v5.15. As one can see
this patch series includes one ATA patch, four SCSI core patches and 16 UFS
patches.

Thanks,

Bart.

Bart Van Assche (21):
  Fix the documentation of the scsi_execute() time parameter
  libsas: Only abort commands from inside the error handler
  Clear host_eh_scheduled from inside the SCSI error handler
  libsas: Stop clearing host_eh_scheduled from the error handler
  ata: Stop clearing host_eh_scheduled from error handlers
  ufs: Reduce power management code duplication
  ufs: Only include power management code if necessary
  ufs: Rename the second ufshcd_probe_hba() argument
  ufs: Use DECLARE_COMPLETION_ONSTACK() where appropriate
  ufs: Remove ufshcd_valid_tag()
  ufs: Verify UIC locking requirements at runtime
  ufs: Improve static type checking for the host controller state
  ufs: Remove several wmb() calls
  ufs: Inline ufshcd_outstanding_req_clear()
  ufs: Rename __ufshcd_transfer_req_compl()
  ufs: Fix the SCSI abort handler
  ufs: Fix a race in the completion path
  ufs: Use the doorbell register instead of the UTRLCNR register
  ufs: Request sense data asynchronously
  ufs: Synchronize SCSI and UFS error handling
  ufs: Retry aborted SCSI commands instead of completing these
    successfully

 drivers/ata/libata-core.c             |   2 -
 drivers/ata/libata-eh.c               |  30 +-
 drivers/scsi/libsas/sas_scsi_host.c   |   9 +-
 drivers/scsi/scsi_error.c             |   7 +
 drivers/scsi/scsi_lib.c               |   2 +-
 drivers/scsi/ufs/cdns-pltfrm.c        |   7 +-
 drivers/scsi/ufs/tc-dwc-g210-pci.c    |  32 +-
 drivers/scsi/ufs/tc-dwc-g210-pltfrm.c |   7 +-
 drivers/scsi/ufs/ufs-exynos.c         |   7 +-
 drivers/scsi/ufs/ufs-hisi.c           |   7 +-
 drivers/scsi/ufs/ufs-mediatek.c       |   7 +-
 drivers/scsi/ufs/ufs-qcom.c           |   7 +-
 drivers/scsi/ufs/ufshcd-pci.c         |  48 +--
 drivers/scsi/ufs/ufshcd-pltfrm.c      |  47 ---
 drivers/scsi/ufs/ufshcd-pltfrm.h      |  18 -
 drivers/scsi/ufs/ufshcd.c             | 467 +++++++++++---------------
 drivers/scsi/ufs/ufshcd.h             |  48 ++-
 include/linux/libata.h                |   1 -
 include/scsi/libsas.h                 |   1 +
 19 files changed, 271 insertions(+), 483 deletions(-)


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 01/21] Fix the documentation of the scsi_execute() time parameter
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-05  5:51   ` Avri Altman
  2021-07-01 21:12 ` [PATCH 02/21] libsas: Only abort commands from inside the error handler Bart Van Assche
                   ` (19 subsequent siblings)
  20 siblings, 1 reply; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, James E.J. Bottomley,
	Hannes Reinecke, Ming Lei, John Garry

The unit of the scsi_execute() timeout parameter is 1/HZ seconds instead of
one second, just like the timeouts used in the block layer. Fix the
documentation header above the definition of the scsi_execute() macro.

Cc: "James E.J. Bottomley" <jejb@linux.ibm.com>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Fixes: "[SCSI] use scatter lists for all block pc requests and simplify hw handlers" # v2.6.16.28
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_lib.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 7184f93dfe15..4b56e06faa5e 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -194,7 +194,7 @@ void scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
  * @bufflen:	len of buffer
  * @sense:	optional sense buffer
  * @sshdr:	optional decoded sense header
- * @timeout:	request timeout in seconds
+ * @timeout:	request timeout in HZ
  * @retries:	number of times to retry request
  * @flags:	flags for ->cmd_flags
  * @rq_flags:	flags for ->rq_flags

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 02/21] libsas: Only abort commands from inside the error handler
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
  2021-07-01 21:12 ` [PATCH 01/21] Fix the documentation of the scsi_execute() time parameter Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-03  2:32   ` Jason Yan
  2021-07-01 21:12 ` [PATCH 03/21] Clear host_eh_scheduled from inside the SCSI " Bart Van Assche
                   ` (18 subsequent siblings)
  20 siblings, 1 reply; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Hannes Reinecke,
	Christoph Hellwig, Ming Lei, John Garry, Yves-Alexis Perez,
	James E.J. Bottomley, Jason Yan, Gustavo A. R. Silva, Yufen Yu

According to the information I found in patch commit descriptions, for SATA
devices commands must be aborted from inside the libsas error handler.
Check host->ehandler to determine whether or not running inside the error
handler since host->host_eh_scheduled != 0 indicates that the SCSI error
handler has been scheduled but does not mean that is already running. This
patch restores code that was removed by commit 909657615d9b ("scsi: libsas:
allow async aborts").

Cc: Hannes Reinecke <hare@suse.de>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Yves-Alexis Perez <corsac@debian.org>
Fixes: c9f926000fe3 ("scsi: libsas: Disable asynchronous aborts for SATA devices")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/libsas/sas_scsi_host.c | 5 ++++-
 include/scsi/libsas.h               | 1 +
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index ee44a0d7730b..95e4d58ab9d4 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -462,6 +462,7 @@ int sas_eh_abort_handler(struct scsi_cmnd *cmd)
 	int res = TMF_RESP_FUNC_FAILED;
 	struct sas_task *task = TO_SAS_TASK(cmd);
 	struct Scsi_Host *host = cmd->device->host;
+	struct sas_ha_struct *ha = SHOST_TO_SAS_HA(host);
 	struct domain_device *dev = cmd_to_domain_dev(cmd);
 	struct sas_internal *i = to_sas_internal(host->transportt);
 	unsigned long flags;
@@ -471,7 +472,7 @@ int sas_eh_abort_handler(struct scsi_cmnd *cmd)
 
 	spin_lock_irqsave(host->host_lock, flags);
 	/* We cannot do async aborts for SATA devices */
-	if (dev_is_sata(dev) && !host->host_eh_scheduled) {
+	if (dev_is_sata(dev) && !ha->eh_running) {
 		spin_unlock_irqrestore(host->host_lock, flags);
 		return FAILED;
 	}
@@ -731,6 +732,7 @@ void sas_scsi_recover_host(struct Scsi_Host *shost)
 	tries++;
 	retry = true;
 	spin_lock_irq(shost->host_lock);
+	ha->eh_running = true;
 	list_splice_init(&shost->eh_cmd_q, &eh_work_q);
 	spin_unlock_irq(shost->host_lock);
 
@@ -767,6 +769,7 @@ void sas_scsi_recover_host(struct Scsi_Host *shost)
 
 	/* check if any new eh work was scheduled during the last run */
 	spin_lock_irq(&ha->lock);
+	ha->eh_running = false;
 	if (ha->eh_active == 0) {
 		shost->host_eh_scheduled = 0;
 		retry = false;
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index 6fe125a71b60..4a8fb324140e 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -364,6 +364,7 @@ struct sas_ha_struct {
 	struct mutex	  drain_mutex;
 	unsigned long	  state;
 	spinlock_t	  lock;
+	bool		  eh_running;
 	int		  eh_active;
 	wait_queue_head_t eh_wait_q;
 	struct list_head  eh_dev_q;

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 03/21] Clear host_eh_scheduled from inside the SCSI error handler
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
  2021-07-01 21:12 ` [PATCH 01/21] Fix the documentation of the scsi_execute() time parameter Bart Van Assche
  2021-07-01 21:12 ` [PATCH 02/21] libsas: Only abort commands from inside the error handler Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-01 21:12 ` [PATCH 04/21] libsas: Stop clearing host_eh_scheduled from the " Bart Van Assche
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Hannes Reinecke,
	Ming Lei, John Garry, James E.J. Bottomley

The current protocol for scheduling the SCSI error handler explicitly
is as follows:
1. The LLD registers a transport layer that defines a eh_strategy_handler.
2. The LLD observes an error, sets variables that indicate the nature of the
   error and calls scsi_schedule_eh(). Currently only the ATA core and libsas
   use scsi_schedule_eh().
3. scsi_schedule_eh() increments host_eh_scheduled.
4. The SCSI error handling thread wakes up and invokes eh_strategy_handler.
5. After all errors have been handled and before the eh_strategy_handler
   implementation returns, host_eh_scheduled is cleared. This must be done
   in such a way that all errors that happened while the error handler was
   running are either handled or result in rerunning the error handler.

Making LLDs responsible for clearing host_eh_scheduled is error prone.
Hence clear host_eh_scheduled from inside the SCSI error handler. A side
effect of this patch is that if scsi_schedule_eh() is called while the
SCSI error handler is active that it will be reactivated immediately.

Cc: Hannes Reinecke <hare@suse.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_error.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index c6cd5a8e5c85..665cc44d8877 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -2242,6 +2242,13 @@ int scsi_error_handler(void *data)
 			continue;
 		}
 
+		/*
+		 * Clear host_eh_scheduled before handling any errors such that
+		 * calling scsi_schedule_eh() while errors are being handled
+		 * causes the error handler to be rerun.
+		 */
+		shost->host_eh_scheduled = 0;
+
 		if (shost->transportt->eh_strategy_handler)
 			shost->transportt->eh_strategy_handler(shost);
 		else

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 04/21] libsas: Stop clearing host_eh_scheduled from the error handler
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (2 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 03/21] Clear host_eh_scheduled from inside the SCSI " Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-01 21:12 ` [PATCH 05/21] ata: Stop clearing host_eh_scheduled from error handlers Bart Van Assche
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Hannes Reinecke,
	Ming Lei, John Garry, James E.J. Bottomley, Yufen Yu,
	Gustavo A. R. Silva

Now that the caller of sas_scsi_recover_host(), namely scsi_error_handler(),
clears host_eh_scheduled, remove the assignment from sas_scsi_recover_host()
that clears this member variable.

Cc: Hannes Reinecke <hare@suse.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/libsas/sas_scsi_host.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 95e4d58ab9d4..ae6c273e743e 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -770,10 +770,8 @@ void sas_scsi_recover_host(struct Scsi_Host *shost)
 	/* check if any new eh work was scheduled during the last run */
 	spin_lock_irq(&ha->lock);
 	ha->eh_running = false;
-	if (ha->eh_active == 0) {
-		shost->host_eh_scheduled = 0;
+	if (ha->eh_active == 0)
 		retry = false;
-	}
 	spin_unlock_irq(&ha->lock);
 
 	if (retry)

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 05/21] ata: Stop clearing host_eh_scheduled from error handlers
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (3 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 04/21] libsas: Stop clearing host_eh_scheduled from the " Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-01 21:12 ` [PATCH 06/21] ufs: Reduce power management code duplication Bart Van Assche
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Jens Axboe,
	Hannes Reinecke, Ming Lei, John Garry

Now that the caller of sas_ata_strategy_handler() clears host_eh_scheduled,
remove the code from the ATA core that that clears host_eh_scheduled.

Cc: Jens Axboe <axboe@kernel.dk>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/ata/libata-core.c |  2 --
 drivers/ata/libata-eh.c   | 30 +++---------------------------
 include/linux/libata.h    |  1 -
 3 files changed, 3 insertions(+), 30 deletions(-)

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 61c762961ca8..b26fb305a56f 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -69,7 +69,6 @@ const struct ata_port_operations ata_base_port_ops = {
 	.postreset		= ata_std_postreset,
 	.error_handler		= ata_std_error_handler,
 	.sched_eh		= ata_std_sched_eh,
-	.end_eh			= ata_std_end_eh,
 };
 
 const struct ata_port_operations sata_port_ops = {
@@ -6419,7 +6418,6 @@ struct ata_port_operations ata_dummy_port_ops = {
 	.qc_issue		= ata_dummy_qc_issue,
 	.error_handler		= ata_dummy_error_handler,
 	.sched_eh		= ata_std_sched_eh,
-	.end_eh			= ata_std_end_eh,
 };
 EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
 
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index bb3637762985..e88ffbe31a36 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -724,12 +724,9 @@ void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap)
 		ata_for_each_link(link, ap, HOST_FIRST)
 			memset(&link->eh_info, 0, sizeof(link->eh_info));
 
-		/* end eh (clear host_eh_scheduled) while holding
-		 * ap->lock such that if exception occurs after this
-		 * point but before EH completion, SCSI midlayer will
-		 * re-initiate EH.
-		 */
-		ap->ops->end_eh(ap);
+		/* end eh while holding ap->lock */
+		if (ap->ops->end_eh)
+			ap->ops->end_eh(ap);
 
 		spin_unlock_irqrestore(ap->lock, flags);
 		ata_eh_release(ap);
@@ -936,27 +933,6 @@ void ata_std_sched_eh(struct ata_port *ap)
 }
 EXPORT_SYMBOL_GPL(ata_std_sched_eh);
 
-/**
- * ata_std_end_eh - non-libsas ata_ports complete eh with this common routine
- * @ap: ATA port to end EH for
- *
- * In the libata object model there is a 1:1 mapping of ata_port to
- * shost, so host fields can be directly manipulated under ap->lock, in
- * the libsas case we need to hold a lock at the ha->level to coordinate
- * these events.
- *
- *	LOCKING:
- *	spin_lock_irqsave(host lock)
- */
-void ata_std_end_eh(struct ata_port *ap)
-{
-	struct Scsi_Host *host = ap->scsi_host;
-
-	host->host_eh_scheduled = 0;
-}
-EXPORT_SYMBOL(ata_std_end_eh);
-
-
 /**
  *	ata_port_schedule_eh - schedule error handling without a qc
  *	@ap: ATA port to schedule EH for
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 5f550eb27f81..88f4f7e466fb 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1356,7 +1356,6 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
 		      ata_postreset_fn_t postreset);
 extern void ata_std_error_handler(struct ata_port *ap);
 extern void ata_std_sched_eh(struct ata_port *ap);
-extern void ata_std_end_eh(struct ata_port *ap);
 extern int ata_link_nr_enabled(struct ata_link *link);
 
 /*

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 06/21] ufs: Reduce power management code duplication
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (4 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 05/21] ata: Stop clearing host_eh_scheduled from error handlers Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-05  6:18   ` Avri Altman
  2021-07-01 21:12 ` [PATCH 07/21] ufs: Only include power management code if necessary Bart Van Assche
                   ` (14 subsequent siblings)
  20 siblings, 1 reply; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Adrian Hunter,
	Stanley Chu, Can Guo, Asutosh Das, Avri Altman,
	James E.J. Bottomley, Pedro Sousa, Krzysztof Kozlowski,
	Andy Gross, Bjorn Andersson, Matthias Brugger, Lee Jones,
	Kiwoong Kim, Alim Akhtar, Bean Huo, Yue Hu, Sergey Shtylyov

Move the dev_get_drvdata() calls into the ufshcd_{system,runtime}_*()
functions. Remove ufshcd_runtime_idle() since it is empty. This patch
does not change any functionality.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Stanley Chu <stanley.chu@mediatek.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Asutosh Das <asutoshd@codeaurora.org>
Cc: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/cdns-pltfrm.c        |  7 ++--
 drivers/scsi/ufs/tc-dwc-g210-pci.c    | 32 ++----------------
 drivers/scsi/ufs/tc-dwc-g210-pltfrm.c |  7 ++--
 drivers/scsi/ufs/ufs-exynos.c         |  7 ++--
 drivers/scsi/ufs/ufs-hisi.c           |  7 ++--
 drivers/scsi/ufs/ufs-mediatek.c       |  7 ++--
 drivers/scsi/ufs/ufs-qcom.c           |  7 ++--
 drivers/scsi/ufs/ufshcd-pci.c         | 48 ++-------------------------
 drivers/scsi/ufs/ufshcd-pltfrm.c      | 47 --------------------------
 drivers/scsi/ufs/ufshcd-pltfrm.h      | 18 ----------
 drivers/scsi/ufs/ufshcd.c             | 41 ++++++++++++-----------
 drivers/scsi/ufs/ufshcd.h             |  9 +++--
 12 files changed, 41 insertions(+), 196 deletions(-)

diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/scsi/ufs/cdns-pltfrm.c
index 908ff39c4856..7da8be2f35c4 100644
--- a/drivers/scsi/ufs/cdns-pltfrm.c
+++ b/drivers/scsi/ufs/cdns-pltfrm.c
@@ -318,11 +318,8 @@ static int cdns_ufs_pltfrm_remove(struct platform_device *pdev)
 }
 
 static const struct dev_pm_ops cdns_ufs_dev_pm_ops = {
-	.suspend         = ufshcd_pltfrm_suspend,
-	.resume          = ufshcd_pltfrm_resume,
-	.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
-	.runtime_resume  = ufshcd_pltfrm_runtime_resume,
-	.runtime_idle    = ufshcd_pltfrm_runtime_idle,
+	SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume)
+	SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL)
 	.prepare	 = ufshcd_suspend_prepare,
 	.complete	 = ufshcd_resume_complete,
 };
diff --git a/drivers/scsi/ufs/tc-dwc-g210-pci.c b/drivers/scsi/ufs/tc-dwc-g210-pci.c
index ec4589afbc13..679289e1a78e 100644
--- a/drivers/scsi/ufs/tc-dwc-g210-pci.c
+++ b/drivers/scsi/ufs/tc-dwc-g210-pci.c
@@ -23,31 +23,6 @@ static int tc_type = TC_G210_INV;
 module_param(tc_type, int, 0);
 MODULE_PARM_DESC(tc_type, "Test Chip Type (20 = 20-bit, 40 = 40-bit)");
 
-static int tc_dwc_g210_pci_suspend(struct device *dev)
-{
-	return ufshcd_system_suspend(dev_get_drvdata(dev));
-}
-
-static int tc_dwc_g210_pci_resume(struct device *dev)
-{
-	return ufshcd_system_resume(dev_get_drvdata(dev));
-}
-
-static int tc_dwc_g210_pci_runtime_suspend(struct device *dev)
-{
-	return ufshcd_runtime_suspend(dev_get_drvdata(dev));
-}
-
-static int tc_dwc_g210_pci_runtime_resume(struct device *dev)
-{
-	return ufshcd_runtime_resume(dev_get_drvdata(dev));
-}
-
-static int tc_dwc_g210_pci_runtime_idle(struct device *dev)
-{
-	return ufshcd_runtime_idle(dev_get_drvdata(dev));
-}
-
 /*
  * struct ufs_hba_dwc_vops - UFS DWC specific variant operations
  */
@@ -143,11 +118,8 @@ tc_dwc_g210_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 }
 
 static const struct dev_pm_ops tc_dwc_g210_pci_pm_ops = {
-	.suspend	= tc_dwc_g210_pci_suspend,
-	.resume		= tc_dwc_g210_pci_resume,
-	.runtime_suspend = tc_dwc_g210_pci_runtime_suspend,
-	.runtime_resume  = tc_dwc_g210_pci_runtime_resume,
-	.runtime_idle    = tc_dwc_g210_pci_runtime_idle,
+	SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume)
+	SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL)
 	.prepare	 = ufshcd_suspend_prepare,
 	.complete	 = ufshcd_resume_complete,
 };
diff --git a/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c b/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c
index a1268e4f44d6..783ec43efa78 100644
--- a/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c
+++ b/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c
@@ -84,11 +84,8 @@ static int tc_dwc_g210_pltfm_remove(struct platform_device *pdev)
 }
 
 static const struct dev_pm_ops tc_dwc_g210_pltfm_pm_ops = {
-	.suspend	= ufshcd_pltfrm_suspend,
-	.resume		= ufshcd_pltfrm_resume,
-	.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
-	.runtime_resume  = ufshcd_pltfrm_runtime_resume,
-	.runtime_idle    = ufshcd_pltfrm_runtime_idle,
+	SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume)
+	SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL)
 };
 
 static struct platform_driver tc_dwc_g210_pltfm_driver = {
diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c
index cf46d6f86e0e..5aa096e5b6cc 100644
--- a/drivers/scsi/ufs/ufs-exynos.c
+++ b/drivers/scsi/ufs/ufs-exynos.c
@@ -1287,11 +1287,8 @@ static const struct of_device_id exynos_ufs_of_match[] = {
 };
 
 static const struct dev_pm_ops exynos_ufs_pm_ops = {
-	.suspend	= ufshcd_pltfrm_suspend,
-	.resume		= ufshcd_pltfrm_resume,
-	.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
-	.runtime_resume  = ufshcd_pltfrm_runtime_resume,
-	.runtime_idle    = ufshcd_pltfrm_runtime_idle,
+	SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume)
+	SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL)
 	.prepare	 = ufshcd_suspend_prepare,
 	.complete	 = ufshcd_resume_complete,
 };
diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c
index 526b911655fe..3b4117ddb3c8 100644
--- a/drivers/scsi/ufs/ufs-hisi.c
+++ b/drivers/scsi/ufs/ufs-hisi.c
@@ -569,11 +569,8 @@ static int ufs_hisi_remove(struct platform_device *pdev)
 }
 
 static const struct dev_pm_ops ufs_hisi_pm_ops = {
-	.suspend	= ufshcd_pltfrm_suspend,
-	.resume		= ufshcd_pltfrm_resume,
-	.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
-	.runtime_resume  = ufshcd_pltfrm_runtime_resume,
-	.runtime_idle    = ufshcd_pltfrm_runtime_idle,
+	SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume)
+	SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL)
 	.prepare	 = ufshcd_suspend_prepare,
 	.complete	 = ufshcd_resume_complete,
 };
diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 32ae67e40086..fe6e678faa2c 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -1123,11 +1123,8 @@ static int ufs_mtk_remove(struct platform_device *pdev)
 }
 
 static const struct dev_pm_ops ufs_mtk_pm_ops = {
-	.suspend         = ufshcd_pltfrm_suspend,
-	.resume          = ufshcd_pltfrm_resume,
-	.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
-	.runtime_resume  = ufshcd_pltfrm_runtime_resume,
-	.runtime_idle    = ufshcd_pltfrm_runtime_idle,
+	SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume)
+	SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL)
 	.prepare	 = ufshcd_suspend_prepare,
 	.complete	 = ufshcd_resume_complete,
 };
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 9b1d18d7c9bb..9d9770f1db4f 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -1546,11 +1546,8 @@ MODULE_DEVICE_TABLE(acpi, ufs_qcom_acpi_match);
 #endif
 
 static const struct dev_pm_ops ufs_qcom_pm_ops = {
-	.suspend	= ufshcd_pltfrm_suspend,
-	.resume		= ufshcd_pltfrm_resume,
-	.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
-	.runtime_resume  = ufshcd_pltfrm_runtime_resume,
-	.runtime_idle    = ufshcd_pltfrm_runtime_idle,
+	SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume)
+	SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL)
 	.prepare	 = ufshcd_suspend_prepare,
 	.complete	 = ufshcd_resume_complete,
 };
diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c
index e6c334bfb4c2..b3bcc5c882da 100644
--- a/drivers/scsi/ufs/ufshcd-pci.c
+++ b/drivers/scsi/ufs/ufshcd-pci.c
@@ -385,48 +385,6 @@ static struct ufs_hba_variant_ops ufs_intel_lkf_hba_vops = {
 	.device_reset		= ufs_intel_device_reset,
 };
 
-#ifdef CONFIG_PM_SLEEP
-/**
- * ufshcd_pci_suspend - suspend power management function
- * @dev: pointer to PCI device handle
- *
- * Returns 0 if successful
- * Returns non-zero otherwise
- */
-static int ufshcd_pci_suspend(struct device *dev)
-{
-	return ufshcd_system_suspend(dev_get_drvdata(dev));
-}
-
-/**
- * ufshcd_pci_resume - resume power management function
- * @dev: pointer to PCI device handle
- *
- * Returns 0 if successful
- * Returns non-zero otherwise
- */
-static int ufshcd_pci_resume(struct device *dev)
-{
-	return ufshcd_system_resume(dev_get_drvdata(dev));
-}
-
-#endif /* !CONFIG_PM_SLEEP */
-
-#ifdef CONFIG_PM
-static int ufshcd_pci_runtime_suspend(struct device *dev)
-{
-	return ufshcd_runtime_suspend(dev_get_drvdata(dev));
-}
-static int ufshcd_pci_runtime_resume(struct device *dev)
-{
-	return ufshcd_runtime_resume(dev_get_drvdata(dev));
-}
-static int ufshcd_pci_runtime_idle(struct device *dev)
-{
-	return ufshcd_runtime_idle(dev_get_drvdata(dev));
-}
-#endif /* !CONFIG_PM */
-
 /**
  * ufshcd_pci_shutdown - main function to put the controller in reset state
  * @pdev: pointer to PCI device handle
@@ -510,10 +468,8 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 }
 
 static const struct dev_pm_ops ufshcd_pci_pm_ops = {
-	SET_RUNTIME_PM_OPS(ufshcd_pci_runtime_suspend,
-			   ufshcd_pci_runtime_resume,
-			   ufshcd_pci_runtime_idle)
-	SET_SYSTEM_SLEEP_PM_OPS(ufshcd_pci_suspend, ufshcd_pci_resume)
+	SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume)
+	SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL)
 #ifdef CONFIG_PM_SLEEP
 	.prepare	= ufshcd_suspend_prepare,
 	.complete	= ufshcd_resume_complete,
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
index 298e22ef907e..8859c13f4e09 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
@@ -170,53 +170,6 @@ static int ufshcd_parse_regulator_info(struct ufs_hba *hba)
 	return err;
 }
 
-#ifdef CONFIG_PM
-/**
- * ufshcd_pltfrm_suspend - suspend power management function
- * @dev: pointer to device handle
- *
- * Returns 0 if successful
- * Returns non-zero otherwise
- */
-int ufshcd_pltfrm_suspend(struct device *dev)
-{
-	return ufshcd_system_suspend(dev_get_drvdata(dev));
-}
-EXPORT_SYMBOL_GPL(ufshcd_pltfrm_suspend);
-
-/**
- * ufshcd_pltfrm_resume - resume power management function
- * @dev: pointer to device handle
- *
- * Returns 0 if successful
- * Returns non-zero otherwise
- */
-int ufshcd_pltfrm_resume(struct device *dev)
-{
-	return ufshcd_system_resume(dev_get_drvdata(dev));
-}
-EXPORT_SYMBOL_GPL(ufshcd_pltfrm_resume);
-
-int ufshcd_pltfrm_runtime_suspend(struct device *dev)
-{
-	return ufshcd_runtime_suspend(dev_get_drvdata(dev));
-}
-EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_suspend);
-
-int ufshcd_pltfrm_runtime_resume(struct device *dev)
-{
-	return ufshcd_runtime_resume(dev_get_drvdata(dev));
-}
-EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_resume);
-
-int ufshcd_pltfrm_runtime_idle(struct device *dev)
-{
-	return ufshcd_runtime_idle(dev_get_drvdata(dev));
-}
-EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_idle);
-
-#endif /* CONFIG_PM */
-
 void ufshcd_pltfrm_shutdown(struct platform_device *pdev)
 {
 	ufshcd_shutdown((struct ufs_hba *)platform_get_drvdata(pdev));
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.h b/drivers/scsi/ufs/ufshcd-pltfrm.h
index 772a8e848098..c33e28ac6ef6 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.h
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.h
@@ -33,22 +33,4 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
 		       const struct ufs_hba_variant_ops *vops);
 void ufshcd_pltfrm_shutdown(struct platform_device *pdev);
 
-#ifdef CONFIG_PM
-
-int ufshcd_pltfrm_suspend(struct device *dev);
-int ufshcd_pltfrm_resume(struct device *dev);
-int ufshcd_pltfrm_runtime_suspend(struct device *dev);
-int ufshcd_pltfrm_runtime_resume(struct device *dev);
-int ufshcd_pltfrm_runtime_idle(struct device *dev);
-
-#else /* !CONFIG_PM */
-
-#define ufshcd_pltfrm_suspend	NULL
-#define ufshcd_pltfrm_resume	NULL
-#define ufshcd_pltfrm_runtime_suspend	NULL
-#define ufshcd_pltfrm_runtime_resume	NULL
-#define ufshcd_pltfrm_runtime_idle	NULL
-
-#endif /* CONFIG_PM */
-
 #endif /* UFSHCD_PLTFRM_H_ */
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 5b31de83a63a..a34aa6d486c7 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -9204,15 +9204,17 @@ static int ufshcd_resume(struct ufs_hba *hba)
 }
 
 /**
- * ufshcd_system_suspend - system suspend routine
- * @hba: per adapter instance
+ * ufshcd_system_suspend - system suspend callback
+ * @dev: Device associated with the UFS controller.
  *
- * Check the description of ufshcd_suspend() function for more details.
+ * Executed before putting the system into a sleep state in which the contents
+ * of main memory are preserved.
  *
  * Returns 0 for success and non-zero for failure
  */
-int ufshcd_system_suspend(struct ufs_hba *hba)
+int ufshcd_system_suspend(struct device *dev)
 {
+	struct ufs_hba *hba = dev_get_drvdata(dev);
 	int ret = 0;
 	ktime_t start = ktime_get();
 
@@ -9229,16 +9231,19 @@ int ufshcd_system_suspend(struct ufs_hba *hba)
 EXPORT_SYMBOL(ufshcd_system_suspend);
 
 /**
- * ufshcd_system_resume - system resume routine
- * @hba: per adapter instance
+ * ufshcd_system_resume - system resume callback
+ * @dev: Device associated with the UFS controller.
+ *
+ * Executed after waking the system up from a sleep state in which the contents
+ * of main memory were preserved.
  *
  * Returns 0 for success and non-zero for failure
  */
-
-int ufshcd_system_resume(struct ufs_hba *hba)
+int ufshcd_system_resume(struct device *dev)
 {
-	int ret = 0;
+	struct ufs_hba *hba = dev_get_drvdata(dev);
 	ktime_t start = ktime_get();
+	int ret = 0;
 
 	if (pm_runtime_suspended(hba->dev))
 		goto out;
@@ -9255,15 +9260,16 @@ int ufshcd_system_resume(struct ufs_hba *hba)
 EXPORT_SYMBOL(ufshcd_system_resume);
 
 /**
- * ufshcd_runtime_suspend - runtime suspend routine
- * @hba: per adapter instance
+ * ufshcd_runtime_suspend - runtime suspend callback
+ * @dev: Device associated with the UFS controller.
  *
  * Check the description of ufshcd_suspend() function for more details.
  *
  * Returns 0 for success and non-zero for failure
  */
-int ufshcd_runtime_suspend(struct ufs_hba *hba)
+int ufshcd_runtime_suspend(struct device *dev)
 {
+	struct ufs_hba *hba = dev_get_drvdata(dev);
 	int ret;
 	ktime_t start = ktime_get();
 
@@ -9278,7 +9284,7 @@ EXPORT_SYMBOL(ufshcd_runtime_suspend);
 
 /**
  * ufshcd_runtime_resume - runtime resume routine
- * @hba: per adapter instance
+ * @dev: Device associated with the UFS controller.
  *
  * This function basically brings controller
  * to active state. Following operations are done in this function:
@@ -9286,8 +9292,9 @@ EXPORT_SYMBOL(ufshcd_runtime_suspend);
  * 1. Turn on all the controller related clocks
  * 2. Turn ON VCC rail
  */
-int ufshcd_runtime_resume(struct ufs_hba *hba)
+int ufshcd_runtime_resume(struct device *dev)
 {
+	struct ufs_hba *hba = dev_get_drvdata(dev);
 	int ret;
 	ktime_t start = ktime_get();
 
@@ -9300,12 +9307,6 @@ int ufshcd_runtime_resume(struct ufs_hba *hba)
 }
 EXPORT_SYMBOL(ufshcd_runtime_resume);
 
-int ufshcd_runtime_idle(struct ufs_hba *hba)
-{
-	return 0;
-}
-EXPORT_SYMBOL(ufshcd_runtime_idle);
-
 /**
  * ufshcd_shutdown - shutdown routine
  * @hba: per adapter instance
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index c98d540ac044..dc75426c609f 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -1009,11 +1009,10 @@ static inline u8 ufshcd_wb_get_query_index(struct ufs_hba *hba)
 	return 0;
 }
 
-extern int ufshcd_runtime_suspend(struct ufs_hba *hba);
-extern int ufshcd_runtime_resume(struct ufs_hba *hba);
-extern int ufshcd_runtime_idle(struct ufs_hba *hba);
-extern int ufshcd_system_suspend(struct ufs_hba *hba);
-extern int ufshcd_system_resume(struct ufs_hba *hba);
+extern int ufshcd_runtime_suspend(struct device *dev);
+extern int ufshcd_runtime_resume(struct device *dev);
+extern int ufshcd_system_suspend(struct device *dev);
+extern int ufshcd_system_resume(struct device *dev);
 extern int ufshcd_shutdown(struct ufs_hba *hba);
 extern int ufshcd_dme_configure_adapt(struct ufs_hba *hba,
 				      int agreed_gear,

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 07/21] ufs: Only include power management code if necessary
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (5 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 06/21] ufs: Reduce power management code duplication Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-05  6:33   ` Avri Altman
  2021-07-08  5:50   ` Avri Altman
  2021-07-01 21:12 ` [PATCH 08/21] ufs: Rename the second ufshcd_probe_hba() argument Bart Van Assche
                   ` (13 subsequent siblings)
  20 siblings, 2 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Adrian Hunter,
	Stanley Chu, Can Guo, Asutosh Das, Avri Altman,
	James E.J. Bottomley, Matthias Brugger, Bean Huo, Kiwoong Kim

This patch slightly reduces the UFS driver size if built with power
management support disabled.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Stanley Chu <stanley.chu@mediatek.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Asutosh Das <asutoshd@codeaurora.org>
Cc: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 8 ++++++++
 drivers/scsi/ufs/ufshcd.h | 4 ++++
 2 files changed, 12 insertions(+)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index a34aa6d486c7..37302a8b3937 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -8736,6 +8736,7 @@ static void ufshcd_vreg_set_lpm(struct ufs_hba *hba)
 		usleep_range(5000, 5100);
 }
 
+#ifdef CONFIG_PM
 static int ufshcd_vreg_set_hpm(struct ufs_hba *hba)
 {
 	int ret = 0;
@@ -8763,6 +8764,7 @@ static int ufshcd_vreg_set_hpm(struct ufs_hba *hba)
 out:
 	return ret;
 }
+#endif /* CONFIG_PM */
 
 static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba)
 {
@@ -9165,6 +9167,7 @@ static int ufshcd_suspend(struct ufs_hba *hba)
 	return ret;
 }
 
+#ifdef CONFIG_PM
 /**
  * ufshcd_resume - helper function for resume operations
  * @hba: per adapter instance
@@ -9202,7 +9205,9 @@ static int ufshcd_resume(struct ufs_hba *hba)
 		ufshcd_update_evt_hist(hba, UFS_EVT_RESUME_ERR, (u32)ret);
 	return ret;
 }
+#endif /* CONFIG_PM */
 
+#ifdef CONFIG_PM_SLEEP
 /**
  * ufshcd_system_suspend - system suspend callback
  * @dev: Device associated with the UFS controller.
@@ -9258,7 +9263,9 @@ int ufshcd_system_resume(struct device *dev)
 	return ret;
 }
 EXPORT_SYMBOL(ufshcd_system_resume);
+#endif /* CONFIG_PM_SLEEP */
 
+#ifdef CONFIG_PM
 /**
  * ufshcd_runtime_suspend - runtime suspend callback
  * @dev: Device associated with the UFS controller.
@@ -9306,6 +9313,7 @@ int ufshcd_runtime_resume(struct device *dev)
 	return ret;
 }
 EXPORT_SYMBOL(ufshcd_runtime_resume);
+#endif /* CONFIG_PM */
 
 /**
  * ufshcd_shutdown - shutdown routine
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index dc75426c609f..79f6c261dfff 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -1009,10 +1009,14 @@ static inline u8 ufshcd_wb_get_query_index(struct ufs_hba *hba)
 	return 0;
 }
 
+#ifdef CONFIG_PM
 extern int ufshcd_runtime_suspend(struct device *dev);
 extern int ufshcd_runtime_resume(struct device *dev);
+#endif
+#ifdef CONFIG_PM_SLEEP
 extern int ufshcd_system_suspend(struct device *dev);
 extern int ufshcd_system_resume(struct device *dev);
+#endif
 extern int ufshcd_shutdown(struct ufs_hba *hba);
 extern int ufshcd_dme_configure_adapt(struct ufs_hba *hba,
 				      int agreed_gear,

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 08/21] ufs: Rename the second ufshcd_probe_hba() argument
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (6 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 07/21] ufs: Only include power management code if necessary Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-01 21:12 ` [PATCH 09/21] ufs: Use DECLARE_COMPLETION_ONSTACK() where appropriate Bart Van Assche
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Avri Altman, Bean Huo,
	Asutosh Das, Can Guo, James E.J. Bottomley, Stanley Chu

Rename the second argument of ufshcd_probe_hba() such that the name of
that argument reflects its purpose instead of how the function is called.
See also commit 1b9e21412f72 ("scsi: ufs: Split ufshcd_probe_hba() based
on its called flow").

Reviewed-by: Avri Altman <avri.altman@wdc.com>
Reviewed-by: Bean Huo <beanhuo@micron.com>
Cc: Asutosh Das <asutoshd@codeaurora.org>
Cc: Can Guo <cang@codeaurora.org>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 37302a8b3937..86ca9e1ce5aa 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -7964,13 +7964,13 @@ static int ufshcd_clear_ua_wluns(struct ufs_hba *hba)
 }
 
 /**
- * ufshcd_probe_hba - probe hba to detect device and initialize
+ * ufshcd_probe_hba - probe hba to detect device and initialize it
  * @hba: per-adapter instance
- * @async: asynchronous execution or not
+ * @init_dev_params: whether or not to call ufshcd_device_params_init().
  *
  * Execute link-startup and verify device initialization
  */
-static int ufshcd_probe_hba(struct ufs_hba *hba, bool async)
+static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params)
 {
 	int ret;
 	unsigned long flags;
@@ -8002,7 +8002,7 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async)
 	 * Initialize UFS device parameters used by driver, these
 	 * parameters are associated with UFS descriptors.
 	 */
-	if (async) {
+	if (init_dev_params) {
 		ret = ufshcd_device_params_init(hba);
 		if (ret)
 			goto out;

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 09/21] ufs: Use DECLARE_COMPLETION_ONSTACK() where appropriate
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (7 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 08/21] ufs: Rename the second ufshcd_probe_hba() argument Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-05  6:38   ` Avri Altman
  2021-07-01 21:12 ` [PATCH 10/21] ufs: Remove ufshcd_valid_tag() Bart Van Assche
                   ` (11 subsequent siblings)
  20 siblings, 1 reply; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Adrian Hunter,
	Stanley Chu, Can Guo, Asutosh Das, Avri Altman,
	James E.J. Bottomley, Matthias Brugger, Bean Huo

From Documentation/scheduler/completion.rst: "When a completion is declared
as a local variable within a function, then the initialization should
always use DECLARE_COMPLETION_ONSTACK() explicitly, not just to make
lockdep happy, but also to make it clear that limited scope had been
considered and is intentional."

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Stanley Chu <stanley.chu@mediatek.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Asutosh Das <asutoshd@codeaurora.org>
Cc: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 86ca9e1ce5aa..2148e123e9db 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2949,11 +2949,11 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
 		enum dev_cmd_type cmd_type, int timeout)
 {
 	struct request_queue *q = hba->cmd_queue;
+	DECLARE_COMPLETION_ONSTACK(wait);
 	struct request *req;
 	struct ufshcd_lrb *lrbp;
 	int err;
 	int tag;
-	struct completion wait;
 
 	down_read(&hba->clk_scaling_lock);
 
@@ -2975,7 +2975,6 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
 		goto out;
 	}
 
-	init_completion(&wait);
 	lrbp = &hba->lrb[tag];
 	WARN_ON(lrbp->cmd);
 	err = ufshcd_compose_dev_cmd(hba, lrbp, cmd_type, tag);
@@ -3980,14 +3979,13 @@ EXPORT_SYMBOL_GPL(ufshcd_dme_get_attr);
  */
 static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd)
 {
-	struct completion uic_async_done;
+	DECLARE_COMPLETION_ONSTACK(uic_async_done);
 	unsigned long flags;
 	u8 status;
 	int ret;
 	bool reenable_intr = false;
 
 	mutex_lock(&hba->uic_cmd_mutex);
-	init_completion(&uic_async_done);
 	ufshcd_add_delay_before_dme_cmd(hba);
 
 	spin_lock_irqsave(hba->host->host_lock, flags);
@@ -6660,11 +6658,11 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba,
 					enum query_opcode desc_op)
 {
 	struct request_queue *q = hba->cmd_queue;
+	DECLARE_COMPLETION_ONSTACK(wait);
 	struct request *req;
 	struct ufshcd_lrb *lrbp;
 	int err = 0;
 	int tag;
-	struct completion wait;
 	u8 upiu_flags;
 
 	down_read(&hba->clk_scaling_lock);
@@ -6682,7 +6680,6 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba,
 		goto out;
 	}
 
-	init_completion(&wait);
 	lrbp = &hba->lrb[tag];
 	WARN_ON(lrbp->cmd);
 	lrbp->cmd = NULL;

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 10/21] ufs: Remove ufshcd_valid_tag()
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (8 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 09/21] ufs: Use DECLARE_COMPLETION_ONSTACK() where appropriate Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-05  6:46   ` Avri Altman
  2021-07-05 19:02   ` Avri Altman
  2021-07-01 21:12 ` [PATCH 11/21] ufs: Verify UIC locking requirements at runtime Bart Van Assche
                   ` (10 subsequent siblings)
  20 siblings, 2 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Alim Akhtar,
	Avri Altman, James E.J. Bottomley, Can Guo, Stanley Chu,
	Bean Huo, Asutosh Das

scsi_add_host() allocates shost->can_queue tags. ufshcd_init() sets
shost->can_queue to hba->nutrs. In other words, we know that tag values
will be in the range [0, hba->nutrs). Hence remove the checks that
verify that blk_get_request() returns a tag in this range. This check
was introduced by commit 14497328b6a6 ("scsi: ufs: verify command tag
validity").

Cc: Alim Akhtar <alim.akhtar@samsung.com>
Cc: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 40 ++++++---------------------------------
 1 file changed, 6 insertions(+), 34 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 2148e123e9db..2e6aa614e3f5 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -253,11 +253,6 @@ static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable);
 static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba);
 static void ufshcd_hba_vreg_set_hpm(struct ufs_hba *hba);
 
-static inline bool ufshcd_valid_tag(struct ufs_hba *hba, int tag)
-{
-	return tag >= 0 && tag < hba->nutrs;
-}
-
 static inline void ufshcd_enable_irq(struct ufs_hba *hba)
 {
 	if (!hba->is_irq_enabled) {
@@ -2701,21 +2696,11 @@ static void ufshcd_init_lrb(struct ufs_hba *hba, struct ufshcd_lrb *lrb, int i)
  */
 static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 {
+	struct ufs_hba *hba = shost_priv(host);
+	int tag = cmd->request->tag;
 	struct ufshcd_lrb *lrbp;
-	struct ufs_hba *hba;
-	int tag;
 	int err = 0;
 
-	hba = shost_priv(host);
-
-	tag = cmd->request->tag;
-	if (!ufshcd_valid_tag(hba, tag)) {
-		dev_err(hba->dev,
-			"%s: invalid command tag %d: cmd=0x%p, cmd->request=0x%p",
-			__func__, tag, cmd, cmd->request);
-		BUG();
-	}
-
 	if (!down_read_trylock(&hba->clk_scaling_lock))
 		return SCSI_MLQUEUE_HOST_BUSY;
 
@@ -2968,7 +2953,6 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
 		goto out_unlock;
 	}
 	tag = req->tag;
-	WARN_ON_ONCE(!ufshcd_valid_tag(hba, tag));
 
 	if (unlikely(test_bit(tag, &hba->outstanding_reqs))) {
 		err = -EBUSY;
@@ -6673,7 +6657,6 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba,
 		goto out_unlock;
 	}
 	tag = req->tag;
-	WARN_ON_ONCE(!ufshcd_valid_tag(hba, tag));
 
 	if (unlikely(test_bit(tag, &hba->outstanding_reqs))) {
 		err = -EBUSY;
@@ -6975,25 +6958,14 @@ static int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag)
  */
 static int ufshcd_abort(struct scsi_cmnd *cmd)
 {
-	struct Scsi_Host *host;
-	struct ufs_hba *hba;
+	struct Scsi_Host *host = cmd->device->host;
+	struct ufs_hba *hba = shost_priv(host);
+	unsigned int tag = cmd->request->tag;
+	struct ufshcd_lrb *lrbp = &hba->lrb[tag];
 	unsigned long flags;
-	unsigned int tag;
 	int err = 0;
-	struct ufshcd_lrb *lrbp;
 	u32 reg;
 
-	host = cmd->device->host;
-	hba = shost_priv(host);
-	tag = cmd->request->tag;
-	lrbp = &hba->lrb[tag];
-	if (!ufshcd_valid_tag(hba, tag)) {
-		dev_err(hba->dev,
-			"%s: invalid command tag %d: cmd=0x%p, cmd->request=0x%p",
-			__func__, tag, cmd, cmd->request);
-		BUG();
-	}
-
 	ufshcd_hold(hba, false);
 	reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
 	/* If command is already aborted/completed, return SUCCESS */

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 11/21] ufs: Verify UIC locking requirements at runtime
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (9 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 10/21] ufs: Remove ufshcd_valid_tag() Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-05  6:52   ` Avri Altman
  2021-07-01 21:12 ` [PATCH 12/21] ufs: Improve static type checking for the host controller state Bart Van Assche
                   ` (9 subsequent siblings)
  20 siblings, 1 reply; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Adrian Hunter,
	Stanley Chu, Can Guo, Asutosh Das, Avri Altman,
	James E.J. Bottomley, Matthias Brugger, Bean Huo, Kiwoong Kim

Instead of documenting the locking requirements of the UIC code as comments,
use lockdep_assert_held() such that lockdep verifies the lockdep
requirements at runtime if lockdep is enabled.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Stanley Chu <stanley.chu@mediatek.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Asutosh Das <asutoshd@codeaurora.org>
Cc: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 16 +++++++++-------
 drivers/scsi/ufs/ufshcd.h |  2 +-
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 2e6aa614e3f5..1262f1a63e0b 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2242,15 +2242,15 @@ static inline u8 ufshcd_get_upmcrs(struct ufs_hba *hba)
 }
 
 /**
- * ufshcd_dispatch_uic_cmd - Dispatch UIC commands to unipro layers
+ * ufshcd_dispatch_uic_cmd - Dispatch an UIC command to the Unipro layer
  * @hba: per adapter instance
  * @uic_cmd: UIC command
- *
- * Mutex must be held.
  */
 static inline void
 ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
 {
+	lockdep_assert_held(&hba->uic_cmd_mutex);
+
 	WARN_ON(hba->active_uic_cmd);
 
 	hba->active_uic_cmd = uic_cmd;
@@ -2268,11 +2268,10 @@ ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
 }
 
 /**
- * ufshcd_wait_for_uic_cmd - Wait complectioin of UIC command
+ * ufshcd_wait_for_uic_cmd - Wait for completion of an UIC command
  * @hba: per adapter instance
  * @uic_cmd: UIC command
  *
- * Must be called with mutex held.
  * Returns 0 only if success.
  */
 static int
@@ -2281,6 +2280,8 @@ ufshcd_wait_for_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
 	int ret;
 	unsigned long flags;
 
+	lockdep_assert_held(&hba->uic_cmd_mutex);
+
 	if (wait_for_completion_timeout(&uic_cmd->done,
 					msecs_to_jiffies(UIC_CMD_TIMEOUT))) {
 		ret = uic_cmd->argument2 & MASK_UIC_COMMAND_RESULT;
@@ -2310,14 +2311,15 @@ ufshcd_wait_for_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
  * @uic_cmd: UIC command
  * @completion: initialize the completion only if this is set to true
  *
- * Identical to ufshcd_send_uic_cmd() expect mutex. Must be called
- * with mutex held and host_lock locked.
  * Returns 0 only if success.
  */
 static int
 __ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd,
 		      bool completion)
 {
+	lockdep_assert_held(&hba->uic_cmd_mutex);
+	lockdep_assert_held(hba->host->host_lock);
+
 	if (!ufshcd_ready_for_uic_cmd(hba)) {
 		dev_err(hba->dev,
 			"Controller not ready to accept UIC commands\n");
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 79f6c261dfff..0dfb5e97ec0d 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -683,7 +683,7 @@ struct ufs_hba_monitor {
  * @priv: pointer to variant specific private data
  * @irq: Irq number of the controller
  * @active_uic_cmd: handle of active UIC command
- * @uic_cmd_mutex: mutex for uic command
+ * @uic_cmd_mutex: mutex for UIC command
  * @tmf_tag_set: TMF tag set.
  * @tmf_queue: Used to allocate TMF tags.
  * @pwr_done: completion for power mode change

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 12/21] ufs: Improve static type checking for the host controller state
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (10 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 11/21] ufs: Verify UIC locking requirements at runtime Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-01 21:12 ` [PATCH 13/21] ufs: Remove several wmb() calls Bart Van Assche
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Avri Altman, Can Guo,
	James E.J. Bottomley, Stanley Chu, Bean Huo, Asutosh Das,
	Adrian Hunter

Assign a name to the enumeration type for UFS host controller states and
remove the default clause from switch statements on this enumeration type
to make the compiler warn about unhandled enumeration labels.

Reviewed-by: Avri Altman <avri.altman@wdc.com>
Cc: Can Guo <cang@codeaurora.org>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 15 ---------------
 drivers/scsi/ufs/ufshcd.h | 25 +++++++++++++++++++++++--
 2 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 1262f1a63e0b..7091798e6245 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -128,15 +128,6 @@ enum {
 	UFSHCD_CAN_QUEUE	= 32,
 };
 
-/* UFSHCD states */
-enum {
-	UFSHCD_STATE_RESET,
-	UFSHCD_STATE_ERROR,
-	UFSHCD_STATE_OPERATIONAL,
-	UFSHCD_STATE_EH_SCHEDULED_FATAL,
-	UFSHCD_STATE_EH_SCHEDULED_NON_FATAL,
-};
-
 /* UFSHCD error handling flags */
 enum {
 	UFSHCD_EH_IN_PROGRESS = (1 << 0),
@@ -2735,12 +2726,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 		set_host_byte(cmd, DID_ERROR);
 		cmd->scsi_done(cmd);
 		goto out;
-	default:
-		dev_WARN_ONCE(hba->dev, 1, "%s: invalid state %d\n",
-				__func__, hba->ufshcd_state);
-		set_host_byte(cmd, DID_BAD_TARGET);
-		cmd->scsi_done(cmd);
-		goto out;
 	}
 
 	hba->req_abort_count = 0;
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 0dfb5e97ec0d..f8766e8f3cac 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -476,6 +476,27 @@ struct ufs_stats {
 	struct ufs_event_hist event[UFS_EVT_CNT];
 };
 
+/**
+ * enum ufshcd_state - UFS host controller state
+ * @UFSHCD_STATE_RESET: Link is not operational. Postpone SCSI command
+ *	processing.
+ * @UFSHCD_STATE_OPERATIONAL: The host controller is operational and can process
+ *	SCSI commands.
+ * @UFSHCD_STATE_EH_SCHEDULED_NON_FATAL: The error handler has been scheduled.
+ *	SCSI commands may be submitted to the controller.
+ * @UFSHCD_STATE_EH_SCHEDULED_FATAL: The error handler has been scheduled. Fail
+ *	newly submitted SCSI commands with error code DID_BAD_TARGET.
+ * @UFSHCD_STATE_ERROR: An unrecoverable error occurred, e.g. link recovery
+ *	failed. Fail all SCSI commands with error code DID_ERROR.
+ */
+enum ufshcd_state {
+	UFSHCD_STATE_RESET,
+	UFSHCD_STATE_OPERATIONAL,
+	UFSHCD_STATE_EH_SCHEDULED_NON_FATAL,
+	UFSHCD_STATE_EH_SCHEDULED_FATAL,
+	UFSHCD_STATE_ERROR,
+};
+
 enum ufshcd_quirks {
 	/* Interrupt aggregation support is broken */
 	UFSHCD_QUIRK_BROKEN_INTR_AGGR			= 1 << 0,
@@ -687,7 +708,7 @@ struct ufs_hba_monitor {
  * @tmf_tag_set: TMF tag set.
  * @tmf_queue: Used to allocate TMF tags.
  * @pwr_done: completion for power mode change
- * @ufshcd_state: UFSHCD states
+ * @ufshcd_state: UFSHCD state
  * @eh_flags: Error handling flags
  * @intr_mask: Interrupt Mask Bits
  * @ee_ctrl_mask: Exception event control mask
@@ -785,7 +806,7 @@ struct ufs_hba {
 	struct mutex uic_cmd_mutex;
 	struct completion *uic_async_done;
 
-	u32 ufshcd_state;
+	enum ufshcd_state ufshcd_state;
 	u32 eh_flags;
 	u32 intr_mask;
 	u16 ee_ctrl_mask; /* Exception event mask */

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 13/21] ufs: Remove several wmb() calls
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (11 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 12/21] ufs: Improve static type checking for the host controller state Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-01 22:26   ` Asutosh Das (asd)
  2021-07-01 21:12 ` [PATCH 14/21] ufs: Inline ufshcd_outstanding_req_clear() Bart Van Assche
                   ` (7 subsequent siblings)
  20 siblings, 1 reply; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Adrian Hunter,
	Stanley Chu, Can Guo, Asutosh Das, Avri Altman,
	James E.J. Bottomley, Matthias Brugger, Bean Huo

From arch/arm/include/asm/io.h

  #define __iowmb() wmb()
  [ ... ]
  #define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); })

From Documentation/memory-barriers.txt: "Note that, when using writel(), a
prior wmb() is not needed to guarantee that the cache coherent memory
writes have completed before writing to the MMIO region."

In other words, calling wmb() before writel() is not necessary. Hence
remove the wmb() calls that precede a writel() call. Remove the wmb()
calls that precede a ufshcd_send_command() call since the latter function
uses writel(). Remove the wmb() call from ufshcd_wait_for_dev_cmd()
since the following chain of events guarantees that the CPU will see
up-to-date LRB values:
* UFS controller writes to host memory.
* UFS controller posts completion interrupt after the memory writes from
  the previous step are visible to the CPU.
* complete(hba->dev_cmd.complete) is called from the UFS interrupt handler.
* The wait_for_completion(hba->dev_cmd.complete) call in
  ufshcd_wait_for_dev_cmd() returns.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Stanley Chu <stanley.chu@mediatek.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Asutosh Das <asutoshd@codeaurora.org>
Cc: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 7091798e6245..25ab603acad1 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2768,8 +2768,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 		ufshcd_release(hba);
 		goto out;
 	}
-	/* Make sure descriptors are ready before ringing the doorbell */
-	wmb();
 
 	ufshcd_send_command(hba, tag);
 out:
@@ -2879,8 +2877,6 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
 	time_left = wait_for_completion_timeout(hba->dev_cmd.complete,
 			msecs_to_jiffies(max_timeout));
 
-	/* Make sure descriptors are ready before ringing the doorbell */
-	wmb();
 	spin_lock_irqsave(hba->host->host_lock, flags);
 	hba->dev_cmd.complete = NULL;
 	if (likely(time_left)) {
@@ -2955,8 +2951,6 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
 	hba->dev_cmd.complete = &wait;
 
 	ufshcd_add_query_upiu_trace(hba, UFS_QUERY_SEND, lrbp->ucd_req_ptr);
-	/* Make sure descriptors are ready before ringing the doorbell */
-	wmb();
 
 	ufshcd_send_command(hba, tag);
 	err = ufshcd_wait_for_dev_cmd(hba, lrbp, timeout);
@@ -6514,9 +6508,6 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
 	/* send command to the controller */
 	__set_bit(task_tag, &hba->outstanding_tasks);
 
-	/* Make sure descriptors are ready before ringing the task doorbell */
-	wmb();
-
 	ufshcd_writel(hba, 1 << task_tag, REG_UTP_TASK_REQ_DOOR_BELL);
 	/* Make sure that doorbell is committed immediately */
 	wmb();
@@ -6687,8 +6678,6 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba,
 	hba->dev_cmd.complete = &wait;
 
 	ufshcd_add_query_upiu_trace(hba, UFS_QUERY_SEND, lrbp->ucd_req_ptr);
-	/* Make sure descriptors are ready before ringing the doorbell */
-	wmb();
 
 	ufshcd_send_command(hba, tag);
 	/*

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 14/21] ufs: Inline ufshcd_outstanding_req_clear()
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (12 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 13/21] ufs: Remove several wmb() calls Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-05  7:03   ` Avri Altman
  2021-07-01 21:12 ` [PATCH 15/21] ufs: Rename __ufshcd_transfer_req_compl() Bart Van Assche
                   ` (6 subsequent siblings)
  20 siblings, 1 reply; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Adrian Hunter,
	Stanley Chu, Can Guo, Asutosh Das, Avri Altman,
	James E.J. Bottomley, Matthias Brugger, Bean Huo

Inline ufshcd_outstanding_req_clear() since it only has one caller and
since its body is only one line long.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Stanley Chu <stanley.chu@mediatek.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Asutosh Das <asutoshd@codeaurora.org>
Cc: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 25ab603acad1..2acf168bc339 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -743,16 +743,6 @@ static inline void ufshcd_utmrl_clear(struct ufs_hba *hba, u32 pos)
 		ufshcd_writel(hba, ~(1 << pos), REG_UTP_TASK_REQ_LIST_CLEAR);
 }
 
-/**
- * ufshcd_outstanding_req_clear - Clear a bit in outstanding request field
- * @hba: per adapter instance
- * @tag: position of the bit to be cleared
- */
-static inline void ufshcd_outstanding_req_clear(struct ufs_hba *hba, int tag)
-{
-	clear_bit(tag, &hba->outstanding_reqs);
-}
-
 /**
  * ufshcd_get_lists_status - Check UCRDY, UTRLRDY and UTMRLRDY
  * @reg: Register value of host controller status
@@ -2898,7 +2888,7 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
 		 * we also need to clear the outstanding_request
 		 * field in hba
 		 */
-		ufshcd_outstanding_req_clear(hba, lrbp->task_tag);
+		clear_bit(lrbp->task_tag, &hba->outstanding_reqs);
 	}
 
 	return err;

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 15/21] ufs: Rename __ufshcd_transfer_req_compl()
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (13 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 14/21] ufs: Inline ufshcd_outstanding_req_clear() Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-01 21:12 ` [PATCH 16/21] ufs: Fix the SCSI abort handler Bart Van Assche
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Adrian Hunter,
	Stanley Chu, Can Guo, Asutosh Das, Avri Altman,
	James E.J. Bottomley, Matthias Brugger, Bean Huo

Before patch "scsi: ufs: Optimize host lock on transfer requests send/compl
paths", the host lock was held around __ufshcd_transfer_req_compl() and the
double underscore prefix indicated this. Since the SCSI host lock is no
longer held around __ufshcd_transfer_req_compl() calls, remove the double
underscore prefix.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Stanley Chu <stanley.chu@mediatek.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Asutosh Das <asutoshd@codeaurora.org>
Cc: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 2acf168bc339..0b7359e0b445 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -5180,12 +5180,12 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status)
 }
 
 /**
- * __ufshcd_transfer_req_compl - handle SCSI and query command completion
+ * ufshcd_transfer_req_compl - handle SCSI and query command completion
  * @hba: per adapter instance
  * @completed_reqs: requests to complete
  */
-static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
-					unsigned long completed_reqs)
+static void ufshcd_transfer_req_compl(struct ufs_hba *hba,
+				      unsigned long completed_reqs)
 {
 	struct ufshcd_lrb *lrbp;
 	struct scsi_cmnd *cmd;
@@ -5270,7 +5270,7 @@ static irqreturn_t ufshcd_trc_handler(struct ufs_hba *hba, bool use_utrlcnr)
 	}
 
 	if (completed_reqs) {
-		__ufshcd_transfer_req_compl(hba, completed_reqs);
+		ufshcd_transfer_req_compl(hba, completed_reqs);
 		return IRQ_HANDLED;
 	} else {
 		return IRQ_NONE;
@@ -6808,7 +6808,7 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd)
 			err = ufshcd_clear_cmd(hba, pos);
 			if (err)
 				break;
-			__ufshcd_transfer_req_compl(hba, pos);
+			ufshcd_transfer_req_compl(hba, pos);
 		}
 	}
 
@@ -6981,7 +6981,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
 	 */
 	if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) {
 		ufshcd_update_evt_hist(hba, UFS_EVT_ABORT, lrbp->lun);
-		__ufshcd_transfer_req_compl(hba, (1UL << tag));
+		ufshcd_transfer_req_compl(hba, 1UL << tag);
 		set_bit(tag, &hba->outstanding_reqs);
 		spin_lock_irqsave(host->host_lock, flags);
 		hba->force_reset = true;
@@ -6998,7 +6998,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
 
 	if (!err) {
 cleanup:
-		__ufshcd_transfer_req_compl(hba, (1UL << tag));
+		ufshcd_transfer_req_compl(hba, 1UL << tag);
 out:
 		err = SUCCESS;
 	} else {

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 16/21] ufs: Fix the SCSI abort handler
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (14 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 15/21] ufs: Rename __ufshcd_transfer_req_compl() Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-01 21:12 ` [PATCH 17/21] ufs: Fix a race in the completion path Bart Van Assche
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Adrian Hunter,
	Stanley Chu, Can Guo, Asutosh Das, Avri Altman,
	James E.J. Bottomley, Matthias Brugger, Bean Huo

Make the following changes in ufshcd_abort():
- Return FAILED instead of SUCCESS if the abort handler notices that a SCSI
  command has already been completed. Returning SUCCESS in this case
  triggers a use-after-free and may trigger a kernel crash.
- Fix the code for aborting SCSI commands submitted to a WLUN.

The current approach for aborting SCSI commands that have been submitted to
a WLUN and that timed out is as follows:
- Report to the SCSI core that the command has completed successfully.
  Let the block layer free any data buffers associated with the command.
- Mark the command as outstanding in 'outstanding_reqs'.
- If the block layer tries to reuse the tag associated with the aborted
  command, busy-wait until the tag is freed.

This approach can result in:
- Memory corruption if the controller accesses the data buffer after the
  block layer has freed the associated data buffers.
- A race condition if ufshcd_queuecommand() or ufshcd_exec_dev_cmd()
  checks the bit that corresponds to an aborted command in 'outstanding_reqs'
  after it has been cleared and before it is reset.
- High energy consumption if ufshcd_queuecommand() repeatedly returns
  SCSI_MLQUEUE_HOST_BUSY.

Fix this by reporting to the SCSI error handler that aborting a SCSI
command failed if the SCSI command was submitted to a WLUN.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Stanley Chu <stanley.chu@mediatek.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Asutosh Das <asutoshd@codeaurora.org>
Cc: Avri Altman <avri.altman@wdc.com>
Fixes: 7a7e66c65d41 ("scsi: ufs: Fix a race condition between ufshcd_abort() and eh_work()")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 57 +++++++++++++--------------------------
 1 file changed, 18 insertions(+), 39 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 0b7359e0b445..aa23fe6f5ddd 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2728,15 +2728,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 	WARN_ON(ufshcd_is_clkgating_allowed(hba) &&
 		(hba->clk_gating.state != CLKS_ON));
 
-	if (unlikely(test_bit(tag, &hba->outstanding_reqs))) {
-		if (hba->pm_op_in_progress)
-			set_host_byte(cmd, DID_BAD_TARGET);
-		else
-			err = SCSI_MLQUEUE_HOST_BUSY;
-		ufshcd_release(hba);
-		goto out;
-	}
-
 	lrbp = &hba->lrb[tag];
 	WARN_ON(lrbp->cmd);
 	lrbp->cmd = cmd;
@@ -2926,12 +2917,6 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
 		goto out_unlock;
 	}
 	tag = req->tag;
-
-	if (unlikely(test_bit(tag, &hba->outstanding_reqs))) {
-		err = -EBUSY;
-		goto out;
-	}
-
 	lrbp = &hba->lrb[tag];
 	WARN_ON(lrbp->cmd);
 	err = ufshcd_compose_dev_cmd(hba, lrbp, cmd_type, tag);
@@ -6929,17 +6914,17 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
 	unsigned int tag = cmd->request->tag;
 	struct ufshcd_lrb *lrbp = &hba->lrb[tag];
 	unsigned long flags;
-	int err = 0;
+	int err = FAILED, res;
 	u32 reg;
 
 	ufshcd_hold(hba, false);
 	reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
-	/* If command is already aborted/completed, return SUCCESS */
+	/* If command is already aborted/completed, return FAILED. */
 	if (!(test_bit(tag, &hba->outstanding_reqs))) {
 		dev_err(hba->dev,
 			"%s: cmd at tag %d already completed, outstanding=0x%lx, doorbell=0x%x\n",
 			__func__, tag, hba->outstanding_reqs, reg);
-		goto out;
+		goto release;
 	}
 
 	/* Print Transfer Request of aborted task */
@@ -6968,7 +6953,8 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
 		dev_err(hba->dev,
 		"%s: cmd was completed, but without a notifying intr, tag = %d",
 		__func__, tag);
-		goto cleanup;
+		ufshcd_transfer_req_compl(hba, 1UL << tag);
+		goto release;
 	}
 
 	/*
@@ -6981,36 +6967,29 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
 	 */
 	if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) {
 		ufshcd_update_evt_hist(hba, UFS_EVT_ABORT, lrbp->lun);
-		ufshcd_transfer_req_compl(hba, 1UL << tag);
-		set_bit(tag, &hba->outstanding_reqs);
+
 		spin_lock_irqsave(host->host_lock, flags);
 		hba->force_reset = true;
 		ufshcd_schedule_eh_work(hba);
 		spin_unlock_irqrestore(host->host_lock, flags);
-		goto out;
+		goto release;
 	}
 
 	/* Skip task abort in case previous aborts failed and report failure */
-	if (lrbp->req_abort_skip)
-		err = -EIO;
-	else
-		err = ufshcd_try_to_abort_task(hba, tag);
-
-	if (!err) {
-cleanup:
-		ufshcd_transfer_req_compl(hba, 1UL << tag);
-out:
-		err = SUCCESS;
-	} else {
-		dev_err(hba->dev, "%s: failed with err %d\n", __func__, err);
+	if (lrbp->req_abort_skip) {
+		dev_err(hba->dev, "%s: failed\n", __func__);
 		ufshcd_set_req_abort_skip(hba, hba->outstanding_reqs);
-		err = FAILED;
+		goto release;
 	}
 
-	/*
-	 * This ufshcd_release() corresponds to the original scsi cmd that got
-	 * aborted here (as we won't get any IRQ for it).
-	 */
+	res = ufshcd_try_to_abort_task(hba, tag);
+	if (res)
+		goto release;
+
+	err = SUCCESS;
+
+release:
+	/* Matches the ufshcd_hold() call at the start of this function. */
 	ufshcd_release(hba);
 	return err;
 }

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 17/21] ufs: Fix a race in the completion path
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (15 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 16/21] ufs: Fix the SCSI abort handler Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-01 21:12 ` [PATCH 18/21] ufs: Use the doorbell register instead of the UTRLCNR register Bart Van Assche
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Adrian Hunter,
	Stanley Chu, Can Guo, Asutosh Das, Avri Altman,
	James E.J. Bottomley, Matthias Brugger, Bean Huo

The following unlikely races can be triggered by the completion path
(ufshcd_trc_handler()):
- After the UTRLCNR register has been read from interrupt context and
  before it is cleared, the UFS error handler reads the UTRLCNR register.
  Hold the SCSI host lock until the UTRLCNR register has been cleared to
  prevent that this register is accessed from another CPU before it has
  been cleared.
- After the doorbell register has been read and before outstanding_reqs
  is cleared, the error handler reads the doorbell register. This can also
  result in double completions. Fix this by clearing outstanding_reqs
  before calling ufshcd_transfer_req_compl().

Due to this change ufshcd_trc_handler() no longer updates outstanding_reqs
atomically. Hence protect all other outstanding_reqs changes with the SCSI
host lock.

This patch is a performance improvement because it reduces the number of
atomic operations in the hot path (test_and_clear_bit()).

See also commit a45f937110fa ("scsi: ufs: Optimize host lock on transfer
requests send/compl paths").

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Stanley Chu <stanley.chu@mediatek.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Asutosh Das <asutoshd@codeaurora.org>
Cc: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 47 +++++++++++++++++----------------------
 1 file changed, 21 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index aa23fe6f5ddd..71db56c72af6 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2088,6 +2088,7 @@ static inline
 void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
 {
 	struct ufshcd_lrb *lrbp = &hba->lrb[task_tag];
+	unsigned long flags;
 
 	lrbp->issue_time_stamp = ktime_get();
 	lrbp->compl_time_stamp = ktime_set(0, 0);
@@ -2096,19 +2097,12 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
 	ufshcd_clk_scaling_start_busy(hba);
 	if (unlikely(ufshcd_should_inform_monitor(hba, lrbp)))
 		ufshcd_start_monitor(hba, lrbp);
-	if (ufshcd_has_utrlcnr(hba)) {
-		set_bit(task_tag, &hba->outstanding_reqs);
-		ufshcd_writel(hba, 1 << task_tag,
-			      REG_UTP_TRANSFER_REQ_DOOR_BELL);
-	} else {
-		unsigned long flags;
 
-		spin_lock_irqsave(hba->host->host_lock, flags);
-		set_bit(task_tag, &hba->outstanding_reqs);
-		ufshcd_writel(hba, 1 << task_tag,
-			      REG_UTP_TRANSFER_REQ_DOOR_BELL);
-		spin_unlock_irqrestore(hba->host->host_lock, flags);
-	}
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	__set_bit(task_tag, &hba->outstanding_reqs);
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+	ufshcd_writel(hba, 1 << task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL);
 	/* Make sure that doorbell is committed immediately */
 	wmb();
 }
@@ -2879,7 +2873,9 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
 		 * we also need to clear the outstanding_request
 		 * field in hba
 		 */
-		clear_bit(lrbp->task_tag, &hba->outstanding_reqs);
+		spin_lock_irqsave(hba->host->host_lock, flags);
+		__clear_bit(lrbp->task_tag, &hba->outstanding_reqs);
+		spin_unlock_irqrestore(hba->host->host_lock, flags);
 	}
 
 	return err;
@@ -5179,8 +5175,6 @@ static void ufshcd_transfer_req_compl(struct ufs_hba *hba,
 	bool update_scaling = false;
 
 	for_each_set_bit(index, &completed_reqs, hba->nutrs) {
-		if (!test_and_clear_bit(index, &hba->outstanding_reqs))
-			continue;
 		lrbp = &hba->lrb[index];
 		lrbp->compl_time_stamp = ktime_get();
 		cmd = lrbp->cmd;
@@ -5223,6 +5217,7 @@ static void ufshcd_transfer_req_compl(struct ufs_hba *hba,
 static irqreturn_t ufshcd_trc_handler(struct ufs_hba *hba, bool use_utrlcnr)
 {
 	unsigned long completed_reqs = 0;
+	unsigned long flags;
 
 	/* Resetting interrupt aggregation counters first and reading the
 	 * DOOR_BELL afterward allows us to handle all the completed requests.
@@ -5235,24 +5230,24 @@ static irqreturn_t ufshcd_trc_handler(struct ufs_hba *hba, bool use_utrlcnr)
 	    !(hba->quirks & UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR))
 		ufshcd_reset_intr_aggr(hba);
 
+	spin_lock_irqsave(hba->host->host_lock, flags);
 	if (use_utrlcnr) {
-		u32 utrlcnr;
-
-		utrlcnr = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_LIST_COMPL);
-		if (utrlcnr) {
-			ufshcd_writel(hba, utrlcnr,
+		completed_reqs = ufshcd_readl(hba,
+					      REG_UTP_TRANSFER_REQ_LIST_COMPL);
+		if (completed_reqs)
+			ufshcd_writel(hba, completed_reqs,
 				      REG_UTP_TRANSFER_REQ_LIST_COMPL);
-			completed_reqs = utrlcnr;
-		}
 	} else {
-		unsigned long flags;
 		u32 tr_doorbell;
 
-		spin_lock_irqsave(hba->host->host_lock, flags);
 		tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
-		completed_reqs = tr_doorbell ^ hba->outstanding_reqs;
-		spin_unlock_irqrestore(hba->host->host_lock, flags);
+		completed_reqs = ~tr_doorbell & hba->outstanding_reqs;
 	}
+	WARN_ONCE(completed_reqs & ~hba->outstanding_reqs,
+		  "completed: %#lx; outstanding: %#lx\n", completed_reqs,
+		  hba->outstanding_reqs);
+	hba->outstanding_reqs &= ~completed_reqs;
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
 
 	if (completed_reqs) {
 		ufshcd_transfer_req_compl(hba, completed_reqs);

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 18/21] ufs: Use the doorbell register instead of the UTRLCNR register
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (16 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 17/21] ufs: Fix a race in the completion path Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-01 21:12 ` [PATCH 19/21] ufs: Request sense data asynchronously Bart Van Assche
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Adrian Hunter,
	Stanley Chu, Can Guo, Asutosh Das, Avri Altman,
	James E.J. Bottomley, Matthias Brugger, Bean Huo, Kiwoong Kim

Using the UTRLCNR register implies performing two MMIO accesses in the hot
path while reading the doorbell register only involves a single MMIO
operation. Hence do not use the UTRLNCR register.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Stanley Chu <stanley.chu@mediatek.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Asutosh Das <asutoshd@codeaurora.org>
Cc: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 2 +-
 drivers/scsi/ufs/ufshcd.h | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 71db56c72af6..250d46ab3584 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -6370,7 +6370,7 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status)
 		retval |= ufshcd_tmc_handler(hba);
 
 	if (intr_status & UTP_TRANSFER_REQ_COMPL)
-		retval |= ufshcd_trc_handler(hba, ufshcd_has_utrlcnr(hba));
+		retval |= ufshcd_trc_handler(hba, ufshcd_use_utrlcnr(hba));
 
 	return retval;
 }
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index f8766e8f3cac..b3d9b487846f 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -1184,9 +1184,9 @@ static inline u32 ufshcd_vops_get_ufs_hci_version(struct ufs_hba *hba)
 	return ufshcd_readl(hba, REG_UFS_VERSION);
 }
 
-static inline bool ufshcd_has_utrlcnr(struct ufs_hba *hba)
+static inline bool ufshcd_use_utrlcnr(struct ufs_hba *hba)
 {
-	return (hba->ufs_version >= ufshci_version(3, 0));
+	return false;
 }
 
 static inline int ufshcd_vops_clk_scale_notify(struct ufs_hba *hba,

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 19/21] ufs: Request sense data asynchronously
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (17 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 18/21] ufs: Use the doorbell register instead of the UTRLCNR register Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-01 21:12 ` [PATCH 20/21] ufs: Synchronize SCSI and UFS error handling Bart Van Assche
  2021-07-01 21:12 ` [PATCH 21/21] ufs: Retry aborted SCSI commands instead of completing these successfully Bart Van Assche
  20 siblings, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Adrian Hunter,
	Stanley Chu, Can Guo, Asutosh Das, Avri Altman,
	James E.J. Bottomley, Matthias Brugger, Bean Huo

Clearing a unit attention synchronously from inside the UFS error handler
may trigger the following deadlock:
- ufshcd_err_handler() calls ufshcd_err_handling_unprepare() and the latter
  function calls ufshcd_clear_ua_wluns().
- ufshcd_clear_ua_wluns() submits a REQUEST SENSE command and that command
  activates the SCSI error handler.
- The SCSI error handler calls ufshcd_host_reset_and_restore().
- ufshcd_host_reset_and_restore() executes the following code:
  ufshcd_schedule_eh_work(hba);
  flush_work(&hba->eh_work);

This sequence results in a deadlock (circular wait). Fix this by requesting
sense data asynchronously.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Stanley Chu <stanley.chu@mediatek.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Asutosh Das <asutoshd@codeaurora.org>
Cc: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 64 ++++++++++++++++++++-------------------
 1 file changed, 33 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 250d46ab3584..a74862813140 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -7815,8 +7815,39 @@ static int ufshcd_add_lus(struct ufs_hba *hba)
 	return ret;
 }
 
+static void ufshcd_request_sense_done(struct request *rq, blk_status_t error)
+{
+	if (error != BLK_STS_OK)
+		pr_err("%s: REQUEST SENSE failed (%d)", __func__, error);
+	blk_put_request(rq);
+}
+
 static int
-ufshcd_send_request_sense(struct ufs_hba *hba, struct scsi_device *sdp);
+ufshcd_request_sense_async(struct ufs_hba *hba, struct scsi_device *sdev)
+{
+	/*
+	 * From SPC-6: the REQUEST SENSE command with any allocation length
+	 * clears the sense data.
+	 */
+	static const u8 cmd[6] = {REQUEST_SENSE, 0, 0, 0, 0, 0};
+	struct scsi_request *rq;
+	struct request *req;
+
+	req = blk_get_request(sdev->request_queue, REQ_OP_SCSI_IN, /*flags=*/0);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	rq = scsi_req(req);
+	rq->cmd_len = ARRAY_SIZE(cmd);
+	memcpy(rq->cmd, cmd, rq->cmd_len);
+	rq->retries = 3;
+	req->timeout = 1 * HZ;
+	req->rq_flags |= RQF_PM | RQF_QUIET;
+
+	blk_execute_rq_nowait(/*bd_disk=*/NULL, req, /*at_head=*/true,
+			      ufshcd_request_sense_done);
+	return 0;
+}
 
 static int ufshcd_clear_ua_wlun(struct ufs_hba *hba, u8 wlun)
 {
@@ -7844,7 +7875,7 @@ static int ufshcd_clear_ua_wlun(struct ufs_hba *hba, u8 wlun)
 	if (ret)
 		goto out_err;
 
-	ret = ufshcd_send_request_sense(hba, sdp);
+	ret = ufshcd_request_sense_async(hba, sdp);
 	scsi_device_put(sdp);
 out_err:
 	if (ret)
@@ -8439,35 +8470,6 @@ static void ufshcd_hba_exit(struct ufs_hba *hba)
 	}
 }
 
-static int
-ufshcd_send_request_sense(struct ufs_hba *hba, struct scsi_device *sdp)
-{
-	unsigned char cmd[6] = {REQUEST_SENSE,
-				0,
-				0,
-				0,
-				UFS_SENSE_SIZE,
-				0};
-	char *buffer;
-	int ret;
-
-	buffer = kzalloc(UFS_SENSE_SIZE, GFP_KERNEL);
-	if (!buffer) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	ret = scsi_execute(sdp, cmd, DMA_FROM_DEVICE, buffer,
-			UFS_SENSE_SIZE, NULL, NULL,
-			msecs_to_jiffies(1000), 3, 0, RQF_PM, NULL);
-	if (ret)
-		pr_err("%s: failed with err %d\n", __func__, ret);
-
-	kfree(buffer);
-out:
-	return ret;
-}
-
 /**
  * ufshcd_set_dev_pwr_mode - sends START STOP UNIT command to set device
  *			     power mode

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 20/21] ufs: Synchronize SCSI and UFS error handling
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (18 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 19/21] ufs: Request sense data asynchronously Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  2021-07-01 21:12 ` [PATCH 21/21] ufs: Retry aborted SCSI commands instead of completing these successfully Bart Van Assche
  20 siblings, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Adrian Hunter,
	Stanley Chu, Can Guo, Asutosh Das, Avri Altman,
	James E.J. Bottomley, Matthias Brugger, Bean Huo

Use the SCSI error handler instead of a custom error handling strategy.
This change reduces the number of potential races in the UFS drivers since
the UFS error handler and the SCSI error handler no longer run concurrently.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Stanley Chu <stanley.chu@mediatek.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Asutosh Das <asutoshd@codeaurora.org>
Cc: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 101 ++++++++++++++++++++------------------
 drivers/scsi/ufs/ufshcd.h |   4 --
 2 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index a74862813140..cfb2d00c325c 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -17,6 +17,8 @@
 #include <linux/blk-pm.h>
 #include <linux/blkdev.h>
 #include <scsi/scsi_driver.h>
+#include <scsi/scsi_transport.h>
+#include "../scsi_transport_api.h"
 #include "ufshcd.h"
 #include "ufs_quirks.h"
 #include "unipro.h"
@@ -233,7 +235,6 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up);
 static irqreturn_t ufshcd_intr(int irq, void *__hba);
 static int ufshcd_change_power_mode(struct ufs_hba *hba,
 			     struct ufs_pa_layer_attr *pwr_mode);
-static void ufshcd_schedule_eh_work(struct ufs_hba *hba);
 static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on);
 static int ufshcd_setup_vreg(struct ufs_hba *hba, bool on);
 static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba,
@@ -3897,6 +3898,35 @@ int ufshcd_dme_get_attr(struct ufs_hba *hba, u32 attr_sel,
 }
 EXPORT_SYMBOL_GPL(ufshcd_dme_get_attr);
 
+static inline bool ufshcd_is_saved_err_fatal(struct ufs_hba *hba)
+{
+	lockdep_assert_held(hba->host->host_lock);
+
+	return (hba->saved_uic_err & UFSHCD_UIC_DL_PA_INIT_ERROR) ||
+	       (hba->saved_err & (INT_FATAL_ERRORS | UFSHCD_UIC_HIBERN8_MASK));
+}
+
+static void ufshcd_schedule_eh(struct ufs_hba *hba)
+{
+	bool schedule_eh = false;
+	unsigned long flags;
+
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	/* handle fatal errors only when link is not in error state */
+	if (hba->ufshcd_state != UFSHCD_STATE_ERROR) {
+		if (hba->force_reset || ufshcd_is_link_broken(hba) ||
+		    ufshcd_is_saved_err_fatal(hba))
+			hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED_FATAL;
+		else
+			hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED_NON_FATAL;
+		schedule_eh = true;
+	}
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+	if (schedule_eh)
+		scsi_schedule_eh(hba->host);
+}
+
 /**
  * ufshcd_uic_pwr_ctrl - executes UIC commands (which affects the link power
  * state) and waits for it to take effect.
@@ -3917,6 +3947,7 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd)
 {
 	DECLARE_COMPLETION_ONSTACK(uic_async_done);
 	unsigned long flags;
+	bool schedule_eh = false;
 	u8 status;
 	int ret;
 	bool reenable_intr = false;
@@ -3986,10 +4017,14 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd)
 		ufshcd_enable_intr(hba, UIC_COMMAND_COMPL);
 	if (ret) {
 		ufshcd_set_link_broken(hba);
-		ufshcd_schedule_eh_work(hba);
+		schedule_eh = true;
 	}
+
 out_unlock:
 	spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+	if (schedule_eh)
+		ufshcd_schedule_eh(hba);
 	mutex_unlock(&hba->uic_cmd_mutex);
 
 	return ret;
@@ -5804,27 +5839,6 @@ static bool ufshcd_quirk_dl_nac_errors(struct ufs_hba *hba)
 	return err_handling;
 }
 
-/* host lock must be held before calling this func */
-static inline bool ufshcd_is_saved_err_fatal(struct ufs_hba *hba)
-{
-	return (hba->saved_uic_err & UFSHCD_UIC_DL_PA_INIT_ERROR) ||
-	       (hba->saved_err & (INT_FATAL_ERRORS | UFSHCD_UIC_HIBERN8_MASK));
-}
-
-/* host lock must be held before calling this func */
-static inline void ufshcd_schedule_eh_work(struct ufs_hba *hba)
-{
-	/* handle fatal errors only when link is not in error state */
-	if (hba->ufshcd_state != UFSHCD_STATE_ERROR) {
-		if (hba->force_reset || ufshcd_is_link_broken(hba) ||
-		    ufshcd_is_saved_err_fatal(hba))
-			hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED_FATAL;
-		else
-			hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED_NON_FATAL;
-		queue_work(hba->eh_wq, &hba->eh_work);
-	}
-}
-
 static void ufshcd_clk_scaling_allow(struct ufs_hba *hba, bool allow)
 {
 	down_write(&hba->clk_scaling_lock);
@@ -5958,11 +5972,11 @@ static bool ufshcd_is_pwr_mode_restore_needed(struct ufs_hba *hba)
 
 /**
  * ufshcd_err_handler - handle UFS errors that require s/w attention
- * @work: pointer to work structure
+ * @host: SCSI host pointer
  */
-static void ufshcd_err_handler(struct work_struct *work)
+static void ufshcd_err_handler(struct Scsi_Host *host)
 {
-	struct ufs_hba *hba;
+	struct ufs_hba *hba = shost_priv(host);
 	unsigned long flags;
 	bool err_xfer = false;
 	bool err_tm = false;
@@ -5970,8 +5984,6 @@ static void ufshcd_err_handler(struct work_struct *work)
 	int tag;
 	bool needs_reset = false, needs_restore = false;
 
-	hba = container_of(work, struct ufs_hba, eh_work);
-
 	down(&hba->host_sem);
 	spin_lock_irqsave(hba->host->host_lock, flags);
 	if (ufshcd_err_handling_should_stop(hba)) {
@@ -6287,7 +6299,6 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status)
 					 "host_regs: ");
 			ufshcd_print_pwr_info(hba);
 		}
-		ufshcd_schedule_eh_work(hba);
 		retval |= IRQ_HANDLED;
 	}
 	/*
@@ -6299,6 +6310,10 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status)
 	hba->errors = 0;
 	hba->uic_error = 0;
 	spin_unlock(hba->host->host_lock);
+
+	if (queue_eh_work)
+		ufshcd_schedule_eh(hba);
+
 	return retval;
 }
 
@@ -6958,15 +6973,17 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
 	 * will be to send LU reset which, again, is a spec violation.
 	 * To avoid these unnecessary/illegal steps, first we clean up
 	 * the lrb taken by this cmd and re-set it in outstanding_reqs,
-	 * then queue the eh_work and bail.
+	 * then queue the error handler and bail.
 	 */
 	if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) {
 		ufshcd_update_evt_hist(hba, UFS_EVT_ABORT, lrbp->lun);
 
 		spin_lock_irqsave(host->host_lock, flags);
 		hba->force_reset = true;
-		ufshcd_schedule_eh_work(hba);
 		spin_unlock_irqrestore(host->host_lock, flags);
+
+		ufshcd_schedule_eh(hba);
+
 		goto release;
 	}
 
@@ -7094,11 +7111,10 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd)
 
 	spin_lock_irqsave(hba->host->host_lock, flags);
 	hba->force_reset = true;
-	ufshcd_schedule_eh_work(hba);
 	dev_err(hba->dev, "%s: reset in progress - 1\n", __func__);
 	spin_unlock_irqrestore(hba->host->host_lock, flags);
 
-	flush_work(&hba->eh_work);
+	ufshcd_err_handler(hba->host);
 
 	spin_lock_irqsave(hba->host->host_lock, flags);
 	if (hba->ufshcd_state == UFSHCD_STATE_ERROR)
@@ -8458,8 +8474,6 @@ static void ufshcd_hba_exit(struct ufs_hba *hba)
 	if (hba->is_powered) {
 		ufshcd_exit_clk_scaling(hba);
 		ufshcd_exit_clk_gating(hba);
-		if (hba->eh_wq)
-			destroy_workqueue(hba->eh_wq);
 		ufs_debugfs_hba_exit(hba);
 		ufshcd_variant_hba_exit(hba);
 		ufshcd_setup_vreg(hba, false);
@@ -9298,6 +9312,10 @@ static int ufshcd_set_dma_mask(struct ufs_hba *hba)
 	return dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(32));
 }
 
+static struct scsi_transport_template ufshcd_transport_template = {
+	.eh_strategy_handler = ufshcd_err_handler,
+};
+
 /**
  * ufshcd_alloc_host - allocate Host Bus Adapter (HBA)
  * @dev: pointer to device handle
@@ -9324,6 +9342,7 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle)
 		err = -ENOMEM;
 		goto out_error;
 	}
+	host->transportt = &ufshcd_transport_template;
 	hba = shost_priv(host);
 	hba->host = host;
 	hba->dev = dev;
@@ -9361,7 +9380,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
 	int err;
 	struct Scsi_Host *host = hba->host;
 	struct device *dev = hba->dev;
-	char eh_wq_name[sizeof("ufs_eh_wq_00")];
 
 	if (!mmio_base) {
 		dev_err(hba->dev,
@@ -9415,17 +9433,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
 
 	hba->max_pwr_info.is_valid = false;
 
-	/* Initialize work queues */
-	snprintf(eh_wq_name, sizeof(eh_wq_name), "ufs_eh_wq_%d",
-		 hba->host->host_no);
-	hba->eh_wq = create_singlethread_workqueue(eh_wq_name);
-	if (!hba->eh_wq) {
-		dev_err(hba->dev, "%s: failed to create eh workqueue\n",
-				__func__);
-		err = -ENOMEM;
-		goto out_disable;
-	}
-	INIT_WORK(&hba->eh_work, ufshcd_err_handler);
 	INIT_WORK(&hba->eeh_work, ufshcd_exception_event_handler);
 
 	sema_init(&hba->host_sem, 1);
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index b3d9b487846f..b821851a62eb 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -715,8 +715,6 @@ struct ufs_hba_monitor {
  * @is_powered: flag to check if HBA is powered
  * @shutting_down: flag to check if shutdown has been invoked
  * @host_sem: semaphore used to serialize concurrent contexts
- * @eh_wq: Workqueue that eh_work works on
- * @eh_work: Worker to handle UFS errors that require s/w attention
  * @eeh_work: Worker to handle exception events
  * @errors: HBA errors
  * @uic_error: UFS interconnect layer error status
@@ -818,8 +816,6 @@ struct ufs_hba {
 	struct semaphore host_sem;
 
 	/* Work Queues */
-	struct workqueue_struct *eh_wq;
-	struct work_struct eh_work;
 	struct work_struct eeh_work;
 
 	/* HBA Errors */

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH 21/21] ufs: Retry aborted SCSI commands instead of completing these successfully
  2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
                   ` (19 preceding siblings ...)
  2021-07-01 21:12 ` [PATCH 20/21] ufs: Synchronize SCSI and UFS error handling Bart Van Assche
@ 2021-07-01 21:12 ` Bart Van Assche
  20 siblings, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 21:12 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Bart Van Assche, Adrian Hunter,
	Stanley Chu, Can Guo, Asutosh Das, Avri Altman,
	James E.J. Bottomley, Matthias Brugger, Bean Huo

Neither SAM nor the UFS standard require that the UFS controller fills in
the completion status of commands that have been aborted (LUN RESET aborts
pending commands). Hence do not rely on the completion status provided by
the UFS controller for aborted commands but instead ask the SCSI core to
retry SCSI commands that have been aborted.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Stanley Chu <stanley.chu@mediatek.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Asutosh Das <asutoshd@codeaurora.org>
Cc: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 38 ++++++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index cfb2d00c325c..72dea37c9f17 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -5198,10 +5198,12 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status)
 /**
  * ufshcd_transfer_req_compl - handle SCSI and query command completion
  * @hba: per adapter instance
- * @completed_reqs: requests to complete
+ * @completed_reqs: bitmask that indicates which requests to complete
+ * @retry_requests: whether to ask the SCSI core to retry completed requests
  */
 static void ufshcd_transfer_req_compl(struct ufs_hba *hba,
-				      unsigned long completed_reqs)
+				      unsigned long completed_reqs,
+				      bool retry_requests)
 {
 	struct ufshcd_lrb *lrbp;
 	struct scsi_cmnd *cmd;
@@ -5217,7 +5219,8 @@ static void ufshcd_transfer_req_compl(struct ufs_hba *hba,
 			if (unlikely(ufshcd_should_inform_monitor(hba, lrbp)))
 				ufshcd_update_monitor(hba, lrbp);
 			ufshcd_add_command_trace(hba, index, UFS_CMD_COMP);
-			result = ufshcd_transfer_rsp_status(hba, lrbp);
+			result = retry_requests ? DID_BUS_BUSY << 16 :
+				ufshcd_transfer_rsp_status(hba, lrbp);
 			scsi_dma_unmap(cmd);
 			cmd->result = result;
 			/* Mark completed command as NULL in LRB */
@@ -5243,13 +5246,15 @@ static void ufshcd_transfer_req_compl(struct ufs_hba *hba,
 /**
  * ufshcd_trc_handler - handle transfer requests completion
  * @hba: per adapter instance
+ * @retry_requests: whether or not to ask to retry requests
  * @use_utrlcnr: get completed requests from UTRLCNR
  *
  * Returns
  *  IRQ_HANDLED - If interrupt is valid
  *  IRQ_NONE    - If invalid interrupt
  */
-static irqreturn_t ufshcd_trc_handler(struct ufs_hba *hba, bool use_utrlcnr)
+static irqreturn_t ufshcd_trc_handler(struct ufs_hba *hba, bool retry_requests,
+				      bool use_utrlcnr)
 {
 	unsigned long completed_reqs = 0;
 	unsigned long flags;
@@ -5285,7 +5290,7 @@ static irqreturn_t ufshcd_trc_handler(struct ufs_hba *hba, bool use_utrlcnr)
 	spin_unlock_irqrestore(hba->host->host_lock, flags);
 
 	if (completed_reqs) {
-		ufshcd_transfer_req_compl(hba, completed_reqs);
+		ufshcd_transfer_req_compl(hba, completed_reqs, retry_requests);
 		return IRQ_HANDLED;
 	} else {
 		return IRQ_NONE;
@@ -5764,7 +5769,14 @@ static void ufshcd_exception_event_handler(struct work_struct *work)
 /* Complete requests that have door-bell cleared */
 static void ufshcd_complete_requests(struct ufs_hba *hba)
 {
-	ufshcd_trc_handler(hba, false);
+	ufshcd_trc_handler(hba, /*retry_requests=*/false,
+			   /*use_utrlcnr=*/false);
+	ufshcd_tmc_handler(hba);
+}
+
+static void ufshcd_retry_aborted_requests(struct ufs_hba *hba)
+{
+	ufshcd_trc_handler(hba, /*retry_requests=*/true, /*use_utrlcnr=*/false);
 	ufshcd_tmc_handler(hba);
 }
 
@@ -6083,8 +6095,7 @@ static void ufshcd_err_handler(struct Scsi_Host *host)
 	}
 
 lock_skip_pending_xfer_clear:
-	/* Complete the requests that are cleared by s/w */
-	ufshcd_complete_requests(hba);
+	ufshcd_retry_aborted_requests(hba);
 
 	spin_lock_irqsave(hba->host->host_lock, flags);
 	hba->silence_err_logs = false;
@@ -6385,7 +6396,8 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status)
 		retval |= ufshcd_tmc_handler(hba);
 
 	if (intr_status & UTP_TRANSFER_REQ_COMPL)
-		retval |= ufshcd_trc_handler(hba, ufshcd_use_utrlcnr(hba));
+		retval |= ufshcd_trc_handler(hba, /*retry_requests=*/false,
+					     ufshcd_use_utrlcnr(hba));
 
 	return retval;
 }
@@ -6803,7 +6815,8 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd)
 			err = ufshcd_clear_cmd(hba, pos);
 			if (err)
 				break;
-			ufshcd_transfer_req_compl(hba, pos);
+			ufshcd_transfer_req_compl(hba, pos,
+						  /*retry_requests=*/true);
 		}
 	}
 
@@ -6963,7 +6976,8 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
 		dev_err(hba->dev,
 		"%s: cmd was completed, but without a notifying intr, tag = %d",
 		__func__, tag);
-		ufshcd_transfer_req_compl(hba, 1UL << tag);
+		ufshcd_transfer_req_compl(hba, 1UL << tag,
+					  /*retry_requests=*/false);
 		goto release;
 	}
 
@@ -7026,7 +7040,7 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba)
 	 */
 	ufshcd_hba_stop(hba);
 	hba->silence_err_logs = true;
-	ufshcd_complete_requests(hba);
+	ufshcd_retry_aborted_requests(hba);
 	hba->silence_err_logs = false;
 
 	/* scale up clocks to max frequency before full reinitialization */

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH 13/21] ufs: Remove several wmb() calls
  2021-07-01 21:12 ` [PATCH 13/21] ufs: Remove several wmb() calls Bart Van Assche
@ 2021-07-01 22:26   ` Asutosh Das (asd)
  2021-07-01 22:52     ` Bart Van Assche
  0 siblings, 1 reply; 39+ messages in thread
From: Asutosh Das (asd) @ 2021-07-01 22:26 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Adrian Hunter, Stanley Chu, Can Guo,
	Avri Altman, James E.J. Bottomley, Matthias Brugger, Bean Huo

On 7/1/2021 2:12 PM, Bart Van Assche wrote:
>  From arch/arm/include/asm/io.h
> 
>    #define __iowmb() wmb()
>    [ ... ]
>    #define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); })
> 
>  From Documentation/memory-barriers.txt: "Note that, when using writel(), a
> prior wmb() is not needed to guarantee that the cache coherent memory
> writes have completed before writing to the MMIO region."
> 
> In other words, calling wmb() before writel() is not necessary. Hence
> remove the wmb() calls that precede a writel() call. Remove the wmb()
> calls that precede a ufshcd_send_command() call since the latter function
> uses writel(). Remove the wmb() call from ufshcd_wait_for_dev_cmd()
> since the following chain of events guarantees that the CPU will see
> up-to-date LRB values:
> * UFS controller writes to host memory.
> * UFS controller posts completion interrupt after the memory writes from
>    the previous step are visible to the CPU.
> * complete(hba->dev_cmd.complete) is called from the UFS interrupt handler.
> * The wait_for_completion(hba->dev_cmd.complete) call in
>    ufshcd_wait_for_dev_cmd() returns.
> 
> Cc: Adrian Hunter <adrian.hunter@intel.com>
> Cc: Stanley Chu <stanley.chu@mediatek.com>
> Cc: Can Guo <cang@codeaurora.org>
> Cc: Asutosh Das <asutoshd@codeaurora.org>
> Cc: Avri Altman <avri.altman@wdc.com>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> ---
>   drivers/scsi/ufs/ufshcd.c | 11 -----------
>   1 file changed, 11 deletions(-)
> 

Hi Bart,
Did you verify this change? I think we've seen OCS errors which were 
fixed with the wmb() in queuecommand.

> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index 7091798e6245..25ab603acad1 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -2768,8 +2768,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
>   		ufshcd_release(hba);
>   		goto out;
>   	}
> -	/* Make sure descriptors are ready before ringing the doorbell */
> -	wmb();
>   
>   	ufshcd_send_command(hba, tag);
>   out:
> @@ -2879,8 +2877,6 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
>   	time_left = wait_for_completion_timeout(hba->dev_cmd.complete,
>   			msecs_to_jiffies(max_timeout));
>   
> -	/* Make sure descriptors are ready before ringing the doorbell */
> -	wmb();
>   	spin_lock_irqsave(hba->host->host_lock, flags);
>   	hba->dev_cmd.complete = NULL;
>   	if (likely(time_left)) {
> @@ -2955,8 +2951,6 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
>   	hba->dev_cmd.complete = &wait;
>   
>   	ufshcd_add_query_upiu_trace(hba, UFS_QUERY_SEND, lrbp->ucd_req_ptr);
> -	/* Make sure descriptors are ready before ringing the doorbell */
> -	wmb();
>   
>   	ufshcd_send_command(hba, tag);
>   	err = ufshcd_wait_for_dev_cmd(hba, lrbp, timeout);
> @@ -6514,9 +6508,6 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
>   	/* send command to the controller */
>   	__set_bit(task_tag, &hba->outstanding_tasks);
>   
> -	/* Make sure descriptors are ready before ringing the task doorbell */
> -	wmb();
> -
>   	ufshcd_writel(hba, 1 << task_tag, REG_UTP_TASK_REQ_DOOR_BELL);
>   	/* Make sure that doorbell is committed immediately */
>   	wmb();
> @@ -6687,8 +6678,6 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba,
>   	hba->dev_cmd.complete = &wait;
>   
>   	ufshcd_add_query_upiu_trace(hba, UFS_QUERY_SEND, lrbp->ucd_req_ptr);
> -	/* Make sure descriptors are ready before ringing the doorbell */
> -	wmb();
>   
>   	ufshcd_send_command(hba, tag);
>   	/*
> 


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH 13/21] ufs: Remove several wmb() calls
  2021-07-01 22:26   ` Asutosh Das (asd)
@ 2021-07-01 22:52     ` Bart Van Assche
  0 siblings, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-01 22:52 UTC (permalink / raw)
  To: Asutosh Das (asd), Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Adrian Hunter, Stanley Chu, Can Guo,
	Avri Altman, James E.J. Bottomley, Matthias Brugger, Bean Huo

On 7/1/21 3:26 PM, Asutosh Das (asd) wrote:
> Did you verify this change? I think we've seen OCS errors which were
> fixed with the wmb() in queuecommand.

Hi Asutosh,

Thanks for having taken a look. This patch has been verified against an
Exynos UFS controller.

Bart.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH 02/21] libsas: Only abort commands from inside the error handler
  2021-07-01 21:12 ` [PATCH 02/21] libsas: Only abort commands from inside the error handler Bart Van Assche
@ 2021-07-03  2:32   ` Jason Yan
  2021-07-04 23:52     ` Bart Van Assche
  2021-07-05  7:16     ` Hannes Reinecke
  0 siblings, 2 replies; 39+ messages in thread
From: Jason Yan @ 2021-07-03  2:32 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Hannes Reinecke, Christoph Hellwig,
	Ming Lei, John Garry, Yves-Alexis Perez, James E.J. Bottomley,
	Gustavo A. R. Silva, Yufen Yu

Hi Bart,

在 2021/7/2 5:12, Bart Van Assche 写道:
> According to the information I found in patch commit descriptions, for SATA
> devices commands must be aborted from inside the libsas error handler.
> Check host->ehandler to determine whether or not running inside the error
> handler since host->host_eh_scheduled != 0 indicates that the SCSI error
> handler has been scheduled but does not mean that is already running. This
> patch restores code that was removed by commit 909657615d9b ("scsi: libsas:
> allow async aborts").
> 
> Cc: Hannes Reinecke <hare@suse.de>
> Cc: Christoph Hellwig <hch@lst.de>
> Cc: Ming Lei <ming.lei@redhat.com>
> Cc: John Garry <john.garry@huawei.com>
> Cc: Yves-Alexis Perez <corsac@debian.org>
> Fixes: c9f926000fe3 ("scsi: libsas: Disable asynchronous aborts for SATA devices")
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> ---
>   drivers/scsi/libsas/sas_scsi_host.c | 5 ++++-
>   include/scsi/libsas.h               | 1 +
>   2 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
> index ee44a0d7730b..95e4d58ab9d4 100644
> --- a/drivers/scsi/libsas/sas_scsi_host.c
> +++ b/drivers/scsi/libsas/sas_scsi_host.c
> @@ -462,6 +462,7 @@ int sas_eh_abort_handler(struct scsi_cmnd *cmd)
>   	int res = TMF_RESP_FUNC_FAILED;
>   	struct sas_task *task = TO_SAS_TASK(cmd);
>   	struct Scsi_Host *host = cmd->device->host;
> +	struct sas_ha_struct *ha = SHOST_TO_SAS_HA(host);
>   	struct domain_device *dev = cmd_to_domain_dev(cmd);
>   	struct sas_internal *i = to_sas_internal(host->transportt);
>   	unsigned long flags;
> @@ -471,7 +472,7 @@ int sas_eh_abort_handler(struct scsi_cmnd *cmd)
>   
>   	spin_lock_irqsave(host->host_lock, flags);
>   	/* We cannot do async aborts for SATA devices */
> -	if (dev_is_sata(dev) && !host->host_eh_scheduled) {
> +	if (dev_is_sata(dev) && !ha->eh_running) {
>   		spin_unlock_irqrestore(host->host_lock, flags);
>   		return FAILED;
>   	}


No idea why sas_eh_abort_handler() is only used by isci. The other
libsas drivers just let the error handler do the aborting work. So my
question is can the isci driver delete this callback and let the error
handler do this? If so, then we cann remove this function directly.

Thanks,
Jason


> @@ -731,6 +732,7 @@ void sas_scsi_recover_host(struct Scsi_Host *shost)
>   	tries++;
>   	retry = true;
>   	spin_lock_irq(shost->host_lock);
> +	ha->eh_running = true;
>   	list_splice_init(&shost->eh_cmd_q, &eh_work_q);
>   	spin_unlock_irq(shost->host_lock);
>   
> @@ -767,6 +769,7 @@ void sas_scsi_recover_host(struct Scsi_Host *shost)
>   
>   	/* check if any new eh work was scheduled during the last run */
>   	spin_lock_irq(&ha->lock);
> +	ha->eh_running = false;
>   	if (ha->eh_active == 0) {
>   		shost->host_eh_scheduled = 0;
>   		retry = false;
> diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
> index 6fe125a71b60..4a8fb324140e 100644
> --- a/include/scsi/libsas.h
> +++ b/include/scsi/libsas.h
> @@ -364,6 +364,7 @@ struct sas_ha_struct {
>   	struct mutex	  drain_mutex;
>   	unsigned long	  state;
>   	spinlock_t	  lock;
> +	bool		  eh_running;
>   	int		  eh_active;
>   	wait_queue_head_t eh_wait_q;
>   	struct list_head  eh_dev_q;
> .
> 

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH 02/21] libsas: Only abort commands from inside the error handler
  2021-07-03  2:32   ` Jason Yan
@ 2021-07-04 23:52     ` Bart Van Assche
  2021-07-05  7:16     ` Hannes Reinecke
  1 sibling, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-04 23:52 UTC (permalink / raw)
  To: Jason Yan, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Hannes Reinecke, Christoph Hellwig,
	Ming Lei, John Garry, Yves-Alexis Perez, James E.J. Bottomley,
	Gustavo A. R. Silva, Yufen Yu

On 7/2/21 7:32 PM, Jason Yan wrote:
> No idea why sas_eh_abort_handler() is only used by isci. The other
> libsas drivers just let the error handler do the aborting work. So my
> question is can the isci driver delete this callback and let the error
> handler do this? If so, then we cann remove this function directly.

Hmm ... I think that's a question for an isci expert. Unfortunately I'm
not familiar with the isci driver myself.

Thanks,

Bart.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* RE: [PATCH 01/21] Fix the documentation of the scsi_execute() time parameter
  2021-07-01 21:12 ` [PATCH 01/21] Fix the documentation of the scsi_execute() time parameter Bart Van Assche
@ 2021-07-05  5:51   ` Avri Altman
  0 siblings, 0 replies; 39+ messages in thread
From: Avri Altman @ 2021-07-05  5:51 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, James E.J. Bottomley, Hannes Reinecke,
	Ming Lei, John Garry

> The unit of the scsi_execute() timeout parameter is 1/HZ seconds instead of
> one second, just like the timeouts used in the block layer. Fix the
> documentation header above the definition of the scsi_execute() macro.
> 
> Cc: "James E.J. Bottomley" <jejb@linux.ibm.com>
> Cc: Hannes Reinecke <hare@suse.de>
> Cc: Ming Lei <ming.lei@redhat.com>
> Cc: John Garry <john.garry@huawei.com>
> Fixes: "[SCSI] use scatter lists for all block pc requests and simplify hw
> handlers" # v2.6.16.28
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Avri Altman <avri.altman@wdc.com>

> ---
>  drivers/scsi/scsi_lib.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index 7184f93dfe15..4b56e06faa5e 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -194,7 +194,7 @@ void scsi_queue_insert(struct scsi_cmnd *cmd, int
> reason)
>   * @bufflen:   len of buffer
>   * @sense:     optional sense buffer
>   * @sshdr:     optional decoded sense header
> - * @timeout:   request timeout in seconds
> + * @timeout:   request timeout in HZ
>   * @retries:   number of times to retry request
>   * @flags:     flags for ->cmd_flags
>   * @rq_flags:  flags for ->rq_flags

^ permalink raw reply	[flat|nested] 39+ messages in thread

* RE: [PATCH 06/21] ufs: Reduce power management code duplication
  2021-07-01 21:12 ` [PATCH 06/21] ufs: Reduce power management code duplication Bart Van Assche
@ 2021-07-05  6:18   ` Avri Altman
  0 siblings, 0 replies; 39+ messages in thread
From: Avri Altman @ 2021-07-05  6:18 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Adrian Hunter, Stanley Chu, Can Guo,
	Asutosh Das, James E.J. Bottomley, Pedro Sousa,
	Krzysztof Kozlowski, Andy Gross, Bjorn Andersson,
	Matthias Brugger, Lee Jones, Kiwoong Kim, Alim Akhtar, Bean Huo,
	Yue Hu, Sergey Shtylyov

> 
> Move the dev_get_drvdata() calls into the ufshcd_{system,runtime}_*()
> functions. Remove ufshcd_runtime_idle() since it is empty. This patch
> does not change any functionality.
> 
> Cc: Adrian Hunter <adrian.hunter@intel.com>
> Cc: Stanley Chu <stanley.chu@mediatek.com>
> Cc: Can Guo <cang@codeaurora.org>
> Cc: Asutosh Das <asutoshd@codeaurora.org>
> Cc: Avri Altman <avri.altman@wdc.com>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Avri Altman <avri.altman@wdc.com>

Thanks for this cleanup.
Avri


^ permalink raw reply	[flat|nested] 39+ messages in thread

* RE: [PATCH 07/21] ufs: Only include power management code if necessary
  2021-07-01 21:12 ` [PATCH 07/21] ufs: Only include power management code if necessary Bart Van Assche
@ 2021-07-05  6:33   ` Avri Altman
  2021-07-07 20:44     ` Bart Van Assche
  2021-07-08  5:50   ` Avri Altman
  1 sibling, 1 reply; 39+ messages in thread
From: Avri Altman @ 2021-07-05  6:33 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Adrian Hunter, Stanley Chu, Can Guo,
	Asutosh Das, James E.J. Bottomley, Matthias Brugger, Bean Huo,
	Kiwoong Kim

> 
> This patch slightly reduces the UFS driver size if built with power
> management support disabled.
> 
> Cc: Adrian Hunter <adrian.hunter@intel.com>
> Cc: Stanley Chu <stanley.chu@mediatek.com>
> Cc: Can Guo <cang@codeaurora.org>
> Cc: Asutosh Das <asutoshd@codeaurora.org>
> Cc: Avri Altman <avri.altman@wdc.com>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> ---
>  drivers/scsi/ufs/ufshcd.c | 8 ++++++++
>  drivers/scsi/ufs/ufshcd.h | 4 ++++
>  2 files changed, 12 insertions(+)
> 
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index a34aa6d486c7..37302a8b3937 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -8736,6 +8736,7 @@ static void ufshcd_vreg_set_lpm(struct ufs_hba
> *hba)
>                 usleep_range(5000, 5100);
>  }
> 
> +#ifdef CONFIG_PM
Maybe move this few lines up to include ufshcd_vreg_set_lpm as well?

Are there any ufs platforms that doesn't use pm management?
Automotive platforms maybe?

Thanks,
Avri

>  static int ufshcd_vreg_set_hpm(struct ufs_hba *hba)
>  {
>         int ret = 0;
> @@ -8763,6 +8764,7 @@ static int ufshcd_vreg_set_hpm(struct ufs_hba
> *hba)
>  out:
>         return ret;
>  }
> +#endif /* CONFIG_PM */
> 
>  static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba)
>  {
> @@ -9165,6 +9167,7 @@ static int ufshcd_suspend(struct ufs_hba *hba)
>         return ret;
>  }
> 
> +#ifdef CONFIG_PM
>  /**
>   * ufshcd_resume - helper function for resume operations
>   * @hba: per adapter instance
> @@ -9202,7 +9205,9 @@ static int ufshcd_resume(struct ufs_hba *hba)
>                 ufshcd_update_evt_hist(hba, UFS_EVT_RESUME_ERR, (u32)ret);
>         return ret;
>  }
> +#endif /* CONFIG_PM */
> 
> +#ifdef CONFIG_PM_SLEEP
>  /**
>   * ufshcd_system_suspend - system suspend callback
>   * @dev: Device associated with the UFS controller.
> @@ -9258,7 +9263,9 @@ int ufshcd_system_resume(struct device *dev)
>         return ret;
>  }
>  EXPORT_SYMBOL(ufshcd_system_resume);
> +#endif /* CONFIG_PM_SLEEP */
> 
> +#ifdef CONFIG_PM
>  /**
>   * ufshcd_runtime_suspend - runtime suspend callback
>   * @dev: Device associated with the UFS controller.
> @@ -9306,6 +9313,7 @@ int ufshcd_runtime_resume(struct device *dev)
>         return ret;
>  }
>  EXPORT_SYMBOL(ufshcd_runtime_resume);
> +#endif /* CONFIG_PM */
> 
>  /**
>   * ufshcd_shutdown - shutdown routine
> diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
> index dc75426c609f..79f6c261dfff 100644
> --- a/drivers/scsi/ufs/ufshcd.h
> +++ b/drivers/scsi/ufs/ufshcd.h
> @@ -1009,10 +1009,14 @@ static inline u8
> ufshcd_wb_get_query_index(struct ufs_hba *hba)
>         return 0;
>  }
> 
> +#ifdef CONFIG_PM
>  extern int ufshcd_runtime_suspend(struct device *dev);
>  extern int ufshcd_runtime_resume(struct device *dev);
> +#endif
> +#ifdef CONFIG_PM_SLEEP
>  extern int ufshcd_system_suspend(struct device *dev);
>  extern int ufshcd_system_resume(struct device *dev);
> +#endif
>  extern int ufshcd_shutdown(struct ufs_hba *hba);
>  extern int ufshcd_dme_configure_adapt(struct ufs_hba *hba,
>                                       int agreed_gear,

^ permalink raw reply	[flat|nested] 39+ messages in thread

* RE: [PATCH 09/21] ufs: Use DECLARE_COMPLETION_ONSTACK() where appropriate
  2021-07-01 21:12 ` [PATCH 09/21] ufs: Use DECLARE_COMPLETION_ONSTACK() where appropriate Bart Van Assche
@ 2021-07-05  6:38   ` Avri Altman
  0 siblings, 0 replies; 39+ messages in thread
From: Avri Altman @ 2021-07-05  6:38 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Adrian Hunter, Stanley Chu, Can Guo,
	Asutosh Das, James E.J. Bottomley, Matthias Brugger, Bean Huo

 
> From Documentation/scheduler/completion.rst: "When a completion is
> declared
> as a local variable within a function, then the initialization should
> always use DECLARE_COMPLETION_ONSTACK() explicitly, not just to make
> lockdep happy, but also to make it clear that limited scope had been
> considered and is intentional."
> 
> Cc: Adrian Hunter <adrian.hunter@intel.com>
> Cc: Stanley Chu <stanley.chu@mediatek.com>
> Cc: Can Guo <cang@codeaurora.org>
> Cc: Asutosh Das <asutoshd@codeaurora.org>
> Cc: Avri Altman <avri.altman@wdc.com>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Avri Altman <avri.altman@wdc.com>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* RE: [PATCH 10/21] ufs: Remove ufshcd_valid_tag()
  2021-07-01 21:12 ` [PATCH 10/21] ufs: Remove ufshcd_valid_tag() Bart Van Assche
@ 2021-07-05  6:46   ` Avri Altman
  2021-07-05 18:08     ` Bart Van Assche
  2021-07-05 19:02   ` Avri Altman
  1 sibling, 1 reply; 39+ messages in thread
From: Avri Altman @ 2021-07-05  6:46 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Alim Akhtar, James E.J. Bottomley,
	Can Guo, Stanley Chu, Bean Huo, Asutosh Das

> 
> scsi_add_host() allocates shost->can_queue tags. ufshcd_init() sets
> shost->can_queue to hba->nutrs. In other words, we know that tag values
> will be in the range [0, hba->nutrs). Hence remove the checks that
> verify that blk_get_request() returns a tag in this range. This check
> was introduced by commit 14497328b6a6 ("scsi: ufs: verify command tag
> validity").
> 
> Cc: Alim Akhtar <alim.akhtar@samsung.com>
> Cc: Avri Altman <avri.altman@wdc.com>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>

>  static int ufshcd_abort(struct scsi_cmnd *cmd)
>  {
> -       struct Scsi_Host *host;
> -       struct ufs_hba *hba;
> +       struct Scsi_Host *host = cmd->device->host;
> +       struct ufs_hba *hba = shost_priv(host);
> +       unsigned int tag = cmd->request->tag;
> +       struct ufshcd_lrb *lrbp = &hba->lrb[tag];
>         unsigned long flags;
> -       unsigned int tag;
>         int err = 0;
> -       struct ufshcd_lrb *lrbp;
>         u32 reg;
> 
> -       host = cmd->device->host;
> -       hba = shost_priv(host);
> -       tag = cmd->request->tag;
> -       lrbp = &hba->lrb[tag];
lrbp is used below ?
if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) ...

Thanks,
Avri

> -       if (!ufshcd_valid_tag(hba, tag)) {
> -               dev_err(hba->dev,
> -                       "%s: invalid command tag %d: cmd=0x%p, cmd-
> >request=0x%p",
> -                       __func__, tag, cmd, cmd->request);
> -               BUG();
> -       }
> -
>         ufshcd_hold(hba, false);
>         reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
>         /* If command is already aborted/completed, return SUCCESS */

^ permalink raw reply	[flat|nested] 39+ messages in thread

* RE: [PATCH 11/21] ufs: Verify UIC locking requirements at runtime
  2021-07-01 21:12 ` [PATCH 11/21] ufs: Verify UIC locking requirements at runtime Bart Van Assche
@ 2021-07-05  6:52   ` Avri Altman
  0 siblings, 0 replies; 39+ messages in thread
From: Avri Altman @ 2021-07-05  6:52 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Adrian Hunter, Stanley Chu, Can Guo,
	Asutosh Das, James E.J. Bottomley, Matthias Brugger, Bean Huo,
	Kiwoong Kim

> Instead of documenting the locking requirements of the UIC code as
> comments,
> use lockdep_assert_held() such that lockdep verifies the lockdep
> requirements at runtime if lockdep is enabled.
> 
> Cc: Adrian Hunter <adrian.hunter@intel.com>
> Cc: Stanley Chu <stanley.chu@mediatek.com>
> Cc: Can Guo <cang@codeaurora.org>
> Cc: Asutosh Das <asutoshd@codeaurora.org>
> Cc: Avri Altman <avri.altman@wdc.com>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Avri Altman <avri.altman@wdc.com>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* RE: [PATCH 14/21] ufs: Inline ufshcd_outstanding_req_clear()
  2021-07-01 21:12 ` [PATCH 14/21] ufs: Inline ufshcd_outstanding_req_clear() Bart Van Assche
@ 2021-07-05  7:03   ` Avri Altman
  0 siblings, 0 replies; 39+ messages in thread
From: Avri Altman @ 2021-07-05  7:03 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Adrian Hunter, Stanley Chu, Can Guo,
	Asutosh Das, James E.J. Bottomley, Matthias Brugger, Bean Huo

> 
> Inline ufshcd_outstanding_req_clear() since it only has one caller and
> since its body is only one line long.
> 
> Cc: Adrian Hunter <adrian.hunter@intel.com>
> Cc: Stanley Chu <stanley.chu@mediatek.com>
> Cc: Can Guo <cang@codeaurora.org>
> Cc: Asutosh Das <asutoshd@codeaurora.org>
> Cc: Avri Altman <avri.altman@wdc.com>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Avri Altman <avri.altman@wdc.com>


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH 02/21] libsas: Only abort commands from inside the error handler
  2021-07-03  2:32   ` Jason Yan
  2021-07-04 23:52     ` Bart Van Assche
@ 2021-07-05  7:16     ` Hannes Reinecke
  1 sibling, 0 replies; 39+ messages in thread
From: Hannes Reinecke @ 2021-07-05  7:16 UTC (permalink / raw)
  To: Jason Yan, Bart Van Assche, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Christoph Hellwig, Ming Lei, John Garry,
	Yves-Alexis Perez, James E.J. Bottomley, Gustavo A. R. Silva,
	Yufen Yu

On 7/3/21 4:32 AM, Jason Yan wrote:
> Hi Bart,
> 
> 在 2021/7/2 5:12, Bart Van Assche 写道:
>> According to the information I found in patch commit descriptions, for 
>> SATA
>> devices commands must be aborted from inside the libsas error handler.
>> Check host->ehandler to determine whether or not running inside the error
>> handler since host->host_eh_scheduled != 0 indicates that the SCSI error
>> handler has been scheduled but does not mean that is already running. 
>> This
>> patch restores code that was removed by commit 909657615d9b ("scsi: 
>> libsas:
>> allow async aborts").
>>
>> Cc: Hannes Reinecke <hare@suse.de>
>> Cc: Christoph Hellwig <hch@lst.de>
>> Cc: Ming Lei <ming.lei@redhat.com>
>> Cc: John Garry <john.garry@huawei.com>
>> Cc: Yves-Alexis Perez <corsac@debian.org>
>> Fixes: c9f926000fe3 ("scsi: libsas: Disable asynchronous aborts for 
>> SATA devices")
>> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
>> ---
>>   drivers/scsi/libsas/sas_scsi_host.c | 5 ++++-
>>   include/scsi/libsas.h               | 1 +
>>   2 files changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/scsi/libsas/sas_scsi_host.c 
>> b/drivers/scsi/libsas/sas_scsi_host.c
>> index ee44a0d7730b..95e4d58ab9d4 100644
>> --- a/drivers/scsi/libsas/sas_scsi_host.c
>> +++ b/drivers/scsi/libsas/sas_scsi_host.c
>> @@ -462,6 +462,7 @@ int sas_eh_abort_handler(struct scsi_cmnd *cmd)
>>       int res = TMF_RESP_FUNC_FAILED;
>>       struct sas_task *task = TO_SAS_TASK(cmd);
>>       struct Scsi_Host *host = cmd->device->host;
>> +    struct sas_ha_struct *ha = SHOST_TO_SAS_HA(host);
>>       struct domain_device *dev = cmd_to_domain_dev(cmd);
>>       struct sas_internal *i = to_sas_internal(host->transportt);
>>       unsigned long flags;
>> @@ -471,7 +472,7 @@ int sas_eh_abort_handler(struct scsi_cmnd *cmd)
>>       spin_lock_irqsave(host->host_lock, flags);
>>       /* We cannot do async aborts for SATA devices */
>> -    if (dev_is_sata(dev) && !host->host_eh_scheduled) {
>> +    if (dev_is_sata(dev) && !ha->eh_running) {
>>           spin_unlock_irqrestore(host->host_lock, flags);
>>           return FAILED;
>>       }
> 
> 
> No idea why sas_eh_abort_handler() is only used by isci. The other
> libsas drivers just let the error handler do the aborting work. So my
> question is can the isci driver delete this callback and let the error
> handler do this? If so, then we cann remove this function directly.
> 
That, indeed, is a good point. SATA commands are being handled by the 
sas_ata_strategy_handler (as they don't really match the SAM logic wrt TMF).
And actually there is no 'abort' command on SATA; the best you can do is 
'abort queue', but that's more like an 'ABORT TASK SET' in SAM.
So either way that callback is pointless.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke                Kernel Storage Architect
hare@suse.de                              +49 911 74053 688
SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH 10/21] ufs: Remove ufshcd_valid_tag()
  2021-07-05  6:46   ` Avri Altman
@ 2021-07-05 18:08     ` Bart Van Assche
  2021-07-05 19:01       ` Avri Altman
  0 siblings, 1 reply; 39+ messages in thread
From: Bart Van Assche @ 2021-07-05 18:08 UTC (permalink / raw)
  To: Avri Altman, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Alim Akhtar, James E.J. Bottomley,
	Can Guo, Stanley Chu, Bean Huo, Asutosh Das

On 7/4/21 11:46 PM, Avri Altman wrote:
>> scsi_add_host() allocates shost->can_queue tags. ufshcd_init() sets
>> shost->can_queue to hba->nutrs. In other words, we know that tag values
>> will be in the range [0, hba->nutrs). Hence remove the checks that
>> verify that blk_get_request() returns a tag in this range. This check
>> was introduced by commit 14497328b6a6 ("scsi: ufs: verify command tag
>> validity").
>>
>> Cc: Alim Akhtar <alim.akhtar@samsung.com>
>> Cc: Avri Altman <avri.altman@wdc.com>
>> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> 
>>  static int ufshcd_abort(struct scsi_cmnd *cmd)
>>  {
>> -       struct Scsi_Host *host;
>> -       struct ufs_hba *hba;
>> +       struct Scsi_Host *host = cmd->device->host;
>> +       struct ufs_hba *hba = shost_priv(host);
>> +       unsigned int tag = cmd->request->tag;
>> +       struct ufshcd_lrb *lrbp = &hba->lrb[tag];
>>         unsigned long flags;
>> -       unsigned int tag;
>>         int err = 0;
>> -       struct ufshcd_lrb *lrbp;
>>         u32 reg;
>>
>> -       host = cmd->device->host;
>> -       hba = shost_priv(host);
>> -       tag = cmd->request->tag;
>> -       lrbp = &hba->lrb[tag];
> lrbp is used below ?
> if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) ...

Hi Avri,

The lrbp assignment is preserved but it has been moved up to the
declaration block.

Bart.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* RE: [PATCH 10/21] ufs: Remove ufshcd_valid_tag()
  2021-07-05 18:08     ` Bart Van Assche
@ 2021-07-05 19:01       ` Avri Altman
  0 siblings, 0 replies; 39+ messages in thread
From: Avri Altman @ 2021-07-05 19:01 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Alim Akhtar, James E.J. Bottomley,
	Can Guo, Stanley Chu, Bean Huo, Asutosh Das

> 
> On 7/4/21 11:46 PM, Avri Altman wrote:
> >> scsi_add_host() allocates shost->can_queue tags. ufshcd_init() sets
> >> shost->can_queue to hba->nutrs. In other words, we know that tag values
> >> will be in the range [0, hba->nutrs). Hence remove the checks that
> >> verify that blk_get_request() returns a tag in this range. This check
> >> was introduced by commit 14497328b6a6 ("scsi: ufs: verify command tag
> >> validity").
> >>
> >> Cc: Alim Akhtar <alim.akhtar@samsung.com>
> >> Cc: Avri Altman <avri.altman@wdc.com>
> >> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> >
> >>  static int ufshcd_abort(struct scsi_cmnd *cmd)
> >>  {
> >> -       struct Scsi_Host *host;
> >> -       struct ufs_hba *hba;
> >> +       struct Scsi_Host *host = cmd->device->host;
> >> +       struct ufs_hba *hba = shost_priv(host);
> >> +       unsigned int tag = cmd->request->tag;
> >> +       struct ufshcd_lrb *lrbp = &hba->lrb[tag];
> >>         unsigned long flags;
> >> -       unsigned int tag;
> >>         int err = 0;
> >> -       struct ufshcd_lrb *lrbp;
> >>         u32 reg;
> >>
> >> -       host = cmd->device->host;
> >> -       hba = shost_priv(host);
> >> -       tag = cmd->request->tag;
> >> -       lrbp = &hba->lrb[tag];
> > lrbp is used below ?
> > if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) ...
> 
> Hi Avri,
> 
> The lrbp assignment is preserved but it has been moved up to the
> declaration block.
Missed that - sorry.

Avri

> Bart.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* RE: [PATCH 10/21] ufs: Remove ufshcd_valid_tag()
  2021-07-01 21:12 ` [PATCH 10/21] ufs: Remove ufshcd_valid_tag() Bart Van Assche
  2021-07-05  6:46   ` Avri Altman
@ 2021-07-05 19:02   ` Avri Altman
  1 sibling, 0 replies; 39+ messages in thread
From: Avri Altman @ 2021-07-05 19:02 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Alim Akhtar, James E.J. Bottomley,
	Can Guo, Stanley Chu, Bean Huo, Asutosh Das

> scsi_add_host() allocates shost->can_queue tags. ufshcd_init() sets
> shost->can_queue to hba->nutrs. In other words, we know that tag values
> will be in the range [0, hba->nutrs). Hence remove the checks that
> verify that blk_get_request() returns a tag in this range. This check
> was introduced by commit 14497328b6a6 ("scsi: ufs: verify command tag
> validity").
> 
> Cc: Alim Akhtar <alim.akhtar@samsung.com>
> Cc: Avri Altman <avri.altman@wdc.com>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Avri Altman <avri.altman@wdc.com>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH 07/21] ufs: Only include power management code if necessary
  2021-07-05  6:33   ` Avri Altman
@ 2021-07-07 20:44     ` Bart Van Assche
  0 siblings, 0 replies; 39+ messages in thread
From: Bart Van Assche @ 2021-07-07 20:44 UTC (permalink / raw)
  To: Avri Altman, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Adrian Hunter, Stanley Chu, Can Guo,
	Asutosh Das, James E.J. Bottomley, Matthias Brugger, Bean Huo,
	Kiwoong Kim

On 7/4/21 11:33 PM, Avri Altman wrote:
>> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
>> index a34aa6d486c7..37302a8b3937 100644
>> --- a/drivers/scsi/ufs/ufshcd.c
>> +++ b/drivers/scsi/ufs/ufshcd.c
>> @@ -8736,6 +8736,7 @@ static void ufshcd_vreg_set_lpm(struct ufs_hba
>> *hba)
>>                 usleep_range(5000, 5100);
>>  }
>>
>> +#ifdef CONFIG_PM
> Maybe move this few lines up to include ufshcd_vreg_set_lpm as well?

The following call chain requires that ufshcd_vreg_set_lpm() is always
available: ufshcd_shutdown() -> ufshcd_suspend() -> ufshcd_vreg_set_lpm().

> Are there any ufs platforms that doesn't use pm management?
> Automotive platforms maybe?

I'm not sure whether there is any platform on which UFS PM is disabled.
My purpose with this patch is to document which code is not used if
power management is disabled.

Bart.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* RE: [PATCH 07/21] ufs: Only include power management code if necessary
  2021-07-01 21:12 ` [PATCH 07/21] ufs: Only include power management code if necessary Bart Van Assche
  2021-07-05  6:33   ` Avri Altman
@ 2021-07-08  5:50   ` Avri Altman
  1 sibling, 0 replies; 39+ messages in thread
From: Avri Altman @ 2021-07-08  5:50 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen
  Cc: linux-scsi, Jaegeuk Kim, Adrian Hunter, Stanley Chu, Can Guo,
	Asutosh Das, James E.J. Bottomley, Matthias Brugger, Bean Huo,
	Kiwoong Kim

> 
> This patch slightly reduces the UFS driver size if built with power
> management support disabled.
> 
> Cc: Adrian Hunter <adrian.hunter@intel.com>
> Cc: Stanley Chu <stanley.chu@mediatek.com>
> Cc: Can Guo <cang@codeaurora.org>
> Cc: Asutosh Das <asutoshd@codeaurora.org>
> Cc: Avri Altman <avri.altman@wdc.com>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Avri Altman <avri.altman@wdc.com>

^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2021-07-08  5:50 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-01 21:12 [PATCH 00/21] UFS patches for kernel v5.15 Bart Van Assche
2021-07-01 21:12 ` [PATCH 01/21] Fix the documentation of the scsi_execute() time parameter Bart Van Assche
2021-07-05  5:51   ` Avri Altman
2021-07-01 21:12 ` [PATCH 02/21] libsas: Only abort commands from inside the error handler Bart Van Assche
2021-07-03  2:32   ` Jason Yan
2021-07-04 23:52     ` Bart Van Assche
2021-07-05  7:16     ` Hannes Reinecke
2021-07-01 21:12 ` [PATCH 03/21] Clear host_eh_scheduled from inside the SCSI " Bart Van Assche
2021-07-01 21:12 ` [PATCH 04/21] libsas: Stop clearing host_eh_scheduled from the " Bart Van Assche
2021-07-01 21:12 ` [PATCH 05/21] ata: Stop clearing host_eh_scheduled from error handlers Bart Van Assche
2021-07-01 21:12 ` [PATCH 06/21] ufs: Reduce power management code duplication Bart Van Assche
2021-07-05  6:18   ` Avri Altman
2021-07-01 21:12 ` [PATCH 07/21] ufs: Only include power management code if necessary Bart Van Assche
2021-07-05  6:33   ` Avri Altman
2021-07-07 20:44     ` Bart Van Assche
2021-07-08  5:50   ` Avri Altman
2021-07-01 21:12 ` [PATCH 08/21] ufs: Rename the second ufshcd_probe_hba() argument Bart Van Assche
2021-07-01 21:12 ` [PATCH 09/21] ufs: Use DECLARE_COMPLETION_ONSTACK() where appropriate Bart Van Assche
2021-07-05  6:38   ` Avri Altman
2021-07-01 21:12 ` [PATCH 10/21] ufs: Remove ufshcd_valid_tag() Bart Van Assche
2021-07-05  6:46   ` Avri Altman
2021-07-05 18:08     ` Bart Van Assche
2021-07-05 19:01       ` Avri Altman
2021-07-05 19:02   ` Avri Altman
2021-07-01 21:12 ` [PATCH 11/21] ufs: Verify UIC locking requirements at runtime Bart Van Assche
2021-07-05  6:52   ` Avri Altman
2021-07-01 21:12 ` [PATCH 12/21] ufs: Improve static type checking for the host controller state Bart Van Assche
2021-07-01 21:12 ` [PATCH 13/21] ufs: Remove several wmb() calls Bart Van Assche
2021-07-01 22:26   ` Asutosh Das (asd)
2021-07-01 22:52     ` Bart Van Assche
2021-07-01 21:12 ` [PATCH 14/21] ufs: Inline ufshcd_outstanding_req_clear() Bart Van Assche
2021-07-05  7:03   ` Avri Altman
2021-07-01 21:12 ` [PATCH 15/21] ufs: Rename __ufshcd_transfer_req_compl() Bart Van Assche
2021-07-01 21:12 ` [PATCH 16/21] ufs: Fix the SCSI abort handler Bart Van Assche
2021-07-01 21:12 ` [PATCH 17/21] ufs: Fix a race in the completion path Bart Van Assche
2021-07-01 21:12 ` [PATCH 18/21] ufs: Use the doorbell register instead of the UTRLCNR register Bart Van Assche
2021-07-01 21:12 ` [PATCH 19/21] ufs: Request sense data asynchronously Bart Van Assche
2021-07-01 21:12 ` [PATCH 20/21] ufs: Synchronize SCSI and UFS error handling Bart Van Assche
2021-07-01 21:12 ` [PATCH 21/21] ufs: Retry aborted SCSI commands instead of completing these successfully Bart Van Assche

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.