diff options
author | Sven Schnelle <svens@linux.ibm.com> | 2022-11-28 19:53:04 +0100 |
---|---|---|
committer | Heiko Carstens <hca@linux.ibm.com> | 2023-01-09 14:33:59 +0100 |
commit | cbb36313bdb696cfe0874406327b24b403c9e8e0 (patch) | |
tree | a63bcdd4fce7fd92766374d44d5dcd452585641e /drivers/s390/char | |
parent | 91621ba7d7b7274cd44e5ee4942a39a6aae977a0 (diff) |
s390/tty3270: resize terminal when the clear key is pressed
There's no easy way to figure out whether the user has re-connected
to the z/VM session. When the user re-connected with a different geometry
to z/VM, the screen layout is broken. Allow the user to force a resizing
by pressing the Clear Key.
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Tested-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Diffstat (limited to 'drivers/s390/char')
-rw-r--r-- | drivers/s390/char/con3270.c | 20 | ||||
-rw-r--r-- | drivers/s390/char/raw3270.c | 14 | ||||
-rw-r--r-- | drivers/s390/char/raw3270.h | 1 |
3 files changed, 27 insertions, 8 deletions
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index caccf5d496fd..61c73eb2471f 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -58,6 +58,10 @@ struct tty3270_line { int len; }; +static const unsigned char sfq_read_partition[] = { + 0x00, 0x07, 0x01, 0xff, 0x03, 0x00, 0x81 +}; + #define ESCAPE_NPAR 8 /* @@ -95,6 +99,7 @@ struct tty3270 { struct string *input; /* Input string for read request. */ struct raw3270_request *read; /* Single read request. */ struct raw3270_request *kreset; /* Single keyboard reset request. */ + struct raw3270_request *readpartreq; unsigned char inattr; /* Visible/invisible input. */ int throttle, attn; /* tty throttle/unthrottle. */ struct tasklet_struct readlet; /* Tasklet to issue read request. */ @@ -581,6 +586,14 @@ static void tty3270_read_tasklet(unsigned long data) /* Display has been cleared. Redraw. */ tp->update_flags = TTY_UPDATE_ALL; tty3270_set_timer(tp, 1); + if (!list_empty(&tp->readpartreq->list)) + break; + raw3270_start_request(&tp->view, tp->readpartreq, TC_WRITESF, + (char *)sfq_read_partition, sizeof(sfq_read_partition)); + break; + case AID_READ_PARTITION: + raw3270_read_modified_cb(tp->readpartreq, tp->input->string); + break; default: break; } @@ -731,9 +744,12 @@ static struct tty3270 *tty3270_alloc_view(void) tp->kreset = raw3270_request_alloc(1); if (IS_ERR(tp->kreset)) goto out_read; + tp->readpartreq = raw3270_request_alloc(sizeof(sfq_read_partition)); + if (IS_ERR(tp->readpartreq)) + goto out_reset; tp->kbd = kbd_alloc(); if (!tp->kbd) - goto out_reset; + goto out_readpartreq; tty_port_init(&tp->port); timer_setup(&tp->timer, tty3270_update, 0); @@ -743,6 +759,8 @@ static struct tty3270 *tty3270_alloc_view(void) (unsigned long) tp); return tp; +out_readpartreq: + raw3270_request_free(tp->readpartreq); out_reset: raw3270_request_free(tp->kreset); out_read: diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 032244c1dd78..e2d703e8ad48 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -465,15 +465,14 @@ static void raw3270_size_device_vm(struct raw3270 *rp) } } -static void raw3270_size_device(struct raw3270 *rp) +static void raw3270_size_device(struct raw3270 *rp, char *init_data) { struct raw3270_ua *uap; /* Got a Query Reply */ - uap = (struct raw3270_ua *) (rp->init_data + 1); + uap = (struct raw3270_ua *)(init_data + 1); /* Paranoia check. */ - if (rp->init_readmod.rc || rp->init_data[0] != 0x88 || - uap->uab.qcode != 0x81) { + if (init_data[0] != 0x88 || uap->uab.qcode != 0x81) { /* Couldn't detect size. Use default model 2. */ rp->model = 2; rp->rows = 24; @@ -534,11 +533,10 @@ static void raw3270_size_device_done(struct raw3270 *rp) schedule_work(&rp->resize_work); } -static void raw3270_read_modified_cb(struct raw3270_request *rq, void *data) +void raw3270_read_modified_cb(struct raw3270_request *rq, void *data) { struct raw3270 *rp = rq->view->dev; - - raw3270_size_device(rp); + raw3270_size_device(rp, data); raw3270_size_device_done(rp); } @@ -554,6 +552,7 @@ static void raw3270_read_modified(struct raw3270 *rp) rp->init_readmod.ccw.count = sizeof(rp->init_data); rp->init_readmod.ccw.cda = (__u32) __pa(rp->init_data); rp->init_readmod.callback = raw3270_read_modified_cb; + rp->init_readmod.callback_data = rp->init_data; rp->state = RAW3270_STATE_READMOD; raw3270_start_irq(&rp->init_view, &rp->init_readmod); } @@ -1287,6 +1286,7 @@ module_init(raw3270_init); module_exit(raw3270_exit); EXPORT_SYMBOL(class3270); +EXPORT_SYMBOL(raw3270_read_modified_cb); EXPORT_SYMBOL(raw3270_request_alloc); EXPORT_SYMBOL(raw3270_request_free); EXPORT_SYMBOL(raw3270_request_reset); diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h index 66f9f8d0e121..05cd501478ee 100644 --- a/drivers/s390/char/raw3270.h +++ b/drivers/s390/char/raw3270.h @@ -182,6 +182,7 @@ struct raw3270_view *raw3270_view(struct raw3270_view *); int raw3270_view_active(struct raw3270_view *); int raw3270_start_request(struct raw3270_view *view, struct raw3270_request *rq, int cmd, void *data, size_t len); +void raw3270_read_modified_cb(struct raw3270_request *rq, void *data); /* Reference count inliner for view structures. */ static inline void |