diff options
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r-- | drivers/scsi/scsi_sysfs.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index c275dcac3f18..96db51c40ef3 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -278,6 +278,7 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv) | |||
278 | 278 | ||
279 | static int scsi_bus_suspend(struct device * dev, pm_message_t state) | 279 | static int scsi_bus_suspend(struct device * dev, pm_message_t state) |
280 | { | 280 | { |
281 | struct device_driver *drv = dev->driver; | ||
281 | struct scsi_device *sdev = to_scsi_device(dev); | 282 | struct scsi_device *sdev = to_scsi_device(dev); |
282 | struct scsi_host_template *sht = sdev->host->hostt; | 283 | struct scsi_host_template *sht = sdev->host->hostt; |
283 | int err; | 284 | int err; |
@@ -286,23 +287,45 @@ static int scsi_bus_suspend(struct device * dev, pm_message_t state) | |||
286 | if (err) | 287 | if (err) |
287 | return err; | 288 | return err; |
288 | 289 | ||
289 | if (sht->suspend) | 290 | /* call HLD suspend first */ |
291 | if (drv && drv->suspend) { | ||
292 | err = drv->suspend(dev, state); | ||
293 | if (err) | ||
294 | return err; | ||
295 | } | ||
296 | |||
297 | /* then, call host suspend */ | ||
298 | if (sht->suspend) { | ||
290 | err = sht->suspend(sdev, state); | 299 | err = sht->suspend(sdev, state); |
300 | if (err) { | ||
301 | if (drv && drv->resume) | ||
302 | drv->resume(dev); | ||
303 | return err; | ||
304 | } | ||
305 | } | ||
291 | 306 | ||
292 | return err; | 307 | return 0; |
293 | } | 308 | } |
294 | 309 | ||
295 | static int scsi_bus_resume(struct device * dev) | 310 | static int scsi_bus_resume(struct device * dev) |
296 | { | 311 | { |
312 | struct device_driver *drv = dev->driver; | ||
297 | struct scsi_device *sdev = to_scsi_device(dev); | 313 | struct scsi_device *sdev = to_scsi_device(dev); |
298 | struct scsi_host_template *sht = sdev->host->hostt; | 314 | struct scsi_host_template *sht = sdev->host->hostt; |
299 | int err = 0; | 315 | int err = 0, err2 = 0; |
300 | 316 | ||
317 | /* call host resume first */ | ||
301 | if (sht->resume) | 318 | if (sht->resume) |
302 | err = sht->resume(sdev); | 319 | err = sht->resume(sdev); |
303 | 320 | ||
321 | /* then, call HLD resume */ | ||
322 | if (drv && drv->resume) | ||
323 | err2 = drv->resume(dev); | ||
324 | |||
304 | scsi_device_resume(sdev); | 325 | scsi_device_resume(sdev); |
305 | return err; | 326 | |
327 | /* favor LLD failure */ | ||
328 | return err ? err : err2;; | ||
306 | } | 329 | } |
307 | 330 | ||
308 | struct bus_type scsi_bus_type = { | 331 | struct bus_type scsi_bus_type = { |