[SCSI] sd: implement START/STOP management
Implement SBC START/STOP management. sdev->mange_start_stop is added. When it's set to one, sd STOPs the device on suspend and shutdown and STARTs it on resume. sdev->manage_start_stop defaults is in sdev instead of scsi_disk cdev to allow ->slave_config() override the default configuration but is exported under scsi_disk sysfs node as sdev->allow_restart is. When manage_start_stop is zero (the default value), this patch doesn't introduce any behavior change. Signed-off-by: Tejun Heo <htejun@gmail.com> Rejections fixed and Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
committed by
James Bottomley
parent
3721050afc
commit
c3c94c5a2f
@@ -278,6 +278,7 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv)
|
||||
|
||||
static int scsi_bus_suspend(struct device * dev, pm_message_t state)
|
||||
{
|
||||
struct device_driver *drv = dev->driver;
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
struct scsi_host_template *sht = sdev->host->hostt;
|
||||
int err;
|
||||
@@ -286,23 +287,45 @@ static int scsi_bus_suspend(struct device * dev, pm_message_t state)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (sht->suspend)
|
||||
err = sht->suspend(sdev, state);
|
||||
/* call HLD suspend first */
|
||||
if (drv && drv->suspend) {
|
||||
err = drv->suspend(dev, state);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
/* then, call host suspend */
|
||||
if (sht->suspend) {
|
||||
err = sht->suspend(sdev, state);
|
||||
if (err) {
|
||||
if (drv && drv->resume)
|
||||
drv->resume(dev);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scsi_bus_resume(struct device * dev)
|
||||
{
|
||||
struct device_driver *drv = dev->driver;
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
struct scsi_host_template *sht = sdev->host->hostt;
|
||||
int err = 0;
|
||||
int err = 0, err2 = 0;
|
||||
|
||||
/* call host resume first */
|
||||
if (sht->resume)
|
||||
err = sht->resume(sdev);
|
||||
|
||||
/* then, call HLD resume */
|
||||
if (drv && drv->resume)
|
||||
err2 = drv->resume(dev);
|
||||
|
||||
scsi_device_resume(sdev);
|
||||
return err;
|
||||
|
||||
/* favor LLD failure */
|
||||
return err ? err : err2;;
|
||||
}
|
||||
|
||||
struct bus_type scsi_bus_type = {
|
||||
|
Reference in New Issue
Block a user