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

📄 serial_netarm.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 5 页
字号:
	retval = startup(info);	if (retval) {		MOD_DEC_USE_COUNT;		return retval;	}	retval = block_til_ready(tty, filp, info);	if (retval) {#ifdef SERIAL_DEBUG_OPEN		printk("rs_open returning after block_til_ready with %d\n",		       retval);#endif		MOD_DEC_USE_COUNT;		return retval;	}	if ((info->state->count == 1) &&	    (info->flags & ASYNC_SPLIT_TERMIOS)) {		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)			*tty->termios = info->state->normal_termios;		else 			*tty->termios = info->state->callout_termios;		change_speed(info, 0);	}#ifdef CONFIG_SERIAL_NETARM_CONSOLE	if (sercons.cflag && sercons.index == line) {		tty->termios->c_cflag = sercons.cflag;		sercons.cflag = 0;		change_speed(info, 0);	}#endif	info->session = current->session;	info->pgrp = current->pgrp;#ifdef SERIAL_DEBUG_OPEN	printk("rs_open ttyS%d successful\n", info->line);#endif	return 0;}/*====================================================================  Support for /proc/netarm-serial */#ifdef CONFIG_PROC_FSstatic struct proc_dir_entry *proc_nas;static inline intline_info(char *buf, struct serial_state *state){	char	stat_buf[30];	int	ret;	unsigned long flags, status, control;	netarm_serial_channel_t *regs;	ret = sprintf(buf, "%d: NetARM SER port:%lX irq:%d",		      state->line, state->port, state->irq);	if (!state->port || (state->type == PORT_UNKNOWN)) {		ret += sprintf(buf+ret, "\n");		return ret;	}	/*	 * Figure out the current RS-232 lines	 */	regs = (netarm_serial_channel_t *) state->iomem_base;	save_flags(flags); cli();	status = regs->status_a;	control = regs->ctrl_a;	restore_flags(flags); 	stat_buf[0] = 0;	stat_buf[1] = 0;	if (control & NETARM_SER_CTLA_RTS_EN)		strcat(stat_buf, "|RTS");	if (status & NETARM_SER_STATA_CTS)		strcat(stat_buf, "|CTS");	if (control & NETARM_SER_CTLA_DTR_EN)		strcat(stat_buf, "|DTR");	if (status & NETARM_SER_STATA_DSR)		strcat(stat_buf, "|DSR");	if (status & NETARM_SER_STATA_DCD)		strcat(stat_buf, "|CD");	if (status & NETARM_SER_STATA_RI)		strcat(stat_buf, "|RI");	ret += sprintf(buf+ret, " tx:%d rx:%d",		      state->icount.tx, state->icount.rx);	if (state->icount.frame)		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);		if (state->icount.parity)		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);		if (state->icount.brk)		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);		if (state->icount.overrun)		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);	/*	 * Last thing is the RS-232 status lines	 */	ret += sprintf(buf+ret, " %s\n", stat_buf+1);	return ret;}intnas_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data){	int i, len = 0, l;	off_t	begin = 0;	len += sprintf(page, "serinfo:1.0 driver:%s%s revision:%s\n",		       serial_version, LOCAL_VERSTRING, serial_revdate);	for (i = 0; i < NR_NAS_PORTS && len < 4000; i++) {		l = line_info(page + len, &rs_table[i]);		len += l;		if (len+begin > off+count)			goto done;		if (len+begin < off) {			begin += len;			len = 0;		}	}	*eof = 1;done:	if (off >= len+begin)		return 0;	*start = page + (off-begin);	return ((count < begin+len-off) ? count : begin+len-off);}#endif/* end of proc support routines *//* * --------------------------------------------------------------------- * rs_init() and friends * * rs_init() is called at boot-time to initialize the serial driver. * --------------------------------------------------------------------- *//* * This routine prints out the appropriate serial driver version * number, and identifies which options were configured into this * driver. */static char serial_options[] __initdata =#ifdef CONFIG_SERIAL_NETARM_CONSOLE       " CONSOLE"#define SERIAL_OPT#endif#ifdef SERIAL_OPT       " enabled\n";#else       " no serial options enabled\n";#endif#undef SERIAL_OPTstatic _INLINE_ voidshow_serial_version(void){ 	printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name,	       serial_version, LOCAL_VERSTRING, serial_revdate,	       serial_options);}/* * This routine is called by rs_init() to initialize a specific serial * port.  It determines what type of UART chip this serial port is * using: 8250, 16450, 16550, 16550A. * In the NetARM case, we already know what's there. */static voidautoconfig(struct serial_state * state){	struct netarm_async_struct *info, scr_info;	unsigned long flags;	if (!CONFIGURED_SERIAL_PORT(state))		return;			state->type = PORT_NETARM;	info = &scr_info;	/* This is just for serial_{in,out} */	info->magic = SERIAL_MAGIC;	info->state = state;	info->port = state->port;	info->flags = state->flags;	info->io_type = state->io_type;	info->registers = (netarm_serial_channel_t *) state->iomem_base;	save_flags(flags); cli();	/* Reset FIFO */	info->registers->status_a = NETARM_SER_STATA_CLR_ALL;	info->SCSRA = 0;	restore_flags(flags);}int register_serial(struct serial_struct *req);void unregister_serial(int line);#if (LINUX_VERSION_CODE > 0x20100)EXPORT_SYMBOL(register_serial);EXPORT_SYMBOL(unregister_serial);#elsestatic struct symbol_table serial_syms = {#include <linux/symtab_begin.h>	X(register_serial),	X(unregister_serial),#include <linux/symtab_end.h>};#endif/* * The serial driver boot-time initialization code */static int __initrs_init(void){	int i;	struct serial_state * state;	init_bh(SERIAL_BH, do_serial_bh);	show_serial_version();	/* Initialize the tty_driver structure */		memset(&serial_driver, 0, sizeof(struct tty_driver));	serial_driver.magic = TTY_DRIVER_MAGIC;#if (LINUX_VERSION_CODE > 0x20100)	serial_driver.driver_name = "NetARM serial";#endif#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))	serial_driver.name = "tts/%d";#else	serial_driver.name = "ttyS";#endif	serial_driver.major = TTY_MAJOR;	serial_driver.minor_start = 64 + SERIAL_DEV_OFFSET;	serial_driver.num = NR_NAS_PORTS;	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 = rs_open;	serial_driver.close = rs_close;	serial_driver.write = rs_write;	serial_driver.put_char = rs_put_char;	serial_driver.flush_chars = rs_flush_chars;	serial_driver.write_room = rs_write_room;	serial_driver.chars_in_buffer = rs_chars_in_buffer;	serial_driver.flush_buffer = rs_flush_buffer;	serial_driver.ioctl = rs_ioctl;	serial_driver.throttle = rs_throttle;	serial_driver.unthrottle = rs_unthrottle;	serial_driver.set_termios = rs_set_termios;	serial_driver.stop = rs_stop;	serial_driver.start = rs_start;	serial_driver.hangup = rs_hangup;	serial_driver.break_ctl = rs_break;	serial_driver.send_xchar = rs_send_xchar;	serial_driver.wait_until_sent = rs_wait_until_sent;	serial_driver.read_proc = nas_read_proc;		/*	 * 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/%d";#else	callout_driver.name = "cua";#endif	callout_driver.major = TTYAUX_MAJOR;	callout_driver.subtype = SERIAL_TYPE_CALLOUT;	callout_driver.read_proc = 0;	callout_driver.proc_entry = 0;	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");		for (i = 0, state = rs_table; i < NR_NAS_PORTS; i++,state++)	{		state->magic = SSTATE_MAGIC;		state->line = i;		state->type = PORT_NETARM;		state->xmit_fifo_size = NETARM_SER_FIFO_SIZE;		state->custom_divisor = 0;		state->close_delay = 5*HZ/10;		state->closing_wait = 30*HZ;		state->callout_termios = callout_driver.init_termios;		state->normal_termios = serial_driver.init_termios;		state->icount.cts = state->icount.dsr = 			state->icount.rng = state->icount.dcd = 0;		state->icount.rx = state->icount.tx = 0;		state->icount.frame = state->icount.parity = 0;		state->icount.overrun = state->icount.brk = 0;		if (i == 0)			state->irq = IRQ_SER1_RX;		else			state->irq = IRQ_SER2_RX;		state->io_type = SERIAL_IO_MEM;/* no need to call request_region		if (state->port && check_region(state->port,8))			continue;*/		if (state->flags & ASYNC_BOOT_AUTOCONF)			autoconfig(state);		printk(KERN_INFO "ttyS%02d at 0x%04lx (irq = %d) is a NetARM\n",		       state->line + SERIAL_DEV_OFFSET,		       state->port, state->irq );		tty_register_devfs(&serial_driver, 0,				   serial_driver.minor_start + state->line);		tty_register_devfs(&callout_driver, 0,				   callout_driver.minor_start + state->line);	}	nas_interrupts_init();#ifdef CONFIG_PROC_FS	if ((proc_nas = create_proc_entry( "netarm-serial", 0, 0 )))	  proc_nas->read_proc = nas_read_proc;#endif	return 0;}static void __exitrs_fini(void) {	unsigned long flags;	int e1, e2;	int i;	/* printk("Unloading %s: version %s\n", serial_name, serial_version); */	del_timer_sync(&serial_timer);	save_flags(flags); cli();        remove_bh(SERIAL_BH);	if ((e1 = tty_unregister_driver(&serial_driver)))		printk("serial: failed to unregister serial driver (%d)\n",		       e1);	if ((e2 = tty_unregister_driver(&callout_driver)))		printk("serial: failed to unregister callout driver (%d)\n", 		       e2);	restore_flags(flags);/*	for (i = 0; i < NR_NAS_PORTS; i++) {		if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) {			release_region(rs_table[i].port, 8);		}	}*/	if (tmp_buf) {		unsigned long pg = (unsigned long) tmp_buf;		tmp_buf = NULL;		free_page(pg);	}}module_init(rs_init);module_exit(rs_fini);MODULE_DESCRIPTION("NetARM serial driver");MODULE_AUTHOR("Rolf Peukert <peukert@imms.de>");/* * ------------------------------------------------------------ * Serial console driver * ------------------------------------------------------------ */#ifdef CONFIG_SERIAL_NETARM_CONSOLE#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)static struct netarm_async_struct async_sercons;/* *	Wait for transmitter & holding register to empty */static inline voidwait_for_xmitr(struct netarm_async_struct *info){	unsigned int status, tmout = 1000000;	do	{		status = info->registers->status_a;		if (status & NETARM_SER_STATA_RX_BRK)			lsr_break_flag = NETARM_SER_STATA_RX_BRK;		if (--tmout == 0)			break;	} while ((status & NETARM_SER_STATA_TX_DMAEN) == 0);	/* This waits until transmitter has finished all characters in fifo.	   FIXME: Waiting for the transmit holding register to empty	   (checking NETARM_SER_STATA_TX_FULL) doesn't seem to work. */	/* Wait for flow control if necessary */	if (info->flags & ASYNC_CONS_FLOW)	{		tmout = 1000000;		while (--tmout && \		       (info->registers->status_a & NETARM_SER_STATA_CTS) == 0)		{}	}}/* *	Print a string to the serial port trying not to disturb *	any possible real use of the port... * *	The console_lock must be held when we get here. */static voidserial_console_write(struct console *co, const char *s, unsigned count){	static struct netarm_async_struct *info = &async_sercons;	volatile netarm_serial_channel_t *regs;	unsigned long ier;	volatile unsigned long *ser_port_fifo;	unsigned long *bPtr = (unsigned long *)s;	unsigned char *zPtr = (unsigned char *)s;	unsigned long ctmp;	int scount;	/*	 *	First save the IER then disable the interrupts	 */	regs = info->registers;	ier  = regs->ctrl_a;	regs->ctrl_a = ier & ~(NETARM_SER_CTLA_IE_RX_ALL | NETARM_SER_CTLA_IE_TX_ALL);	/*	 *	Now, do all characters, add CR to every LF	 */	ser_port_fifo = (volatile unsigned long *) &(regs->fifo);	zPtr = (unsigned char *)bPtr;	while ( count > 0 )	{		ctmp = 0 ;		scount = 0 ;  		while ( ( count > 0 ) && ( scount < 4 ) )		{			ctmp += *zPtr << ( scount << 3 ) ;			if (*zPtr == '\n')			{				if ( scount < 3 )				{					scount++;					ctmp += '\r' << (scount << 3) ; 				}				else				{					NAS_TX_WAIT_RDY(regs);					*ser_port_fifo = ctmp;					scount = 0 ;					ctmp = '\r' ;					}			}			zPtr++;			count -- ;			scount ++ ;		}		NAS_TX_WAIT_RDY(regs);		*ser_port_fifo = ctmp;		}	/*	 *	Finally, Wait for transmitter & holding register to empty	 * 	and 

⌨️ 快捷键说明

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