diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-16 11:48:13 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-16 11:48:13 -0700 |
commit | 6a454f71d795368c00d9c329b60cc4d58929e7bc (patch) | |
tree | f85a7ed30ba1d25606a22cc07e7383e73fc49972 /drivers/s390/char/tape_core.c | |
parent | d613839ef987d20f7c9347732b452efd921b97d9 (diff) | |
parent | 155af2f95f905c830688dd0ca7c7cac4107334fd (diff) |
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (33 commits)
[S390] s390: hibernation support for s390
[S390] pm: dcssblk power management callbacks.
[S390] pm: monreader power management callbacks.
[S390] pm: monwriter power management callbacks.
[S390] pm: memory hotplug power management callbacks
[S390] pm: con3270 power management callbacks.
[S390] pm: smsgiucv power management callbacks.
[S390] pm: hvc_iucv power management callbacks
[S390] PM: af_iucv power management callbacks.
[S390] pm: netiucv power management callbacks.
[S390] pm: iucv power management callbacks.
[S390] iucv: establish reboot notifier
[S390] pm: power management support for SCLP drivers.
[S390] pm: tape power management callbacks
[S390] pm: vmlogrdr power management callbacks
[S390] pm: vmur driver power management callbacks
[S390] pm: appldata power management callbacks
[S390] pm: vmwatchdog power management callbacks.
[S390] pm: zfcp driver power management callbacks
[S390] pm: claw driver power management callbacks
...
Diffstat (limited to 'drivers/s390/char/tape_core.c')
-rw-r--r-- | drivers/s390/char/tape_core.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 8a109f3b69c..3ebaa8eb5c8 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -3,7 +3,7 @@ * basic function of the tape device driver * * S390 and zSeries version - * Copyright IBM Corp. 2001,2006 + * Copyright IBM Corp. 2001, 2009 * Author(s): Carsten Otte <cotte@de.ibm.com> * Michael Holzheu <holzheu@de.ibm.com> * Tuan Ngo-Anh <ngoanh@de.ibm.com> @@ -380,6 +380,55 @@ tape_cleanup_device(struct tape_device *device) } /* + * Suspend device. + * + * Called by the common I/O layer if the drive should be suspended on user + * request. We refuse to suspend if the device is loaded or in use for the + * following reason: + * While the Linux guest is suspended, it might be logged off which causes + * devices to be detached. Tape devices are automatically rewound and unloaded + * during DETACH processing (unless the tape device was attached with the + * NOASSIGN or MULTIUSER option). After rewind/unload, there is no way to + * resume the original state of the tape device, since we would need to + * manually re-load the cartridge which was active at suspend time. + */ +int tape_generic_pm_suspend(struct ccw_device *cdev) +{ + struct tape_device *device; + + device = cdev->dev.driver_data; + if (!device) { + return -ENODEV; + } + + DBF_LH(3, "(%08x): tape_generic_pm_suspend(%p)\n", + device->cdev_id, device); + + if (device->medium_state != MS_UNLOADED) { + pr_err("A cartridge is loaded in tape device %s, " + "refusing to suspend\n", dev_name(&cdev->dev)); + return -EBUSY; + } + + spin_lock_irq(get_ccwdev_lock(device->cdev)); + switch (device->tape_state) { + case TS_INIT: + case TS_NOT_OPER: + case TS_UNUSED: + spin_unlock_irq(get_ccwdev_lock(device->cdev)); + break; + default: + pr_err("Tape device %s is busy, refusing to " + "suspend\n", dev_name(&cdev->dev)); + spin_unlock_irq(get_ccwdev_lock(device->cdev)); + return -EBUSY; + } + + DBF_LH(3, "(%08x): Drive suspended.\n", device->cdev_id); + return 0; +} + +/* * Set device offline. * * Called by the common I/O layer if the drive should set offline on user @@ -1273,6 +1322,7 @@ EXPORT_SYMBOL(tape_generic_remove); EXPORT_SYMBOL(tape_generic_probe); EXPORT_SYMBOL(tape_generic_online); EXPORT_SYMBOL(tape_generic_offline); +EXPORT_SYMBOL(tape_generic_pm_suspend); EXPORT_SYMBOL(tape_put_device); EXPORT_SYMBOL(tape_get_device_reference); EXPORT_SYMBOL(tape_state_verbose); |