// SPDX-License-Identifier: GPL-2.0
/*
 *    IBM/3270 Driver - tty 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 IBM Corp. 2003
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kdev_t.h>
#include <linux/tty.h>
#include <linux/vt_kern.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>

#include <linux/slab.h>
#include <linux/memblock.h>
#include <linux/compat.h>

#include <asm/ccwdev.h>
#include <asm/cio.h>
#include <asm/ebcdic.h>
#include <linux/uaccess.h>

#include "raw3270.h"
#include "tty3270.h"
#include "keyboard.h"

#define TTY3270_CHAR_BUF_SIZE 256
#define TTY3270_OUTPUT_BUFFER_SIZE 1024
#define TTY3270_STRING_PAGES 5

struct tty_driver *tty3270_driver;
static int tty3270_max_index;

static struct raw3270_fn tty3270_fn;

struct tty3270_cell {
	unsigned char character;
	unsigned char highlight;
	unsigned char f_color;
};

struct tty3270_line {
	struct tty3270_cell *cells;
	int len;
};

#define ESCAPE_NPAR 8

/*
 * The main tty view data structure.
 * FIXME:
 * 1) describe line orientation & lines list concept against screen
 * 2) describe conversion of screen to lines
 * 3) describe line format.
 */
struct tty3270 {
	struct raw3270_view view;
	struct tty_port port;
	void **freemem_pages;		/* Array of pages used for freemem. */
	struct list_head freemem;	/* List of free memory for strings. */

	/* Output stuff. */
	struct list_head lines;		/* List of lines. */
	struct list_head update;	/* List of lines to update. */
	unsigned char wcc;		/* Write control character. */
	int nr_lines;			/* # lines in list. */
	int nr_up;			/* # lines up in history. */
	unsigned long update_flags;	/* Update indication bits. */
	struct string *status;		/* Lower right of display. */
	struct raw3270_request *write;	/* Single write request. */
	struct timer_list timer;	/* Output delay timer. */

	/* Current tty screen. */
	unsigned int cx, cy;		/* Current output position. */
	unsigned int highlight;		/* Blink/reverse/underscore */
	unsigned int f_color;		/* Foreground color */
	struct tty3270_line *screen;
	unsigned int n_model, n_cols, n_rows;	/* New model & size */
	struct work_struct resize_work;

	/* Input stuff. */
	struct string *prompt;		/* Output string for input area. */
	struct string *input;		/* Input string for read request. */
	struct raw3270_request *read;	/* Single read request. */
	struct raw3270_request *kreset;	/* Single keyboard reset request. */
	unsigned char inattr;		/* Visible/invisible input. */
	int throttle, attn;		/* tty throttle/unthrottle. */
	struct tasklet_struct readlet;	/* Tasklet to issue read request. */
	struct tasklet_struct hanglet;	/* Tasklet to hang up the tty. */
	struct kbd_data *kbd;		/* key_maps stuff. */

	/* Escape sequence parsing. */
	int esc_state, esc_ques, esc_npar;
	int esc_par[ESCAPE_NPAR];
	unsigned int saved_cx, saved_cy;
	unsigned int saved_highlight, saved_f_color;

	/* Command recalling. */
	struct list_head rcl_lines;	/* List of recallable lines. */
	struct list_head *rcl_walk;	/* Point in rcl_lines list. */
	int rcl_nr, rcl_max;		/* Number/max number of rcl_lines. */

	/* Character array for put_char/flush_chars. */
	unsigned int char_count;
	char char_buf[TTY3270_CHAR_BUF_SIZE];
};

/* tty3270->update_flags. See tty3270_update for details. */
#define TTY_UPDATE_ERASE	1	/* Use EWRITEA instead of WRITE. */
#define TTY_UPDATE_LIST		2	/* Update lines in tty3270->update. */
#define TTY_UPDATE_INPUT	4	/* Update input line. */
#define TTY_UPDATE_STATUS	8	/* Update status line. */
#define TTY_UPDATE_ALL		16	/* Recreate screen. */

static void tty3270_update(struct timer_list *);
static void tty3270_resize_work(struct work_struct *work);

/*
 * Setup timeout for a device. On timeout trigger an update.
 */
static void tty3270_set_timer(struct tty3270 *tp, int expires)
{
	mod_timer(&tp->timer, jiffies + expires);
}

/*
 * The input line are the two last lines of the screen.
 */
static void
tty3270_update_prompt(struct tty3270 *tp, char *input, int count)
{
	struct string *line;
	unsigned int off;

	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) {
		line->string[7 + count] = TO_RA;
		line->string[10 + count] = 0;
		off = tp->view.cols * tp->view.rows - 9;
		raw3270_buffer_address(tp->view.dev, line->string+count+8, off);
		line->len = 11 + count;
	} else
		line->len = 7 + count;
	tp->update_flags |= TTY_UPDATE_INPUT;
}

static void
tty3270_create_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;
	unsigned int offset;

	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. */
	offset = tp->view.cols * (tp->view.rows - 2);
	raw3270_buffer_address(tp->view.dev, line->string + 1, offset);
	offset = tp->view.cols * tp->view.rows - 9;
	raw3270_buffer_address(tp->view.dev, line->string + 8, offset);

	/* Allocate input string for reading. */
	tp->input = alloc_string(&tp->freemem, tp->view.cols * 2 - 9 + 6);
}

/*
 * The status line is the last line of the screen. It shows the string
 * "Running"/"Holding" in the lower right corner of the screen.
 */
static void
tty3270_update_status(struct tty3270 * tp)
{
	char *str;

	str = (tp->nr_up != 0) ? "History" : "Running";
	memcpy(tp->status->string + 8, str, 7);
	codepage_convert(tp->view.ascebc, tp->status->string + 8, 7);
	tp->update_flags |= TTY_UPDATE_STATUS;
}

static void
tty3270_create_status(struct tty3270 * tp)
{
	static const unsigned char blueprint[] =
		{ TO_SBA, 0, 0, TO_SF, TF_LOG, TO_SA, TAT_COLOR, TAC_GREEN,
		  0, 0, 0, 0, 0, 0, 0, TO_SF, TF_LOG, TO_SA, TAT_COLOR,
		  TAC_RESET };
	struct string *line;
	unsigned int offset;

	line = alloc_string(&tp->freemem,sizeof(blueprint));
	tp->status = line;
	/* Copy blueprint to status line */
	memcpy(line->string, blueprint, sizeof(blueprint));
	/* Set address to start of status string (= last 9 characters). */
	offset = tp->view.cols * tp->view.rows - 9;
	raw3270_buffer_address(tp->view.dev, line->string + 1, offset);
}

/*
 * Set output offsets to 3270 datastream fragment of a tty string.
 * (TO_SBA offset at the start and TO_RA offset at the end of the string)
 */
static void
tty3270_update_string(struct tty3270 *tp, struct string *line, int nr)
{
	unsigned char *cp;

	raw3270_buffer_address(tp->view.dev, line->string + 1,
			       tp->view.cols * nr);
	cp = line->string + line->len - 4;
	if (*cp == TO_RA)
		raw3270_buffer_address(tp->view.dev, cp + 1,
				       tp->view.cols * (nr + 1));
}

/*
 * Rebuild update list to print all lines.
 */
static void
tty3270_rebuild_update(struct tty3270 *tp)
{
	struct string *s, *n;
	int line, nr_up;

	/* 
	 * Throw away update list and create a new one,
	 * containing all lines that will fit on the screen.
	 */
	list_for_each_entry_safe(s, n, &tp->update, update)
		list_del_init(&s->update);
	line = tp->view.rows - 3;
	nr_up = tp->nr_up;
	list_for_each_entry_reverse(s, &tp->lines, list) {
		if (nr_up > 0) {
			nr_up--;
			continue;
		}
		tty3270_update_string(tp, s, line);
		list_add(&s->update, &tp->update);
		if (--line < 0)
			break;
	}
	tp->update_flags |= TTY_UPDATE_LIST;
}

/*
 * Alloc string for size bytes. If there is not enough room in
 * freemem, free strings until there is room.
 */
static struct string *
tty3270_alloc_string(struct tty3270 *tp, size_t size)
{
	struct string *s, *n;

	s = alloc_string(&tp->freemem, size);
	if (s)
		return s;
	list_for_each_entry_safe(s, n, &tp->lines, list) {
		BUG_ON(tp->nr_lines <= tp->view.rows - 2);
		list_del(&s->list);
		if (!list_empty(&s->update))
			list_del(&s->update);
		tp->nr_lines--;
		if (free_string(&tp->freemem, s) >= size)
			break;
	}
	s = alloc_string(&tp->freemem, size);
	BUG_ON(!s);
	if (tp->nr_up != 0 &&
	    tp->nr_up + tp->view.rows - 2 >= tp->nr_lines) {
		tp->nr_up = tp->nr_lines - tp->view.rows + 2;
		tty3270_rebuild_update(tp);
		tty3270_update_status(tp);
	}
	return s;
}

/*
 * Add an empty line to the list.
 */
static void
tty3270_blank_line(struct tty3270 *tp)
{
	static const unsigned char blueprint[] =
		{ TO_SBA, 0, 0, TO_SA, TAT_EXTHI, TAX_RESET,
		  TO_SA, TAT_COLOR, TAC_RESET, TO_RA, 0, 0, 0 };
	struct string *s;

	s = tty3270_alloc_string(tp, sizeof(blueprint));
	memcpy(s->string, blueprint, sizeof(blueprint));
	s->len = sizeof(blueprint);
	list_add_tail(&s->list, &tp->lines);
	tp->nr_lines++;
	if (tp->nr_up != 0)
		tp->nr_up++;
}

/*
 * Create a blank screen and remove all lines from the history.
 */
static void
tty3270_blank_screen(struct tty3270 *tp)
{
	struct string *s, *n;
	int i;

	for (i = 0; i < tp->view.rows - 2; i++)
		tp->screen[i].len = 0;
	tp->nr_up = 0;
	list_for_each_entry_safe(s, n, &tp->lines, list) {
		list_del(&s->list);
		if (!list_empty(&s->update))
			list_del(&s->update);
		tp->nr_lines--;
		free_string(&tp->freemem, s);
	}
}

/*
 * Write request completion callback.
 */
static void
tty3270_write_callback(struct raw3270_request *rq, void *data)
{
	struct tty3270 *tp = container_of(rq->view, struct tty3270, view);

	if (rq->rc != 0) {
		/* Write wasn't successful. Refresh all. */
		tp->update_flags = TTY_UPDATE_ALL;
		tty3270_set_timer(tp, 1);
	}
	raw3270_request_reset(rq);
	xchg(&tp->write, rq);
}

/*
 * Update 3270 display.
 */
static void
tty3270_update(struct timer_list *t)
{
	struct tty3270 *tp = from_timer(tp, t, timer);
	static char invalid_sba[2] = { 0xff, 0xff };
	struct raw3270_request *wrq;
	unsigned long updated;
	struct string *s, *n;
	char *sba, *str;
	int rc, len;

	wrq = xchg(&tp->write, 0);
	if (!wrq) {
		tty3270_set_timer(tp, 1);
		return;
	}

	spin_lock(&tp->view.lock);
	updated = 0;
	if (tp->update_flags & TTY_UPDATE_ALL) {
		tty3270_rebuild_update(tp);
		tty3270_update_status(tp);
		tp->update_flags = TTY_UPDATE_ERASE | TTY_UPDATE_LIST |
			TTY_UPDATE_INPUT | TTY_UPDATE_STATUS;
	}
	if (tp->update_flags & TTY_UPDATE_ERASE) {
		/* Use erase write alternate to erase display. */
		raw3270_request_set_cmd(wrq, TC_EWRITEA);
		updated |= TTY_UPDATE_ERASE;
	} else
		raw3270_request_set_cmd(wrq, TC_WRITE);

	raw3270_request_add_data(wrq, &tp->wcc, 1);
	tp->wcc = TW_NONE;

	/*
	 * Update status line.
	 */
	if (tp->update_flags & TTY_UPDATE_STATUS)
		if (raw3270_request_add_data(wrq, tp->status->string,
					     tp->status->len) == 0)
			updated |= TTY_UPDATE_STATUS;

	/*
	 * Write input line.
	 */
	if (tp->update_flags & TTY_UPDATE_INPUT)
		if (raw3270_request_add_data(wrq, tp->prompt->string,
					     tp->prompt->len) == 0)
			updated |= TTY_UPDATE_INPUT;

	sba = invalid_sba;
	
	if (tp->update_flags & TTY_UPDATE_LIST) {
		/* Write strings in the update list to the screen. */
		list_for_each_entry_safe(s, n, &tp->update, update) {
			str = s->string;
			len = s->len;
			/*
			 * Skip TO_SBA at the start of the string if the
			 * last output position matches the start address
			 * of this line.
			 */
			if (s->string[1] == sba[0] && s->string[2] == sba[1]) {
				str += 3;
				len -= 3;
			}
			if (raw3270_request_add_data(wrq, str, len) != 0)
				break;
			list_del_init(&s->update);
			if (s->string[s->len - 4] == TO_RA)
				sba = s->string + s->len - 3;
			else
				sba = invalid_sba;
		}
		if (list_empty(&tp->update))
			updated |= TTY_UPDATE_LIST;
	}
	wrq->callback = tty3270_write_callback;
	rc = raw3270_start(&tp->view, wrq);
	if (rc == 0) {
		tp->update_flags &= ~updated;
		if (tp->update_flags)
			tty3270_set_timer(tp, 1);
	} else {
		raw3270_request_reset(wrq);
		xchg(&tp->write, wrq);
	}
	spin_unlock(&tp->view.lock);
}

/*
 * Command recalling.
 */
static void
tty3270_rcl_add(struct tty3270 *tp, char *input, int len)
{
	struct string *s;

	tp->rcl_walk = NULL;
	if (len <= 0)
		return;
	if (tp->rcl_nr >= tp->rcl_max) {
		s = list_entry(tp->rcl_lines.next, struct string, list);
		list_del(&s->list);
		free_string(&tp->freemem, s);
		tp->rcl_nr--;
	}
	s = tty3270_alloc_string(tp, len);
	memcpy(s->string, input, len);
	list_add_tail(&s->list, &tp->rcl_lines);
	tp->rcl_nr++;
}

