/*
 *  drivers/s390/char/sclp_tty.c
 *    SCLP line mode terminal driver.
 *
 *  S390 version
 *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *    Author(s): Martin Peschke <mpeschke@de.ibm.com>
 *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
 */

#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>

#include "ctrlchar.h"
#include "sclp.h"
#include "sclp_rw.h"
#include "sclp_tty.h"

#define SCLP_TTY_PRINT_HEADER "sclp tty driver: "

/*
 * size of a buffer that collects single characters coming in
 * via sclp_tty_put_char()
 */
#define SCLP_TTY_BUF_SIZE 512

/*
 * There is exactly one SCLP terminal, so we can keep things simple
 * and allocate all variables statically.
 */

/* Lock to guard over changes to global variables. */
static spinlock_t sclp_tty_lock;
/* List of free pages that can be used for console output buffering. */
static struct list_head sclp_tty_pages;
/* List of full struct sclp_buffer structures ready for output. */
static struct list_head sclp_tty_outqueue;
/* Counter how many buffers are emitted. */
static int sclp_tty_buffer_count;
/* Pointer to current console buffer. */
static struct sclp_buffer *sclp_ttybuf;
/* Timer for delayed output of console messages. */
static struct timer_list sclp_tty_timer;
/* Waitqueue to wait for buffers to get empty. */
static wait_queue_head_t sclp_tty_waitq;

static struct tty_struct *sclp_tty;
static unsigned char sclp_tty_chars[SCLP_TTY_BUF_SIZE];
static unsigned short int sclp_tty_chars_count;

struct tty_driver *sclp_tty_driver;

extern struct termios  tty_std_termios;

static struct sclp_ioctls sclp_ioctls;
static struct sclp_ioctls sclp_ioctls_init =
{
	8,			/* 1 hor. tab. = 8 spaces */
	0,			/* no echo of input by this driver */
	80,			/* 80 characters/line */
	1,			/* write after 1/10 s without final new line */
	MAX_KMEM_PAGES,		/* quick fix: avoid __alloc_pages */
	MAX_KMEM_PAGES,		/* take 32/64 pages from kernel memory, */
	0,			/* do not convert to lower case */
	0x6c			/* to seprate upper and lower case */
				/* ('%' in EBCDIC) */
};

/* This routine is called whenever we try to open a SCLP terminal. */
static int
sclp_tty_open(struct tty_struct *tty, struct file *filp)
{
	sclp_tty = tty;
	tty->driver_data = NULL;
	tty->low_latency = 0;
	return 0;
}

/* This routine is called when the SCLP terminal is closed. */
static void
sclp_tty_close(struct tty_struct *tty, struct file *filp)
{
	if (tty->count > 1)
		return;
	sclp_tty = NULL;
}

/* execute commands to control the i/o behaviour of the SCLP tty at runtime */
static int
sclp_tty_ioctl(struct tty_struct *tty, struct file * file,
	       unsigned int cmd, unsigned long arg)
{
	unsigned long flags;
	unsigned int obuf;
	int check;
	int rc;

	if (tty->flags & (1 << TTY_IO_ERROR))
		return -EIO;
	rc = 0;
	check = 0;
	switch (cmd) {
	case TIOCSCLPSHTAB:
		/* set width of horizontal tab	*/
		if (get_user(sclp_ioctls.htab, (unsigned short __user *) arg))
			rc = -EFAULT;
		else
			check = 1;
		break;
	case TIOCSCLPGHTAB:
		/* get width of horizontal tab	*/
		if (put_user(sclp_ioctls.htab, (unsigned short __user *) arg))
			rc = -EFAULT;
		break;
	case TIOCSCLPSECHO:
		/* enable/disable echo of input */
		if (get_user(sclp_ioctls.echo, (unsigned char __user *) arg))
			rc = -EFAULT;
		break;
	case TIOCSCLPGECHO:
		/* Is echo of input enabled ?  */
		if (put_user(sclp_ioctls.echo, (unsigned char __user *) arg))
			rc = -EFAULT;
		break;
	case TIOCSCLPSCOLS:
		/* set number of columns for output  */
		if (get_user(sclp_ioctls.columns, (unsigned short __user *) arg))
			rc = -EFAULT;
		else
			check = 1;
		break;
	case TIOCSCLPGCOLS:
		/* get number of columns for output  */
		if (put_user(sclp_ioctls.columns, (unsigned short __user *) arg))
			rc = -EFAULT;
		break;
	case TIOCSCLPSNL:
		/* enable/disable writing without final new line character  */
		if (get_user(sclp_ioctls.final_nl, (signed char __user *) arg))
			rc = -EFAULT;
		break;
	case TIOCSCLPGNL:
		/* Is writing without final new line character enabled ?  */
		if (put_user(sclp_ioctls.final_nl, (signed char __user *) arg))
			rc = -EFAULT;
		break;
	case TIOCSCLPSOBUF:
		/*
		 * set the maximum buffers size for output, will be rounded
		 * up to next 4kB boundary and stored as number of SCCBs
		 * (4kB Buffers) limitation: 256 x 4kB
		 */
		if (get_user(obuf, (unsigned int __user *) arg) == 0) {
			if (obuf & 0xFFF)
				sclp_ioctls.max_sccb = (obuf >> 12) + 1;
			else
				sclp_ioctls.max_sccb = (obuf >> 12);
		} else
			rc = -EFAULT;
		break;
	case TIOCSCLPGOBUF:
		/* get the maximum buffers size for output  */
		obuf = sclp_ioctls.max_sccb << 12;
		if (put_user(obuf, (unsigned int __user *) arg))
			rc = -EFAULT;
		break;
	case TIOCSCLPGKBUF:
		/* get the number of buffers got from kernel at startup */
		if (put_user(sclp_ioctls.kmem_sccb, (unsigned short __user *) arg))
			rc = -EFAULT;
		break;
	case TIOCSCLPSCASE:
		/* enable/disable conversion from upper to lower case */
		if (get_user(sclp_ioctls.tolower, (unsigned char __user *) arg))
			rc = -EFAULT;
		break;
	case TIOCSCLPGCASE:
		/* Is conversion from upper to lower case of input enabled? */
		if (put_user(sclp_ioctls.tolower, (unsigned char __user *) arg))
			rc = -EFAULT;
		break;
	case TIOCSCLPSDELIM:
		/*
		 * set special character used for separating upper and
		 * lower case, 0x00 disables this feature
		 */
		if (get_user(sclp_ioctls.delim, (unsigned char __user *) arg))
			rc = -EFAULT;
		break;
	case TIOCSCLPGDELIM:
		/*
		 * get special character used for separating upper and
		 * lower case, 0x00 disables this feature
		 */
		if (put_user(sclp_ioctls.delim, (unsigned char __user *) arg))
			rc = -EFAULT;
		break;
	case TIOCSCLPSINIT:
		/* set initial (default) sclp ioctls  */
		sclp_ioctls = sclp_ioctls_init;
		check = 1;
		break;
	default:
		rc = -ENOIOCTLCMD;
		break;
	}
	if (check) {
		spin_lock_irqsave(&sclp_tty_lock, flags);
		if (sclp_ttybuf != NULL) {
			sclp_set_htab(sclp_ttybuf, sclp_ioctls.htab);
			sclp_set_columns(sclp_ttybuf, sclp_ioctls.columns);
		}
		spin_unlock_irqrestore(&sclp_tty_lock, flags);
	}
	return rc;
}

/*
 * This routine returns the numbers of characters the tty driver
 * will accept for queuing to be written.  This number is subject
 * to change as output buffers get emptied, or if the output flow
 * control is acted. This is not an exact number because not every
 * character needs the same space in the sccb. The worst case is
 * a string of newlines. Every newlines creates a new mto which
 * needs 8 bytes.
 */
static int
sclp_tty_write_room (struct tty_struct *tty)
{
	unsigned long flags;
	struct list_head *l;
	int count;

	spin_lock_irqsave(&sclp_tty_lock, flags);
	count = 0;
	if (sclp_ttybuf != NULL)
		count = sclp_buffer_space(sclp_ttybuf) / sizeof(struct mto);
	list_for_each(l, &sclp_tty_pages)
		count += NR_EMPTY_MTO_PER_SCCB;
	spin_unlock_irqrestore(&sclp_tty_lock, flags);
	return count;
}

