aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/s390/char
diff options
context:
space:
mode:
authorSven Schnelle <svens@linux.ibm.com>2022-11-24 21:22:29 +0100
committerHeiko Carstens <hca@linux.ibm.com>2023-01-09 14:34:00 +0100
commitb2057c870231edce4105c9825f8e5e1f20aebabc (patch)
tree382753750e7ceccf78b7ab46cad4e025f4e7c265 /drivers/s390/char
parents390/con3270: add helper to get number of tty rows (diff)
downloadwireguard-linux-b2057c870231edce4105c9825f8e5e1f20aebabc.tar.xz
wireguard-linux-b2057c870231edce4105c9825f8e5e1f20aebabc.zip
s390/tty3270: allocate screen with scrollback
No functional change (except more memory consumption), in preparation for the line buffer rework. 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.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index 1c1390249342..d3c9fb27a03f 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -36,6 +36,8 @@
#define TTY3270_OUTPUT_BUFFER_SIZE 1024
#define TTY3270_STRING_PAGES 5
+#define TTY3270_SCREEN_PAGES 8 /* has to be power-of-two */
+
static struct tty_driver *tty3270_driver;
static int tty3270_max_index;
static struct tty3270 *condev;
@@ -56,6 +58,7 @@ struct tty3270_cell {
struct tty3270_line {
struct tty3270_cell *cells;
int len;
+ int dirty;
};
static const unsigned char sfq_read_partition[] = {
@@ -92,6 +95,7 @@ struct tty3270 {
unsigned int cx, cy; /* Current output position. */
struct tty3270_attribute attributes;
struct tty3270_attribute saved_attributes;
+ int allocated_lines;
struct tty3270_line *screen;
/* Input stuff. */
@@ -805,22 +809,22 @@ static void tty3270_free_view(struct tty3270 *tp)
/*
* Allocate tty3270 screen.
*/
-static struct tty3270_line *tty3270_alloc_screen(unsigned int rows, unsigned int cols)
+static struct tty3270_line *tty3270_alloc_screen(struct tty3270 *tp, unsigned int rows,
+ unsigned int cols, int *allocated_out)
{
struct tty3270_line *screen;
- unsigned long size;
- int lines;
+ int allocated, lines;
- size = sizeof(struct tty3270_line) * (rows - 2);
- screen = kzalloc(size, GFP_KERNEL);
+ allocated = __roundup_pow_of_two(rows) * TTY3270_SCREEN_PAGES;
+ screen = kcalloc(allocated, sizeof(struct tty3270_line), GFP_KERNEL);
if (!screen)
goto out_err;
- for (lines = 0; lines < rows - 2; lines++) {
- size = sizeof(struct tty3270_cell) * cols;
- screen[lines].cells = kzalloc(size, GFP_KERNEL);
+ for (lines = 0; lines < allocated; lines++) {
+ screen[lines].cells = kcalloc(cols, sizeof(struct tty3270_cell), GFP_KERNEL);
if (!screen[lines].cells)
goto out_screen;
}
+ *allocated_out = allocated;
return screen;
out_screen:
while (lines--)
@@ -833,11 +837,11 @@ out_err:
/*
* Free tty3270 screen.
*/
-static void tty3270_free_screen(struct tty3270_line *screen, unsigned int rows)
+static void tty3270_free_screen(struct tty3270_line *screen, int old_lines)
{
int lines;
- for (lines = 0; lines < rows - 2; lines++)
+ for (lines = 0; lines < old_lines; lines++)
kfree(screen[lines].cells);
kfree(screen);
}
@@ -853,6 +857,7 @@ static void tty3270_resize(struct raw3270_view *view,
struct tty3270_line *screen, *oscreen;
struct tty_struct *tty;
struct winsize ws;
+ int new_allocated, old_allocated = tp->allocated_lines;
if (old_model == new_model &&
old_cols == new_cols &&
@@ -863,7 +868,7 @@ static void tty3270_resize(struct raw3270_view *view,
spin_unlock_irq(&tp->view.lock);
return;
}
- screen = tty3270_alloc_screen(new_rows, new_cols);
+ screen = tty3270_alloc_screen(tp, new_rows, new_cols, &new_allocated);
if (IS_ERR(screen))
return;
/* Switch to new output size */
@@ -871,6 +876,7 @@ static void tty3270_resize(struct raw3270_view *view,
tty3270_blank_screen(tp);
oscreen = tp->screen;
tp->screen = screen;
+ tp->allocated_lines = new_allocated;
tp->view.rows = new_rows;
tp->view.cols = new_cols;
tp->view.model = new_model;
@@ -883,7 +889,7 @@ static void tty3270_resize(struct raw3270_view *view,
tty3270_blank_line(tp);
tp->update_flags = TTY_UPDATE_ALL;
spin_unlock_irq(&tp->view.lock);
- tty3270_free_screen(oscreen, old_rows);
+ tty3270_free_screen(oscreen, old_allocated);
tty3270_set_timer(tp, 1);
/* Informat tty layer about new size */
tty = tty_port_tty_get(&tp->port);
@@ -920,7 +926,7 @@ static void tty3270_free(struct raw3270_view *view)
struct tty3270 *tp = container_of(view, struct tty3270, view);
del_timer_sync(&tp->timer);
- tty3270_free_screen(tp->screen, tp->view.rows);
+ tty3270_free_screen(tp->screen, tp->allocated_lines);
tty3270_free_view(tp);
}
@@ -969,7 +975,8 @@ tty3270_create_view(int index, struct tty3270 **newtp)
return rc;
}
- tp->screen = tty3270_alloc_screen(tp->view.rows, tp->view.cols);
+ tp->screen = tty3270_alloc_screen(tp, tp->view.rows, tp->view.cols,
+ &tp->allocated_lines);
if (IS_ERR(tp->screen)) {
rc = PTR_ERR(tp->screen);
raw3270_put_view(&tp->view);