scsi: sd: try more retries of START_STOP when resuming scsi device

ANBZ: #11194

commit 26bd36add0d81ca28a7c5de6e6cc0b7a93b13241 openeuler

driver inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7BNF8
CVE: NA

----------------------------------------------------------------------

When sending START_STOP commands to resume scsi_device, it may be
interrupted by exception operations such as host reset or FLR.
Once the command of START_STOP is failed, the runtime_status of
scsi device will be error and it is difficult for user to recover it.
So try more retries to increase robustness as the process of
command SYNCHRONIZE_CACHE in function sd_sync_cache() when suspending
scsi device.

Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: xiabing <xiabing12@h-partners.com>
Signed-off-by: Slim6882 <yangjunshuo@huawei.com>
Signed-off-by: Min Li <gumi@linux.alibaba.com>
Reviewed-by: Guixin Liu <kanie@linux.alibaba.com>
Acked-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: Xunlei Pang <xlpang@linux.alibaba.com>
Link: https://gitee.com/anolis/cloud-kernel/pulls/4229
This commit is contained in:
Xiang Chen 2023-06-08 11:04:47 +08:00 committed by 小龙
parent 25e4e65426
commit d6b34441b8
1 changed files with 18 additions and 6 deletions

View File

@ -3660,6 +3660,7 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors)
{
struct scsi_disk *sdkp = dev_get_drvdata(dev);
struct scsi_sense_hdr sshdr;
int retries;
int ret = 0;
if (!sdkp) /* E.g.: runtime suspend following sd_remove() */
@ -3690,9 +3691,15 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors)
if (sdkp->device->manage_start_stop) {
sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
/* an error is not worth aborting a system sleep */
ret = sd_start_stop_device(sdkp, 0);
if (ignore_stop_errors)
ret = 0;
for (retries = 3; retries > 0; --retries) {
ret = sd_start_stop_device(sdkp, 0);
if (!ret)
break;
if (ignore_stop_errors) {
ret = 0;
break;
}
}
}
return ret;
@ -3711,6 +3718,7 @@ static int sd_suspend_runtime(struct device *dev)
static int sd_resume(struct device *dev)
{
struct scsi_disk *sdkp = dev_get_drvdata(dev);
int retries;
int ret;
if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */
@ -3720,9 +3728,13 @@ static int sd_resume(struct device *dev)
return 0;
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
ret = sd_start_stop_device(sdkp, 1);
if (!ret)
opal_unlock_from_suspend(sdkp->opal_dev);
for (retries = 3; retries > 0; --retries) {
ret = sd_start_stop_device(sdkp, 1);
if (!ret) {
opal_unlock_from_suspend(sdkp->opal_dev);
break;
}
}
return ret;
}