/*
 *  drivers/s390/char/con3270.c
 *    IBM/3270 Driver - console view.
 *
 *  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 (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
 */

#include <linux/bootmem.h>
#include <linux/console.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/types.h>
#include <linux/err.h>

#include <asm/ccwdev.h>
#include <asm/cio.h>
#include <asm/cpcmd.h>
#include <asm/ebcdic.h>

#include "raw3270.h"
#include "ctrlchar.h"

#define CON3270_OUTPUT_BUFFER_SIZE 1024
#define CON3270_STRING_PAGES 4

static struct raw3270_fn con3270_fn;

/*
 * Main 3270 console view data structure.
 */
struct con3270 {
	struct raw3270_view view;
	spinlock_t lock;
	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. */
	int line_nr;			/* line number for next update. */
	int nr_lines;			/* # lines in list. */
	int nr_up;			/* # lines up in history. */
	unsigned long update_flags;	/* Update indication bits. */
	struct string *cline;		/* current output line. */
	struct string *status;		/* last line of display. */
	struct raw3270_request *write;	/* single write request. */
	struct timer_list timer;

	/* Input stuff. */
	struct string *input;		/* input string for read request. */
	struct raw3270_request *read;	/* single read request. */
	struct raw3270_request *kreset;	/* single keyboard reset request. */
	struct tasklet_struct readlet;	/* tasklet to issue read request. */
};

static struct con3270 *condev;

/* con3270->update_flags. See con3270_update for details. */
#define CON_UPDATE_ERASE	1	/* Use EWRITEA instead of WRITE. */
#define CON_UPDATE_LIST		2	/* Update lines in tty3270->update. */
#define CON_UPDATE_STATUS	4	/* Update status line. */
#define CON_UPDATE_ALL		7

static void con3270_update(struct con3270 *);

/*
 * Setup timeout for a device. On timeout trigger an update.
 */
static void con3270_set_timer(struct con3270 *cp, int expires)
{
	if (expires == 0) {
		if (timer_pending(&cp->timer))
			del_timer(&cp->timer);
		return;
	}
	if (timer_pending(&cp->timer) &&
	    mod_timer(&cp->timer, jiffies + expires))
		return;
	cp->timer.function = (void (*)(unsigned long)) con3270_update;
	cp->timer.data = (unsigned long) cp;
	cp->timer.expires = jiffies + expires;
	add_timer(&cp->timer);
}

/*
 * The status line is the last line of the screen. It shows the string
 * "console view" in the lower left corner and "Running"/"More..."/"Holding"
 * in the lower right corner of the screen.
 */
static void
con3270_update_status(struct con3270 *cp)
{
	char *str;

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

static void
con3270_create_status(struct con3270 *cp)
{
	static const unsigned char blueprint[] =
		{ TO_SBA, 0, 0, TO_SF,TF_LOG,TO_SA,TAT_COLOR, TAC_GREEN,
		  'c','o','n','s','o','l','e',' ','v','i','e','w',
		  TO_RA,0,0,0,'R','u','n','n','i','n','g',TO_SF,TF_LOG };

	cp->status = alloc_string(&cp->freemem, sizeof(blueprint));
	/* Copy blueprint to status line */
	memcpy(cp->status->string, blueprint, sizeof(blueprint));
	/* Set TO_RA addresses. */
	raw3270_buffer_address(cp->view.dev, cp->status->string + 1,
			       cp->view.cols * (cp->view.rows - 1));
	raw3270_buffer_address(cp->view.dev, cp->status->string + 21,
			       cp->view.cols * cp->view.rows - 8);
	/* Convert strings to ebcdic. */
	codepage_convert(cp->view.ascebc, cp->status->string + 8, 12);
	codepage_convert(cp->view.ascebc, cp->status->string + 24, 7);
}

/*
 * Set output offsets to 3270 datastream fragment of a console string.
 */
static void
con3270_update_string(struct con3270 *cp, struct string *s, int nr)
{
	if (s->len >= cp->view.cols - 5)
		return;
	raw3270_buffer_address(cp->view.dev, s->string + s->len - 3,
			       cp->view.cols * (nr + 1));
}

/*
 * Rebuild update list to print all lines.
 */
static void
con3270_rebuild_update(struct con3270 *cp)
{
	struct string *s, *n;
	int nr;

	/* 
	 * 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, &cp->update, update)
		list_del_init(&s->update);
	nr = cp->view.rows - 2 + cp->nr_up;
	list_for_each_entry_reverse(s, &cp->lines, list) {
		if (nr < cp->view.rows - 1)
			list_add(&s->update, &cp->update);
		if (--nr < 0)
			break;
	}
	cp->line_nr = 0;
	cp->update_flags |= CON_UPDATE_LIST;
}

/*
 * Alloc string for size bytes. Free strings from history if necessary.
 */
static struct string *
con3270_alloc_string(struct con3270 *cp, size_t size)
{
	struct string *s, *n;

	s = alloc_string(&cp->freemem, size);
	if (s)
		return s;
	list_for_each_entry_safe(s, n, &cp->lines, list) {
		list_del(&s->list);
		if (!list_empty(&s->update))
			list_del(&s->update);
		cp->nr_lines--;
		if (free_string(&cp->freemem, s) >= size)
			break;
	}
	s = alloc_string(&cp->freemem, size);
	BUG_ON(!s);
	if (cp->nr_up != 0 && cp->nr_up + cp->view.rows > cp->nr_lines) {
		cp->nr_up = cp->nr_lines - cp->view.rows + 1;
		con3270_rebuild_update(cp);
		con3270_update_status(cp);
	}
	return s;
}

/*
 * Write completion callback.
 */
static void
con3270_write_callback(struct raw3270_request *rq, void *data)
{
	raw3270_request_reset(rq);
	xchg(&((struct con3270 *) rq->view)->write, rq);
}

/*
 * Update console display.
 */
static void
con3270_update(struct con3270 *cp)
{
	struct raw3270_request *wrq;
	char wcc, prolog[6];
	unsigned long flags;
	unsigned long updated;
	struct string *s, *n;
	int rc;

	if (cp->view.dev)
		raw3270_activate_view(&cp->view);

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

	spin_lock_irqsave(&cp->view.lock, flags);
	updated = 0;
	if (cp->update_flags & CON_UPDATE_ERASE) {
		/* Use erase write alternate to initialize display. */
		raw3270_request_set_cmd(wrq, TC_EWRITEA);
		updated |= CON_UPDATE_ERASE;
	} else
		raw3270_request_set_cmd(wrq, TC_WRITE);

	wcc = TW_NONE;
	raw3270_request_add_data(wrq, &wcc, 1);

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

	if (cp->update_flags & CON_UPDATE_LIST) {
		prolog[0] = TO_SBA;
		prolog[3] = TO_SA;
		prolog[4] = TAT_COLOR;
		prolog[5] = TAC_TURQ;
		raw3270_buffer_address(cp->view.dev, prolog + 1,
				       cp->view.cols * cp->line_nr);
		raw3270_request_add_data(wrq, prolog, 6);
		/* Write strings in the update list to the screen. */
		list_for_each_entry_safe(s, n, &cp->update, update) {
			if (s != cp->cline)
				con3270_update_string(cp, s, cp->line_nr);
			if (raw3270_request_add_data(wrq, s->string,
						     s->len) != 0)
				break;
			list_del_init(&s->update);
			if (s != cp->cline)
				cp->line_nr++;
		}
		if (list_empty(&cp->update))
			updated |= CON_UPDATE_LIST;
	}
	wrq->callback = con3270_write_callback;
	rc = raw3270_start(&cp->view, wrq);
	if (rc == 0) {
		cp->update_flags &= ~updated;
		if (cp->update_flags)
			con3270_set_timer(cp, 1);
	} else {
		raw3270_request_reset(wrq);
		xchg(&cp->write, wrq);
	}
	spin_unlock_irqrestore(&cp->view.lock, flags);
}

/*
 * Read tasklet.
 */
static void
con3270_read_tasklet(struct raw3270_request *rrq)
{
	static char kreset_data = TW_KR;
	struct con3270 *cp;
	unsigned long flags;
	int nr_up, deactivate;

	cp = (struct con3270 *) rrq->view;
	spin_lock_irqsave(&cp->view.lock, flags);
	nr_up = cp->nr_up;
	deactivate = 0;
	/* Check aid byte. */
	switch (cp->input->string[0]) {
	case 0x7d:	/* enter: jump to bottom. */
		nr_up = 0;
		break;
	case 0xf3:	/* PF3: deactivate the console view. */
		deactivate = 1;
		break;
	case 0x6d:	/* clear: start from scratch. */
		con3270_rebuild_update(cp);
		cp->update_flags = CON_UPDATE_ALL;
		con3270_set_timer(cp, 1);
		break;
	case 0xf7:	/* PF7: do a page up in the console log. */
		nr_up += cp->view.rows - 2;
		if (nr_up + cp->view.rows - 1 > cp->nr_lines) {
			nr_up = cp->nr_lines - cp->view.rows + 1;
			if (nr_up < 0)
				nr_up = 0;
		}
		break;
	case 0xf8:	/* PF8: do a page down in the console log. */
		nr_up -= cp->view.rows - 2;
		if (nr_up < 0)
			nr_up = 0;
		break;
	}
	if (nr_up != cp->nr_up) {
		cp->nr_up = nr_up;
		con3270_rebuild_update(cp);
		con3270_update_status(cp);
		con3270_set_timer(cp, 1);
	}
	spin_unlock_irqrestore(&cp->view.lock, flags);

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

	if (deactivate)
		raw3270_deactivate_view(&cp->view);

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

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

/*
 * Issue a read request. Called only from interrupt function.
 */
static void
con3270_issue_read(struct con3270 *cp)
{
	struct raw3270_request *rrq;
	int rc;

	rrq = xchg(&cp->read, 0);
	if (!rrq)
		/* Read already scheduled. */
		return;
	rrq->callback = con3270_read_callback;
	rrq->callback_data = cp;
	raw3270_request_set_cmd(rrq, TC_READMOD);
	raw3270_request_set_data(rrq, cp->input->string, cp->input->len);
	/* Issue the read modified request. */
	rc = raw3270_start_irq(&cp->view, rrq);
	if (rc)
		raw3270_request_reset(rrq);
}

/*
 * Switch to the console view.
 */
static int
con3270_activate(struct raw3270_view *view)
{
	unsigned long flags;
	struct con3270 *cp;

	cp = (struct con3270 *) view;
	spin_lock_irqsave(&cp->view.lock, flags);
	cp->nr_up = 0;
	con3270_rebuild_update(cp);
	con3270_update_status(cp);
	cp->update_flags = CON_UPDATE_ALL;
	con3270_set_timer(cp, 1);
	spin_unlock_irqrestore(&cp->view.lock, flags);
	return 0;
}

static void
con3270_deactivate(struct raw3270_view *view)
{
	unsigned long flags;
	struct con3270 *cp;

	cp = (struct con3270 *) view;
	spin_lock_irqsave(&cp->view.lock, flags);
	del_timer(&cp->timer);
	spin_unlock_irqrestore(&cp->view.lock, flags);
}

static int
con3270_irq(struct con3270 *cp, struct raw3270_request *rq, struct irb *irb)
{
	/* Handle ATTN. Schedule tasklet to read aid. */
	if (irb->scsw.dstat & DEV_STAT_ATTENTION)
		con3270_issue_read(cp);

	if (rq) {
		if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK)
			rq->rc = -EIO;
		else
			/* Normal end. Copy residual count. */
			rq->rescnt = irb->scsw.count;
	}
	return RAW3270_IO_DONE;
}

/* Console view to a 3270 device. */
static struct raw3270_fn con3270_fn = {
	.activate = con3270_activate,
	.deactivate = con3270_deactivate,
	.intv = (void *) con3270_irq
};

static inline void
con3270_cline_add(struct con3270 *cp)
{
	if (!list_empty(&cp->cline->list))
		/* Already added. */
		return;
	list_add_tail(&cp->cline->list, &cp->lines);
	cp->nr_lines++;
	con3270_rebuild_update(cp);
}

static inline void
con3270_cline_insert(struct con3270 *cp, unsigned char c)
{
	cp->cline->string[cp->cline->len++] = 
		cp->view.ascebc[(c < ' ') ? ' ' : c];
	if (list_empty(&cp->cline->update)) {
		list_add_tail(&cp->cline->update, &cp->update);
		cp->update_flags |= CON_UPDATE_LIST;
	}
}

static inline void
con3270_cline_end(struct con3270 *cp)
{
	struct string *s;
	unsigned int size;

	/* Copy cline. */
	size = (cp->cline->len < cp->view.cols - 5) ?
		cp->cline->len + 4 : cp->view.cols;
	s = con3270_alloc_string(cp, size);
	memcpy(s->string, cp->cline->string, cp->cline->len);
	if (s->len < cp->view.cols - 5) {
		s->string[s->len - 4] = TO_RA;
		s->string[s->len - 1] = 0;
	} else {
		while (--size > cp->cline->len)
			s->string[size] = cp->view.ascebc[' '];
	}
	/* Replace cline with allocated line s and reset cline. */
	list_add(&s->list, &cp->cline->list);
	list_del_init(&cp->cline->list);
	if (!list_empty(&cp->cline->update)) {
		list_add(&s->update, &cp->cline->update);
		list_del_init(&cp->cline->update);
	}
	cp->cline->len = 0;
}

/*
 * Write a string to the 3270 console
 */
static void
con3270_write(struct console *co, const char *str, unsigned int count)
{
	struct con3270 *cp;
	unsigned long flags;
	unsigned char c;

	cp = condev;
	spin_lock_irqsave(&cp->view.lock, flags);
	while (count-- > 0) {
		c = *str++;
		if (cp->cline->len == 0)
			con3270_cline_add(cp);
		if (c != '\n')
			con3270_cline_insert(cp, c);
		if (c == '\n' || cp->cline->len >= cp->view.cols)
			con3270_cline_end(cp);
	}
	/* Setup timer to output current console buffer after 1/10 second */
	if (cp->view.dev && !timer_pending(&cp->timer))
		con3270_set_timer(cp, HZ/10);
	spin_unlock_irqrestore(&cp->view.lock,flags);
}

extern struct tty_driver *tty3270_driver;

static struct tty_driver *
con3270_device(struct console *c, int *index)
{
	*index = c->index;
	return tty3270_driver;
}

/*
 * Wait for end of write request.
 */
static void
con3270_wait_write(struct con3270 *cp)
{
	while (!cp->write) {
		raw3270_wait_cons_dev(cp->view.dev);
		barrier();
	}
}

/*
 * panic() calls console_unblank before the system enters a
 * disabled, endless loop.
 */
static void
con3270_unblank(void)
{
	struct con3270 *cp;
	unsigned long flags;

	cp = condev;
	if (!cp->view.dev)
		return;
	spin_lock_irqsave(&cp->view.lock, flags);
	con3270_wait_write(cp);
	cp->nr_up = 0;
	con3270_rebuild_update(cp);
	con3270_update_status(cp);
	while (cp->update_flags != 0) {
		spin_unlock_irqrestore(&cp->view.lock, flags);
		con3270_update(cp);
		spin_lock_irqsave(&cp->view.lock, flags);
		con3270_wait_write(cp);
	}
	spin_unlock_irqrestore(&cp->view.lock, flags);
}

/*
 *  The console structure for the 3270 console
 */
static struct console con3270 = {
	.name	 = "tty3270",
	.write	 = con3270_write,
	.device	 = con3270_device,
	.unblank = con3270_unblank,
	.flags	 = CON_PRINTBUFFER,
};

/*
 * 3270 console initialization code called from console_init().
 * NOTE: This is called before kmalloc is available.
 */
static int __init
con3270_init(void)
{
	struct ccw_device *cdev;
	struct raw3270 *rp;
	void *cbuf;
	int i;

	/* Check if 3270 is to be the console */
	if (!CONSOLE_IS_3270)
		return -ENODEV;

	/* Set the console mode for VM */
	if (MACHINE_IS_VM) {
		cpcmd("TERM CONMODE 3270", NULL, 0, NULL);
		cpcmd("TERM AUTOCR OFF", NULL, 0, NULL);
	}

	cdev = ccw_device_probe_console();
	if (IS_ERR(cdev))
		return -ENODEV;
	rp = raw3270_setup_console(cdev);
	if (IS_ERR(rp))
		return PTR_ERR(rp);

	condev = (struct con3270 *) alloc_bootmem_low(sizeof(struct con3270));
	memset(condev, 0, sizeof(struct con3270));
	condev->view.dev = rp;

	condev->read = raw3270_request_alloc_bootmem(0);
	condev->read->callback = con3270_read_callback;
	condev->read->callback_data = condev;
	condev->write = 
		raw3270_request_alloc_bootmem(CON3270_OUTPUT_BUFFER_SIZE);
	condev->kreset = raw3270_request_alloc_bootmem(1);

	INIT_LIST_HEAD(&condev->lines);
	INIT_LIST_HEAD(&condev->update);
	init_timer(&condev->timer);
	tasklet_init(&condev->readlet, 
		     (void (*)(unsigned long)) con3270_read_tasklet,
		     (unsigned long) condev->read);

	raw3270_add_view(&condev->view, &con3270_fn, 1);

	INIT_LIST_HEAD(&condev->freemem);
	for (i = 0; i < CON3270_STRING_PAGES; i++) {
		cbuf = (void *) alloc_bootmem_low_pages(PAGE_SIZE);
		add_string_memory(&condev->freemem, cbuf, PAGE_SIZE);
	}
	condev->cline = alloc_string(&condev->freemem, condev->view.cols);
	condev->cline->len = 0;
	con3270_create_status(condev);
	condev->input = alloc_string(&condev->freemem, 80);
	register_console(&con3270);
	return 0;
}

console_initcall(con3270_init);
