aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_sysfs.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-03-20 11:13:59 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-03-20 13:06:20 -0400
commitc3c94c5a2fb43a654e777f509d5032b0db8ed09f (patch)
treecbc9b0adfa0a83fc5859344d6f9911d3010a29ac /drivers/scsi/scsi_sysfs.c
parent3721050afc6cb6ddf6de0f782e2054ebcc225e9b (diff)
[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>
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r--drivers/scsi/scsi_sysfs.c31
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
279static int scsi_bus_suspend(struct device * dev, pm_message_t state) 279static 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
295static int scsi_bus_resume(struct device * dev) 310static 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
308struct bus_type scsi_bus_type = { 331struct bus_type scsi_bus_type = {