Skip to content

Commit b09d7f8

Browse files
damien-lemoalmartinkpetersen
authored andcommitted
scsi: sd: Fix system start for ATA devices
It is not always possible to keep a device in the runtime suspended state when a system level suspend/resume cycle is executed. E.g. for ATA devices connected to AHCI adapters, system resume resets the ATA ports, which causes connected devices to spin up. In such case, a runtime suspended disk will incorrectly be seen with a suspended runtime state because the device is not resumed by sd_resume_system(). The power state seen by the user is different than the actual device physical power state. Fix this issue by introducing the struct scsi_device flag force_runtime_start_on_system_start. When set, this flag causes sd_resume_system() to request a runtime resume operation for runtime suspended devices. This results in the user seeing the device runtime_state as active after a system resume, thus correctly reflecting the device physical power state. Fixes: 9131bff ("scsi: core: pm: Only runtime resume if necessary") Cc: <[email protected]> Signed-off-by: Damien Le Moal <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 6371be7 commit b09d7f8

File tree

3 files changed

+19
-1
lines changed

3 files changed

+19
-1
lines changed

drivers/ata/libata-scsi.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,9 +1055,14 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev)
10551055
* Ask the sd driver to issue START STOP UNIT on runtime suspend
10561056
* and resume and shutdown only. For system level suspend/resume,
10571057
* devices power state is handled directly by libata EH.
1058+
* Given that disks are always spun up on system resume, also
1059+
* make sure that the sd driver forces runtime suspended disks
1060+
* to be resumed to correctly reflect the power state of the
1061+
* device.
10581062
*/
10591063
sdev->manage_runtime_start_stop = 1;
10601064
sdev->manage_shutdown = 1;
1065+
sdev->force_runtime_start_on_system_start = 1;
10611066
}
10621067

10631068
/*

drivers/scsi/sd.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3949,8 +3949,15 @@ static int sd_resume(struct device *dev, bool runtime)
39493949

39503950
static int sd_resume_system(struct device *dev)
39513951
{
3952-
if (pm_runtime_suspended(dev))
3952+
if (pm_runtime_suspended(dev)) {
3953+
struct scsi_disk *sdkp = dev_get_drvdata(dev);
3954+
struct scsi_device *sdp = sdkp ? sdkp->device : NULL;
3955+
3956+
if (sdp && sdp->force_runtime_start_on_system_start)
3957+
pm_request_resume(dev);
3958+
39533959
return 0;
3960+
}
39543961

39553962
return sd_resume(dev, false);
39563963
}

include/scsi/scsi_device.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ struct scsi_device {
181181
*/
182182
unsigned manage_shutdown:1;
183183

184+
/*
185+
* If set and if the device is runtime suspended, ask the high-level
186+
* device driver (sd) to force a runtime resume of the device.
187+
*/
188+
unsigned force_runtime_start_on_system_start:1;
189+
184190
unsigned removable:1;
185191
unsigned changed:1; /* Data invalid due to media change */
186192
unsigned busy:1; /* Used to prevent races */

0 commit comments

Comments
 (0)