Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

+95 -29
+6 -6
drivers/s390/char/con3270.c
··· 1 1 /* 2 - * drivers/s390/char/con3270.c 3 - * IBM/3270 Driver - console view. 2 + * IBM/3270 Driver - console view. 4 3 * 5 - * Author(s): 6 - * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 7 - * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 8 - * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 4 + * Author(s): 5 + * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 6 + * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 7 + * Copyright IBM Corp. 2003, 2009 9 8 */ 10 9 11 10 #include <linux/bootmem.h> ··· 529 530 cp = condev; 530 531 if (!cp->view.dev) 531 532 return; 533 + raw3270_pm_unfreeze(&cp->view); 532 534 spin_lock_irqsave(&cp->view.lock, flags); 533 535 con3270_wait_write(cp); 534 536 cp->nr_up = 0;
+10 -6
drivers/s390/char/fs3270.c
··· 1 1 /* 2 - * drivers/s390/char/fs3270.c 3 - * IBM/3270 Driver - fullscreen driver. 2 + * IBM/3270 Driver - fullscreen driver. 4 3 * 5 - * Author(s): 6 - * 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> 8 - * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 4 + * Author(s): 5 + * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 6 + * Rewritten for 2.5/2.6 by Martin Schwidefsky <schwidefsky@de.ibm.com> 7 + * Copyright IBM Corp. 2003, 2009 9 8 */ 10 9 11 10 #include <linux/bootmem.h> ··· 398 399 static void 399 400 fs3270_release(struct raw3270_view *view) 400 401 { 402 + struct fs3270 *fp; 403 + 404 + fp = (struct fs3270 *) view; 405 + if (fp->fs_pid) 406 + kill_pid(fp->fs_pid, SIGHUP, 1); 401 407 } 402 408 403 409 /* View to a 3270 device. Can be console, tty or fullscreen. */
+73 -11
drivers/s390/char/raw3270.c
··· 1 1 /* 2 - * drivers/s390/char/raw3270.c 3 - * IBM/3270 Driver - core functions. 2 + * IBM/3270 Driver - core functions. 4 3 * 5 - * Author(s): 6 - * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 7 - * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 8 - * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 4 + * Author(s): 5 + * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 6 + * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 7 + * Copyright IBM Corp. 2003, 2009 9 8 */ 10 9 11 10 #include <linux/bootmem.h> ··· 60 61 #define RAW3270_FLAGS_ATTN 2 /* Device sent an ATTN interrupt */ 61 62 #define RAW3270_FLAGS_READY 4 /* Device is useable by views */ 62 63 #define RAW3270_FLAGS_CONSOLE 8 /* Device is the console. */ 64 + #define RAW3270_FLAGS_FROZEN 16 /* set if 3270 is frozen for suspend */ 63 65 64 66 /* Semaphore to protect global data of raw3270 (devices, views, etc). */ 65 67 static DEFINE_MUTEX(raw3270_mutex); ··· 306 306 307 307 spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags); 308 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 311 rc = -EACCES; 311 312 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 312 313 rc = -ENODEV; ··· 324 323 int rc; 325 324 326 325 rp = view->dev; 327 - if (!rp || rp->view != view) 326 + if (!rp || rp->view != view || 327 + test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) 328 328 rc = -EACCES; 329 329 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 330 330 rc = -ENODEV; ··· 766 764 int rc; 767 765 768 766 rp = view->dev; 769 - if (!rp || rp->view != view) 767 + if (!rp || rp->view != view || 768 + test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) 770 769 rc = -EACCES; 771 770 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 772 771 rc = -ENODEV; ··· 925 922 rc = 0; 926 923 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 927 924 rc = -ENODEV; 925 + else if (test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) 926 + rc = -EACCES; 928 927 else { 929 928 oldview = NULL; 930 929 if (rp->view) { ··· 974 969 list_del_init(&view->list); 975 970 list_add_tail(&view->list, &rp->view_list); 976 971 /* Try to activate another view. */ 977 - if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) { 972 + if (test_bit(RAW3270_FLAGS_READY, &rp->flags) && 973 + !test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) { 978 974 list_for_each_entry(view, &rp->view_list, list) { 979 975 rp->view = view; 980 976 if (view->fn->activate(view) == 0) ··· 1074 1068 rp->view = NULL; 1075 1069 } 1076 1070 list_del_init(&view->list); 1077 - if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags)) { 1071 + if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags) && 1072 + !test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) { 1078 1073 /* Try to activate another view. */ 1079 1074 list_for_each_entry(nv, &rp->view_list, list) { 1080 1075 if (nv->fn->activate(nv) == 0) { ··· 1344 1337 return 0; 1345 1338 } 1346 1339 1340 + static int raw3270_pm_stop(struct ccw_device *cdev) 1341 + { 1342 + struct raw3270 *rp; 1343 + struct raw3270_view *view; 1344 + unsigned long flags; 1345 + 1346 + rp = cdev->dev.driver_data; 1347 + if (!rp) 1348 + return 0; 1349 + spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags); 1350 + if (rp->view) 1351 + rp->view->fn->deactivate(rp->view); 1352 + if (!test_bit(RAW3270_FLAGS_CONSOLE, &rp->flags)) { 1353 + /* 1354 + * Release tty and fullscreen for all non-console 1355 + * devices. 1356 + */ 1357 + list_for_each_entry(view, &rp->view_list, list) { 1358 + if (view->fn->release) 1359 + view->fn->release(view); 1360 + } 1361 + } 1362 + set_bit(RAW3270_FLAGS_FROZEN, &rp->flags); 1363 + spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags); 1364 + return 0; 1365 + } 1366 + 1367 + static int raw3270_pm_start(struct ccw_device *cdev) 1368 + { 1369 + struct raw3270 *rp; 1370 + unsigned long flags; 1371 + 1372 + rp = cdev->dev.driver_data; 1373 + if (!rp) 1374 + return 0; 1375 + spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags); 1376 + clear_bit(RAW3270_FLAGS_FROZEN, &rp->flags); 1377 + if (rp->view) 1378 + rp->view->fn->activate(rp->view); 1379 + spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags); 1380 + return 0; 1381 + } 1382 + 1383 + void raw3270_pm_unfreeze(struct raw3270_view *view) 1384 + { 1385 + struct raw3270 *rp; 1386 + 1387 + rp = view->dev; 1388 + if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) 1389 + ccw_device_force_console(); 1390 + } 1391 + 1347 1392 static struct ccw_device_id raw3270_id[] = { 1348 1393 { CCW_DEVICE(0x3270, 0) }, 1349 1394 { CCW_DEVICE(0x3271, 0) }, ··· 1419 1360 .remove = &raw3270_remove, 1420 1361 .set_online = &raw3270_set_online, 1421 1362 .set_offline = &raw3270_set_offline, 1363 + .freeze = &raw3270_pm_stop, 1364 + .thaw = &raw3270_pm_start, 1365 + .restore = &raw3270_pm_start, 1422 1366 }; 1423 1367 1424 1368 static int
+6 -6
drivers/s390/char/raw3270.h
··· 1 1 /* 2 - * drivers/s390/char/raw3270.h 3 - * IBM/3270 Driver 2 + * IBM/3270 Driver 4 3 * 5 - * Author(s): 6 - * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 7 - * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 8 - * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 4 + * Author(s): 5 + * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 6 + * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 7 + * Copyright IBM Corp. 2003, 2009 9 8 */ 10 9 11 10 #include <asm/idals.h> ··· 194 195 /* Notifier for device addition/removal */ 195 196 int raw3270_register_notifier(void (*notifier)(int, int)); 196 197 void raw3270_unregister_notifier(void (*notifier)(int, int)); 198 + void raw3270_pm_unfreeze(struct raw3270_view *); 197 199 198 200 /* 199 201 * Little memory allocator for string objects.