FROMGIT: scsi: ufs: Enable block layer runtime PM for well-known logical units

Block layer RPM is enabled for the genernal UFS SCSI devices when they are
probed by their driver. However block layer RPM is not enabled for UFS
well-known SCSI devices.

As UFS SCSI devices have their corresponding BSG char devices, accessing a
BSG char device via IOCTL may send requests to its corresponding SCSI
device through its request queue. If BSG IOCTL sends a request to a
well-known SCSI device when HBA is not runtime active, due to block layer
RPM not being enabled for the well-known SCSI devices, the HBA, which is at
the top of a SCSI device's parent chain, will not be resumed.

This change enables block layer RPM for the well-known SCSI devices so that
block layer can handle RPM for the well-known SCSI devices just like for
the general SCSI devices.

Reviewed-by: Avri Altman <avri.altman@wdc.com>
Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
Signed-off-by: Can Guo <cang@codeaurora.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

Bug: 152930830
Change-Id: Id5cc396a1d072eff5d55080f097c2f8d3c60b58f
(cherry picked from commit fb276f770118ac1464316231868e711e04218d53
https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git 5.7/scsi-queue)
Signed-off-by: Can Guo <cang@codeaurora.org>
This commit is contained in:
Can Guo 2020-03-25 18:09:59 -07:00 • committed by Todd Kjos
commit e2bb35c426

View file

@ -42,6 +42,7 @@
#include <linux/nls.h>
#include <linux/of.h>
#include <linux/bitfield.h>
#include <linux/blk-pm.h>
#include "ufshcd.h"
#include "ufs_quirks.h"
#include "unipro.h"
@ -6682,6 +6683,16 @@ out:
kfree(desc_buf);
}
static inline void ufshcd_blk_pm_runtime_init(struct scsi_device *sdev)
{
scsi_autopm_get_device(sdev);
blk_pm_runtime_init(sdev->request_queue, &sdev->sdev_gendev);
if (sdev->rpm_autosuspend)
pm_runtime_set_autosuspend_delay(&sdev->sdev_gendev,
RPM_AUTOSUSPEND_DELAY_MS);
scsi_autopm_put_device(sdev);
}
/**
* ufshcd_scsi_add_wlus - Adds required W-LUs
* @hba: per-adapter instance
@ -6721,6 +6732,7 @@ static int ufshcd_scsi_add_wlus(struct ufs_hba *hba)
hba->sdev_ufs_device = NULL;
goto out;
}
ufshcd_blk_pm_runtime_init(hba->sdev_ufs_device);
scsi_device_put(hba->sdev_ufs_device);
sdev_rpmb = __scsi_add_device(hba->host, 0, 0,
@ -6729,14 +6741,17 @@ static int ufshcd_scsi_add_wlus(struct ufs_hba *hba)
ret = PTR_ERR(sdev_rpmb);
goto remove_sdev_ufs_device;
}
ufshcd_blk_pm_runtime_init(sdev_rpmb);
scsi_device_put(sdev_rpmb);
sdev_boot = __scsi_add_device(hba->host, 0, 0,
ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_BOOT_WLUN), NULL);
if (IS_ERR(sdev_boot))
if (IS_ERR(sdev_boot)) {
dev_err(hba->dev, "%s: BOOT WLUN not found\n", __func__);
else
} else {
ufshcd_blk_pm_runtime_init(sdev_boot);
scsi_device_put(sdev_boot);
}
goto out;
remove_sdev_ufs_device: