aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2009-06-16 04:30:47 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-06-16 04:31:20 -0400
commit4b214a0c7720bfcfaca936047a359f8859fc8424 (patch)
tree33cbc967ffd4b7a316cada0917006bd7031ccfb2
parent6a1d96dced593bc17d7a17fdb93c99b275e71eba (diff)
[S390] pm: con3270 power management callbacks.
Introduce the power management callbacks to the 3270 driver. On suspend the current 3270 view is deactivated and for non-console 3270 device the release callback is done. This disconnects the current tty / fullscreen application from the 3270 device. On resume the current view is reactivated, on the tty you get a fresh login. If the system panics before the 3270 device has been resumed, the ccw device for the 3270 console is reactivated with ccw_device_force_console. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/char/con3270.c12
-rw-r--r--drivers/s390/char/fs3270.c16
-rw-r--r--drivers/s390/char/raw3270.c84
-rw-r--r--drivers/s390/char/raw3270.h12
4 files changed, 95 insertions, 29 deletions
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index ed5396dae58e..44d02e371c04 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/con3270.c 2 * IBM/3270 Driver - console view.
3 * IBM/3270 Driver - console view.
4 * 3 *
5 * Author(s): 4 * Author(s):
6 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 5 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
7 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Copyright IBM Corp. 2003, 2009
9 */ 8 */
10 9
11#include <linux/bootmem.h> 10#include <linux/bootmem.h>
@@ -530,6 +529,7 @@ con3270_flush(void)
530 cp = condev; 529 cp = condev;
531 if (!cp->view.dev) 530 if (!cp->view.dev)
532 return; 531 return;
532 raw3270_pm_unfreeze(&cp->view);
533 spin_lock_irqsave(&cp->view.lock, flags); 533 spin_lock_irqsave(&cp->view.lock, flags);
534 con3270_wait_write(cp); 534 con3270_wait_write(cp);
535 cp->nr_up = 0; 535 cp->nr_up = 0;
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index 40759c33477d..097d3846a828 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/fs3270.c 2 * IBM/3270 Driver - fullscreen driver.
3 * IBM/3270 Driver - fullscreen driver.
4 * 3 *
5 * Author(s): 4 * Author(s):
6 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 5 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
7 * Rewritten for 2.5/2.6 by Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Rewritten for 2.5/2.6 by Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Copyright IBM Corp. 2003, 2009
9 */ 8 */
10 9
11#include <linux/bootmem.h> 10#include <linux/bootmem.h>
@@ -399,6 +398,11 @@ fs3270_free_view(struct raw3270_view *view)
399static void 398static void
400fs3270_release(struct raw3270_view *view) 399fs3270_release(struct raw3270_view *view)
401{ 400{
401 struct fs3270 *fp;
402
403 fp = (struct fs3270 *) view;
404 if (fp->fs_pid)
405 kill_pid(fp->fs_pid, SIGHUP, 1);
402} 406}
403 407
404/* View to a 3270 device. Can be console, tty or fullscreen. */ 408/* View to a 3270 device. Can be console, tty or fullscreen. */
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 0b15cf107ec9..81c151b5f0ac 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/raw3270.c 2 * IBM/3270 Driver - core functions.
3 * IBM/3270 Driver - core functions.
4 * 3 *
5 * Author(s): 4 * Author(s):
6 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 5 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
7 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Copyright IBM Corp. 2003, 2009
9 */ 8 */
10 9
11#include <linux/bootmem.h> 10#include <linux/bootmem.h>
@@ -61,6 +60,7 @@ struct raw3270 {
61#define RAW3270_FLAGS_ATTN 2 /* Device sent an ATTN interrupt */ 60#define RAW3270_FLAGS_ATTN 2 /* Device sent an ATTN interrupt */
62#define RAW3270_FLAGS_READY 4 /* Device is useable by views */ 61#define RAW3270_FLAGS_READY 4 /* Device is useable by views */
63#define RAW3270_FLAGS_CONSOLE 8 /* Device is the console. */ 62#define RAW3270_FLAGS_CONSOLE 8 /* Device is the console. */
63#define RAW3270_FLAGS_FROZEN 16 /* set if 3270 is frozen for suspend */
64 64
65/* Semaphore to protect global data of raw3270 (devices, views, etc). */ 65/* Semaphore to protect global data of raw3270 (devices, views, etc). */
66static DEFINE_MUTEX(raw3270_mutex); 66static DEFINE_MUTEX(raw3270_mutex);
@@ -306,7 +306,8 @@ raw3270_start(struct raw3270_view *view, struct raw3270_request *rq)
306 306
307 spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags); 307 spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags);
308 rp = view->dev; 308 rp = view->dev;
309 if (!rp || rp->view != view) 309 if (!rp || rp->view != view ||
310 test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
310 rc = -EACCES; 311 rc = -EACCES;
311 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 312 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
312 rc = -ENODEV; 313 rc = -ENODEV;
@@ -323,7 +324,8 @@ raw3270_start_locked(struct raw3270_view *view, struct raw3270_request *rq)
323 int rc; 324 int rc;
324 325
325 rp = view->dev; 326 rp = view->dev;
326 if (!rp || rp->view != view) 327 if (!rp || rp->view != view ||
328 test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
327 rc = -EACCES; 329 rc = -EACCES;
328 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 330 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
329 rc = -ENODEV; 331 rc = -ENODEV;
@@ -764,7 +766,8 @@ raw3270_reset(struct raw3270_view *view)
764 int rc; 766 int rc;
765 767
766 rp = view->dev; 768 rp = view->dev;
767 if (!rp || rp->view != view) 769 if (!rp || rp->view != view ||
770 test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
768 rc = -EACCES; 771 rc = -EACCES;
769 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 772 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
770 rc = -ENODEV; 773 rc = -ENODEV;
@@ -922,6 +925,8 @@ raw3270_activate_view(struct raw3270_view *view)
922 rc = 0; 925 rc = 0;
923 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 926 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
924 rc = -ENODEV; 927 rc = -ENODEV;
928 else if (test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
929 rc = -EACCES;
925 else { 930 else {
926 oldview = NULL; 931 oldview = NULL;
927 if (rp->view) { 932 if (rp->view) {
@@ -969,7 +974,8 @@ raw3270_deactivate_view(struct raw3270_view *view)
969 list_del_init(&view->list); 974 list_del_init(&view->list);
970 list_add_tail(&view->list, &rp->view_list); 975 list_add_tail(&view->list, &rp->view_list);
971 /* Try to activate another view. */ 976 /* Try to activate another view. */
972 if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) { 977 if (test_bit(RAW3270_FLAGS_READY, &rp->flags) &&
978 !test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) {
973 list_for_each_entry(view, &rp->view_list, list) { 979 list_for_each_entry(view, &rp->view_list, list) {
974 rp->view = view; 980 rp->view = view;
975 if (view->fn->activate(view) == 0) 981 if (view->fn->activate(view) == 0)
@@ -1068,7 +1074,8 @@ raw3270_del_view(struct raw3270_view *view)
1068 rp->view = NULL; 1074 rp->view = NULL;
1069 } 1075 }
1070 list_del_init(&view->list); 1076 list_del_init(&view->list);
1071 if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags)) { 1077 if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags) &&
1078 !test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) {
1072 /* Try to activate another view. */ 1079 /* Try to activate another view. */
1073 list_for_each_entry(nv, &rp->view_list, list) { 1080 list_for_each_entry(nv, &rp->view_list, list) {
1074 if (nv->fn->activate(nv) == 0) { 1081 if (nv->fn->activate(nv) == 0) {
@@ -1337,6 +1344,58 @@ raw3270_set_offline (struct ccw_device *cdev)
1337 return 0; 1344 return 0;
1338} 1345}
1339 1346
1347static int raw3270_pm_stop(struct ccw_device *cdev)
1348{
1349 struct raw3270 *rp;
1350 struct raw3270_view *view;
1351 unsigned long flags;
1352
1353 rp = cdev->dev.driver_data;
1354 if (!rp)
1355 return 0;
1356 spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
1357 if (rp->view)
1358 rp->view->fn->deactivate(rp->view);
1359 if (!test_bit(RAW3270_FLAGS_CONSOLE, &rp->flags)) {
1360 /*
1361 * Release tty and fullscreen for all non-console
1362 * devices.
1363 */
1364 list_for_each_entry(view, &rp->view_list, list) {
1365 if (view->fn->release)
1366 view->fn->release(view);
1367 }
1368 }
1369 set_bit(RAW3270_FLAGS_FROZEN, &rp->flags);
1370 spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
1371 return 0;
1372}
1373
1374static int raw3270_pm_start(struct ccw_device *cdev)
1375{
1376 struct raw3270 *rp;
1377 unsigned long flags;
1378
1379 rp = cdev->dev.driver_data;
1380 if (!rp)
1381 return 0;
1382 spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
1383 clear_bit(RAW3270_FLAGS_FROZEN, &rp->flags);
1384 if (rp->view)
1385 rp->view->fn->activate(rp->view);
1386 spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
1387 return 0;
1388}
1389
1390void raw3270_pm_unfreeze(struct raw3270_view *view)
1391{
1392 struct raw3270 *rp;
1393
1394 rp = view->dev;
1395 if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
1396 ccw_device_force_console();
1397}
1398
1340static struct ccw_device_id raw3270_id[] = { 1399static struct ccw_device_id raw3270_id[] = {
1341 { CCW_DEVICE(0x3270, 0) }, 1400 { CCW_DEVICE(0x3270, 0) },
1342 { CCW_DEVICE(0x3271, 0) }, 1401 { CCW_DEVICE(0x3271, 0) },
@@ -1360,6 +1419,9 @@ static struct ccw_driver raw3270_ccw_driver = {
1360 .remove = &raw3270_remove, 1419 .remove = &raw3270_remove,
1361 .set_online = &raw3270_set_online, 1420 .set_online = &raw3270_set_online,
1362 .set_offline = &raw3270_set_offline, 1421 .set_offline = &raw3270_set_offline,
1422 .freeze = &raw3270_pm_stop,
1423 .thaw = &raw3270_pm_start,
1424 .restore = &raw3270_pm_start,
1363}; 1425};
1364 1426
1365static int 1427static int
diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h
index 90beaa80a782..ed34eb2199cc 100644
--- a/drivers/s390/char/raw3270.h
+++ b/drivers/s390/char/raw3270.h
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/raw3270.h 2 * IBM/3270 Driver
3 * IBM/3270 Driver
4 * 3 *
5 * Author(s): 4 * Author(s):
6 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 5 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
7 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Copyright IBM Corp. 2003, 2009
9 */ 8 */
10 9
11#include <asm/idals.h> 10#include <asm/idals.h>
@@ -195,6 +194,7 @@ void raw3270_wait_cons_dev(struct raw3270 *);
195/* Notifier for device addition/removal */ 194/* Notifier for device addition/removal */
196int raw3270_register_notifier(void (*notifier)(int, int)); 195int raw3270_register_notifier(void (*notifier)(int, int));
197void raw3270_unregister_notifier(void (*notifier)(int, int)); 196void raw3270_unregister_notifier(void (*notifier)(int, int));
197void raw3270_pm_unfreeze(struct raw3270_view *);
198 198
199/* 199/*
200 * Little memory allocator for string objects. 200 * Little memory allocator for string objects.