⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tubtty.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  IBM/3270 Driver -- Copyright (C) 2000, 2001 UTS Global LLC * *  tubtty.c -- Linemode tty driver * * * * * *  Author:  Richard Hitt */#include <linux/config.h>#include "tubio.h"/* Initialization & uninitialization for tubtty */int tty3270_init(void);void tty3270_fini(void);/* Interface routines from the upper tty layer to the tty driver */static int tty3270_open(struct tty_struct *, struct file *);static void tty3270_close(struct tty_struct *, struct file *);static int tty3270_write(struct tty_struct *, int,        const unsigned char *, int);static void tty3270_put_char(struct tty_struct *, unsigned char);static void tty3270_flush_chars(struct tty_struct *);static int tty3270_write_room(struct tty_struct *);static int tty3270_chars_in_buffer(struct tty_struct *);static int tty3270_ioctl(struct tty_struct *, struct file *,	unsigned int cmd, unsigned long arg);static void tty3270_set_termios(struct tty_struct *, struct termios *);static void tty3270_hangup(struct tty_struct *);static void tty3270_flush_buffer(struct tty_struct *);static int tty3270_read_proc(char *, char **, off_t, int, int *, void *);static int tty3270_write_proc(struct file *, const char *,	unsigned long, void *);/* tty3270 utility functions */static void tty3270_bh(void *);       void tty3270_sched_bh(tub_t *);static int tty3270_wait(tub_t *, long *);       void tty3270_int(tub_t *, devstat_t *);       int tty3270_try_logging(tub_t *);static void tty3270_start_input(tub_t *);static void tty3270_do_input(tub_t *);static void tty3270_do_enter(tub_t *, char *, int);static void tty3270_do_showi(tub_t *, char *, int);       int tty3270_io(tub_t *);static int tty3270_show_tube(int, char *, int);int tty3270_major = -1;struct tty_driver tty3270_driver;int tty3270_refcount;struct tty_struct *tty3270_table[TUBMAXMINS];struct termios *tty3270_termios[TUBMAXMINS];struct termios *tty3270_termios_locked[TUBMAXMINS];#ifdef CONFIG_TN3270_CONSOLEint con3270_major = -1;struct tty_driver con3270_driver;int con3270_refcount;struct tty_struct *con3270_table[1];struct termios *con3270_termios[1];struct termios *con3270_termios_locked[1];#endif /* CONFIG_TN3270_CONSOLE */int tty3270_proc_index;int tty3270_proc_data;int tty3270_proc_misc;enum tubwhat tty3270_proc_what;/* * tty3270_init() -- Register the tty3270 driver */inttty3270_init(void){	struct tty_driver *td = &tty3270_driver;	int rc;	/* Initialize for tty driver */	td->magic = TTY_DRIVER_MAGIC;	td->driver_name = "tty3270";	td->name = "tty3270";	td->major = IBM_TTY3270_MAJOR;	td->minor_start = 0;	td->num = TUBMAXMINS;	td->type = TTY_DRIVER_TYPE_SYSTEM;	td->subtype = SYSTEM_TYPE_TTY;	td->init_termios = tty_std_termios;	td->flags = TTY_DRIVER_RESET_TERMIOS;#ifdef CONFIG_DEVFS_FS	td->flags |= TTY_DRIVER_NO_DEVFS;#endif	td->refcount = &tty3270_refcount;	td->table = tty3270_table;	td->termios = tty3270_termios;	td->termios_locked = tty3270_termios_locked;	td->open = tty3270_open;	td->close = tty3270_close;	td->write = tty3270_write;	td->put_char = tty3270_put_char;	td->flush_chars = tty3270_flush_chars;	td->write_room = tty3270_write_room;	td->chars_in_buffer = tty3270_chars_in_buffer;	td->ioctl = tty3270_ioctl;	td->ioctl = NULL;	td->set_termios = tty3270_set_termios;	td->throttle = NULL;	td->unthrottle = NULL;	td->stop = NULL;	td->start = NULL;	td->hangup = tty3270_hangup;	td->break_ctl = NULL;	td->flush_buffer = tty3270_flush_buffer;	td->set_ldisc = NULL;	td->wait_until_sent = NULL;	td->send_xchar = NULL;	td->read_proc = tty3270_read_proc;	td->write_proc = tty3270_write_proc;	rc = tty_register_driver(td);	if (rc) {		printk(KERN_ERR "tty3270 registration failed with %d\n", rc);	} else {		tty3270_major = IBM_TTY3270_MAJOR;		if (td->proc_entry != NULL)			td->proc_entry->mode = S_IRUGO | S_IWUGO;	}#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))#ifdef CONFIG_TN3270_CONSOLE	if (CONSOLE_IS_3270) {		tty3270_con_driver = *td;		td = &tty3270_con_driver;		td->driver_name = "con3270";		td->name = "con3270";		td->major = MAJOR(S390_CONSOLE_DEV);		td->minor_start = MINOR(S390_CONSOLE_DEV);		td->num = 1;		td->refcount = &con3270_refcount;		td->table = con3270_table;		td->termios = con3270_termios;		td->termios_locked = con3270_termios_locked;		rc = tty_register_driver(td);		if (rc) {			printk(KERN_ERR			       "con3270 registration failed with %d\n", rc);		} else {			con3270_major = MAJOR(S390_CONSOLE_DEV);			if (td->proc_entry != NULL)				td->proc_entry->mode = S_IRUGO | S_IWUGO;		}	}#endif /* ifdef CONFIG_TN3270_CONSOLE */#endif /* if LINUX_VERSION_CODE */	return rc;}/* * tty3270_fini() -- Uninitialize linemode tubes */voidtty3270_fini(void){	if (tty3270_major != -1) {		tty_unregister_driver(&tty3270_driver);		tty3270_major = -1;	}#ifdef CONFIG_TN3270_CONSOLE	if (CONSOLE_IS_3270 && con3270_major != -1) {		tty_unregister_driver(&con3270_driver);		con3270_major = -1;	}#endif}static int tty3270_open(struct tty_struct *tty, struct file *filp){	tub_t *tubp;	long flags;	int rc;	int cmd;	if ((tubp = TTY2TUB(tty)) == NULL) {		return -ENODEV;	}	tub_inc_use_count();	if ((rc = tty3270_wait(tubp, &flags)) != 0)		goto do_fail;	if (tubp->lnopen > 0) {		tubp->lnopen++;		TUBUNLOCK(tubp->irq, flags);		return 0;	}	if (tubp->flags & TUB_OPEN_STET) {		cmd = TBC_UPDLOG;	} else {		cmd = TBC_OPEN;		tubp->flags &= ~TUB_SIZED;	}	if ((rc = tty3270_size(tubp, &flags)) != 0)		goto do_fail;	if ((rc = tty3270_rcl_init(tubp)) != 0)		goto do_fail;	if ((rc = tty3270_aid_init(tubp)) != 0)		goto do_fail;	if ((rc = tty3270_scl_init(tubp)) != 0)		goto do_fail;	tubp->mode = TBM_LN;	tubp->intv = tty3270_int;	tubp->tty = tty;	tubp->lnopen = 1;	tty->driver_data = tubp;	tty->winsize.ws_row = tubp->geom_rows;	tty->winsize.ws_col = tubp->geom_cols;	tubp->tty_inattr = TF_INPUT;	tubp->cmd = cmd;	tty3270_build(tubp);	TUBUNLOCK(tubp->irq, flags);	return 0;do_fail:	tty3270_scl_fini(tubp);	tty3270_aid_fini(tubp);	tty3270_rcl_fini(tubp);	TUBUNLOCK(tubp->irq, flags);	tub_dec_use_count();	return rc;}static voidtty3270_close(struct tty_struct *tty, struct file *filp){	tub_t *tubp;	long flags;	if ((tubp = tty->driver_data) == NULL)		return;	tty3270_wait(tubp, &flags);	if (--tubp->lnopen > 0)		goto do_return;	tubp->tty = NULL;	tty->driver_data = NULL;	tty3270_aid_fini(tubp);	tty3270_rcl_fini(tubp);	tty3270_scl_fini(tubp);do_return:	tub_dec_use_count();	TUBUNLOCK(tubp->irq, flags);}static int tty3270_write(struct tty_struct *tty, int fromuser,		const unsigned char *buf, int count){	tub_t *tubp;	long flags;	bcb_t obcb;	int rc = 0;	if ((tubp = tty->driver_data) == NULL)		return -1;#ifdef CONFIG_TN3270_CONSOLE	if (CONSOLE_IS_3270 && tub3270_con_tubp == tubp)		tub3270_con_copy(tubp);#endif /* CONFIG_TN3270_CONSOLE */	obcb.bc_buf = (char *)buf;	obcb.bc_len = obcb.bc_cnt = obcb.bc_wr = count;	obcb.bc_rd = 0;	TUBLOCK(tubp->irq, flags);	rc = tub3270_movedata(&obcb, &tubp->tty_bcb, fromuser);	tty3270_try_logging(tubp);	TUBUNLOCK(tubp->irq, flags);	return rc;} static voidtty3270_put_char(struct tty_struct *tty, unsigned char ch){	long flags;	tub_t *tubp;	bcb_t *ob;	if ((tubp = tty->driver_data) == NULL)		return;	TUBLOCK(tubp->irq, flags);	ob = &tubp->tty_bcb;	if (ob->bc_cnt < ob->bc_len) {		ob->bc_buf[ob->bc_wr++] = ch;		if (ob->bc_wr == ob->bc_len)			ob->bc_wr = 0;		ob->bc_cnt++;	}	tty3270_try_logging(tubp);	TUBUNLOCK(tubp->irq, flags);}static voidtty3270_flush_chars(struct tty_struct *tty){	tub_t *tubp;	long flags;	if ((tubp = tty->driver_data) == NULL)		return;	TUBLOCK(tubp->irq, flags);	tty3270_try_logging(tubp);	TUBUNLOCK(tubp->irq, flags);}static int tty3270_write_room(struct tty_struct *tty){	tub_t *tubp;	bcb_t *ob;	if ((tubp = tty->driver_data) == NULL)		return -1;	ob = &tubp->tty_bcb;	return ob->bc_len - ob->bc_cnt;}static inttty3270_chars_in_buffer(struct tty_struct *tty){	tub_t *tubp;	bcb_t *ob;	if ((tubp = tty->driver_data) == NULL)		return -1;	ob = &tubp->tty_bcb;	return ob->bc_cnt;}static inttty3270_ioctl(struct tty_struct *tty, struct file *file,		unsigned int cmd, unsigned long arg){	tub_t *tubp;	long flags;	int ret = 0;	struct termios termios;	if ((tubp = tty->driver_data) == NULL)		return -ENODEV;	TUBLOCK(tubp->irq, flags);	if (tty->flags * (1 << TTY_IO_ERROR)) {		ret = -EIO;		goto do_return;	}	switch(cmd) {	case TCGETS:		ret = -ENOIOCTLCMD;		goto do_return;	case TCFLSH:            /* arg:  2 or 0 */		ret = -ENOIOCTLCMD;		goto do_return;	case TCSETSF:		if (user_termios_to_kernel_termios(&termios,		    (struct termios *)arg)) {			ret = -EFAULT;			goto do_return;		}		ret = -ENOIOCTLCMD;		goto do_return;	case TCGETA:		ret = -ENOIOCTLCMD;		goto do_return;	case TCSETA:		if (user_termio_to_kernel_termios(&termios,		    (struct termio *)arg)) {			ret = -EFAULT;			goto do_return;		}		ret = -ENOIOCTLCMD;		goto do_return;	default:		ret = -ENOIOCTLCMD;		break;	}do_return:	TUBUNLOCK(tubp->irq, flags);	return ret;}static voidtty3270_set_termios(struct tty_struct *tty, struct termios *old){	tub_t *tubp;	long flags;	int new;	if ((tubp = tty->driver_data) == NULL)		return;	if (tty3270_wait(tubp, &flags) != 0) {		TUBUNLOCK(tubp->irq, flags);		return;	}	new = L_ICANON(tty)? L_ECHO(tty)? TF_INPUT: TF_INPUTN:		tubp->tty_inattr;	if (new != tubp->tty_inattr) {		tubp->tty_inattr = new;		tubp->cmd = TBC_CLRINPUT;		tty3270_build(tubp);	}	TUBUNLOCK(tubp->irq, flags);}static voidtty3270_flush_buffer(struct tty_struct *tty){	tub_t *tubp;	bcb_t *ob;	long flags;	if ((tubp = tty->driver_data) == NULL)		return;	if (tubp->mode == TBM_FS && tubp->fs_pid != 0) {		kill_proc(tubp->fs_pid, SIGHUP, 1);	}	if ((tubp->flags & TUB_OPEN_STET) == 0) {		ob = &tubp->tty_bcb;		TUBLOCK(tubp->irq, flags);		ob->bc_rd = 0;		ob->bc_wr = 0;		ob->bc_cnt = 0;		TUBUNLOCK(tubp->irq, flags);	}	wake_up_interruptible(&tty->write_wait);	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&	    tty->ldisc.write_wakeup)		(tty->ldisc.write_wakeup)(tty);}static inttty3270_read_proc(char *buf, char **start, off_t off, int count,		int *eof, void *data){	tub_t *tubp;	int begin = 0;	int i;	int rc;	int len = 0;	if (tty3270_proc_what == TW_CONFIG) {		/*		 * Describe the 3270 configuration in ascii lines.		 * Line 1:		0 <fsmajor> 0		 * Console line:	<devnum> CONSOLE <minor>		 * Other lines:		<devnum> <ttymajor> <minor>		 */		len += sprintf(buf + len, "0 %d 0\n", fs3270_major);		for (i = 1; i <= tubnummins; i++) {			tubp = (*tubminors)[i];#ifdef CONFIG_TN3270_CONSOLE			if (CONSOLE_IS_3270 && tubp == tub3270_con_tubp)				len += sprintf(buf + len, "%.3x CONSOLE %d\n",					       tubp->devno, i);			else#endif				len += sprintf(buf + len, "%.3x %d %d\n",					       tubp->devno, tty3270_major, i);			if (begin + len > off + count)				break;			if (begin + len < off) {				begin += len;				len = 0;			}		}		if (i > tubnummins)			*eof = 1;		if (off >= begin + len) {			rc = 0;		} else {			*start = buf + off - begin;			rc = MIN(count, begin + len - off);		}		if (*eof && rc == 0)			tty3270_proc_what = TW_BOGUS;		return rc;	}	len += sprintf(buf, "There are %d devices.  fs major is %d, "		"tty major is %d.\n", tubnummins, fs3270_major,		tty3270_major);	len += sprintf(buf+len, "        index=%d data=%d misc=%d\n",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -