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

📄 dz.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 3 页
字号:
		info->count = 0;	}	if (info->count) {		restore_flags(flags);		return;	}	info->flags |= DZ_CLOSING;	/*	 * Save the termios structure, since this port may have	 * separate termios for callout and dialin.	 */	if (info->flags & DZ_NORMAL_ACTIVE)		info->normal_termios = *tty->termios;	if (info->flags & DZ_CALLOUT_ACTIVE)		info->callout_termios = *tty->termios;	/*	 * Now we wait for the transmit buffer to clear; and we notify the line	 * discipline to only process XON/XOFF characters.	 */	tty->closing = 1;	if (info->closing_wait != DZ_CLOSING_WAIT_NONE)		tty_wait_until_sent(tty, info->closing_wait);	/*	 * At this point we stop accepting input.  To do this, we disable the	 * receive line status interrupts.	 */	shutdown(info);	if (tty->driver.flush_buffer)		tty->driver.flush_buffer (tty);	if (tty->ldisc.flush_buffer)		tty->ldisc.flush_buffer (tty);	tty->closing = 0;	info->event = 0;	info->tty = 0;	if (tty->ldisc.num != ldiscs[N_TTY].num) {		if (tty->ldisc.close)			tty->ldisc.close(tty);		tty->ldisc = ldiscs[N_TTY];		tty->termios->c_line = N_TTY;		if (tty->ldisc.open)			tty->ldisc.open(tty);	}	if (info->blocked_open) {		if (info->close_delay) {			current->state = TASK_INTERRUPTIBLE;			schedule_timeout(info->close_delay);		}		wake_up_interruptible(&info->open_wait);	}	info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE | DZ_CLOSING);	wake_up_interruptible(&info->close_wait);	restore_flags(flags);}/* * dz_hangup () --- called by tty_hangup() when a hangup is signaled. */static void dz_hangup (struct tty_struct *tty){	struct dz_serial *info = (struct dz_serial *) tty->driver_data;  	dz_flush_buffer(tty);	shutdown(info);	info->event = 0;	info->count = 0;	info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE);	info->tty = 0;	wake_up_interruptible(&info->open_wait);}/* * ------------------------------------------------------------ * rs_open() and friends * ------------------------------------------------------------ */static int block_til_ready(struct tty_struct *tty, struct file *filp,                           struct dz_serial *info){	DECLARE_WAITQUEUE(wait, current); 	int retval;	int do_clocal = 0;	/*	 * If the device is in the middle of being closed, then block	 * until it's done, and then try again.	 */	if (info->flags & DZ_CLOSING) {		interruptible_sleep_on(&info->close_wait);		return -EAGAIN;	}	/*	 * If this is a callout device, then just make sure the normal	 * device isn't being used.	 */	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {		if (info->flags & DZ_NORMAL_ACTIVE)			return -EBUSY;    		if ((info->flags & DZ_CALLOUT_ACTIVE) &&		    (info->flags & DZ_SESSION_LOCKOUT) &&		    (info->session != current->session))			return -EBUSY;    		if ((info->flags & DZ_CALLOUT_ACTIVE) &&		    (info->flags & DZ_PGRP_LOCKOUT) &&		    (info->pgrp != current->pgrp))			return -EBUSY;		info->flags |= DZ_CALLOUT_ACTIVE;		return 0;	}	/*	 * If non-blocking mode is set, or the port is not enabled, then make	 * the check up front and then exit.	 */	if ((filp->f_flags & O_NONBLOCK) ||	    (tty->flags & (1 << TTY_IO_ERROR))) {		if (info->flags & DZ_CALLOUT_ACTIVE)			return -EBUSY;		info->flags |= DZ_NORMAL_ACTIVE;		return 0;	}	if (info->flags & DZ_CALLOUT_ACTIVE) {		if (info->normal_termios.c_cflag & CLOCAL)			do_clocal = 1;	} else {		if (tty->termios->c_cflag & CLOCAL)		do_clocal = 1;	}	/*	 * Block waiting for the carrier detect and the line to become free	 * (i.e., not in use by the callout).  While we are in this loop,	 * info->count is dropped by one, so that dz_close() knows when to free	 * things.  We restore it upon exit, either normal or abnormal.	 */	retval = 0;	add_wait_queue(&info->open_wait, &wait);	info->count--;	info->blocked_open++;	while (1) {		set_current_state(TASK_INTERRUPTIBLE);		if (tty_hung_up_p (filp) || !(info->is_initialized)) {			retval = -EAGAIN;			break;		}		if (!(info->flags & DZ_CALLOUT_ACTIVE) &&		    !(info->flags & DZ_CLOSING) && do_clocal)			break;		if (signal_pending(current)) {			retval = -ERESTARTSYS;			break;		}		schedule();	}			current->state = TASK_RUNNING;	remove_wait_queue (&info->open_wait, &wait);	if (!tty_hung_up_p(filp))		info->count++;	info->blocked_open--;	if (retval)		return retval;	info->flags |= DZ_NORMAL_ACTIVE;	return 0;}/* * This routine is called whenever a serial port is opened.  It * enables interrupts for a serial port. It also performs the  * serial-specific initialization for the tty structure. */static int dz_open (struct tty_struct *tty, struct file *filp){	struct dz_serial *info;	int retval, line;	line = MINOR(tty->device) - tty->driver.minor_start;	/*	 * The dz lines for the mouse/keyboard must be opened using their	 * respective drivers.	 */	if ((line < 0) || (line >= DZ_NB_PORT))		return -ENODEV;	if ((line == DZ_KEYBOARD) || (line == DZ_MOUSE))		return -ENODEV;	info = lines[line];	info->count++;	tty->driver_data = info;	info->tty = tty;	/*	 * Start up serial port	 */	retval = startup (info);	if (retval)		return retval;	retval = block_til_ready (tty, filp, info);	if (retval)		return retval;	if ((info->count == 1) && (info->flags & DZ_SPLIT_TERMIOS)) {		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)			*tty->termios = info->normal_termios;		else 			*tty->termios = info->callout_termios;		change_speed(info);	}	info->session = current->session;	info->pgrp = current->pgrp;	return 0;}static void show_serial_version (void){	printk("%s%s\n", dz_name, dz_version);}int __init dz_init(void){	int i, flags;	struct dz_serial *info;	/* Setup base handler, and timer table. */	init_bh(SERIAL_BH, do_serial_bh);	show_serial_version();	memset(&serial_driver, 0, sizeof(struct tty_driver));	serial_driver.magic = TTY_DRIVER_MAGIC;#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))	serial_driver.name = "ttyS";#else	serial_driver.name = "tts/%d";#endif	serial_driver.major = TTY_MAJOR;	serial_driver.minor_start = 64;	serial_driver.num = DZ_NB_PORT;	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;	serial_driver.subtype = SERIAL_TYPE_NORMAL;	serial_driver.init_termios = tty_std_termios;	serial_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |	                                     CLOCAL;	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;	serial_driver.refcount = &serial_refcount;	serial_driver.table = serial_table;	serial_driver.termios = serial_termios;	serial_driver.termios_locked = serial_termios_locked;	serial_driver.open = dz_open;	serial_driver.close = dz_close;	serial_driver.write = dz_write;	serial_driver.flush_chars = dz_flush_chars;	serial_driver.write_room = dz_write_room;	serial_driver.chars_in_buffer = dz_chars_in_buffer;	serial_driver.flush_buffer = dz_flush_buffer;	serial_driver.ioctl = dz_ioctl;	serial_driver.throttle = dz_throttle;	serial_driver.unthrottle = dz_unthrottle;	serial_driver.send_xchar = dz_send_xchar;	serial_driver.set_termios = dz_set_termios;	serial_driver.stop = dz_stop;	serial_driver.start = dz_start;	serial_driver.hangup = dz_hangup;	/*	 * The callout device is just like normal device except for major	 * number and the subtype code.	 */	callout_driver = serial_driver;#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))	callout_driver.name = "cua";#else	callout_driver.name = "cua/%d";#endif	callout_driver.major = TTYAUX_MAJOR;	callout_driver.subtype = SERIAL_TYPE_CALLOUT;	if (tty_register_driver (&serial_driver))		panic("Couldn't register serial driver\n");	if (tty_register_driver (&callout_driver))		panic("Couldn't register callout driver\n");	save_flags(flags); cli();	for (i=0; i < DZ_NB_PORT;  i++) {		info = &multi[i]; 		lines[i] = info;		info->magic = SERIAL_MAGIC;		if ((mips_machtype == MACH_DS23100) ||		    (mips_machtype == MACH_DS5100)) 			info->port = (unsigned long) KN01_DZ11_BASE;		else 			info->port = (unsigned long) KN02_DZ11_BASE;		info->line = i;		info->tty = 0;		info->close_delay = 50;		info->closing_wait = 3000;		info->x_char = 0;		info->event = 0;		info->count = 0;		info->blocked_open = 0;		info->tqueue.routine = do_softint;		info->tqueue.data = info;		info->tqueue_hangup.routine = do_serial_hangup;		info->tqueue_hangup.data = info;		info->callout_termios = callout_driver.init_termios;		info->normal_termios = serial_driver.init_termios;		init_waitqueue_head(&info->open_wait); 		init_waitqueue_head(&info->close_wait); 		/*		 * If we are pointing to address zero then punt - not correctly		 * set up in setup.c to handle this.		 */		if (! info->port)			return 0;		printk("ttyS%02d at 0x%08x (irq = %d)\n", info->line,		       info->port, SERIAL);		tty_register_devfs(&serial_driver, 0,		                   serial_driver.minor_start + info->line);		tty_register_devfs(&callout_driver, 0,		                   callout_driver.minor_start + info->line);	}	/* Reset the chip */#ifndef CONFIG_SERIAL_CONSOLE	{		int tmp;		dz_out(info, DZ_CSR, DZ_CLR);		while ((tmp = dz_in(info,DZ_CSR)) & DZ_CLR);		wbflush();  		/* Enable scanning */		dz_out(info, DZ_CSR, DZ_MSE); 	}#endif  	/*	 * Order matters here... the trick is that flags is updated... in	 * request_irq - to immediatedly obliterate it is unwise.	 */	restore_flags(flags);	if (request_irq(SERIAL, dz_interrupt, SA_INTERRUPT, "DZ", lines[0]))		panic("Unable to register DZ interrupt\n"); 	return 0;}#ifdef CONFIG_SERIAL_CONSOLEstatic void dz_console_put_char (unsigned char ch){	unsigned long flags;	int  loops = 2500;	unsigned short tmp = ch;	/*	 * this code sends stuff out to serial device - spinning its wheels and	 * waiting.	 */	/* force the issue - point it at lines[3]*/	dz_console = &multi[CONSOLE_LINE];	save_and_cli(flags);	/* spin our wheels */	while (((dz_in(dz_console, DZ_CSR) & DZ_TRDY) != DZ_TRDY) &&  loops--)		;  	/* Actually transmit the character. */	dz_out(dz_console, DZ_TDR, tmp);	restore_flags(flags); }/*  * ------------------------------------------------------------------- * dz_console_print () * * dz_console_print is registered for printk. * The console must be locked when we get here. * -------------------------------------------------------------------  */static void dz_console_print (struct console *cons, 			      const char *str, 			      unsigned int count){#ifdef DEBUG_DZ	prom_printf((char *)str);#endif	while (count--) {		if (*str == '\n')			dz_console_put_char('\r');		dz_console_put_char(*str++);	}}static int dz_console_wait_key(struct console *co){	return 0;}static kdev_t dz_console_device(struct console *c){	return MKDEV(TTY_MAJOR, 64 + c->index);}static int __init dz_console_setup(struct console *co, char *options){	int baud = 9600;	int bits = 8;	int parity = 'n';	int cflag = CREAD | HUPCL | CLOCAL;	char *s;	unsigned short mask,tmp;	if (options) {		baud = simple_strtoul(options, NULL, 10);		s = options;		while (*s >= '0' && *s <= '9')			s++;		if (*s)			parity = *s++;		if (*s)			bits   = *s - '0';	}	/*	 * Now construct a cflag setting.	 */	switch (baud) {	case 1200:		cflag |= DZ_B1200;		break;	case 2400:		cflag |= DZ_B2400;		break;	case 4800:		cflag |= DZ_B4800;		break;	case 9600:	default:		cflag |= DZ_B9600;		break;	}	switch (bits) {	case 7:		cflag |= DZ_CS7;		break;	default:	case 8:		cflag |= DZ_CS8;		break;	}	switch (parity) {	case 'o':	case 'O':		cflag |= DZ_PARODD;		break;	case 'e':	case 'E':		cflag |= DZ_PARENB;		break;	}	co->cflag = cflag;	/* TOFIX: force to console line */	dz_console = &multi[CONSOLE_LINE];	if ((mips_machtype == MACH_DS23100) || (mips_machtype == MACH_DS5100)) 		dz_console->port = KN01_DZ11_BASE;	else 		dz_console->port = KN02_DZ11_BASE; 	dz_console->line = CONSOLE_LINE;	dz_out(dz_console, DZ_CSR, DZ_CLR);	while ((tmp = dz_in(dz_console,DZ_CSR)) & DZ_CLR)		;	/* enable scanning */	dz_out(dz_console, DZ_CSR, DZ_MSE); 	/*  Set up flags... */	dz_console->cflags = 0;	dz_console->cflags |= DZ_B9600;	dz_console->cflags |= DZ_CS8;	dz_console->cflags |= DZ_PARENB;	dz_out(dz_console, DZ_LPR, dz_console->cflags);	mask = 1 << dz_console->line;	tmp = dz_in (dz_console, DZ_TCR);		/* read the TX flag */	if (!(tmp & mask)) {		tmp |= mask;				/* set the TX flag */		dz_out (dz_console, DZ_TCR, tmp); 	}	return 0;}static struct console dz_sercons = {    name:	"ttyS",    write:	dz_console_print,    device:	dz_console_device,    wait_key:	dz_console_wait_key,    setup:	dz_console_setup,    flags:	CON_CONSDEV | CON_PRINTBUFFER,    index:	CONSOLE_LINE,};void __init dz_serial_console_init(void){	register_console(&dz_sercons);}#endif /* ifdef CONFIG_SERIAL_CONSOLE */MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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