static void
sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc)
{
	unsigned long flags;
	void *page;

	do {
		page = sclp_unmake_buffer(buffer);
		spin_lock_irqsave(&sclp_tty_lock, flags);
		/* Remove buffer from outqueue */
		list_del(&buffer->list);
		sclp_tty_buffer_count--;
		list_add_tail((struct list_head *) page, &sclp_tty_pages);
		/* Check if there is a pending buffer on the out queue. */
		buffer = NULL;
		if (!list_empty(&sclp_tty_outqueue))
			buffer = list_entry(sclp_tty_outqueue.next,
					    struct sclp_buffer, list);
		spin_unlock_irqrestore(&sclp_tty_lock, flags);
	} while (buffer && sclp_emit_buffer(buffer, sclp_ttybuf_callback));
	wake_up(&sclp_tty_waitq);
	/* check if the tty needs a wake up call */
	if (sclp_tty != NULL) {
		tty_wakeup(sclp_tty);
	}
}

static inline void
__sclp_ttybuf_emit(struct sclp_buffer *buffer)
{
	unsigned long flags;
	int count;
	int rc;

	spin_lock_irqsave(&sclp_tty_lock, flags);
	list_add_tail(&buffer->list, &sclp_tty_outqueue);
	count = sclp_tty_buffer_count++;
	spin_unlock_irqrestore(&sclp_tty_lock, flags);
	if (count)
		return;
	rc = sclp_emit_buffer(buffer, sclp_ttybuf_callback);
	if (rc)
		sclp_ttybuf_callback(buffer, rc);
}

/*
 * When this routine is called from the timer then we flush the
 * temporary write buffer.
 */
static void
sclp_tty_timeout(unsigned long data)
{
	unsigned long flags;
	struct sclp_buffer *buf;

	spin_lock_irqsave(&sclp_tty_lock, flags);
	buf = sclp_ttybuf;
	sclp_ttybuf = NULL;
	spin_unlock_irqrestore(&sclp_tty_lock, flags);

	if (buf != NULL) {
		__sclp_ttybuf_emit(buf);
	}
}

/*
 * Write a string to the sclp tty.
 */
static void
sclp_tty_write_string(const unsigned char *str, int count)
{
	unsigned long flags;
	void *page;
	int written;
	struct sclp_buffer *buf;

	if (count <= 0)
		return;
	spin_lock_irqsave(&sclp_tty_lock, flags);
	do {
		/* Create a sclp output buffer if none exists yet */
		if (sclp_ttybuf == NULL) {
			while (list_empty(&sclp_tty_pages)) {
				spin_unlock_irqrestore(&sclp_tty_lock, flags);
				if (in_interrupt())
					sclp_sync_wait();
				else
					wait_event(sclp_tty_waitq,
						!list_empty(&sclp_tty_pages));
				spin_lock_irqsave(&sclp_tty_lock, flags);
			}
			page = sclp_tty_pages.next;
			list_del((struct list_head *) page);
			sclp_ttybuf = sclp_make_buffer(page,
						       sclp_ioctls.columns,
						       sclp_ioctls.htab);
		}
		/* try to write the string to the current output buffer */
		written = sclp_write(sclp_ttybuf, str, count);
		if (written == count)
			break;
		/*
		 * Not all characters could be written to the current
		 * output buffer. Emit the buffer, create a new buffer
		 * and then output the rest of the string.
		 */
		buf = sclp_ttybuf;
		sclp_ttybuf = NULL;
		spin_unlock_irqrestore(&sclp_tty_lock, flags);
		__sclp_ttybuf_emit(buf);
		spin_lock_irqsave(&sclp_tty_lock, flags);
		str += written;
		count -= written;
	} while (count > 0);
	/* Setup timer to output current console buffer after 1/10 second */
	if (sclp_ioctls.final_nl) {
		if (sclp_ttybuf != NULL &&
		    sclp_chars_in_buffer(sclp_ttybuf) != 0 &&
		    !timer_pending(&sclp_tty_timer)) {
			init_timer(&sclp_tty_timer);
			sclp_tty_timer.function = sclp_tty_timeout;
			sclp_tty_timer.data = 0UL;
			sclp_tty_timer.expires = jiffies + HZ/10;
			add_timer(&sclp_tty_timer);
		}
	} else {
		if (sclp_ttybuf != NULL &&
		    sclp_chars_in_buffer(sclp_ttybuf) != 0) {
			buf = sclp_ttybuf;
			sclp_ttybuf = NULL;
			spin_unlock_irqrestore(&sclp_tty_lock, flags);
			__sclp_ttybuf_emit(buf);
			spin_lock_irqsave(&sclp_tty_lock, flags);
		}
	}
	spin_unlock_irqrestore(&sclp_tty_lock, flags);
}

/*
 * This routine is called by the kernel to write a series of characters to the
 * tty device. The characters may come from user space or kernel space. This
 * routine will return the number of characters actually accepted for writing.
 */
static int
sclp_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
	if (sclp_tty_chars_count > 0) {
		sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count);
		sclp_tty_chars_count = 0;
	}
	sclp_tty_write_string(buf, count);
	return count;
}

/*
 * This routine is called by the kernel to write a single character to the tty
 * device. If the kernel uses this routine, it must call the flush_chars()
 * routine (if defined) when it is done stuffing characters into the driver.
 *
 * Characters provided to sclp_tty_put_char() are buffered by the SCLP driver.
 * If the given character is a '\n' the contents of the SCLP write buffer
 * - including previous characters from sclp_tty_put_char() and strings from
 * sclp_write() without final '\n' - will be written.
 */
static void
sclp_tty_put_char(struct tty_struct *tty, unsigned char ch)
{
	sclp_tty_chars[sclp_tty_chars_count++] = ch;
	if (ch == '\n' || sclp_tty_chars_count >= SCLP_TTY_BUF_SIZE) {
		sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count);
		sclp_tty_chars_count = 0;
	}
}

/*
 * This routine is called by the kernel after it has written a series of
 * characters to the tty device using put_char().
 */
static void
sclp_tty_flush_chars(struct tty_struct *tty)
{
	if (sclp_tty_chars_count > 0) {
		sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count);
		sclp_tty_chars_count = 0;
	}
}

/*
 * This routine returns the number of characters in the write buffer of the
 * SCLP driver. The provided number includes all characters that are stored
 * in the SCCB (will be written next time the SCLP is not busy) as well as
 * characters in the write buffer (will not be written as long as there is a
 * final line feed missing).
 */
static int
sclp_tty_chars_in_buffer(struct tty_struct *tty)
{
	unsigned long flags;
	struct list_head *l;
	struct sclp_buffer *t;
	int count;

	spin_lock_irqsave(&sclp_tty_lock, flags);
	count = 0;
	if (sclp_ttybuf != NULL)
		count = sclp_chars_in_buffer(sclp_ttybuf);
	list_for_each(l, &sclp_tty_outqueue) {
		t = list_entry(l, struct sclp_buffer, list);
		count += sclp_chars_in_buffer(t);
	}
	spin_unlock_irqrestore(&sclp_tty_lock, flags);
	return count;
}

/*
 * removes all content from buffers of low level driver
 */
static void
sclp_tty_flush_buffer(struct tty_struct *tty)
{
	if (sclp_tty_chars_count > 0) {
		sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count);
		sclp_tty_chars_count = 0;
	}
}

/*
 * push input to tty
 */
static void
sclp_tty_input(unsigned char* buf, unsigned int count)
{
	unsigned int cchar;

	/*
	 * If this tty driver is currently closed
	 * then throw the received input away.
	 */
	if (sclp_tty == NULL)
		return;
	cchar = ctrlchar_handle(buf, count, sclp_tty);
	switch (cchar & CTRLCHAR_MASK) {
	case CTRLCHAR_SYSRQ:
		break;
	case CTRLCHAR_CTRL:
		tty_insert_flip_char(sclp_tty, cchar, TTY_NORMAL);
		tty_flip_buffer_push(sclp_tty);
		break;
	case CTRLCHAR_NONE:
		/* send (normal) input to line discipline */
		if (count < 2 ||
		    (strncmp((const char *) buf + count - 2, "^n", 2) &&
		     strncmp((const char *) buf + count - 2, "\252n", 2))) {
			/* add the auto \n */
			tty_insert_flip_string(sclp_tty, buf, count);
			tty_insert_flip_char(sclp_tty, '\n', TTY_NORMAL);
		} else
			tty_insert_flip_string(sclp_tty, buf, count - 2);
		tty_flip_buffer_push(sclp_tty);
		break;
	}
}

/*
 * get a EBCDIC string in upper/lower case,
 * find out characters in lower/upper case separated by a special character,
 * modifiy original string,
 * returns length of resulting string
 */
