Commit b2057c87 authored by Sven Schnelle's avatar Sven Schnelle Committed by Heiko Carstens

s390/tty3270: allocate screen with scrollback

No functional change (except more memory consumption), in preparation
for the line buffer rework.
Signed-off-by: default avatarSven Schnelle <svens@linux.ibm.com>
Acked-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Tested-by: default avatarNiklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent 9eb99b94
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#define TTY3270_OUTPUT_BUFFER_SIZE 1024 #define TTY3270_OUTPUT_BUFFER_SIZE 1024
#define TTY3270_STRING_PAGES 5 #define TTY3270_STRING_PAGES 5
#define TTY3270_SCREEN_PAGES 8 /* has to be power-of-two */
static struct tty_driver *tty3270_driver; static struct tty_driver *tty3270_driver;
static int tty3270_max_index; static int tty3270_max_index;
static struct tty3270 *condev; static struct tty3270 *condev;
...@@ -56,6 +58,7 @@ struct tty3270_cell { ...@@ -56,6 +58,7 @@ struct tty3270_cell {
struct tty3270_line { struct tty3270_line {
struct tty3270_cell *cells; struct tty3270_cell *cells;
int len; int len;
int dirty;
}; };
static const unsigned char sfq_read_partition[] = { static const unsigned char sfq_read_partition[] = {
...@@ -92,6 +95,7 @@ struct tty3270 { ...@@ -92,6 +95,7 @@ struct tty3270 {
unsigned int cx, cy; /* Current output position. */ unsigned int cx, cy; /* Current output position. */
struct tty3270_attribute attributes; struct tty3270_attribute attributes;
struct tty3270_attribute saved_attributes; struct tty3270_attribute saved_attributes;
int allocated_lines;
struct tty3270_line *screen; struct tty3270_line *screen;
/* Input stuff. */ /* Input stuff. */
...@@ -805,22 +809,22 @@ static void tty3270_free_view(struct tty3270 *tp) ...@@ -805,22 +809,22 @@ static void tty3270_free_view(struct tty3270 *tp)
/* /*
* Allocate tty3270 screen. * 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; struct tty3270_line *screen;
unsigned long size; int allocated, lines;
int lines;
size = sizeof(struct tty3270_line) * (rows - 2); allocated = __roundup_pow_of_two(rows) * TTY3270_SCREEN_PAGES;
screen = kzalloc(size, GFP_KERNEL); screen = kcalloc(allocated, sizeof(struct tty3270_line), GFP_KERNEL);
if (!screen) if (!screen)
goto out_err; goto out_err;
for (lines = 0; lines < rows - 2; lines++) { for (lines = 0; lines < allocated; lines++) {
size = sizeof(struct tty3270_cell) * cols; screen[lines].cells = kcalloc(cols, sizeof(struct tty3270_cell), GFP_KERNEL);
screen[lines].cells = kzalloc(size, GFP_KERNEL);
if (!screen[lines].cells) if (!screen[lines].cells)
goto out_screen; goto out_screen;
} }
*allocated_out = allocated;
return screen; return screen;
out_screen: out_screen:
while (lines--) while (lines--)
...@@ -833,11 +837,11 @@ static struct tty3270_line *tty3270_alloc_screen(unsigned int rows, unsigned int ...@@ -833,11 +837,11 @@ static struct tty3270_line *tty3270_alloc_screen(unsigned int rows, unsigned int
/* /*
* Free tty3270 screen. * 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; int lines;
for (lines = 0; lines < rows - 2; lines++) for (lines = 0; lines < old_lines; lines++)
kfree(screen[lines].cells); kfree(screen[lines].cells);
kfree(screen); kfree(screen);
} }
...@@ -853,6 +857,7 @@ static void tty3270_resize(struct raw3270_view *view, ...@@ -853,6 +857,7 @@ static void tty3270_resize(struct raw3270_view *view,
struct tty3270_line *screen, *oscreen; struct tty3270_line *screen, *oscreen;
struct tty_struct *tty; struct tty_struct *tty;
struct winsize ws; struct winsize ws;
int new_allocated, old_allocated = tp->allocated_lines;
if (old_model == new_model && if (old_model == new_model &&
old_cols == new_cols && old_cols == new_cols &&
...@@ -863,7 +868,7 @@ static void tty3270_resize(struct raw3270_view *view, ...@@ -863,7 +868,7 @@ static void tty3270_resize(struct raw3270_view *view,
spin_unlock_irq(&tp->view.lock); spin_unlock_irq(&tp->view.lock);
return; return;
} }
screen = tty3270_alloc_screen(new_rows, new_cols); screen = tty3270_alloc_screen(tp, new_rows, new_cols, &new_allocated);
if (IS_ERR(screen)) if (IS_ERR(screen))
return; return;
/* Switch to new output size */ /* Switch to new output size */
...@@ -871,6 +876,7 @@ static void tty3270_resize(struct raw3270_view *view, ...@@ -871,6 +876,7 @@ static void tty3270_resize(struct raw3270_view *view,
tty3270_blank_screen(tp); tty3270_blank_screen(tp);
oscreen = tp->screen; oscreen = tp->screen;
tp->screen = screen; tp->screen = screen;
tp->allocated_lines = new_allocated;
tp->view.rows = new_rows; tp->view.rows = new_rows;
tp->view.cols = new_cols; tp->view.cols = new_cols;
tp->view.model = new_model; tp->view.model = new_model;
...@@ -883,7 +889,7 @@ static void tty3270_resize(struct raw3270_view *view, ...@@ -883,7 +889,7 @@ static void tty3270_resize(struct raw3270_view *view,
tty3270_blank_line(tp); tty3270_blank_line(tp);
tp->update_flags = TTY_UPDATE_ALL; tp->update_flags = TTY_UPDATE_ALL;
spin_unlock_irq(&tp->view.lock); spin_unlock_irq(&tp->view.lock);
tty3270_free_screen(oscreen, old_rows); tty3270_free_screen(oscreen, old_allocated);
tty3270_set_timer(tp, 1); tty3270_set_timer(tp, 1);
/* Informat tty layer about new size */ /* Informat tty layer about new size */
tty = tty_port_tty_get(&tp->port); tty = tty_port_tty_get(&tp->port);
...@@ -920,7 +926,7 @@ static void tty3270_free(struct raw3270_view *view) ...@@ -920,7 +926,7 @@ static void tty3270_free(struct raw3270_view *view)
struct tty3270 *tp = container_of(view, struct tty3270, view); struct tty3270 *tp = container_of(view, struct tty3270, view);
del_timer_sync(&tp->timer); 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); tty3270_free_view(tp);
} }
...@@ -969,7 +975,8 @@ tty3270_create_view(int index, struct tty3270 **newtp) ...@@ -969,7 +975,8 @@ tty3270_create_view(int index, struct tty3270 **newtp)
return rc; 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)) { if (IS_ERR(tp->screen)) {
rc = PTR_ERR(tp->screen); rc = PTR_ERR(tp->screen);
raw3270_put_view(&tp->view); raw3270_put_view(&tp->view);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment