Skip to content

Commit

Permalink
[S390] pm: con3270 power management callbacks.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Martin Schwidefsky committed Jun 16, 2009
1 parent 6a1d96d commit 4b214a0
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 29 deletions.
12 changes: 6 additions & 6 deletions drivers/s390/char/con3270.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
/*
* drivers/s390/char/con3270.c
* IBM/3270 Driver - console view.
* IBM/3270 Driver - console view.
*
* Author(s):
* Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
* Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
* -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s):
* Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
* Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
* Copyright IBM Corp. 2003, 2009
*/

#include <linux/bootmem.h>
Expand Down Expand Up @@ -530,6 +529,7 @@ con3270_flush(void)
cp = condev;
if (!cp->view.dev)
return;
raw3270_pm_unfreeze(&cp->view);
spin_lock_irqsave(&cp->view.lock, flags);
con3270_wait_write(cp);
cp->nr_up = 0;
Expand Down
16 changes: 10 additions & 6 deletions drivers/s390/char/fs3270.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
/*
* drivers/s390/char/fs3270.c
* IBM/3270 Driver - fullscreen driver.
* IBM/3270 Driver - fullscreen driver.
*
* Author(s):
* Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
* Rewritten for 2.5/2.6 by Martin Schwidefsky <schwidefsky@de.ibm.com>
* -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s):
* Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
* Rewritten for 2.5/2.6 by Martin Schwidefsky <schwidefsky@de.ibm.com>
* Copyright IBM Corp. 2003, 2009
*/

#include <linux/bootmem.h>
Expand Down Expand Up @@ -399,6 +398,11 @@ fs3270_free_view(struct raw3270_view *view)
static void
fs3270_release(struct raw3270_view *view)
{
struct fs3270 *fp;

fp = (struct fs3270 *) view;
if (fp->fs_pid)
kill_pid(fp->fs_pid, SIGHUP, 1);
}

/* View to a 3270 device. Can be console, tty or fullscreen. */
Expand Down
84 changes: 73 additions & 11 deletions drivers/s390/char/raw3270.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
/*
* drivers/s390/char/raw3270.c
* IBM/3270 Driver - core functions.
* IBM/3270 Driver - core functions.
*
* Author(s):
* Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
* Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
* -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s):
* Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
* Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
* Copyright IBM Corp. 2003, 2009
*/

#include <linux/bootmem.h>
Expand Down Expand Up @@ -61,6 +60,7 @@ struct raw3270 {
#define RAW3270_FLAGS_ATTN 2 /* Device sent an ATTN interrupt */
#define RAW3270_FLAGS_READY 4 /* Device is useable by views */
#define RAW3270_FLAGS_CONSOLE 8 /* Device is the console. */
#define RAW3270_FLAGS_FROZEN 16 /* set if 3270 is frozen for suspend */

/* Semaphore to protect global data of raw3270 (devices, views, etc). */
static DEFINE_MUTEX(raw3270_mutex);
Expand Down Expand Up @@ -306,7 +306,8 @@ raw3270_start(struct raw3270_view *view, struct raw3270_request *rq)

spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags);
rp = view->dev;
if (!rp || rp->view != view)
if (!rp || rp->view != view ||
test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
rc = -EACCES;
else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
rc = -ENODEV;
Expand All @@ -323,7 +324,8 @@ raw3270_start_locked(struct raw3270_view *view, struct raw3270_request *rq)
int rc;

rp = view->dev;
if (!rp || rp->view != view)
if (!rp || rp->view != view ||
test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
rc = -EACCES;
else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
rc = -ENODEV;
Expand Down Expand Up @@ -764,7 +766,8 @@ raw3270_reset(struct raw3270_view *view)
int rc;

rp = view->dev;
if (!rp || rp->view != view)
if (!rp || rp->view != view ||
test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
rc = -EACCES;
else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
rc = -ENODEV;
Expand Down Expand Up @@ -922,6 +925,8 @@ raw3270_activate_view(struct raw3270_view *view)
rc = 0;
else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
rc = -ENODEV;
else if (test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
rc = -EACCES;
else {
oldview = NULL;
if (rp->view) {
Expand Down Expand Up @@ -969,7 +974,8 @@ raw3270_deactivate_view(struct raw3270_view *view)
list_del_init(&view->list);
list_add_tail(&view->list, &rp->view_list);
/* Try to activate another view. */
if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
if (test_bit(RAW3270_FLAGS_READY, &rp->flags) &&
!test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) {
list_for_each_entry(view, &rp->view_list, list) {
rp->view = view;
if (view->fn->activate(view) == 0)
Expand Down Expand Up @@ -1068,7 +1074,8 @@ raw3270_del_view(struct raw3270_view *view)
rp->view = NULL;
}
list_del_init(&view->list);
if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags) &&
!test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) {
/* Try to activate another view. */
list_for_each_entry(nv, &rp->view_list, list) {
if (nv->fn->activate(nv) == 0) {
Expand Down Expand Up @@ -1337,6 +1344,58 @@ raw3270_set_offline (struct ccw_device *cdev)
return 0;
}

static int raw3270_pm_stop(struct ccw_device *cdev)
{
struct raw3270 *rp;
struct raw3270_view *view;
unsigned long flags;

rp = cdev->dev.driver_data;
if (!rp)
return 0;
spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
if (rp->view)
rp->view->fn->deactivate(rp->view);
if (!test_bit(RAW3270_FLAGS_CONSOLE, &rp->flags)) {
/*
* Release tty and fullscreen for all non-console
* devices.
*/
list_for_each_entry(view, &rp->view_list, list) {
if (view->fn->release)
view->fn->release(view);
}
}
set_bit(RAW3270_FLAGS_FROZEN, &rp->flags);
spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
return 0;
}

static int raw3270_pm_start(struct ccw_device *cdev)
{
struct raw3270 *rp;
unsigned long flags;

rp = cdev->dev.driver_data;
if (!rp)
return 0;
spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
clear_bit(RAW3270_FLAGS_FROZEN, &rp->flags);
if (rp->view)
rp->view->fn->activate(rp->view);
spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
return 0;
}

void raw3270_pm_unfreeze(struct raw3270_view *view)
{
struct raw3270 *rp;

rp = view->dev;
if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
ccw_device_force_console();
}

static struct ccw_device_id raw3270_id[] = {
{ CCW_DEVICE(0x3270, 0) },
{ CCW_DEVICE(0x3271, 0) },
Expand All @@ -1360,6 +1419,9 @@ static struct ccw_driver raw3270_ccw_driver = {
.remove = &raw3270_remove,
.set_online = &raw3270_set_online,
.set_offline = &raw3270_set_offline,
.freeze = &raw3270_pm_stop,
.thaw = &raw3270_pm_start,
.restore = &raw3270_pm_start,
};

static int
Expand Down
12 changes: 6 additions & 6 deletions drivers/s390/char/raw3270.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
/*
* drivers/s390/char/raw3270.h
* IBM/3270 Driver
* IBM/3270 Driver
*
* Author(s):
* Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
* Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
* -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s):
* Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
* Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
* Copyright IBM Corp. 2003, 2009
*/

#include <asm/idals.h>
Expand Down Expand Up @@ -195,6 +194,7 @@ void raw3270_wait_cons_dev(struct raw3270 *);
/* Notifier for device addition/removal */
int raw3270_register_notifier(void (*notifier)(int, int));
void raw3270_unregister_notifier(void (*notifier)(int, int));
void raw3270_pm_unfreeze(struct raw3270_view *);

/*
* Little memory allocator for string objects.
Expand Down

0 comments on commit 4b214a0

Please sign in to comment.