aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r--drivers/scsi/scsi_sysfs.c68
1 files changed, 19 insertions, 49 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index c23ab978c3ba..562fb3bce261 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -11,6 +11,7 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/blkdev.h> 12#include <linux/blkdev.h>
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/pm_runtime.h>
14 15
15#include <scsi/scsi.h> 16#include <scsi/scsi.h>
16#include <scsi/scsi_device.h> 17#include <scsi/scsi_device.h>
@@ -376,57 +377,11 @@ static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
376 return 0; 377 return 0;
377} 378}
378 379
379static int scsi_bus_suspend(struct device * dev, pm_message_t state)
380{
381 struct device_driver *drv;
382 struct scsi_device *sdev;
383 int err;
384
385 if (dev->type != &scsi_dev_type)
386 return 0;
387
388 drv = dev->driver;
389 sdev = to_scsi_device(dev);
390
391 err = scsi_device_quiesce(sdev);
392 if (err)
393 return err;
394
395 if (drv && drv->suspend) {
396 err = drv->suspend(dev, state);
397 if (err)
398 return err;
399 }
400
401 return 0;
402}
403
404static int scsi_bus_resume(struct device * dev)
405{
406 struct device_driver *drv;
407 struct scsi_device *sdev;
408 int err = 0;
409
410 if (dev->type != &scsi_dev_type)
411 return 0;
412
413 drv = dev->driver;
414 sdev = to_scsi_device(dev);
415
416 if (drv && drv->resume)
417 err = drv->resume(dev);
418
419 scsi_device_resume(sdev);
420
421 return err;
422}
423
424struct bus_type scsi_bus_type = { 380struct bus_type scsi_bus_type = {
425 .name = "scsi", 381 .name = "scsi",
426 .match = scsi_bus_match, 382 .match = scsi_bus_match,
427 .uevent = scsi_bus_uevent, 383 .uevent = scsi_bus_uevent,
428 .suspend = scsi_bus_suspend, 384 .pm = &scsi_bus_pm_ops,
429 .resume = scsi_bus_resume,
430}; 385};
431EXPORT_SYMBOL_GPL(scsi_bus_type); 386EXPORT_SYMBOL_GPL(scsi_bus_type);
432 387
@@ -848,8 +803,6 @@ static int scsi_target_add(struct scsi_target *starget)
848 if (starget->state != STARGET_CREATED) 803 if (starget->state != STARGET_CREATED)
849 return 0; 804 return 0;
850 805
851 device_enable_async_suspend(&starget->dev);
852
853 error = device_add(&starget->dev); 806 error = device_add(&starget->dev);
854 if (error) { 807 if (error) {
855 dev_err(&starget->dev, "target device_add failed, error %d\n", error); 808 dev_err(&starget->dev, "target device_add failed, error %d\n", error);
@@ -858,6 +811,10 @@ static int scsi_target_add(struct scsi_target *starget)
858 transport_add_device(&starget->dev); 811 transport_add_device(&starget->dev);
859 starget->state = STARGET_RUNNING; 812 starget->state = STARGET_RUNNING;
860 813
814 pm_runtime_set_active(&starget->dev);
815 pm_runtime_enable(&starget->dev);
816 device_enable_async_suspend(&starget->dev);
817
861 return 0; 818 return 0;
862} 819}
863 820
@@ -887,7 +844,20 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
887 return error; 844 return error;
888 845
889 transport_configure_device(&starget->dev); 846 transport_configure_device(&starget->dev);
847
890 device_enable_async_suspend(&sdev->sdev_gendev); 848 device_enable_async_suspend(&sdev->sdev_gendev);
849 scsi_autopm_get_target(starget);
850 pm_runtime_set_active(&sdev->sdev_gendev);
851 pm_runtime_forbid(&sdev->sdev_gendev);
852 pm_runtime_enable(&sdev->sdev_gendev);
853 scsi_autopm_put_target(starget);
854
855 /* The following call will keep sdev active indefinitely, until
856 * its driver does a corresponding scsi_autopm_pm_device(). Only
857 * drivers supporting autosuspend will do this.
858 */
859 scsi_autopm_get_device(sdev);
860
891 error = device_add(&sdev->sdev_gendev); 861 error = device_add(&sdev->sdev_gendev);
892 if (error) { 862 if (error) {
893 printk(KERN_INFO "error 1\n"); 863 printk(KERN_INFO "error 1\n");