summaryrefslogtreecommitdiff
path: root/drivers/s390/char
diff options
context:
space:
mode:
authorSven Schnelle <svens@linux.ibm.com>2022-11-28 09:31:49 +0300
committerHeiko Carstens <hca@linux.ibm.com>2023-01-09 16:34:01 +0300
commit164eb669348045894b50eaecc5936ec07b4307f0 (patch)
tree90eff431f37a9ea2418e3d82f85cbdfc8721d779 /drivers/s390/char
parent9c138af9b777f466226787cf24a34ff94d4f80e2 (diff)
downloadlinux-164eb669348045894b50eaecc5936ec07b4307f0.tar.xz
s390/tty3270: use normal char buffer for prompt/input
Preparation patch to allow removing the custom 3270 memory allocator. 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.c136
1 files changed, 81 insertions, 55 deletions
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index 00e6e01cf8c8..e3eee0492fea 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -100,8 +100,8 @@ struct tty3270 {
struct tty3270_line *screen;
/* Input stuff. */
- struct string *prompt; /* Output string for input area. */
- struct string *input; /* Input string for read request. */
+ char *prompt; /* Output string for input area. */
+ char *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;
@@ -198,53 +198,44 @@ static struct tty3270_line *tty3270_get_view_line(struct tty3270 *tp, unsigned i
return tp->screen + tty3270_line_increment(tp, tp->line_view_start, num - tp->nr_up);
}
-/*
- * The input line are the two last lines of the screen.
- */
-static void tty3270_update_prompt(struct tty3270 *tp, char *input, int count)
+static int tty3270_input_size(int cols)
{
- struct string *line;
+ return cols * 2 - 11;
+}
- line = tp->prompt;
- if (count != 0)
- line->string[5] = TF_INMDT;
- else
- line->string[5] = tp->inattr;
- if (count > tp->view.cols * 2 - 11)
- count = tp->view.cols * 2 - 11;
- memcpy(line->string + 6, input, count);
- line->string[6 + count] = TO_IC;
- /* Clear to end of input line. */
- if (count < tp->view.cols * 2 - 11) {
- tty3270_add_ra(tp, line->string + count + 7, -9, -1, 0);
- line->len = 11 + count;
- } else
- line->len = 7 + count;
+static void tty3270_update_prompt(struct tty3270 *tp, char *input, int count)
+{
+ memcpy(tp->prompt, input, count);
+ tp->prompt[count] = '\0';
tp->update_flags |= TTY_UPDATE_INPUT;
+ tty3270_set_timer(tp, 1);
}
-static void tty3270_create_prompt(struct tty3270 *tp)
+/*
+ * The input line are the two last lines of the screen.
+ */
+static int tty3270_add_prompt(struct tty3270 *tp)
{
- static const unsigned char blueprint[] =
- { TO_SBA, 0, 0, 0x6e, TO_SF, TF_INPUT,
- /* empty input string */
- TO_IC, TO_RA, 0, 0, 0 };
- struct string *line;
-
- line = alloc_string(&tp->freemem,
- sizeof(blueprint) + tp->view.cols * 2 - 9);
- tp->prompt = line;
- tp->inattr = TF_INPUT;
- /* Copy blueprint to status line */
- memcpy(line->string, blueprint, sizeof(blueprint));
- line->len = sizeof(blueprint);
- /* Set output offsets. */
+ int count = 0;
+ char *cp;
- raw3270_buffer_address(tp->view.dev, line->string + 1, 0, -2);
- raw3270_buffer_address(tp->view.dev, line->string + 8, -9, -1);
+ cp = tp->converted_line;
+ cp = tty3270_add_ba(tp, cp, TO_SBA, 0, -2);
+ *cp++ = tp->view.ascebc['>'];
- /* Allocate input string for reading. */
- tp->input = alloc_string(&tp->freemem, tp->view.cols * 2 - 9 + 6);
+ if (*tp->prompt) {
+ cp = tty3270_add_sf(tp, cp, TF_INMDT);
+ count = min_t(int, strlen(tp->prompt), tp->view.cols * 2 - 11);
+ memcpy(cp, tp->prompt, count);
+ cp += count;
+ } else {
+ cp = tty3270_add_sf(tp, cp, tp->inattr);
+ }
+ *cp++ = TO_IC;
+ /* Clear to end of input line. */
+ if (count < tp->view.cols * 2 - 11)
+ cp = tty3270_add_ra(tp, cp, -9, -1, 0);
+ return cp - tp->converted_line;
}
/*
@@ -513,10 +504,11 @@ static void tty3270_update(struct timer_list *t)
/*
* Write input line.
*/
- if (tp->update_flags & TTY_UPDATE_INPUT)
- if (raw3270_request_add_data(wrq, tp->prompt->string,
- tp->prompt->len) == 0)
+ if (tp->update_flags & TTY_UPDATE_INPUT) {
+ len = tty3270_add_prompt(tp);
+ if (raw3270_request_add_data(wrq, tp->converted_line, len) == 0)
updated |= TTY_UPDATE_INPUT;
+ }
for (i = 0; i < tty3270_tty_rows(tp); i++) {
line = tty3270_get_view_line(tp, i);
@@ -662,11 +654,11 @@ static void tty3270_read_tasklet(unsigned long data)
*/
input = NULL;
len = 0;
- switch (tp->input->string[0]) {
+ switch (tp->input[0]) {
case AID_ENTER:
/* Enter: write input to tty. */
- input = tp->input->string + 6;
- len = tp->input->len - 6 - rrq->rescnt;
+ input = tp->input + 6;
+ len = tty3270_input_size(tp->view.cols) - 6 - rrq->rescnt;
if (tp->inattr != TF_INPUTN)
tty3270_rcl_add(tp, input, len);
if (tp->nr_up > 0)
@@ -685,7 +677,7 @@ static void tty3270_read_tasklet(unsigned long data)
(char *)sfq_read_partition, sizeof(sfq_read_partition));
break;
case AID_READ_PARTITION:
- raw3270_read_modified_cb(tp->readpartreq, tp->input->string);
+ raw3270_read_modified_cb(tp->readpartreq, tp->input);
break;
default:
break;
@@ -698,7 +690,7 @@ static void tty3270_read_tasklet(unsigned long data)
while (len-- > 0)
kbd_keycode(tp->kbd, *input++);
/* Emit keycode for AID byte. */
- kbd_keycode(tp->kbd, 256 + tp->input->string[0]);
+ kbd_keycode(tp->kbd, 256 + tp->input[0]);
raw3270_request_reset(rrq);
xchg(&tp->read, rrq);
@@ -731,7 +723,7 @@ static void tty3270_issue_read(struct tty3270 *tp, int lock)
rrq->callback = tty3270_read_callback;
rrq->callback_data = tp;
raw3270_request_set_cmd(rrq, TC_READMOD);
- raw3270_request_set_data(rrq, tp->input->string, tp->input->len);
+ raw3270_request_set_data(rrq, tp->input, tty3270_input_size(tp->view.cols));
/* Issue the read modified request. */
if (lock) {
rc = raw3270_start(&tp->view, rrq);
@@ -938,6 +930,8 @@ static void tty3270_resize(struct raw3270_view *view,
{
struct tty3270 *tp = container_of(view, struct tty3270, view);
struct tty3270_line *screen, *oscreen;
+ char *old_prompt, *new_prompt;
+ char *old_input, *new_input;
struct tty_struct *tty;
struct winsize ws;
int new_allocated, old_allocated = tp->allocated_lines;
@@ -950,9 +944,17 @@ static void tty3270_resize(struct raw3270_view *view,
spin_unlock_irq(&tp->view.lock);
return;
}
+
+ new_input = kzalloc(tty3270_input_size(new_cols), GFP_KERNEL | GFP_DMA);
+ if (!new_input)
+ return;
+ new_prompt = kzalloc(tty3270_input_size(new_cols), GFP_KERNEL);
+ if (!new_prompt)
+ goto out_input;
screen = tty3270_alloc_screen(tp, new_rows, new_cols, &new_allocated);
if (IS_ERR(screen))
- return;
+ goto out_prompt;
+
/* Switch to new output size */
spin_lock_irq(&tp->view.lock);
tty3270_blank_screen(tp);
@@ -962,12 +964,15 @@ static void tty3270_resize(struct raw3270_view *view,
tp->view.rows = new_rows;
tp->view.cols = new_cols;
tp->view.model = new_model;
-
- free_string(&tp->freemem, tp->prompt);
- tty3270_create_prompt(tp);
tp->update_flags = TTY_UPDATE_ALL;
+ old_input = tp->input;
+ old_prompt = tp->prompt;
+ tp->input = new_input;
+ tp->prompt = new_prompt;
spin_unlock_irq(&tp->view.lock);
tty3270_free_screen(oscreen, old_allocated);
+ kfree(old_input);
+ kfree(old_prompt);
tty3270_set_timer(tp, 1);
/* Informat tty layer about new size */
tty = tty_port_tty_get(&tp->port);
@@ -977,6 +982,11 @@ static void tty3270_resize(struct raw3270_view *view,
ws.ws_col = tp->view.cols;
tty_do_resize(tty, &ws);
tty_kref_put(tty);
+ return;
+out_prompt:
+ kfree(new_prompt);
+out_input:
+ kfree(new_input);
}
/*
@@ -1006,6 +1016,8 @@ static void tty3270_free(struct raw3270_view *view)
del_timer_sync(&tp->timer);
tty3270_free_screen(tp->screen, tp->allocated_lines);
free_page((unsigned long)tp->converted_line);
+ kfree(tp->input);
+ kfree(tp->prompt);
tty3270_free_view(tp);
}
@@ -1065,7 +1077,17 @@ tty3270_create_view(int index, struct tty3270 **newtp)
goto out_free_screen;
}
- tty3270_create_prompt(tp);
+ tp->input = kzalloc(tty3270_input_size(tp->view.cols), GFP_KERNEL | GFP_DMA);
+ if (!tp->input) {
+ rc = -ENOMEM;
+ goto out_free_converted_line;
+ }
+
+ tp->prompt = kzalloc(tty3270_input_size(tp->view.cols), GFP_KERNEL);
+ if (!tp->prompt) {
+ rc = -ENOMEM;
+ goto out_free_input;
+ }
/* Create blank line for every line in the tty output area. */
tty3270_blank_screen(tp);
@@ -1082,6 +1104,10 @@ tty3270_create_view(int index, struct tty3270 **newtp)
*newtp = tp;
return 0;
+out_free_input:
+ kfree(tp->input);
+out_free_converted_line:
+ free_page((unsigned long)tp->converted_line);
out_free_screen:
tty3270_free_screen(tp->screen, tp->view.rows);
out_put_view: