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

📄 hwc_tty.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
字号:
/* *  drivers/s390/char/hwc_tty.c *    HWC line mode terminal driver. * *  S390 version *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation *    Author(s): Martin Peschke <peschke@fh-brandenburg.de> * *  Thanks to Martin Schwidefsky. */#include <linux/major.h>#include <linux/termios.h>#include <linux/tty.h>#include <linux/tty_driver.h>#include <linux/sched.h>#include <linux/mm.h>#include <asm/uaccess.h>#include "hwc_rw.h"#define HWC_TTY_PRINT_HEADER "hwc tty driver: "#define HWC_TTY_BUF_SIZE 512typedef struct {	struct tty_struct *tty;	unsigned char buf[HWC_TTY_BUF_SIZE];	unsigned short int buf_count;	spinlock_t lock;} hwc_tty_data_struct;static hwc_tty_data_struct hwc_tty_data;static struct tty_driver hwc_tty_driver;static struct tty_struct *hwc_tty_table[1];static struct termios *hwc_tty_termios[1];static struct termios *hwc_tty_termios_locked[1];static int hwc_tty_refcount = 0;extern struct termios tty_std_termios;static int hwc_tty_open (struct tty_struct *tty,	      struct file *filp){	if (MINOR (tty->device) - tty->driver.minor_start)		return -ENODEV;	tty->driver_data = &hwc_tty_data;	hwc_tty_data.buf_count = 0;	hwc_tty_data.tty = tty;	tty->low_latency = 0;	return 0;}void wake_up_hwc_tty (void){	if (hwc_tty_data.tty == NULL)		return;	if ((hwc_tty_data.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&	    hwc_tty_data.tty->ldisc.write_wakeup)		(hwc_tty_data.tty->ldisc.write_wakeup) (hwc_tty_data.tty);	wake_up_interruptible (&hwc_tty_data.tty->write_wait);}static void hwc_tty_close (struct tty_struct *tty,	       struct file *filp){	if (MINOR (tty->device) != tty->driver.minor_start) {		printk (KERN_WARNING HWC_TTY_PRINT_HEADER			"do not close hwc tty because of wrong device number");		return;	}	hwc_tty_data.tty = NULL;}static int hwc_tty_write_room (struct tty_struct *tty){	int retval;	retval = hwc_write_room (IN_BUFS_TOTAL);	return retval;}static int hwc_tty_write (struct tty_struct *tty,	       int from_user,	       const unsigned char *buf,	       int count){	int retval;	if (hwc_tty_data.buf_count > 0) {		hwc_write (0, hwc_tty_data.buf, hwc_tty_data.buf_count);		hwc_tty_data.buf_count = 0;	}	retval = hwc_write (from_user, buf, count);	return retval;}static void hwc_tty_put_char (struct tty_struct *tty,		  unsigned char ch){	unsigned long flags;	spin_lock_irqsave (&hwc_tty_data.lock, flags);	if (hwc_tty_data.buf_count >= HWC_TTY_BUF_SIZE) {		hwc_write (0, hwc_tty_data.buf, hwc_tty_data.buf_count);		hwc_tty_data.buf_count = 0;	}	hwc_tty_data.buf[hwc_tty_data.buf_count] = ch;	hwc_tty_data.buf_count++;	spin_unlock_irqrestore (&hwc_tty_data.lock, flags);}static void hwc_tty_flush_chars (struct tty_struct *tty){	unsigned long flags;	spin_lock_irqsave (&hwc_tty_data.lock, flags);	hwc_write (0, hwc_tty_data.buf, hwc_tty_data.buf_count);	hwc_tty_data.buf_count = 0;	spin_unlock_irqrestore (&hwc_tty_data.lock, flags);}static int hwc_tty_chars_in_buffer (struct tty_struct *tty){	int retval;	retval = hwc_chars_in_buffer (IN_BUFS_TOTAL);	return retval;}static void hwc_tty_flush_buffer (struct tty_struct *tty){	wake_up_hwc_tty ();}static int hwc_tty_ioctl (		      struct tty_struct *tty,		      struct file *file,		      unsigned int cmd,		      unsigned long arg){	if (tty->flags & (1 << TTY_IO_ERROR))		return -EIO;	return hwc_ioctl (cmd, arg);}void store_hwc_input (unsigned char *buf, unsigned int count){	struct tty_struct *tty = hwc_tty_data.tty;	if (tty != NULL) {		if (count == 2 && (		/* hat is 0xb0 in codepage 037 (US etc.) and thus */		/* converted to 0x5e in ascii ('^') */					  strncmp (buf, "^c", 2) == 0 ||		/* hat is 0xb0 in several other codepages (German, */		/* UK, ...) and thus converted to ascii octal 252 */					  strncmp (buf, "\0252c", 2) == 0)) {			tty->flip.count++;			*tty->flip.flag_buf_ptr++ = TTY_NORMAL;			*tty->flip.char_buf_ptr++ = INTR_CHAR (tty);		} else if (count == 2 && (						 strncmp (buf, "^d", 2) == 0 ||					   strncmp (buf, "\0252d", 2) == 0)) {			tty->flip.count++;			*tty->flip.flag_buf_ptr++ = TTY_NORMAL;			*tty->flip.char_buf_ptr++ = EOF_CHAR (tty);		} else if (count == 2 && (						 strncmp (buf, "^z", 2) == 0 ||					   strncmp (buf, "\0252z", 2) == 0)) {			tty->flip.count++;			*tty->flip.flag_buf_ptr++ = TTY_NORMAL;			*tty->flip.char_buf_ptr++ = SUSP_CHAR (tty);		} else {			memcpy (tty->flip.char_buf_ptr, buf, count);			if (count < 2 || (					 strncmp (buf + count - 2, "^n", 2) ||				    strncmp (buf + count - 2, "\0252n", 2))) {				tty->flip.char_buf_ptr[count] = '\n';				count++;			} else				count -= 2;			memset (tty->flip.flag_buf_ptr, TTY_NORMAL, count);			tty->flip.char_buf_ptr += count;			tty->flip.flag_buf_ptr += count;			tty->flip.count += count;		}		tty_flip_buffer_push (tty);		wake_up_hwc_tty ();	}}void hwc_tty_init (void){	memset (&hwc_tty_driver, 0, sizeof (struct tty_driver));	memset (&hwc_tty_data, 0, sizeof (hwc_tty_data_struct));	hwc_tty_driver.magic = TTY_DRIVER_MAGIC;	hwc_tty_driver.driver_name = "tty_hwc";	hwc_tty_driver.name = "ttyS";	hwc_tty_driver.name_base = 0;	hwc_tty_driver.major = TTY_MAJOR;	hwc_tty_driver.minor_start = 64;	hwc_tty_driver.num = 1;	hwc_tty_driver.type = TTY_DRIVER_TYPE_SYSTEM;	hwc_tty_driver.subtype = SYSTEM_TYPE_TTY;	hwc_tty_driver.init_termios = tty_std_termios;	hwc_tty_driver.init_termios.c_iflag = IGNBRK | IGNPAR;	hwc_tty_driver.init_termios.c_oflag = ONLCR;	hwc_tty_driver.init_termios.c_lflag = ISIG | ECHO;	hwc_tty_driver.flags = TTY_DRIVER_REAL_RAW;	hwc_tty_driver.refcount = &hwc_tty_refcount;	hwc_tty_driver.table = hwc_tty_table;	hwc_tty_driver.termios = hwc_tty_termios;	hwc_tty_driver.termios_locked = hwc_tty_termios_locked;	hwc_tty_driver.open = hwc_tty_open;	hwc_tty_driver.close = NULL /* hwc_tty_close */ ;	hwc_tty_driver.write = hwc_tty_write;	hwc_tty_driver.put_char = hwc_tty_put_char;	hwc_tty_driver.flush_chars = hwc_tty_flush_chars;	hwc_tty_driver.write_room = hwc_tty_write_room;	hwc_tty_driver.chars_in_buffer = hwc_tty_chars_in_buffer;	hwc_tty_driver.flush_buffer = hwc_tty_flush_buffer;	hwc_tty_driver.ioctl = hwc_tty_ioctl;	hwc_tty_driver.throttle = NULL;	hwc_tty_driver.unthrottle = NULL;	hwc_tty_driver.send_xchar = NULL;	hwc_tty_driver.set_termios = NULL;	hwc_tty_driver.set_ldisc = NULL;	hwc_tty_driver.stop = NULL;	hwc_tty_driver.start = NULL;	hwc_tty_driver.hangup = NULL;	hwc_tty_driver.break_ctl = NULL;	hwc_tty_driver.wait_until_sent = NULL;	hwc_tty_driver.read_proc = NULL;	hwc_tty_driver.write_proc = NULL;	if (tty_register_driver (&hwc_tty_driver))		panic ("Couldn't register hwc_tty driver\n");}

⌨️ 快捷键说明

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