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

📄 aurora.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	tmp.type = PORT_CIRRUS;	tmp.line = port - aurora_port;	tmp.port = 0;	tmp.irq  = bp->irq;	tmp.flags = port->flags;	tmp.baud_base = (bp->oscfreq + CD180_TPC/2) / CD180_TPC;	tmp.close_delay = port->close_delay * HZ/100;	tmp.closing_wait = port->closing_wait * HZ/100;	tmp.xmit_fifo_size = CD180_NFIFO;	copy_to_user(retinfo, &tmp, sizeof(tmp));#ifdef AURORA_DEBUGprintk("aurora_get_serial_info: end\n");#endif	return 0;}static int aurora_ioctl(struct tty_struct * tty, struct file * filp, 		    unsigned int cmd, unsigned long arg)		    {	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	int error;	int retval;#ifdef AURORA_DEBUG	printk("aurora_ioctl: start\n");#endif	if (aurora_paranoia_check(port, tty->device, "aurora_ioctl"))		return -ENODEV;		switch (cmd) {	case TCSBRK:	/* SVID version: non-zero arg --> no break */		retval = tty_check_change(tty);		if (retval)			return retval;		tty_wait_until_sent(tty, 0);		if (!arg)			aurora_send_break(port, HZ/4);	/* 1/4 second */		return 0;	case TCSBRKP:	/* support for POSIX tcsendbreak() */		retval = tty_check_change(tty);		if (retval)			return retval;		tty_wait_until_sent(tty, 0);		aurora_send_break(port, arg ? arg*(HZ/10) : HZ/4);		return 0;	case TIOCGSOFTCAR:		error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));		if (error)			return error;		put_user(C_CLOCAL(tty) ? 1 : 0,			 (unsigned long *) arg);		return 0;	case TIOCSSOFTCAR:		retval = get_user(arg,(unsigned long *) arg);		if (retval)			return retval;		tty->termios->c_cflag =			((tty->termios->c_cflag & ~CLOCAL) |			 (arg ? CLOCAL : 0));		return 0;	case TIOCMGET:		error = verify_area(VERIFY_WRITE, (void *) arg,				    sizeof(unsigned int));		if (error)			return error;		return aurora_get_modem_info(port, (unsigned int *) arg);	case TIOCMBIS:	case TIOCMBIC:	case TIOCMSET:		return aurora_set_modem_info(port, cmd, (unsigned int *) arg);	case TIOCGSERIAL:			return aurora_get_serial_info(port, (struct serial_struct *) arg);	case TIOCSSERIAL:			return aurora_set_serial_info(port, (struct serial_struct *) arg);	default:		return -ENOIOCTLCMD;	};#ifdef AURORA_DEBUG	printk("aurora_ioctl: end\n");#endif	return 0;}static void aurora_throttle(struct tty_struct * tty){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	struct Aurora_board *bp;	unsigned long flags;	unsigned char chip;#ifdef AURORA_DEBUG	printk("aurora_throttle: start\n");#endif	if (aurora_paranoia_check(port, tty->device, "aurora_throttle"))		return;		bp = port_Board(port);	chip = AURORA_CD180(port_No(port));		save_flags(flags); cli();	port->MSVR &= ~bp->RTS;	sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);	udelay(1);	if (I_IXOFF(tty))  {		aurora_wait_CCR(bp->r[chip]);		sbus_writeb(CCR_SSCH2, &bp->r[chip]->r[CD180_CCR]);		aurora_wait_CCR(bp->r[chip]);	}	sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);	restore_flags(flags);#ifdef AURORA_DEBUG	printk("aurora_throttle: end\n");#endif}static void aurora_unthrottle(struct tty_struct * tty){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	struct Aurora_board *bp;	unsigned long flags;	unsigned char chip;#ifdef AURORA_DEBUG	printk("aurora_unthrottle: start\n");#endif	if (aurora_paranoia_check(port, tty->device, "aurora_unthrottle"))		return;		bp = port_Board(port);		chip = AURORA_CD180(port_No(port));		save_flags(flags); cli();	port->MSVR |= bp->RTS;	sbus_writeb(port_No(port) & 7,		    &bp->r[chip]->r[CD180_CAR]);	udelay(1);	if (I_IXOFF(tty))  {		aurora_wait_CCR(bp->r[chip]);		sbus_writeb(CCR_SSCH1,			    &bp->r[chip]->r[CD180_CCR]);		aurora_wait_CCR(bp->r[chip]);	}	sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);	restore_flags(flags);#ifdef AURORA_DEBUG	printk("aurora_unthrottle: end\n");#endif}static void aurora_stop(struct tty_struct * tty){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	struct Aurora_board *bp;	unsigned long flags;	unsigned char chip;#ifdef AURORA_DEBUG	printk("aurora_stop: start\n");#endif	if (aurora_paranoia_check(port, tty->device, "aurora_stop"))		return;		bp = port_Board(port);		chip = AURORA_CD180(port_No(port));		save_flags(flags); cli();	port->SRER &= ~SRER_TXRDY;	sbus_writeb(port_No(port) & 7,		    &bp->r[chip]->r[CD180_CAR]);	udelay(1);	sbus_writeb(port->SRER,		    &bp->r[chip]->r[CD180_SRER]);	restore_flags(flags);#ifdef AURORA_DEBUG	printk("aurora_stop: end\n");#endif}static void aurora_start(struct tty_struct * tty){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	struct Aurora_board *bp;	unsigned long flags;	unsigned char chip;#ifdef AURORA_DEBUG	printk("aurora_start: start\n");#endif	if (aurora_paranoia_check(port, tty->device, "aurora_start"))		return;		bp = port_Board(port);		chip = AURORA_CD180(port_No(port));		save_flags(flags); cli();	if (port->xmit_cnt && port->xmit_buf && !(port->SRER & SRER_TXRDY))  {		port->SRER |= SRER_TXRDY;		sbus_writeb(port_No(port) & 7,			    &bp->r[chip]->r[CD180_CAR]);		udelay(1);		sbus_writeb(port->SRER,			    &bp->r[chip]->r[CD180_SRER]);	}	restore_flags(flags);#ifdef AURORA_DEBUG	printk("aurora_start: end\n");#endif}/* * This routine is called from the scheduler tqueue when the interrupt * routine has signalled that a hangup has occurred.  The path of * hangup processing is: * * 	serial interrupt routine -> (scheduler tqueue) -> * 	do_aurora_hangup() -> tty->hangup() -> aurora_hangup() *  */static void do_aurora_hangup(void *private_){	struct Aurora_port	*port = (struct Aurora_port *) private_;	struct tty_struct	*tty;#ifdef AURORA_DEBUG	printk("do_aurora_hangup: start\n");#endif	tty = port->tty;	if (tty != NULL) {		tty_hangup(tty);	/* FIXME: module removal race - AKPM */#ifdef AURORA_DEBUG		printk("do_aurora_hangup: end\n");#endif	}	MOD_DEC_USE_COUNT;}static void aurora_hangup(struct tty_struct * tty){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	struct Aurora_board *bp;				#ifdef AURORA_DEBUG	printk("aurora_hangup: start\n");#endif	if (aurora_paranoia_check(port, tty->device, "aurora_hangup"))		return;		bp = port_Board(port);		aurora_shutdown_port(bp, port);	port->event = 0;	port->count = 0;	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);	port->tty = 0;	wake_up_interruptible(&port->open_wait);#ifdef AURORA_DEBUG	printk("aurora_hangup: end\n");#endif}static void aurora_set_termios(struct tty_struct * tty, struct termios * old_termios){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	unsigned long flags;#ifdef AURORA_DEBUG	printk("aurora_set_termios: start\n");#endif	if (aurora_paranoia_check(port, tty->device, "aurora_set_termios"))		return;		if (tty->termios->c_cflag == old_termios->c_cflag &&	    tty->termios->c_iflag == old_termios->c_iflag)		return;	save_flags(flags); cli();	aurora_change_speed(port_Board(port), port);	restore_flags(flags);	if ((old_termios->c_cflag & CRTSCTS) &&	    !(tty->termios->c_cflag & CRTSCTS)) {		tty->hw_stopped = 0;		aurora_start(tty);	}#ifdef AURORA_DEBUG	printk("aurora_set_termios: end\n");#endif}static void do_aurora_bh(void){	 run_task_queue(&tq_aurora);}static void do_softint(void *private_){	struct Aurora_port	*port = (struct Aurora_port *) private_;	struct tty_struct	*tty;#ifdef AURORA_DEBUG	printk("do_softint: start\n");#endif	tty = port->tty;	if (tty == NULL)		return;	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&		    tty->ldisc.write_wakeup)			(tty->ldisc.write_wakeup)(tty);		wake_up_interruptible(&tty->write_wait);	}#ifdef AURORA_DEBUG	printk("do_softint: end\n");#endif}static int aurora_init_drivers(void){	int error;	int i;#ifdef AURORA_DEBUG	printk("aurora_init_drivers: start\n");#endif	tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL);	if (tmp_buf == NULL) {		printk(KERN_ERR "aurora: Couldn't get free page.\n");		return 1;	}	init_bh(AURORA_BH, do_aurora_bh);/*	memset(IRQ_to_board, 0, sizeof(IRQ_to_board));*/	memset(&aurora_driver, 0, sizeof(aurora_driver));	aurora_driver.magic = TTY_DRIVER_MAGIC;	aurora_driver.name = "ttyA";	aurora_driver.major = AURORA_MAJOR;	aurora_driver.num = AURORA_TNPORTS;	aurora_driver.type = TTY_DRIVER_TYPE_SERIAL;	aurora_driver.subtype = AURORA_TYPE_NORMAL;	aurora_driver.init_termios = tty_std_termios;	aurora_driver.init_termios.c_cflag =		B9600 | CS8 | CREAD | HUPCL | CLOCAL;	aurora_driver.flags = TTY_DRIVER_REAL_RAW;	aurora_driver.refcount = &aurora_refcount;	aurora_driver.table = aurora_table;	aurora_driver.termios = aurora_termios;	aurora_driver.termios_locked = aurora_termios_locked;	aurora_driver.open  = aurora_open;	aurora_driver.close = aurora_close;	aurora_driver.write = aurora_write;	aurora_driver.put_char = aurora_put_char;	aurora_driver.flush_chars = aurora_flush_chars;	aurora_driver.write_room = aurora_write_room;	aurora_driver.chars_in_buffer = aurora_chars_in_buffer;	aurora_driver.flush_buffer = aurora_flush_buffer;	aurora_driver.ioctl = aurora_ioctl;	aurora_driver.throttle = aurora_throttle;	aurora_driver.unthrottle = aurora_unthrottle;	aurora_driver.set_termios = aurora_set_termios;	aurora_driver.stop = aurora_stop;	aurora_driver.start = aurora_start;	aurora_driver.hangup = aurora_hangup;	error = tty_register_driver(&aurora_driver);	if (error) {		free_page((unsigned long) tmp_buf);		printk(KERN_ERR "aurora: Couldn't register aurora driver, error = %d\n",		       error);		return 1;	}		memset(aurora_port, 0, sizeof(aurora_port));	for (i = 0; i < AURORA_TNPORTS; i++)  {		aurora_port[i].normal_termios  = aurora_driver.init_termios;		aurora_port[i].magic = AURORA_MAGIC;		aurora_port[i].tqueue.routine = do_softint;		aurora_port[i].tqueue.data = &aurora_port[i];		aurora_port[i].tqueue_hangup.routine = do_aurora_hangup;		aurora_port[i].tqueue_hangup.data = &aurora_port[i];		aurora_port[i].close_delay = 50 * HZ/100;		aurora_port[i].closing_wait = 3000 * HZ/100;		init_waitqueue_head(&aurora_port[i].open_wait);		init_waitqueue_head(&aurora_port[i].close_wait);	}#ifdef AURORA_DEBUG	printk("aurora_init_drivers: end\n");#endif	return 0;}static void aurora_release_drivers(void){#ifdef AURORA_DEBUG	printk("aurora_release_drivers: start\n");#endif	free_page((unsigned long)tmp_buf);	tty_unregister_driver(&aurora_driver);#ifdef AURORA_DEBUG	printk("aurora_release_drivers: end\n");#endif}/* * Called at boot time. * * You can specify IO base for up to RC_NBOARD cards, * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt. * Note that there will be no probing at default * addresses in this case. * */void __init aurora_setup(char *str, int *ints){	int i;	for(i=0;(i<ints[0])&&(i<4);i++) {		if (ints[i+1]) irqs[i]=ints[i+1];		}}static int __init aurora_real_init(void){	int found;	int i;	printk(KERN_INFO "aurora: Driver starting.\n");	if(aurora_init_drivers())		return -EIO;	found = aurora_probe();	if(!found) {		aurora_release_drivers();		printk(KERN_INFO "aurora: No Aurora Multiport boards detected.\n");		return -EIO;	} else {		printk(KERN_INFO "aurora: %d boards found.\n", found);	}	for (i = 0; i < found; i++) {		int ret = aurora_setup_board(&aurora_board[i]);		if (ret) {#ifdef AURORA_DEBUG			printk(KERN_ERR "aurora_init: error aurora_setup_board ret %d\n",			       ret);#endif			return ret;		}	}	return 0;}int irq  = 0;int irq1 = 0;int irq2 = 0;int irq3 = 0;MODULE_PARM(irq , "i");MODULE_PARM(irq1, "i");MODULE_PARM(irq2, "i");MODULE_PARM(irq3, "i");static int __init aurora_init(void) {	if (irq ) irqs[0]=irq ;	if (irq1) irqs[1]=irq1;	if (irq2) irqs[2]=irq2;	if (irq3) irqs[3]=irq3;	return aurora_real_init();}	static void __exit aurora_cleanup(void){	int i;	#ifdef AURORA_DEBUGprintk("cleanup_module: aurora_release_drivers\n");#endif;	aurora_release_drivers();	for (i = 0; i < AURORA_NBOARD; i++)		if (aurora_board[i].flags & AURORA_BOARD_PRESENT) {			aurora_shutdown_board(&aurora_board[i]);			aurora_release_io_range(&aurora_board[i]);		}}module_init(aurora_init);module_exit(aurora_cleanup);

⌨️ 快捷键说明

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