static void
tty3270_rcl_backward(struct kbd_data *kbd)
{
	struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
	struct string *s;

	spin_lock_bh(&tp->view.lock);
	if (tp->inattr == TF_INPUT) {
		if (tp->rcl_walk && tp->rcl_walk->prev != &tp->rcl_lines)
			tp->rcl_walk = tp->rcl_walk->prev;
		else if (!list_empty(&tp->rcl_lines))
			tp->rcl_walk = tp->rcl_lines.prev;
		s = tp->rcl_walk ? 
			list_entry(tp->rcl_walk, struct string, list) : NULL;
		if (tp->rcl_walk) {
			s = list_entry(tp->rcl_walk, struct string, list);
			tty3270_update_prompt(tp, s->string, s->len);
		} else
			tty3270_update_prompt(tp, NULL, 0);
		tty3270_set_timer(tp, 1);
	}
	spin_unlock_bh(&tp->view.lock);
}

/*
 * Deactivate tty view.
 */
static void
tty3270_exit_tty(struct kbd_data *kbd)
{
	struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);

	raw3270_deactivate_view(&tp->view);
}

/*
 * Scroll forward in history.
 */
static void
tty3270_scroll_forward(struct kbd_data *kbd)
{
	struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
	int nr_up;

	spin_lock_bh(&tp->view.lock);
	nr_up = tp->nr_up - tp->view.rows + 2;
	if (nr_up < 0)
		nr_up = 0;
	if (nr_up != tp->nr_up) {
		tp->nr_up = nr_up;
		tty3270_rebuild_update(tp);
		tty3270_update_status(tp);
		tty3270_set_timer(tp, 1);
	}
	spin_unlock_bh(&tp->view.lock);
}

/*
 * Scroll backward in history.
 */
static void
tty3270_scroll_backward(struct kbd_data *kbd)
{
	struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
	int nr_up;

	spin_lock_bh(&tp->view.lock);
	nr_up = tp->nr_up + tp->view.rows - 2;
	if (nr_up + tp->view.rows - 2 > tp->nr_lines)
		nr_up = tp->nr_lines - tp->view.rows + 2;
	if (nr_up != tp->nr_up) {
		tp->nr_up = nr_up;
		tty3270_rebuild_update(tp);
		tty3270_update_status(tp);
		tty3270_set_timer(tp, 1);
	}
	spin_unlock_bh(&tp->view.lock);
}

/*
 * Pass input line to tty.
 */
static void
tty3270_read_tasklet(unsigned long data)
{
	struct raw3270_request *rrq = (struct raw3270_request *)data;
	static char kreset_data = TW_KR;
	struct tty3270 *tp = container_of(rrq->view, struct tty3270, view);
	char *input;
	int len;

	spin_lock_bh(&tp->view.lock);
	/*
	 * Two AID keys are special: For 0x7d (enter) the input line
	 * has to be emitted to the tty and for 0x6d the screen
	 * needs to be redrawn.
	 */
	input = NULL;
	len = 0;
	if (tp->input->string[0] == 0x7d) {
		/* Enter: write input to tty. */
		input = tp->input->string + 6;
		len = tp->input->len - 6 - rrq->rescnt;
		if (tp->inattr != TF_INPUTN)
			tty3270_rcl_add(tp, input, len);
		if (tp->nr_up > 0) {
			tp->nr_up = 0;
			tty3270_rebuild_update(tp);
			tty3270_update_status(tp);
		}
		/* Clear input area. */
		tty3270_update_prompt(tp, NULL, 0);
		tty3270_set_timer(tp, 1);
	} else if (tp->input->string[0] == 0x6d) {
		/* Display has been cleared. Redraw. */
		tp->update_flags = TTY_UPDATE_ALL;
		tty3270_set_timer(tp, 1);
	}
	spin_unlock_bh(&tp->view.lock);

	/* Start keyboard reset command. */
	raw3270_request_reset(tp->kreset);
	raw3270_request_set_cmd(tp->kreset, TC_WRITE);
	raw3270_request_add_data(tp->kreset, &kreset_data, 1);
	raw3270_start(&tp->view, tp->kreset);

	while (len-- > 0)
		kbd_keycode(tp->kbd, *input++);
	/* Emit keycode for AID byte. */
	kbd_keycode(tp->kbd, 256 + tp->input->string[0]);

	raw3270_request_reset(rrq);
	xchg(&tp->read, rrq);
	raw3270_put_view(&tp->view);
}

/*
 * Read request completion callback.
 */
static void
tty3270_read_callback(struct raw3270_request *rq, void *data)
{
	struct tty3270 *tp = container_of(rq->view, struct tty3270, view);
	raw3270_get_view(rq->view);
	/* Schedule tasklet to pass input to tty. */
	tasklet_schedule(&tp->readlet);
}

/*
 * Issue a read request. Call with device lock.
 */
static void
tty3270_issue_read(struct tty3270 *tp, int lock)
{
	struct raw3270_request *rrq;
	int rc;

	rrq = xchg(&tp->read, 0);
	if (!rrq)
		/* Read already scheduled. */
		return;
	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);
	/* Issue the read modified request. */
	if (lock) {
		rc = raw3270_start(&tp->view, rrq);
	} else
		rc = raw3270_start_irq(&tp->view, rrq);
	if (rc) {
		raw3270_request_reset(rrq);
		xchg(&tp->read, rrq);
	}
}

/*
 * Hang up the tty
 */
static void
tty3270_hangup_tasklet(unsigned long data)
{
	struct tty3270 *tp = (struct tty3270 *)data;
	tty_port_tty_hangup(&tp->port, true);
	raw3270_put_view(&tp->view);
}

/*
 * Switch to the tty view.
 */
static int
tty3270_activate(struct raw3270_view *view)
{
	struct tty3270 *tp = container_of(view, struct tty3270, view);

	tp->update_flags = TTY_UPDATE_ALL;
	tty3270_set_timer(tp, 1);
	return 0;
}

static void
tty3270_deactivate(struct raw3270_view *view)
{
	struct tty3270 *tp = container_of(view, struct tty3270, view);

	del_timer(&tp->timer);
}

static void
tty3270_irq(struct tty3270 *tp, struct raw3270_request *rq, struct irb *irb)
{
	/* Handle ATTN. Schedule tasklet to read aid. */
	if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) {
		if (!tp->throttle)
			tty3270_issue_read(tp, 0);
		else
			tp->attn = 1;
	}

	if (rq) {
		if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
			rq->rc = -EIO;
			raw3270_get_view(&tp->view);
			tasklet_schedule(&tp->hanglet);
		} else {
			/* Normal end. Copy residual count. */
			rq->rescnt = irb->scsw.cmd.count;
		}
	} else if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) {
		/* Interrupt without an outstanding request -> update all */
		tp->update_flags = TTY_UPDATE_ALL;
		tty3270_set_timer(tp, 1);
	}
}

/*
 * Allocate tty3270 structure.
 */