static int
sclp_switch_cases(unsigned char *buf, int count,
		  unsigned char delim, int tolower)
{
	unsigned char *ip, *op;
	int toggle;

	/* initially changing case is off */
	toggle = 0;
	ip = op = buf;
	while (count-- > 0) {
		/* compare with special character */
		if (*ip == delim) {
			/* followed by another special character? */
			if (count && ip[1] == delim) {
				/*
				 * ... then put a single copy of the special
				 * character to the output string
				 */
				*op++ = *ip++;
				count--;
			} else
				/*
				 * ... special character follower by a normal
				 * character toggles the case change behaviour
				 */
				toggle = ~toggle;
			/* skip special character */
			ip++;
		} else
			/* not the special character */
			if (toggle)
				/* but case switching is on */
				if (tolower)
					/* switch to uppercase */
					*op++ = _ebc_toupper[(int) *ip++];
				else
					/* switch to lowercase */
					*op++ = _ebc_tolower[(int) *ip++];
			else
				/* no case switching, copy the character */
				*op++ = *ip++;
	}
	/* return length of reformatted string. */
	return op - buf;
}

static void
sclp_get_input(unsigned char *start, unsigned char *end)
{
	int count;

	count = end - start;
	/*
	 * if set in ioctl convert EBCDIC to lower case
	 * (modify original input in SCCB)
	 */
	if (sclp_ioctls.tolower)
		EBC_TOLOWER(start, count);

	/*
	 * if set in ioctl find out characters in lower or upper case
	 * (depends on current case) separated by a special character,
	 * works on EBCDIC
	 */
	if (sclp_ioctls.delim)
		count = sclp_switch_cases(start, count,
					  sclp_ioctls.delim,
					  sclp_ioctls.tolower);

	/* convert EBCDIC to ASCII (modify original input in SCCB) */
	sclp_ebcasc_str(start, count);

	/* if set in ioctl write operators input to console  */
	if (sclp_ioctls.echo)
		sclp_tty_write(sclp_tty, start, count);

	/* transfer input to high level driver */
	sclp_tty_input(start, count);
}

static inline struct gds_vector *
find_gds_vector(struct gds_vector *start, struct gds_vector *end, u16 id)
{
	struct gds_vector *vec;

	for (vec = start; vec < end; vec = (void *) vec + vec->length)
		if (vec->gds_id == id)
			return vec;
	return NULL;
}

static inline struct gds_subvector *
find_gds_subvector(struct gds_subvector *start,
		   struct gds_subvector *end, u8 key)
{
	struct gds_subvector *subvec;

	for (subvec = start; subvec < end;
	     subvec = (void *) subvec + subvec->length)
		if (subvec->key == key)
			return subvec;
	return NULL;
}

static inline void
sclp_eval_selfdeftextmsg(struct gds_subvector *start,
			 struct gds_subvector *end)
{
	struct gds_subvector *subvec;

	subvec = start;
	while (subvec < end) {
		subvec = find_gds_subvector(subvec, end, 0x30);
		if (!subvec)
			break;
		sclp_get_input((unsigned char *)(subvec + 1),
			       (unsigned char *) subvec + subvec->length);
		subvec = (void *) subvec + subvec->length;
	}
}

static inline void
sclp_eval_textcmd(struct gds_subvector *start,
		  struct gds_subvector *end)
{
	struct gds_subvector *subvec;

	subvec = start;
	while (subvec < end) {
		subvec = find_gds_subvector(subvec, end,
					    GDS_KEY_SelfDefTextMsg);
		if (!subvec)
			break;
		sclp_eval_selfdeftextmsg((struct gds_subvector *)(subvec + 1),
					 (void *)subvec + subvec->length);
		subvec = (void *) subvec + subvec->length;
	}
}

static inline void
sclp_eval_cpmsu(struct gds_vector *start, struct gds_vector *end)
{
	struct gds_vector *vec;

	vec = start;
	while (vec < end) {
		vec = find_gds_vector(vec, end, GDS_ID_TextCmd);
		if (!vec)
			break;
		sclp_eval_textcmd((struct gds_subvector *)(vec + 1),
				  (void *) vec + vec->length);
		vec = (void *) vec + vec->length;
	}
}


static inline void
sclp_eval_mdsmu(struct gds_vector *start, void *end)
{
	struct gds_vector *vec;

	vec = find_gds_vector(start, end, GDS_ID_CPMSU);
	if (vec)
		sclp_eval_cpmsu(vec + 1, (void *) vec + vec->length);
}

static void
sclp_tty_receiver(struct evbuf_header *evbuf)
{
	struct gds_vector *start, *end, *vec;

	start = (struct gds_vector *)(evbuf + 1);
	end = (void *) evbuf + evbuf->length;
	vec = find_gds_vector(start, end, GDS_ID_MDSMU);
	if (vec)
		sclp_eval_mdsmu(vec + 1, (void *) vec + vec->length);
}

static void
sclp_tty_state_change(struct sclp_register *reg)
{
}

static struct sclp_register sclp_input_event =
{
	.receive_mask = EvTyp_OpCmd_Mask | EvTyp_PMsgCmd_Mask,
	.state_change_fn = sclp_tty_state_change,
	.receiver_fn = sclp_tty_receiver
};

static struct tty_operations sclp_ops = {
	.open = sclp_tty_open,
	.close = sclp_tty_close,
	.write = sclp_tty_write,
	.put_char = sclp_tty_put_char,
	.flush_chars = sclp_tty_flush_chars,
	.write_room = sclp_tty_write_room,
	.chars_in_buffer = sclp_tty_chars_in_buffer,
	.flush_buffer = sclp_tty_flush_buffer,
	.ioctl = sclp_tty_ioctl,
};

int __init
sclp_tty_init(void)
{
	struct tty_driver *driver;
	void *page;
	int i;
	int rc;

	if (!CONSOLE_IS_SCLP)
		return 0;
	driver = alloc_tty_driver(1);
	if (!driver)
		return -ENOMEM;

	rc = sclp_rw_init();
	if (rc) {
		printk(KERN_ERR SCLP_TTY_PRINT_HEADER
		       "could not register tty - "
		       "sclp_rw_init returned %d\n", rc);
		put_tty_driver(driver);
		return rc;
	}
	/* Allocate pages for output buffering */
	INIT_LIST_HEAD(&sclp_tty_pages);
	for (i = 0; i < MAX_KMEM_PAGES; i++) {
		page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
		if (page == NULL) {
			put_tty_driver(driver);
			return -ENOMEM;
		}
		list_add_tail((struct list_head *) page, &sclp_tty_pages);
	}
	INIT_LIST_HEAD(&sclp_tty_outqueue);
	spin_lock_init(&sclp_tty_lock);
	init_waitqueue_head(&sclp_tty_waitq);
	init_timer(&sclp_tty_timer);
	sclp_ttybuf = NULL;
	sclp_tty_buffer_count = 0;
	if (MACHINE_IS_VM) {
		/*
		 * save 4 characters for the CPU number
		 * written at start of each line by VM/CP
		 */
		sclp_ioctls_init.columns = 76;
		/* case input lines to lowercase */
		sclp_ioctls_init.tolower = 1;
	}
	sclp_ioctls = sclp_ioctls_init;
	sclp_tty_chars_count = 0;
	sclp_tty = NULL;

	rc = sclp_register(&sclp_input_event);
	if (rc) {
		put_tty_driver(driver);
		return rc;
	}

	driver->owner = THIS_MODULE;
	driver->driver_name = "sclp_line";
	driver->name = "sclp_line";
	driver->major = TTY_MAJOR;
	driver->minor_start = 64;
	driver->type = TTY_DRIVER_TYPE_SYSTEM;
	driver->subtype = SYSTEM_TYPE_TTY;
	driver->init_termios = tty_std_termios;
	driver->init_termios.c_iflag = IGNBRK | IGNPAR;
	driver->init_termios.c_oflag = ONLCR | XTABS;
	driver->init_termios.c_lflag = ISIG | ECHO;
	driver->flags = TTY_DRIVER_REAL_RAW;
	tty_set_operations(driver, &sclp_ops);
	rc = tty_register_driver(driver);
	if (rc) {
		printk(KERN_ERR SCLP_TTY_PRINT_HEADER
		       "could not register tty - "
		       "tty_register_driver returned %d\n", rc);
		put_tty_driver(driver);
		return rc;
	}
	sclp_tty_driver = driver;
	return 0;
}
module_init(sclp_tty_init);
