Skip to content

Commit a19a93e

Browse files
bvanasschemartinkpetersen
authored andcommitted
scsi: core: pm: Rely on the device driver core for async power management
Instead of implementing asynchronous resume support in the SCSI core, rely on the device driver core for resuming SCSI devices asynchronously. Instead of only supporting asynchronous resumes, also support asynchronous suspends. Link: https://lore.kernel.org/r/20211006215453.3318929-2-bvanassche@acm.org Cc: Alan Stern <stern@rowland.harvard.edu> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Hannes Reinecke <hare@suse.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Martin Kepplinger <martin.kepplinger@puri.sm> Signed-off-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent a4bcbf7 commit a19a93e

File tree

7 files changed

+22
-54
lines changed

7 files changed

+22
-54
lines changed

drivers/scsi/hosts.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
475475
dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
476476
shost->shost_gendev.bus = &scsi_bus_type;
477477
shost->shost_gendev.type = &scsi_host_type;
478+
scsi_enable_async_suspend(&shost->shost_gendev);
478479

479480
device_initialize(&shost->shost_dev);
480481
shost->shost_dev.parent = &shost->shost_gendev;

drivers/scsi/scsi.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,6 @@ unsigned int scsi_logging_level;
8686
EXPORT_SYMBOL(scsi_logging_level);
8787
#endif
8888

89-
/*
90-
* Domain for asynchronous system resume operations. It is marked 'exclusive'
91-
* to avoid being included in the async_synchronize_full() that is invoked by
92-
* dpm_resume().
93-
*/
94-
ASYNC_DOMAIN_EXCLUSIVE(scsi_sd_pm_domain);
95-
EXPORT_SYMBOL(scsi_sd_pm_domain);
96-
9789
#ifdef CONFIG_SCSI_LOGGING
9890
void scsi_log_send(struct scsi_cmnd *cmd)
9991
{

drivers/scsi/scsi_pm.c

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@ static int scsi_dev_type_suspend(struct device *dev,
5656
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
5757
int err;
5858

59-
/* flush pending in-flight resume operations, suspend is synchronous */
60-
async_synchronize_full_domain(&scsi_sd_pm_domain);
61-
6259
err = scsi_device_quiesce(to_scsi_device(dev));
6360
if (err == 0) {
6461
err = cb(dev, pm);
@@ -123,48 +120,11 @@ scsi_bus_suspend_common(struct device *dev,
123120
return err;
124121
}
125122

126-
static void async_sdev_resume(void *dev, async_cookie_t cookie)
127-
{
128-
scsi_dev_type_resume(dev, do_scsi_resume);
129-
}
130-
131-
static void async_sdev_thaw(void *dev, async_cookie_t cookie)
132-
{
133-
scsi_dev_type_resume(dev, do_scsi_thaw);
134-
}
135-
136-
static void async_sdev_restore(void *dev, async_cookie_t cookie)
137-
{
138-
scsi_dev_type_resume(dev, do_scsi_restore);
139-
}
140-
141123
static int scsi_bus_resume_common(struct device *dev,
142124
int (*cb)(struct device *, const struct dev_pm_ops *))
143125
{
144-
async_func_t fn;
145-
146-
if (!scsi_is_sdev_device(dev))
147-
fn = NULL;
148-
else if (cb == do_scsi_resume)
149-
fn = async_sdev_resume;
150-
else if (cb == do_scsi_thaw)
151-
fn = async_sdev_thaw;
152-
else if (cb == do_scsi_restore)
153-
fn = async_sdev_restore;
154-
else
155-
fn = NULL;
156-
157-
if (fn) {
158-
async_schedule_domain(fn, dev, &scsi_sd_pm_domain);
159-
160-
/*
161-
* If a user has disabled async probing a likely reason
162-
* is due to a storage enclosure that does not inject
163-
* staggered spin-ups. For safety, make resume
164-
* synchronous as well in that case.
165-
*/
166-
if (strncmp(scsi_scan_type, "async", 5) != 0)
167-
async_synchronize_full_domain(&scsi_sd_pm_domain);
126+
if (scsi_is_sdev_device(dev)) {
127+
scsi_dev_type_resume(dev, cb);
168128
} else {
169129
pm_runtime_disable(dev);
170130
pm_runtime_set_active(dev);

drivers/scsi/scsi_priv.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ extern void scsi_exit_procfs(void);
116116
#endif /* CONFIG_PROC_FS */
117117

118118
/* scsi_scan.c */
119-
extern char scsi_scan_type[];
119+
void scsi_enable_async_suspend(struct device *dev);
120120
extern int scsi_complete_async_scans(void);
121121
extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int,
122122
unsigned int, u64, enum scsi_scan_mode);
@@ -170,8 +170,6 @@ static inline int scsi_autopm_get_host(struct Scsi_Host *h) { return 0; }
170170
static inline void scsi_autopm_put_host(struct Scsi_Host *h) {}
171171
#endif /* CONFIG_PM */
172172

173-
extern struct async_domain scsi_sd_pm_domain;
174-
175173
/* scsi_dh.c */
176174
#ifdef CONFIG_SCSI_DH
177175
void scsi_dh_add_device(struct scsi_device *sdev);

drivers/scsi/scsi_scan.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,22 @@ struct async_scan_data {
122122
struct completion prev_finished;
123123
};
124124

125+
/**
126+
* scsi_enable_async_suspend - Enable async suspend and resume
127+
*/
128+
void scsi_enable_async_suspend(struct device *dev)
129+
{
130+
/*
131+
* If a user has disabled async probing a likely reason is due to a
132+
* storage enclosure that does not inject staggered spin-ups. For
133+
* safety, make resume synchronous as well in that case.
134+
*/
135+
if (strncmp(scsi_scan_type, "async", 5) != 0)
136+
return;
137+
/* Enable asynchronous suspend and resume. */
138+
device_enable_async_suspend(dev);
139+
}
140+
125141
/**
126142
* scsi_complete_async_scans - Wait for asynchronous scans to complete
127143
*
@@ -454,6 +470,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
454470
dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id);
455471
dev->bus = &scsi_bus_type;
456472
dev->type = &scsi_target_type;
473+
scsi_enable_async_suspend(dev);
457474
starget->id = id;
458475
starget->channel = channel;
459476
starget->can_queue = 0;

drivers/scsi/scsi_sysfs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,7 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev)
16161616
device_initialize(&sdev->sdev_gendev);
16171617
sdev->sdev_gendev.bus = &scsi_bus_type;
16181618
sdev->sdev_gendev.type = &scsi_dev_type;
1619+
scsi_enable_async_suspend(&sdev->sdev_gendev);
16191620
dev_set_name(&sdev->sdev_gendev, "%d:%d:%d:%llu",
16201621
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
16211622

drivers/scsi/sd.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3504,7 +3504,6 @@ static int sd_remove(struct device *dev)
35043504
sdkp = dev_get_drvdata(dev);
35053505
scsi_autopm_get_device(sdkp->device);
35063506

3507-
async_synchronize_full_domain(&scsi_sd_pm_domain);
35083507
device_del(&sdkp->dev);
35093508
del_gendisk(sdkp->disk);
35103509
sd_shutdown(dev);

0 commit comments

Comments
 (0)