diff options
-rw-r--r-- | drivers/s390/char/tape.h | 3 | ||||
-rw-r--r-- | drivers/s390/char/tape_34xx.c | 3 | ||||
-rw-r--r-- | drivers/s390/char/tape_3590.c | 3 | ||||
-rw-r--r-- | drivers/s390/char/tape_core.c | 52 |
4 files changed, 57 insertions, 4 deletions
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index 5469e099597e..a26333774701 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * tape device driver for 3480/3490E/3590 tapes. | 3 | * tape device driver for 3480/3490E/3590 tapes. |
4 | * | 4 | * |
5 | * S390 and zSeries version | 5 | * S390 and zSeries version |
6 | * Copyright IBM Corp. 2001,2006 | 6 | * Copyright IBM Corp. 2001, 2009 |
7 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 7 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
8 | * Tuan Ngo-Anh <ngoanh@de.ibm.com> | 8 | * Tuan Ngo-Anh <ngoanh@de.ibm.com> |
9 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 9 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
@@ -286,6 +286,7 @@ extern void tape_state_set(struct tape_device *, enum tape_state); | |||
286 | 286 | ||
287 | extern int tape_generic_online(struct tape_device *, struct tape_discipline *); | 287 | extern int tape_generic_online(struct tape_device *, struct tape_discipline *); |
288 | extern int tape_generic_offline(struct ccw_device *); | 288 | extern int tape_generic_offline(struct ccw_device *); |
289 | extern int tape_generic_pm_suspend(struct ccw_device *); | ||
289 | 290 | ||
290 | /* Externals from tape_devmap.c */ | 291 | /* Externals from tape_devmap.c */ |
291 | extern int tape_generic_probe(struct ccw_device *); | 292 | extern int tape_generic_probe(struct ccw_device *); |
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 2d00a383a475..144d2a5e1a92 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * drivers/s390/char/tape_34xx.c | 2 | * drivers/s390/char/tape_34xx.c |
3 | * tape device discipline for 3480/3490 tapes. | 3 | * tape device discipline for 3480/3490 tapes. |
4 | * | 4 | * |
5 | * Copyright (C) IBM Corp. 2001,2006 | 5 | * Copyright IBM Corp. 2001, 2009 |
6 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 6 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
7 | * Tuan Ngo-Anh <ngoanh@de.ibm.com> | 7 | * Tuan Ngo-Anh <ngoanh@de.ibm.com> |
8 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 8 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
@@ -1302,6 +1302,7 @@ static struct ccw_driver tape_34xx_driver = { | |||
1302 | .remove = tape_generic_remove, | 1302 | .remove = tape_generic_remove, |
1303 | .set_online = tape_34xx_online, | 1303 | .set_online = tape_34xx_online, |
1304 | .set_offline = tape_generic_offline, | 1304 | .set_offline = tape_generic_offline, |
1305 | .freeze = tape_generic_pm_suspend, | ||
1305 | }; | 1306 | }; |
1306 | 1307 | ||
1307 | static int | 1308 | static int |
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index c453b2f3e9f4..23e6598bc4b5 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * drivers/s390/char/tape_3590.c | 2 | * drivers/s390/char/tape_3590.c |
3 | * tape device discipline for 3590 tapes. | 3 | * tape device discipline for 3590 tapes. |
4 | * | 4 | * |
5 | * Copyright IBM Corp. 2001,2006 | 5 | * Copyright IBM Corp. 2001, 2009 |
6 | * Author(s): Stefan Bader <shbader@de.ibm.com> | 6 | * Author(s): Stefan Bader <shbader@de.ibm.com> |
7 | * Michael Holzheu <holzheu@de.ibm.com> | 7 | * Michael Holzheu <holzheu@de.ibm.com> |
8 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 8 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
@@ -1715,6 +1715,7 @@ static struct ccw_driver tape_3590_driver = { | |||
1715 | .remove = tape_generic_remove, | 1715 | .remove = tape_generic_remove, |
1716 | .set_offline = tape_generic_offline, | 1716 | .set_offline = tape_generic_offline, |
1717 | .set_online = tape_3590_online, | 1717 | .set_online = tape_3590_online, |
1718 | .freeze = tape_generic_pm_suspend, | ||
1718 | }; | 1719 | }; |
1719 | 1720 | ||
1720 | /* | 1721 | /* |
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 8a109f3b69c6..3ebaa8eb5c86 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * basic function of the tape device driver | 3 | * basic function of the tape device driver |
4 | * | 4 | * |
5 | * S390 and zSeries version | 5 | * S390 and zSeries version |
6 | * Copyright IBM Corp. 2001,2006 | 6 | * Copyright IBM Corp. 2001, 2009 |
7 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 7 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
8 | * Michael Holzheu <holzheu@de.ibm.com> | 8 | * Michael Holzheu <holzheu@de.ibm.com> |
9 | * Tuan Ngo-Anh <ngoanh@de.ibm.com> | 9 | * Tuan Ngo-Anh <ngoanh@de.ibm.com> |
@@ -380,6 +380,55 @@ tape_cleanup_device(struct tape_device *device) | |||
380 | } | 380 | } |
381 | 381 | ||
382 | /* | 382 | /* |
383 | * Suspend device. | ||
384 | * | ||
385 | * Called by the common I/O layer if the drive should be suspended on user | ||
386 | * request. We refuse to suspend if the device is loaded or in use for the | ||
387 | * following reason: | ||
388 | * While the Linux guest is suspended, it might be logged off which causes | ||
389 | * devices to be detached. Tape devices are automatically rewound and unloaded | ||
390 | * during DETACH processing (unless the tape device was attached with the | ||
391 | * NOASSIGN or MULTIUSER option). After rewind/unload, there is no way to | ||
392 | * resume the original state of the tape device, since we would need to | ||
393 | * manually re-load the cartridge which was active at suspend time. | ||
394 | */ | ||
395 | int tape_generic_pm_suspend(struct ccw_device *cdev) | ||
396 | { | ||
397 | struct tape_device *device; | ||
398 | |||
399 | device = cdev->dev.driver_data; | ||
400 | if (!device) { | ||
401 | return -ENODEV; | ||
402 | } | ||
403 | |||
404 | DBF_LH(3, "(%08x): tape_generic_pm_suspend(%p)\n", | ||
405 | device->cdev_id, device); | ||
406 | |||
407 | if (device->medium_state != MS_UNLOADED) { | ||
408 | pr_err("A cartridge is loaded in tape device %s, " | ||
409 | "refusing to suspend\n", dev_name(&cdev->dev)); | ||
410 | return -EBUSY; | ||
411 | } | ||
412 | |||
413 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | ||
414 | switch (device->tape_state) { | ||
415 | case TS_INIT: | ||
416 | case TS_NOT_OPER: | ||
417 | case TS_UNUSED: | ||
418 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | ||
419 | break; | ||
420 | default: | ||
421 | pr_err("Tape device %s is busy, refusing to " | ||
422 | "suspend\n", dev_name(&cdev->dev)); | ||
423 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | ||
424 | return -EBUSY; | ||
425 | } | ||
426 | |||
427 | DBF_LH(3, "(%08x): Drive suspended.\n", device->cdev_id); | ||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | /* | ||
383 | * Set device offline. | 432 | * Set device offline. |
384 | * | 433 | * |
385 | * Called by the common I/O layer if the drive should set offline on user | 434 | * Called by the common I/O layer if the drive should set offline on user |
@@ -1273,6 +1322,7 @@ EXPORT_SYMBOL(tape_generic_remove); | |||
1273 | EXPORT_SYMBOL(tape_generic_probe); | 1322 | EXPORT_SYMBOL(tape_generic_probe); |
1274 | EXPORT_SYMBOL(tape_generic_online); | 1323 | EXPORT_SYMBOL(tape_generic_online); |
1275 | EXPORT_SYMBOL(tape_generic_offline); | 1324 | EXPORT_SYMBOL(tape_generic_offline); |
1325 | EXPORT_SYMBOL(tape_generic_pm_suspend); | ||
1276 | EXPORT_SYMBOL(tape_put_device); | 1326 | EXPORT_SYMBOL(tape_put_device); |
1277 | EXPORT_SYMBOL(tape_get_device_reference); | 1327 | EXPORT_SYMBOL(tape_get_device_reference); |
1278 | EXPORT_SYMBOL(tape_state_verbose); | 1328 | EXPORT_SYMBOL(tape_state_verbose); |