static struct tty3270 *
tty3270_alloc_view(void)
{
	struct tty3270 *tp;
	int pages;

	tp = kzalloc(sizeof(struct tty3270), GFP_KERNEL);
	if (!tp)
		goto out_err;
	tp->freemem_pages =
		kmalloc_array(TTY3270_STRING_PAGES, sizeof(void *),
			      GFP_KERNEL);
	if (!tp->freemem_pages)
		goto out_tp;
	INIT_LIST_HEAD(&tp->freemem);
	INIT_LIST_HEAD(&tp->lines);
	INIT_LIST_HEAD(&tp->update);
	INIT_LIST_HEAD(&tp->rcl_lines);
	tp->rcl_max = 20;

	for (pages = 0; pages < TTY3270_STRING_PAGES; pages++) {
		tp->freemem_pages[pages] = (void *)
			__get_free_pages(GFP_KERNEL|GFP_DMA, 0);
		if (!tp->freemem_pages[pages])
			goto out_pages;
		add_string_memory(&tp->freemem,
				  tp->freemem_pages[pages], PAGE_SIZE);
	}
	tp->write = raw3270_request_alloc(TTY3270_OUTPUT_BUFFER_SIZE);
	if (IS_ERR(tp->write))
		goto out_pages;
	tp->read = raw3270_request_alloc(0);
	if (IS_ERR(tp->read))
		goto out_write;
	tp->kreset = raw3270_request_alloc(1);
	if (IS_ERR(tp->kreset))
		goto out_read;
	tp->kbd = kbd_alloc();
	if (!tp->kbd)
		goto out_reset;

	tty_port_init(&tp->port);
	timer_setup(&tp->timer, tty3270_update, 0);
	tasklet_init(&tp->readlet, tty3270_read_tasklet,
		     (unsigned long) tp->read);
	tasklet_init(&tp->hanglet, tty3270_hangup_tasklet,
		     (unsigned long) tp);
	INIT_WORK(&tp->resize_work, tty3270_resize_work);

	return tp;

out_reset:
	raw3270_request_free(tp->kreset);
out_read:
	raw3270_request_free(tp->read);
out_write:
	raw3270_request_free(tp->write);
out_pages:
	while (pages--)
		free_pages((unsigned long) tp->freemem_pages[pages], 0);
	kfree(tp->freemem_pages);
	tty_port_destroy(&tp->port);
out_tp:
	kfree(tp);
out_err:
	return ERR_PTR(-ENOMEM);
}

/*
 * Free tty3270 structure.
 */
static void
tty3270_free_view(struct tty3270 *tp)
{
	int pages;

	kbd_free(tp->kbd);
	raw3270_request_free(tp->kreset);
	raw3270_request_free(tp->read);
	raw3270_request_free(tp->write);
	for (pages = 0; pages < TTY3270_STRING_PAGES; pages++)
		free_pages((unsigned long) tp->freemem_pages[pages], 0);
	kfree(tp->freemem_pages);
	tty_port_destroy(&tp->port);
	kfree(tp);
}

/*
 * Allocate tty3270 screen.
 */
static struct tty3270_line *
tty3270_alloc_screen(unsigned int rows, unsigned int cols)
{
	struct tty3270_line *screen;
	unsigned long size;
	int lines;

	size = sizeof(struct tty3270_line) * (rows - 2);
	screen = kzalloc(size, 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);
		if (!screen[lines].cells)
			goto out_screen;
	}
	return screen;
out_screen:
	while (lines--)
		kfree(screen[lines].cells);
	kfree(screen);
out_err:
	return ERR_PTR(-ENOMEM);
}

/*
 * Free tty3270 screen.
 */
static void
tty3270_free_screen(struct tty3270_line *screen, unsigned int rows)
{
	int lines;

	for (lines = 0; lines < rows - 2; lines++)
		kfree(screen[lines].cells);
	kfree(screen);
}

/*
 * Resize tty3270 screen
 */
static void tty3270_resize_work(struct work_struct *work)
{
	struct tty3270 *tp = container_of(work, struct tty3270, resize_work);
	struct tty3270_line *screen, *oscreen;
	struct tty_struct *tty;
	unsigned int orows;
	struct winsize ws;

	screen = tty3270_alloc_screen(tp->n_rows, tp->n_cols);
	if (IS_ERR(screen))
		return;
	/* Switch to new output size */
	spin_lock_bh(&tp->view.lock);
	tty3270_blank_screen(tp);
	oscreen = tp->screen;
	orows = tp->view.rows;
	tp->view.model = tp->n_model;
	tp->view.rows = tp->n_rows;
	tp->view.cols = tp->n_cols;
	tp->screen = screen;
	free_string(&tp->freemem, tp->prompt);
	free_string(&tp->freemem, tp->status);
	tty3270_create_prompt(tp);
	tty3270_create_status(tp);
	while (tp->nr_lines < tp->view.rows - 2)
		tty3270_blank_line(tp);
	tp->update_flags = TTY_UPDATE_ALL;
	spin_unlock_bh(&tp->view.lock);
	tty3270_free_screen(oscreen, orows);
	tty3270_set_timer(tp, 1);
	/* Informat tty layer about new size */
	tty = tty_port_tty_get(&tp->port);
	if (!tty)
		return;
	ws.ws_row = tp->view.rows - 2;
	ws.ws_col = tp->view.cols;
	tty_do_resize(tty, &ws);
	tty_kref_put(tty);
}

static void
tty3270_resize(struct raw3270_view *view, int model, int rows, int cols)
{
	struct tty3270 *tp = container_of(view, struct tty3270, view);

	if (tp->n_model == model && tp->n_rows == rows && tp->n_cols == cols)
		return;
	tp->n_model = model;
	tp->n_rows = rows;
	tp->n_cols = cols;
	schedule_work(&tp->resize_work);
}

/*
 * Unlink tty3270 data structure from tty.
 */
static void
tty3270_release(struct raw3270_view *view)
{
	struct tty3270 *tp = container_of(view, struct tty3270, view);
	struct tty_struct *tty = tty_port_tty_get(&tp->port);

	if (tty) {
		tty->driver_data = NULL;
		tty_port_tty_set(&tp->port, NULL);
		tty_hangup(tty);
		raw3270_put_view(&tp->view);
		tty_kref_put(tty);
	}
}

/*
 * Free tty3270 data structure
 */
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_view(tp);
}

/*
 * Delayed freeing of tty3270 views.
 */
static void
tty3270_del_views(void)
{
	int i;

	for (i = RAW3270_FIRSTMINOR; i <= tty3270_max_index; i++) {
		struct raw3270_view *view = raw3270_find_view(&tty3270_fn, i);
		if (!IS_ERR(view))
			raw3270_del_view(view);
	}
}

static struct raw3270_fn tty3270_fn = {
	.activate = tty3270_activate,
	.deactivate = tty3270_deactivate,
	.intv = (void *) tty3270_irq,
	.release = tty3270_release,
	.free = tty3270_free,
	.resize = tty3270_resize
};

/*
 * This routine is called whenever a 3270 tty is opened first time.
 */
static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
{
	struct raw3270_view *view;
	struct tty3270 *tp;
	int i, rc;

	/* Check if the tty3270 is already there. */
	view = raw3270_find_view(&tty3270_fn, tty->index + RAW3270_FIRSTMINOR);
	if (!IS_ERR(view)) {
		tp = container_of(view, struct tty3270, view);
		tty->driver_data = tp;
		tty->winsize.ws_row = tp->view.rows - 2;
		tty->winsize.ws_col = tp->view.cols;
		tp->inattr = TF_INPUT;
		goto port_install;
	}
	if (tty3270_max_index < tty->index + 1)
		tty3270_max_index = tty->index + 1;

	/* Allocate tty3270 structure on first open. */
	tp = tty3270_alloc_view();
	if (IS_ERR(tp))
		return PTR_ERR(tp);

	rc = raw3270_add_view(&tp->view, &tty3270_fn,
			      tty->index + RAW3270_FIRSTMINOR,
			      RAW3270_VIEW_LOCK_BH);
	if (rc) {
		tty3270_free_view(tp);
		return rc;
	}

	tp->screen = tty3270_alloc_screen(tp->view.rows, tp->view.cols);
	if (IS_ERR(tp->screen)) {
		rc = PTR_ERR(tp->screen);
		raw3270_put_view(&tp->view);
		raw3270_del_view(&tp->view);
		tty3270_free_view(tp);
		return rc;
	}

	tty->winsize.ws_row = tp->view.rows - 2;
	tty->winsize.ws_col = tp->view.cols;

	tty3270_create_prompt(tp);
	tty3270_create_status(tp);
	tty3270_update_status(tp);

	/* Create blank line for every line in the tty output area. */
	for (i = 0; i < tp->view.rows - 2; i++)
		tty3270_blank_line(tp);

	tp->kbd->port = &tp->port;
	tp->kbd->fn_handler[KVAL(K_INCRCONSOLE)] = tty3270_exit_tty;
	tp->kbd->fn_handler[KVAL(K_SCROLLBACK)] = tty3270_scroll_backward;
	tp->kbd->fn_handler[KVAL(K_SCROLLFORW)] = tty3270_scroll_forward;
	tp->kbd->fn_handler[KVAL(K_CONS)] = tty3270_rcl_backward;
	kbd_ascebc(tp->kbd, tp->view.ascebc);

	raw3270_activate_view(&tp->view);

port_install:
	rc = tty_port_install(&tp->port, driver, tty);
	if (rc) {
		raw3270_put_view(&tp->view);
		return rc;
	}

	tty->driver_data = tp;

	return 0;
}

/*
 * This routine is called whenever a 3270 tty is opened.
 */
static int
tty3270_open(struct tty_struct *tty, struct file *filp)
{
	struct tty3270 *tp = tty->driver_data;
	struct tty_port *port = &tp->port;

	port->count++;
	tty_port_tty_set(port, tty);
	return 0;
}

/*
 * This routine is called when the 3270 tty is closed. We wait
 * for the remaining request to be completed. Then we clean up.
 */
static void
tty3270_close(struct tty_struct *tty, struct file * filp)
{
	struct tty3270 *tp = tty->driver_data;

	if (tty->count > 1)
		return;
	if (tp)
		tty_port_tty_set(&tp->port, NULL);
}

static void tty3270_cleanup(struct tty_struct *tty)
{
	struct tty3270 *tp = tty->driver_data;

	if (tp) {
		tty->driver_data = NULL;
		raw3270_put_view(&tp->view);
	}
}

/*
 * We always have room.
 */
static unsigned int
tty3270_write_room(struct tty_struct *tty)
{
	return INT_MAX;
}

/*
 * Insert character into the screen at the current position with the
 * current color and highlight. This function does NOT do cursor movement.
 */
static void tty3270_put_character(struct tty3270 *tp, char ch)
{
	struct tty3270_line *line;
	struct tty3270_cell *cell;

	line = tp->screen + tp->cy;
	if (line->len <= tp->cx) {
		while (line->len < tp->cx) {
			cell = line->cells + line->len;
			cell->character = tp->view.ascebc[' '];
			cell->highlight = tp->highlight;
			cell->f_color = tp->f_color;
			line->len++;
		}
		line->len++;
	}
	cell = line->cells + tp->cx;
	cell->character = tp->view.ascebc[(unsigned int) ch];
	cell->highlight = tp->highlight;
	cell->f_color = tp->f_color;
}

/*
 * Convert a tty3270_line to a 3270 data fragment usable for output.
 */
static void
tty3270_convert_line(struct tty3270 *tp, int line_nr)
{
	struct tty3270_line *line;
	struct tty3270_cell *cell;
	struct string *s, *n;
	unsigned char highlight;
	unsigned char f_color;
	char *cp;
	int flen, i;

	/* Determine how long the fragment will be. */
	flen = 3;		/* Prefix (TO_SBA). */
	line = tp->screen + line_nr;
	flen += line->len;
	highlight = TAX_RESET;
	f_color = TAC_RESET;
	for (i = 0, cell = line->cells; i < line->len; i++, cell++) {
		if (cell->highlight != highlight) {
			flen += 3;	/* TO_SA to switch highlight. */
			highlight = cell->highlight;
		}
		if (cell->f_color != f_color) {
			flen += 3;	/* TO_SA to switch color. */
			f_color = cell->f_color;
		}
	}
	if (highlight != TAX_RESET)
		flen += 3;	/* TO_SA to reset hightlight. */
	if (f_color != TAC_RESET)
		flen += 3;	/* TO_SA to reset color. */
	if (line->len < tp->view.cols)
		flen += 4;	/* Postfix (TO_RA). */

	/* Find the line in the list. */
	i = tp->view.rows - 2 - line_nr;
	list_for_each_entry_reverse(s, &tp->lines, list)
		if (--i <= 0)
			break;
	/*
	 * Check if the line needs to get reallocated.
	 */
	if (s->len != flen) {
		/* Reallocate string. */
		n = tty3270_alloc_string(tp, flen);
		list_add(&n->list, &s->list);
		list_del_init(&s->list);
		if (!list_empty(&s->update))
			list_del_init(&s->update);
		free_string(&tp->freemem, s);
		s = n;
	}

	/* Write 3270 data fragment. */
	cp = s->string;
	*cp++ = TO_SBA;
	*cp++ = 0;
	*cp++ = 0;

	highlight = TAX_RESET;
	f_color = TAC_RESET;
	for (i = 0, cell = line->cells; i < line->len; i++, cell++) {
		if (cell->highlight != highlight) {
			*cp++ = TO_SA;
			*cp++ = TAT_EXTHI;
			*cp++ = cell->highlight;
			highlight = cell->highlight;
		}
		if (cell->f_color != f_color) {
			*cp++ = TO_SA;
			*cp++ = TAT_COLOR;
			*cp++ = cell->f_color;
			f_color = cell->f_color;
		}
		*cp++ = cell->character;
	}
	if (highlight != TAX_RESET) {
		*cp++ = TO_SA;
		*cp++ = TAT_EXTHI;
		*cp++ = TAX_RESET;
	}
	if (f_color != TAC_RESET) {
		*cp++ = TO_SA;
		*cp++ = TAT_COLOR;
		*cp++ = TAC_RESET;
	}
	if (line->len < tp->view.cols) {
		*cp++ = TO_RA;
		*cp++ = 0;
		*cp++ = 0;
		*cp++ = 0;
	}

	if (tp->nr_up + line_nr < tp->view.rows - 2) {
		/* Line is currently visible on screen. */
		tty3270_update_string(tp, s, line_nr);
		/* Add line to update list. */
		if (list_empty(&s->update)) {
			list_add_tail(&s->update, &tp->update);
			tp->update_flags |= TTY_UPDATE_LIST;
		}
	}
}

/*
 * Do carriage return.
 */
static void
tty3270_cr(struct tty3270 *tp)
{
	tp->cx = 0;
}

/*
 * Do line feed.
 */
static void
tty3270_lf(struct tty3270 *tp)
{
	struct tty3270_line temp;
	int i;

	tty3270_convert_line(tp, tp->cy);
	if (tp->cy < tp->view.rows - 3) {
		tp->cy++;
		return;
	}
	/* Last line just filled up. Add new, blank line. */
	tty3270_blank_line(tp);
	temp = tp->screen[0];
	temp.len = 0;
	for (i = 0; i < tp->view.rows - 3; i++)
		tp->screen[i] = tp->screen[i+1];
	tp->screen[tp->view.rows - 3] = temp;
	tty3270_rebuild_update(tp);
}

static void
tty3270_ri(struct tty3270 *tp)
{
	if (tp->cy > 0) {
	    tty3270_convert_line(tp, tp->cy);
	    tp->cy--;
	}
}

