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

📄 zs.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
			}			request_region((unsigned long)				       zs_channels[n_channels].control,				       ZS_CHAN_IO_SIZE, "SCC");#endif			zs_soft[n_channels].zs_channel = &zs_channels[n_channels];			zs_soft[n_channels].irq = zs_parms->irq;			/* 			 *  Identification of channel A. Location of channel A                         *  inside chip depends on mapping of internal address			 *  the chip decodes channels by.			 *  CHANNEL_A_NR returns either 0 (in case of 			 *  DECstations) or 1 (in case of Baget).			 */			if (CHANNEL_A_NR == channel)				zs_soft[n_channels].zs_chan_a = 				    &zs_channels[n_channels+1-2*CHANNEL_A_NR];			else				zs_soft[n_channels].zs_chan_a = 				    &zs_channels[n_channels];			*pp = &zs_soft[n_channels];			pp = &zs_soft[n_channels].zs_next;			n_channels++;		}	}	*pp = 0;	zs_channels_found = n_channels;	for (n = 0; n < zs_channels_found; n++) {		for (i = 0; i < 16; i++) {			zs_soft[n].zs_channel->curregs[i] = zs_init_regs[i];		}	}/*	save_and_cli(flags);	for (n = 0; n < zs_channels_found; n++) {		if (((int)zs_channels[n].control & 0xf) == 1) {			write_zsreg(zs_soft[n].zs_chan_a, R9, FHWRES);			mdelay(10);			write_zsreg(zs_soft[n].zs_chan_a, R9, 0);		}		load_zsregs(zs_soft[n].zs_channel, zs_soft[n].zs_channel->curregs);	} 	restore_flags(flags); */}/* zs_init inits the driver */int __init zs_init(void){	int channel, i;	unsigned long flags;	struct dec_serial *info;	if(!BUS_PRESENT)		return -ENODEV;	/* Setup base handler, and timer table. */	init_bh(SERIAL_BH, do_serial_bh);	/* Find out how many Z8530 SCCs we have */	if (zs_chain == 0)		probe_sccs();	show_serial_version();	/* Initialize the tty_driver structure */	/* Not all of this is exactly right for us. */	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 = "tts/%d";#else	serial_driver.name = "ttyS";#endif	serial_driver.major = TTY_MAJOR;	serial_driver.minor_start = 64;	serial_driver.num = zs_channels_found;	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.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.wait_until_sent = rs_wait_until_sent;	/*	 * 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;	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 (channel = 0; channel < zs_channels_found; ++channel) {		if (zs_soft[channel].hook &&		    zs_soft[channel].hook->init_channel)			(*zs_soft[channel].hook->init_channel)				(&zs_soft[channel]);		zs_soft[channel].clk_divisor = 16;		zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]);		if (request_irq(zs_parms->irq, rs_interrupt, SA_SHIRQ,				"SCC", &zs_soft[channel]))			printk(KERN_ERR "decserial: can't get irq %d\n",			       zs_parms->irq);	}	for (info = zs_chain, i = 0; info; info = info->zs_next, i++)	{		if (info->hook && info->hook->init_info) {			(*info->hook->init_info)(info);			continue;		}		info->magic = SERIAL_MAGIC;		info->port = (int) info->zs_channel->control;		info->line = i;		info->tty = 0;		info->custom_divisor = 16;		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->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);		printk("ttyS%02d at 0x%08x (irq = %d)", info->line, 		       info->port, info->irq);		printk(" is a Z85C30 SCC\n");		tty_register_devfs(&serial_driver, 0,				   serial_driver.minor_start + info->line);		tty_register_devfs(&callout_driver, 0,				   callout_driver.minor_start + info->line);	}	restore_flags(flags);	return 0;}/* * register_serial and unregister_serial allows for serial ports to be * configured at run-time, to support PCMCIA modems. *//* PowerMac: Unused at this time, just here to make things link. */int register_serial(struct serial_struct *req){	return -1;}void unregister_serial(int line){	return;}/* * polling I/O routines */static intzs_poll_tx_char(struct dec_serial *info, unsigned char ch){	struct dec_zschannel *chan = info->zs_channel;	int    ret;	if(chan) {		int loops = 10000;//		int nine = read_zsreg(chan, R9);		RECOVERY_DELAY;//        	write_zsreg(chan, R9, nine & ~MIE);               	wbflush();		RECOVERY_DELAY;        	while (!(*(chan->control) & Tx_BUF_EMP) && --loops)	        	RECOVERY_DELAY;                if (loops) {                        ret = 0;        	        *(chan->data) = ch;                	wbflush();			RECOVERY_DELAY;                } else                        ret = -EAGAIN;//        	write_zsreg(chan, R9, nine);               	wbflush();		RECOVERY_DELAY;                return ret;        }	return -ENODEV;}static intzs_poll_rx_char(struct dec_serial *info){        struct dec_zschannel *chan = info->zs_channel;        int    ret;	if(chan) {                int loops = 10000;                while((read_zsreg(chan, 0) & Rx_CH_AV) == 0)		        loops--;                if (loops)                        ret = read_zsdata(chan);                else                        ret = -EAGAIN;                return ret;        } else                return -ENODEV;}unsigned int register_zs_hook(unsigned int channel, struct zs_hook *hook){	struct dec_serial *info = &zs_soft[channel];	if (info->hook) {		printk(__FUNCTION__": line %d has already a hook registered\n", channel);		return 0;	} else {		info->hook = hook;		if (zs_chain == 0)			probe_sccs();		if (!(info->flags & ZILOG_INITIALIZED))			zs_startup(info);		hook->poll_rx_char = zs_poll_rx_char;		hook->poll_tx_char = zs_poll_tx_char;		return 1;	}}unsigned int unregister_zs_hook(unsigned int channel){	struct dec_serial *info = &zs_soft[channel];        if (info->hook) {                info->hook = NULL;                return 1;        } else {                printk(__FUNCTION__": trying to unregister hook on line %d,"                       " but none is registered\n", channel);                return 0;        }}/* * ------------------------------------------------------------ * Serial console driver * ------------------------------------------------------------ */#ifdef CONFIG_SERIAL_CONSOLE/* *	Print a string to the serial port trying not to disturb *	any possible real use of the port... */static void serial_console_write(struct console *co, const char *s,				 unsigned count){	struct dec_serial *info;	int i;	info = zs_soft + co->index;	for (i = 0; i < count; i++, s++) {		if(*s == '\n')			zs_poll_tx_char(info, '\r');		zs_poll_tx_char(info, *s);	}}/* *	Receive character from the serial port */static int serial_console_wait_key(struct console *co){	struct dec_serial *info;        info = zs_soft + co->index;        return zs_poll_rx_char(info);}static kdev_t serial_console_device(struct console *c){	return MKDEV(TTY_MAJOR, 64 + c->index);}/* *	Setup initial baud/bits/parity. We do two things here: *	- construct a cflag setting for the first rs_open() *	- initialize the serial port *	Return non-zero if we didn't find a serial port. */static int __init serial_console_setup(struct console *co, char *options){	struct dec_serial *info;	int	baud = 9600;	int	bits = 8;	int	parity = 'n';	int	cflag = CREAD | HUPCL | CLOCAL;	char	*s;	unsigned long flags;	if(!BUS_PRESENT)		return -ENODEV;	info = zs_soft + co->index;	if (zs_chain == 0)		probe_sccs();	info->is_cons = 1;	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 |= B1200;		break;	case 2400:		cflag |= B2400;		break;	case 4800:		cflag |= B4800;		break;	case 19200:		cflag |= B19200;		break;	case 38400:		cflag |= B38400;		break;	case 57600:		cflag |= B57600;		break;	case 115200:		cflag |= B115200;		break;	case 9600:	default:		cflag |= B9600;		break;	}	switch(bits) {	case 7:		cflag |= CS7;		break;	default:	case 8:		cflag |= CS8;		break;	}	switch(parity) {	case 'o': case 'O':		cflag |= PARODD;		break;	case 'e': case 'E':		cflag |= PARENB;		break;	}	co->cflag = cflag;#if 1 	save_and_cli(flags);	/*	 * Turn on RTS and DTR.	 */	zs_rtsdtr(info, RTS | DTR, 1);	/*	 * Finally, enable sequencing	 */	info->zs_channel->curregs[3] |= (RxENABLE | Rx8);	info->zs_channel->curregs[5] |= (TxENAB | Tx8);	info->zs_channel->curregs[9] |= (VIS);	write_zsreg(info->zs_channel, 3, info->zs_channel->curregs[3]);	write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]);	write_zsreg(info->zs_channel, 9, info->zs_channel->curregs[9]);	/*	 * Clear the interrupt registers.	 */	write_zsreg(info->zs_channel, 0, ERR_RES);	write_zsreg(info->zs_channel, 0, RES_H_IUS);	/*	 * Set the speed of the serial port	 */	change_speed(info);	/* Save the current value of RR0 */	info->read_reg_zero = read_zsreg(info->zs_channel, 0);	zs_soft[co->index].clk_divisor = 16;	zs_soft[co->index].zs_baud = get_zsbaud(&zs_soft[co->index]);	restore_flags(flags);#endif	return 0;}static struct console sercons = {	name:		"ttyS",	write:		serial_console_write,	device:		serial_console_device,	wait_key:	serial_console_wait_key,	setup:		serial_console_setup,	flags:		CON_PRINTBUFFER,	index:		-1,};/* *	Register console. */void __init zs_serial_console_init(void){	register_console(&sercons);}#endif /* ifdef CONFIG_SERIAL_CONSOLE */#ifdef CONFIG_KGDBstruct dec_zschannel *zs_kgdbchan;static unsigned char scc_inittab[] = {	9,  0x80,	/* reset A side (CHRA) */	13, 0,		/* set baud rate divisor */	12, 1,	14, 1,		/* baud rate gen enable, src=rtxc (BRENABL) */	11, 0x50,	/* clocks = br gen (RCBR | TCBR) */	5,  0x6a,	/* tx 8 bits, assert RTS (Tx8 | TxENAB | RTS) */	4,  0x44,	/* x16 clock, 1 stop (SB1 | X16CLK)*/	3,  0xc1,	/* rx enable, 8 bits (RxENABLE | Rx8)*/};/* These are for receiving and sending characters under the kgdb * source level kernel debugger. */void putDebugChar(char kgdb_char){	struct dec_zschannel *chan = zs_kgdbchan;	while ((read_zsreg(chan, 0) & Tx_BUF_EMP) == 0)		RECOVERY_DELAY;	write_zsdata(chan, kgdb_char);}char getDebugChar(void){	struct dec_zschannel *chan = zs_kgdbchan;	while((read_zsreg(chan, 0) & Rx_CH_AV) == 0)		eieio(); /*barrier();*/	return read_zsdata(chan);}void kgdb_interruptible(int yes){	struct dec_zschannel *chan = zs_kgdbchan;	int one, nine;	nine = read_zsreg(chan, 9);	if (yes == 1) {		one = EXT_INT_ENAB|INT_ALL_Rx;		nine |= MIE;		printk("turning serial ints on\n");	} else {		one = RxINT_DISAB;		nine &= ~MIE;		printk("turning serial ints off\n");	}	write_zsreg(chan, 1, one);	write_zsreg(chan, 9, nine);}static int kgdbhook_init_channel(struct dec_serial* info) {	return 0;}static void kgdbhook_init_info(struct dec_serial* info){}static void kgdbhook_rx_char(struct dec_serial* info, 			     unsigned char ch, unsigned char stat){	if (ch == 0x03 || ch == '$')		breakpoint();	if (stat & (Rx_OVR|FRM_ERR|PAR_ERR))		write_zsreg(info->zs_channel, 0, ERR_RES);}/* This sets up the serial port we're using, and turns on * interrupts for that channel, so kgdb is usable once we're done. */static inline void kgdb_chaninit(struct dec_zschannel *ms, int intson, int bps){	int brg;	int i, x;	volatile char *sccc = ms->control;	brg = BPS_TO_BRG(bps, zs_parms->clock/16);	printk("setting bps on kgdb line to %d [brg=%x]\n", bps, brg);	for (i = 20000; i != 0; --i) {		x = *sccc; eieio();	}	for (i = 0; i < sizeof(scc_inittab); ++i) {		write_zsreg(ms, scc_inittab[i], scc_inittab[i+1]);		i++;	}}/* This is called at boot time to prime the kgdb serial debugging * serial line.  The 'tty_num' argument is 0 for /dev/ttya and 1 * for /dev/ttyb which is determined in setup_arch() from the * boot command line flags. */struct zs_hook zs_kgdbhook = {	init_channel : kgdbhook_init_channel,	init_info    : kgdbhook_init_info,	cflags       : B38400|CS8|CLOCAL,	rx_char      : kgdbhook_rx_char,}void __init zs_kgdb_hook(int tty_num){	/* Find out how many Z8530 SCCs we have */	if (zs_chain == 0)		probe_sccs();	zs_soft[tty_num].zs_channel = &zs_channels[tty_num];	zs_kgdbchan = zs_soft[tty_num].zs_channel;	zs_soft[tty_num].change_needed = 0;	zs_soft[tty_num].clk_divisor = 16;	zs_soft[tty_num].zs_baud = 38400; 	zs_soft[tty_num].hook = &zs_kgdbhook; /* This runs kgdb */	/* Turn on transmitter/receiver at 8-bits/char */        kgdb_chaninit(zs_soft[tty_num].zs_channel, 1, 38400);	printk("KGDB: on channel %d initialized\n", tty_num);	set_debug_traps(); /* init stub */}#endif /* ifdef CONFIG_KGDB */

⌨️ 快捷键说明

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