diff options
-rw-r--r-- | drivers/scsi/scsi_pm.c | 16 | ||||
-rw-r--r-- | drivers/scsi/scsi_priv.h | 1 |
2 files changed, 17 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c index bf8bf79e6a1f..c4670642d023 100644 --- a/drivers/scsi/scsi_pm.c +++ b/drivers/scsi/scsi_pm.c | |||
@@ -7,6 +7,7 @@ | |||
7 | 7 | ||
8 | #include <linux/pm_runtime.h> | 8 | #include <linux/pm_runtime.h> |
9 | #include <linux/export.h> | 9 | #include <linux/export.h> |
10 | #include <linux/async.h> | ||
10 | 11 | ||
11 | #include <scsi/scsi.h> | 12 | #include <scsi/scsi.h> |
12 | #include <scsi/scsi_device.h> | 13 | #include <scsi/scsi_device.h> |
@@ -92,6 +93,19 @@ static int scsi_bus_resume_common(struct device *dev) | |||
92 | return err; | 93 | return err; |
93 | } | 94 | } |
94 | 95 | ||
96 | static int scsi_bus_prepare(struct device *dev) | ||
97 | { | ||
98 | if (scsi_is_sdev_device(dev)) { | ||
99 | /* sd probing uses async_schedule. Wait until it finishes. */ | ||
100 | async_synchronize_full(); | ||
101 | |||
102 | } else if (scsi_is_host_device(dev)) { | ||
103 | /* Wait until async scanning is finished */ | ||
104 | scsi_complete_async_scans(); | ||
105 | } | ||
106 | return 0; | ||
107 | } | ||
108 | |||
95 | static int scsi_bus_suspend(struct device *dev) | 109 | static int scsi_bus_suspend(struct device *dev) |
96 | { | 110 | { |
97 | return scsi_bus_suspend_common(dev, PMSG_SUSPEND); | 111 | return scsi_bus_suspend_common(dev, PMSG_SUSPEND); |
@@ -110,6 +124,7 @@ static int scsi_bus_poweroff(struct device *dev) | |||
110 | #else /* CONFIG_PM_SLEEP */ | 124 | #else /* CONFIG_PM_SLEEP */ |
111 | 125 | ||
112 | #define scsi_bus_resume_common NULL | 126 | #define scsi_bus_resume_common NULL |
127 | #define scsi_bus_prepare NULL | ||
113 | #define scsi_bus_suspend NULL | 128 | #define scsi_bus_suspend NULL |
114 | #define scsi_bus_freeze NULL | 129 | #define scsi_bus_freeze NULL |
115 | #define scsi_bus_poweroff NULL | 130 | #define scsi_bus_poweroff NULL |
@@ -218,6 +233,7 @@ void scsi_autopm_put_host(struct Scsi_Host *shost) | |||
218 | #endif /* CONFIG_PM_RUNTIME */ | 233 | #endif /* CONFIG_PM_RUNTIME */ |
219 | 234 | ||
220 | const struct dev_pm_ops scsi_bus_pm_ops = { | 235 | const struct dev_pm_ops scsi_bus_pm_ops = { |
236 | .prepare = scsi_bus_prepare, | ||
221 | .suspend = scsi_bus_suspend, | 237 | .suspend = scsi_bus_suspend, |
222 | .resume = scsi_bus_resume_common, | 238 | .resume = scsi_bus_resume_common, |
223 | .freeze = scsi_bus_freeze, | 239 | .freeze = scsi_bus_freeze, |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 68eadd1c67fd..be4fa6d179b1 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -109,6 +109,7 @@ extern void scsi_exit_procfs(void); | |||
109 | #endif /* CONFIG_PROC_FS */ | 109 | #endif /* CONFIG_PROC_FS */ |
110 | 110 | ||
111 | /* scsi_scan.c */ | 111 | /* scsi_scan.c */ |
112 | extern int scsi_complete_async_scans(void); | ||
112 | extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int, | 113 | extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int, |
113 | unsigned int, unsigned int, int); | 114 | unsigned int, unsigned int, int); |
114 | extern void scsi_forget_host(struct Scsi_Host *); | 115 | extern void scsi_forget_host(struct Scsi_Host *); |