/*
 * Insert characters at current position.
 */
static void
tty3270_insert_characters(struct tty3270 *tp, int n)
{
	struct tty3270_line *line;
	int k;

	line = tp->screen + tp->cy;
	while (line->len < tp->cx) {
		line->cells[line->len].character = tp->view.ascebc[' '];
		line->cells[line->len].highlight = TAX_RESET;
		line->cells[line->len].f_color = TAC_RESET;
		line->len++;
	}
	if (n > tp->view.cols - tp->cx)
		n = tp->view.cols - tp->cx;
	k = min_t(int, line->len - tp->cx, tp->view.cols - tp->cx - n);
	while (k--)
		line->cells[tp->cx + n + k] = line->cells[tp->cx + k];
	line->len += n;
	if (line->len > tp->view.cols)
		line->len = tp->view.cols;
	while (n-- > 0) {
		line->cells[tp->cx + n].character = tp->view.ascebc[' '];
		line->cells[tp->cx + n].highlight = tp->highlight;
		line->cells[tp->cx + n].f_color = tp->f_color;
	}
}

/*
 * Delete characters at current position.
 */
static void
tty3270_delete_characters(struct tty3270 *tp, int n)
{
	struct tty3270_line *line;
	int i;

	line = tp->screen + tp->cy;
	if (line->len <= tp->cx)
		return;
	if (line->len - tp->cx <= n) {
		line->len = tp->cx;
		return;
	}
	for (i = tp->cx; i + n < line->len; i++)
		line->cells[i] = line->cells[i + n];
	line->len -= n;
}

/*
 * Erase characters at current position.
 */
static void
tty3270_erase_characters(struct tty3270 *tp, int n)
{
	struct tty3270_line *line;
	struct tty3270_cell *cell;

	line = tp->screen + tp->cy;
	while (line->len > tp->cx && n-- > 0) {
		cell = line->cells + tp->cx++;
		cell->character = ' ';
		cell->highlight = TAX_RESET;
		cell->f_color = TAC_RESET;
	}
	tp->cx += n;
	tp->cx = min_t(int, tp->cx, tp->view.cols - 1);
}

/*
 * Erase line, 3 different cases:
 *  Esc [ 0 K	Erase from current position to end of line inclusive
 *  Esc [ 1 K	Erase from beginning of line to current position inclusive
 *  Esc [ 2 K	Erase entire line (without moving cursor)
 */
static void
tty3270_erase_line(struct tty3270 *tp, int mode)
{
	struct tty3270_line *line;
	struct tty3270_cell *cell;
	int i;

	line = tp->screen + tp->cy;
	if (mode == 0)
		line->len = tp->cx;
	else if (mode == 1) {
		for (i = 0; i < tp->cx; i++) {
			cell = line->cells + i;
			cell->character = ' ';
			cell->highlight = TAX_RESET;
			cell->f_color = TAC_RESET;
		}
		if (line->len <= tp->cx)
			line->len = tp->cx + 1;
	} else if (mode == 2)
		line->len = 0;
	tty3270_convert_line(tp, tp->cy);
}

/*
 * Erase display, 3 different cases:
 *  Esc [ 0 J	Erase from current position to bottom of screen inclusive
 *  Esc [ 1 J	Erase from top of screen to current position inclusive
 *  Esc [ 2 J	Erase entire screen (without moving the cursor)
 */
static void
tty3270_erase_display(struct tty3270 *tp, int mode)
{
	int i;

	if (mode == 0) {
		tty3270_erase_line(tp, 0);
		for (i = tp->cy + 1; i < tp->view.rows - 2; i++) {
			tp->screen[i].len = 0;
			tty3270_convert_line(tp, i);
		}
	} else if (mode == 1) {
		for (i = 0; i < tp->cy; i++) {
			tp->screen[i].len = 0;
			tty3270_convert_line(tp, i);
		}
		tty3270_erase_line(tp, 1);
	} else if (mode == 2) {
		for (i = 0; i < tp->view.rows - 2; i++) {
			tp->screen[i].len = 0;
			tty3270_convert_line(tp, i);
		}
	}
	tty3270_rebuild_update(tp);
}

/*
 * Set attributes found in an escape sequence.
 *  Esc [ <attr> ; <attr> ; ... m
 */
static void
tty3270_set_attributes(struct tty3270 *tp)
{
	static unsigned char f_colors[] = {
		TAC_DEFAULT, TAC_RED, TAC_GREEN, TAC_YELLOW, TAC_BLUE,
		TAC_PINK, TAC_TURQ, TAC_WHITE, 0, TAC_DEFAULT
	};
	int i, attr;

	for (i = 0; i <= tp->esc_npar; i++) {
		attr = tp->esc_par[i];
		switch (attr) {
		case 0:		/* Reset */
			tp->highlight = TAX_RESET;
			tp->f_color = TAC_RESET;
			break;
		/* Highlight. */
		case 4:		/* Start underlining. */
			tp->highlight = TAX_UNDER;
			break;
		case 5:		/* Start blink. */
			tp->highlight = TAX_BLINK;
			break;
		case 7:		/* Start reverse. */
			tp->highlight = TAX_REVER;
			break;
		case 24:	/* End underlining */
			if (tp->highlight == TAX_UNDER)
				tp->highlight = TAX_RESET;
			break;
		case 25:	/* End blink. */
			if (tp->highlight == TAX_BLINK)
				tp->highlight = TAX_RESET;
			break;
		case 27:	/* End reverse. */
			if (tp->highlight == TAX_REVER)
				tp->highlight = TAX_RESET;
			break;
		/* Foreground color. */
		case 30:	/* Black */
		case 31:	/* Red */
		case 32:	/* Green */
		case 33:	/* Yellow */
		case 34:	/* Blue */
		case 35:	/* Magenta */
		case 36:	/* Cyan */
		case 37:	/* White */
		case 39:	/* Black */
			tp->f_color = f_colors[attr - 30];
			break;
		}
	}
}

static inline int
tty3270_getpar(struct tty3270 *tp, int ix)
{
	return (tp->esc_par[ix] > 0) ? tp->esc_par[ix] : 1;
}

static void
tty3270_goto_xy(struct tty3270 *tp, int cx, int cy)
{
	int max_cx = max(0, cx);
	int max_cy = max(0, cy);

	tp->cx = min_t(int, tp->view.cols - 1, max_cx);
	cy = min_t(int, tp->view.rows - 3, max_cy);
	if (cy != tp->cy) {
		tty3270_convert_line(tp, tp->cy);
		tp->cy = cy;
	}
}

/*
 * Process escape sequences. Known sequences:
 *  Esc 7			Save Cursor Position
 *  Esc 8			Restore Cursor Position
 *  Esc [ Pn ; Pn ; .. m	Set attributes
 *  Esc [ Pn ; Pn H		Cursor Position
 *  Esc [ Pn ; Pn f		Cursor Position
 *  Esc [ Pn A			Cursor Up
 *  Esc [ Pn B			Cursor Down
 *  Esc [ Pn C			Cursor Forward
 *  Esc [ Pn D			Cursor Backward
 *  Esc [ Pn G			Cursor Horizontal Absolute
 *  Esc [ Pn X			Erase Characters
 *  Esc [ Ps J			Erase in Display
 *  Esc [ Ps K			Erase in Line
 * // FIXME: add all the new ones.
 *
 *  Pn is a numeric parameter, a string of zero or more decimal digits.
 *  Ps is a selective parameter.
 */
static void
tty3270_escape_sequence(struct tty3270 *tp, char ch)
{
	enum { ESnormal, ESesc, ESsquare, ESgetpars };

	if (tp->esc_state == ESnormal) {
		if (ch == 0x1b)
			/* Starting new escape sequence. */
			tp->esc_state = ESesc;
		return;
	}
	if (tp->esc_state == ESesc) {
		tp->esc_state = ESnormal;
		switch (ch) {
		case '[':
			tp->esc_state = ESsquare;
			break;
		case 'E':
			tty3270_cr(tp);
			tty3270_lf(tp);
			break;
		case 'M':
			tty3270_ri(tp);
			break;
		case 'D':
			tty3270_lf(tp);
			break;
		case 'Z':		/* Respond ID. */
			kbd_puts_queue(&tp->port, "\033[?6c");
			break;
		case '7':		/* Save cursor position. */
			tp->saved_cx = tp->cx;
			tp->saved_cy = tp->cy;
			tp->saved_highlight = tp->highlight;
			tp->saved_f_color = tp->f_color;
			break;
		case '8':		/* Restore cursor position. */
			tty3270_convert_line(tp, tp->cy);
			tty3270_goto_xy(tp, tp->saved_cx, tp->saved_cy);
			tp->highlight = tp->saved_highlight;
			tp->f_color = tp->saved_f_color;
			break;
		case 'c':		/* Reset terminal. */
			tp->cx = tp->saved_cx = 0;
			tp->cy = tp->saved_cy = 0;
			tp->highlight = tp->saved_highlight = TAX_RESET;
			tp->f_color = tp->saved_f_color = TAC_RESET;
			tty3270_erase_display(tp, 2);
			break;
		}
		return;
	}
	if (tp->esc_state == ESsquare) {
		tp->esc_state = ESgetpars;
		memset(tp->esc_par, 0, sizeof(tp->esc_par));
		tp->esc_npar = 0;
		tp->esc_ques = (ch == '?');
		if (tp->esc_ques)
			return;
	}
	if (tp->esc_state == ESgetpars) {
		if (ch == ';' && tp->esc_npar < ESCAPE_NPAR - 1) {
			tp->esc_npar++;
			return;
		}
		if (ch >= '0' && ch <= '9') {
			tp->esc_par[tp->esc_npar] *= 10;
			tp->esc_par[tp->esc_npar] += ch - '0';
			return;
		}
	}
	tp->esc_state = ESnormal;
	if (ch == 'n' && !tp->esc_ques) {
		if (tp->esc_par[0] == 5)		/* Status report. */
			kbd_puts_queue(&tp->port, "\033[0n");
		else if (tp->esc_par[0] == 6) {	/* Cursor report. */
			char buf[40];
			sprintf(buf, "\033[%d;%dR", tp->cy + 1, tp->cx + 1);
			kbd_puts_queue(&tp->port, buf);
		}
		return;
	}
	if (tp->esc_ques)
		return;
	switch (ch) {
	case 'm':
		tty3270_set_attributes(tp);
		break;
	case 'H':	/* Set cursor position. */
	case 'f':
		tty3270_goto_xy(tp, tty3270_getpar(tp, 1) - 1,
				tty3270_getpar(tp, 0) - 1);
		break;
	case 'd':	/* Set y position. */
		tty3270_goto_xy(tp, tp->cx, tty3270_getpar(tp, 0) - 1);
		break;
	case 'A':	/* Cursor up. */
	case 'F':
		tty3270_goto_xy(tp, tp->cx, tp->cy - tty3270_getpar(tp, 0));
		break;
	case 'B':	/* Cursor down. */
	case 'e':
	case 'E':
		tty3270_goto_xy(tp, tp->cx, tp->cy + tty3270_getpar(tp, 0));
		break;
	case 'C':	/* Cursor forward. */
	case 'a':
		tty3270_goto_xy(tp, tp->cx + tty3270_getpar(tp, 0), tp->cy);
		break;
	case 'D':	/* Cursor backward. */
		tty3270_goto_xy(tp, tp->cx - tty3270_getpar(tp, 0), tp->cy);
		break;
	case 'G':	/* Set x position. */
	case '`':
		tty3270_goto_xy(tp, tty3270_getpar(tp, 0), tp->cy);
		break;
	case 'X':	/* Erase Characters. */
		tty3270_erase_characters(tp, tty3270_getpar(tp, 0));
		break;
	case 'J':	/* Erase display. */
		tty3270_erase_display(tp, tp->esc_par[0]);
		break;
	case 'K':	/* Erase line. */
		tty3270_erase_line(tp, tp->esc_par[0]);
		break;
	case 'P':	/* Delete characters. */
		tty3270_delete_characters(tp, tty3270_getpar(tp, 0));
		break;
	case '@':	/* Insert characters. */
		tty3270_insert_characters(tp, tty3270_getpar(tp, 0));
		break;
	case 's':	/* Save cursor position. */
		tp->saved_cx = tp->cx;
		tp->saved_cy = tp->cy;
		tp->saved_highlight = tp->highlight;
		tp->saved_f_color = tp->f_color;
		break;
	case 'u':	/* Restore cursor position. */
		tty3270_convert_line(tp, tp->cy);
		tty3270_goto_xy(tp, tp->saved_cx, tp->saved_cy);
		tp->highlight = tp->saved_highlight;
		tp->f_color = tp->saved_f_color;
		break;
	}
}

/*
 * String write routine for 3270 ttys
 */
static void
tty3270_do_write(struct tty3270 *tp, struct tty_struct *tty,
		const unsigned char *buf, int count)
{
	int i_msg, i;

	spin_lock_bh(&tp->view.lock);
	for (i_msg = 0; !tty->flow.stopped && i_msg < count; i_msg++) {
		if (tp->esc_state != 0) {
			/* Continue escape sequence. */
			tty3270_escape_sequence(tp, buf[i_msg]);
			continue;
		}

		switch (buf[i_msg]) {
		case 0x07:		/* '\a' -- Alarm */
			tp->wcc |= TW_PLUSALARM;
			break;
		case 0x08:		/* Backspace. */
			if (tp->cx > 0) {
				tp->cx--;
				tty3270_put_character(tp, ' ');
			}
			break;
		case 0x09:		/* '\t' -- Tabulate */
			for (i = tp->cx % 8; i < 8; i++) {
				if (tp->cx >= tp->view.cols) {
					tty3270_cr(tp);
					tty3270_lf(tp);
					break;
				}
				tty3270_put_character(tp, ' ');
				tp->cx++;
			}
			break;
		case 0x0a:		/* '\n' -- New Line */
			tty3270_cr(tp);
			tty3270_lf(tp);
			break;
		case 0x0c:		/* '\f' -- Form Feed */
			tty3270_erase_display(tp, 2);
			tp->cx = tp->cy = 0;
			break;
		case 0x0d:		/* '\r' -- Carriage Return */
			tp->cx = 0;
			break;
		case 0x0f:		/* SuSE "exit alternate mode" */
			break;
		case 0x1b:		/* Start escape sequence. */
			tty3270_escape_sequence(tp, buf[i_msg]);
			break;
		default:		/* Insert normal character. */
			if (tp->cx >= tp->view.cols) {
				tty3270_cr(tp);
				tty3270_lf(tp);
			}
			tty3270_put_character(tp, buf[i_msg]);
			tp->cx++;
			break;
		}
	}
	/* Convert current line to 3270 data fragment. */
	tty3270_convert_line(tp, tp->cy);

	/* Setup timer to update display after 1/10 second */
	if (!timer_pending(&tp->timer))
		tty3270_set_timer(tp, HZ/10);

	spin_unlock_bh(&tp->view.lock);
}

/*
 * String write routine for 3270 ttys
 */
static int
tty3270_write(struct tty_struct * tty,
	      const unsigned char *buf, int count)
{
	struct tty3270 *tp;

	tp = tty->driver_data;
	if (!tp)
		return 0;
	if (tp->char_count > 0) {
		tty3270_do_write(tp, tty, tp->char_buf, tp->char_count);
		tp->char_count = 0;
	}
	tty3270_do_write(tp, tty, buf, count);
	return count;
}

/*
 * Put single characters to the ttys character buffer
 */
static int tty3270_put_char(struct tty_struct *tty, unsigned char ch)
{
	struct tty3270 *tp;

	tp = tty->driver_data;
	if (!tp || tp->char_count >= TTY3270_CHAR_BUF_SIZE)
		return 0;
	tp->char_buf[tp->char_count++] = ch;
	return 1;
}

/*
 * Flush all characters from the ttys characeter buffer put there
 * by tty3270_put_char.
 */
static void
tty3270_flush_chars(struct tty_struct *tty)
{
	struct tty3270 *tp;

	tp = tty->driver_data;
	if (!tp)
		return;
	if (tp->char_count > 0) {
		tty3270_do_write(tp, tty, tp->char_buf, tp->char_count);
		tp->char_count = 0;
	}
}

/*
 * Check for visible/invisible input switches
 */
static void
tty3270_set_termios(struct tty_struct *tty, struct ktermios *old)
{
	struct tty3270 *tp;
	int new;

	tp = tty->driver_data;
	if (!tp)
		return;
	spin_lock_bh(&tp->view.lock);
	if (L_ICANON(tty)) {
		new = L_ECHO(tty) ? TF_INPUT: TF_INPUTN;
		if (new != tp->inattr) {
			tp->inattr = new;
			tty3270_update_prompt(tp, NULL, 0);
			tty3270_set_timer(tp, 1);
		}
	}
	spin_unlock_bh(&tp->view.lock);
}

/*
 * Disable reading from a 3270 tty
 */
static void
tty3270_throttle(struct tty_struct * tty)
{
	struct tty3270 *tp;

	tp = tty->driver_data;
	if (!tp)
		return;
	tp->throttle = 1;
}

/*
 * Enable reading from a 3270 tty
 */
static void
tty3270_unthrottle(struct tty_struct * tty)
{
	struct tty3270 *tp;

	tp = tty->driver_data;
	if (!tp)
		return;
	tp->throttle = 0;
	if (tp->attn)
		tty3270_issue_read(tp, 1);
}

/*
 * Hang up the tty device.
 */
static void
tty3270_hangup(struct tty_struct *tty)
{
	struct tty3270 *tp;

	tp = tty->driver_data;
	if (!tp)
		return;
	spin_lock_bh(&tp->view.lock);
	tp->cx = tp->saved_cx = 0;
	tp->cy = tp->saved_cy = 0;
	tp->highlight = tp->saved_highlight = TAX_RESET;
	tp->f_color = tp->saved_f_color = TAC_RESET;
	tty3270_blank_screen(tp);
	while (tp->nr_lines < tp->view.rows - 2)
		tty3270_blank_line(tp);
	tp->update_flags = TTY_UPDATE_ALL;
	spin_unlock_bh(&tp->view.lock);
	tty3270_set_timer(tp, 1);
}

static void
tty3270_wait_until_sent(struct tty_struct *tty, int timeout)
{
}

static int tty3270_ioctl(struct tty_struct *tty, unsigned int cmd,
			 unsigned long arg)
{
	struct tty3270 *tp;

	tp = tty->driver_data;
	if (!tp)
		return -ENODEV;
	if (tty_io_error(tty))
		return -EIO;
	return kbd_ioctl(tp->kbd, cmd, arg);
}

#ifdef CONFIG_COMPAT
static long tty3270_compat_ioctl(struct tty_struct *tty,
				 unsigned int cmd, unsigned long arg)
{
	struct tty3270 *tp;

	tp = tty->driver_data;
	if (!tp)
		return -ENODEV;
	if (tty_io_error(tty))
		return -EIO;
	return kbd_ioctl(tp->kbd, cmd, (unsigned long)compat_ptr(arg));
}
#endif

static const struct tty_operations tty3270_ops = {
	.install = tty3270_install,
	.cleanup = tty3270_cleanup,
	.open = tty3270_open,
	.close = tty3270_close,
	.write = tty3270_write,
	.put_char = tty3270_put_char,
	.flush_chars = tty3270_flush_chars,
	.write_room = tty3270_write_room,
	.throttle = tty3270_throttle,
	.unthrottle = tty3270_unthrottle,
	.hangup = tty3270_hangup,
	.wait_until_sent = tty3270_wait_until_sent,
	.ioctl = tty3270_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl = tty3270_compat_ioctl,
#endif
	.set_termios = tty3270_set_termios
};

static void tty3270_create_cb(int minor)
{
	tty_register_device(tty3270_driver, minor - RAW3270_FIRSTMINOR, NULL);
}

static void tty3270_destroy_cb(int minor)
{
	tty_unregister_device(tty3270_driver, minor - RAW3270_FIRSTMINOR);
}

static struct raw3270_notifier tty3270_notifier =
{
	.create = tty3270_create_cb,
	.destroy = tty3270_destroy_cb,
};

/*
 * 3270 tty registration code called from tty_init().
 * Most kernel services (incl. kmalloc) are available at this poimt.
 */
static int __init tty3270_init(void)
{
	struct tty_driver *driver;
	int ret;

	driver = tty_alloc_driver(RAW3270_MAXDEVS,
				  TTY_DRIVER_REAL_RAW |
				  TTY_DRIVER_DYNAMIC_DEV |
				  TTY_DRIVER_RESET_TERMIOS);
	if (IS_ERR(driver))
		return PTR_ERR(driver);

	/*
	 * Initialize the tty_driver structure
	 * Entries in tty3270_driver that are NOT initialized:
	 * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc
	 */
	driver->driver_name = "tty3270";
	driver->name = "3270/tty";
	driver->major = IBM_TTY3270_MAJOR;
	driver->minor_start = RAW3270_FIRSTMINOR;
	driver->name_base = RAW3270_FIRSTMINOR;
	driver->type = TTY_DRIVER_TYPE_SYSTEM;
	driver->subtype = SYSTEM_TYPE_TTY;
	driver->init_termios = tty_std_termios;
	tty_set_operations(driver, &tty3270_ops);
	ret = tty_register_driver(driver);
	if (ret) {
		tty_driver_kref_put(driver);
		return ret;
	}
	tty3270_driver = driver;
	raw3270_register_notifier(&tty3270_notifier);
	return 0;
}

static void __exit
tty3270_exit(void)
{
	struct tty_driver *driver;

	raw3270_unregister_notifier(&tty3270_notifier);
	driver = tty3270_driver;
	tty3270_driver = NULL;
	tty_unregister_driver(driver);
	tty_driver_kref_put(driver);
	tty3270_del_views();
}

MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV_MAJOR(IBM_TTY3270_MAJOR);

module_init(tty3270_init);
module_exit(tty3270_exit);
