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

📄 aurora.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*	IRQ_to_board[bp->irq&0xf] = NULL;*/#endif		/* Drop all DTR's */	for(i=0;i<16;i++){		sbus_writeb(i & 7, &bp->r[i>>3]->r[CD180_CAR]);		udelay(1);		sbus_writeb(0, &bp->r[i>>3]->r[CD180_MSVR]);		udelay(1);	}	/* Board shutdown */	sbus_writeb(0, &bp->r0->r);#ifdef AURORA_DEBUG	printk("aurora_shutdown_board: end\n");#endif}/* Setting up port characteristics.  * Must be called with disabled interrupts */static void aurora_change_speed(struct Aurora_board *bp, struct Aurora_port *port){	struct tty_struct *tty;	unsigned long baud;	long tmp;	unsigned char cor1 = 0, cor3 = 0;	unsigned char mcor1 = 0, mcor2 = 0,chip;	#ifdef AURORA_DEBUG	printk("aurora_change_speed: start\n");#endif	if (!(tty = port->tty) || !tty->termios)		return;			chip = AURORA_CD180(port_No(port));	port->SRER  = 0;	port->COR2 = 0;	port->MSVR = MSVR_RTS|MSVR_DTR;		baud = C_BAUD(tty);		if (baud & CBAUDEX) {		baud &= ~CBAUDEX;		if (baud < 1 || baud > 2) 			port->tty->termios->c_cflag &= ~CBAUDEX;		else			baud += 15;	}	if (baud == 15)  {		if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)			baud ++;		if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)			baud += 2;	}		/* Select port on the board */	sbus_writeb(port_No(port) & 7,		    &bp->r[chip]->r[CD180_CAR]);	udelay(1);		if (!baud_table[baud])  {		/* Drop DTR & exit */		port->MSVR &= ~(bp->DTR|bp->RTS);		sbus_writeb(port->MSVR,			    &bp->r[chip]->r[CD180_MSVR]);		return;	} else  {		/* Set DTR on */		port->MSVR |= bp->DTR;		sbus_writeb(port->MSVR,			    &bp->r[chip]->r[CD180_MSVR]);	}		/* Now we must calculate some speed dependant things. */		/* Set baud rate for port. */	tmp = (((bp->oscfreq + baud_table[baud]/2) / baud_table[baud] +		CD180_TPC/2) / CD180_TPC);/*	tmp = (bp->oscfreq/7)/baud_table[baud];	if((tmp%10)>4)tmp=tmp/10+1;else tmp=tmp/10;*//*	printk("Prescaler period: %d\n",tmp);*/	sbus_writeb((tmp >> 8) & 0xff,		    &bp->r[chip]->r[CD180_RBPRH]);	sbus_writeb((tmp >> 8) & 0xff,		    &bp->r[chip]->r[CD180_TBPRH]);	sbus_writeb(tmp & 0xff, &bp->r[chip]->r[CD180_RBPRL]);	sbus_writeb(tmp & 0xff, &bp->r[chip]->r[CD180_TBPRL]);		baud = (baud_table[baud] + 5) / 10;   /* Estimated CPS */		/* Two timer ticks seems enough to wakeup something like SLIP driver */	tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;			port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?					      SERIAL_XMIT_SIZE - 1 : tmp);		/* Receiver timeout will be transmission time for 1.5 chars */	tmp = (AURORA_TPS + AURORA_TPS/2 + baud/2) / baud;	tmp = (tmp > 0xff) ? 0xff : tmp;	sbus_writeb(tmp, &bp->r[chip]->r[CD180_RTPR]);		switch (C_CSIZE(tty))  {	 case CS5:		cor1 |= COR1_5BITS;		break;	 case CS6:		cor1 |= COR1_6BITS;		break;	 case CS7:		cor1 |= COR1_7BITS;		break;	 case CS8:		cor1 |= COR1_8BITS;		break;	}		if (C_CSTOPB(tty)) 		cor1 |= COR1_2SB;		cor1 |= COR1_IGNORE;	if (C_PARENB(tty))  {		cor1 |= COR1_NORMPAR;		if (C_PARODD(tty)) 			cor1 |= COR1_ODDP;		if (I_INPCK(tty)) 			cor1 &= ~COR1_IGNORE;	}	/* Set marking of some errors */	port->mark_mask = RCSR_OE | RCSR_TOUT;	if (I_INPCK(tty)) 		port->mark_mask |= RCSR_FE | RCSR_PE;	if (I_BRKINT(tty) || I_PARMRK(tty)) 		port->mark_mask |= RCSR_BREAK;	if (I_IGNPAR(tty)) 		port->mark_mask &= ~(RCSR_FE | RCSR_PE);	if (I_IGNBRK(tty))  {		port->mark_mask &= ~RCSR_BREAK;		if (I_IGNPAR(tty)) 			/* Real raw mode. Ignore all */			port->mark_mask &= ~RCSR_OE;	}	/* Enable Hardware Flow Control */	if (C_CRTSCTS(tty))  {/*#ifdef AURORA_BRAIN_DAMAGED_CTS		port->SRER |= SRER_DSR | SRER_CTS;		mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;		mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;		tty->hw_stopped = !(aurora_in(bp, CD180_MSVR) & (MSVR_CTS|MSVR_DSR));#else*/		port->COR2 |= COR2_CTSAE;/*#endif*/		if (bp->flags&AURORA_BOARD_DTR_FLOW_OK) {			mcor1 |= AURORA_RXTH;		}	}	/* Enable Software Flow Control. FIXME: I'm not sure about this */	/* Some people reported that it works, but I still doubt */	if (I_IXON(tty))  {		port->COR2 |= COR2_TXIBE;		cor3 |= (COR3_FCT | COR3_SCDE);		if (I_IXANY(tty))			port->COR2 |= COR2_IXM;		sbus_writeb(START_CHAR(tty),			    &bp->r[chip]->r[CD180_SCHR1]);		sbus_writeb(STOP_CHAR(tty),			    &bp->r[chip]->r[CD180_SCHR2]);		sbus_writeb(START_CHAR(tty),			    &bp->r[chip]->r[CD180_SCHR3]);		sbus_writeb(STOP_CHAR(tty),			    &bp->r[chip]->r[CD180_SCHR4]);	}	if (!C_CLOCAL(tty))  {		/* Enable CD check */		port->SRER |= SRER_CD;		mcor1 |= MCOR1_CDZD;		mcor2 |= MCOR2_CDOD;	}		if (C_CREAD(tty)) 		/* Enable receiver */		port->SRER |= SRER_RXD;		/* Set input FIFO size (1-8 bytes) */	cor3 |= AURORA_RXFIFO; 	/* Setting up CD180 channel registers */	sbus_writeb(cor1, &bp->r[chip]->r[CD180_COR1]);	sbus_writeb(port->COR2, &bp->r[chip]->r[CD180_COR2]);	sbus_writeb(cor3, &bp->r[chip]->r[CD180_COR3]);	/* Make CD180 know about registers change */	aurora_wait_CCR(bp->r[chip]);	sbus_writeb(CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3,		    &bp->r[chip]->r[CD180_CCR]);	/* Setting up modem option registers */	sbus_writeb(mcor1, &bp->r[chip]->r[CD180_MCOR1]);	sbus_writeb(mcor2, &bp->r[chip]->r[CD180_MCOR2]);	/* Enable CD180 transmitter & receiver */	aurora_wait_CCR(bp->r[chip]);	sbus_writeb(CCR_TXEN | CCR_RXEN, &bp->r[chip]->r[CD180_CCR]);	/* Enable interrupts */	sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);	/* And finally set RTS on */	sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);#ifdef AURORA_DEBUG	printk("aurora_change_speed: end\n");#endif}/* Must be called with interrupts enabled */static int aurora_setup_port(struct Aurora_board *bp, struct Aurora_port *port){	unsigned long flags;	#ifdef AURORA_DEBUG	printk("aurora_setup_port: start %d\n",port_No(port));#endif	if (port->flags & ASYNC_INITIALIZED)		return 0;			if (!port->xmit_buf) {		/* We may sleep in get_free_page() */		unsigned long tmp;				if (!(tmp = get_free_page(GFP_KERNEL)))			return -ENOMEM;		    		if (port->xmit_buf) {			free_page(tmp);			return -ERESTARTSYS;		}		port->xmit_buf = (unsigned char *) tmp;	}			save_flags(flags); cli();			if (port->tty) 		clear_bit(TTY_IO_ERROR, &port->tty->flags);		#ifdef MODULE	if (port->count == 1) {		MOD_INC_USE_COUNT;		if((++bp->count) == 1)			bp->flags |= AURORA_BOARD_ACTIVE;	}#endif	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;	aurora_change_speed(bp, port);	port->flags |= ASYNC_INITIALIZED;			restore_flags(flags);#ifdef AURORA_DEBUG	printk("aurora_setup_port: end\n");#endif	return 0;}/* Must be called with interrupts disabled */static void aurora_shutdown_port(struct Aurora_board *bp, struct Aurora_port *port){	struct tty_struct *tty;	unsigned char chip;#ifdef AURORA_DEBUG	printk("aurora_shutdown_port: start\n");#endif	if (!(port->flags & ASYNC_INITIALIZED)) 		return;		chip = AURORA_CD180(port_No(port));	#ifdef AURORA_REPORT_OVERRUN	printk("aurora%d: port %d: Total %ld overruns were detected.\n",	       board_No(bp), port_No(port), port->overrun);#endif	#ifdef AURORA_REPORT_FIFO	{		int i;				printk("aurora%d: port %d: FIFO hits [ ",		       board_No(bp), port_No(port));		for (i = 0; i < 10; i++)  {			printk("%ld ", port->hits[i]);		}		printk("].\n");	}#endif		if (port->xmit_buf)  {		free_page((unsigned long) port->xmit_buf);		port->xmit_buf = NULL;	}	if (!(tty = port->tty) || C_HUPCL(tty))  {		/* Drop DTR */		port->MSVR &= ~(bp->DTR|bp->RTS);		sbus_writeb(port->MSVR,			    &bp->r[chip]->r[CD180_MSVR]);	}	        /* Select port */	sbus_writeb(port_No(port) & 7,		    &bp->r[chip]->r[CD180_CAR]);	udelay(1);	/* Reset port */	aurora_wait_CCR(bp->r[chip]);	sbus_writeb(CCR_SOFTRESET, &bp->r[chip]->r[CD180_CCR]);	/* Disable all interrupts from this port */	port->SRER = 0;	sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);		if (tty)  		set_bit(TTY_IO_ERROR, &tty->flags);	port->flags &= ~ASYNC_INITIALIZED;#ifdef MODULE	if (--bp->count < 0)  {		printk(KERN_DEBUG "aurora%d: aurora_shutdown_port: "		       "bad board count: %d\n",		       board_No(bp), bp->count);		bp->count = 0;	}		MOD_DEC_USE_COUNT;	if (!bp->count)		bp->flags &= ~AURORA_BOARD_ACTIVE;#endif#ifdef AURORA_DEBUG	printk("aurora_shutdown_port: end\n");#endif}	static int block_til_ready(struct tty_struct *tty, struct file * filp,			   struct Aurora_port *port){	DECLARE_WAITQUEUE(wait, current);	struct Aurora_board *bp = port_Board(port);	int    retval;	int    do_clocal = 0;	int    CD;	unsigned char chip;	#ifdef AURORA_DEBUG	printk("block_til_ready: start\n");#endif	chip = AURORA_CD180(port_No(port));	/* If the device is in the middle of being closed, then block	 * until it's done, and then try again.	 */	if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {		interruptible_sleep_on(&port->close_wait);		if (port->flags & ASYNC_HUP_NOTIFY)			return -EAGAIN;		else			return -ERESTARTSYS;	}	/* 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 (port->flags & ASYNC_CALLOUT_ACTIVE)			return -EBUSY;		port->flags |= ASYNC_NORMAL_ACTIVE;		return 0;	}	if (port->flags & ASYNC_CALLOUT_ACTIVE) {		if (port->normal_termios.c_cflag & CLOCAL) 			do_clocal = 1;	} else {		if (C_CLOCAL(tty))  			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	 * rs_close() knows when to free things.  We restore it upon	 * exit, either normal or abnormal.	 */	retval = 0;	add_wait_queue(&port->open_wait, &wait);	cli();	if (!tty_hung_up_p(filp))		port->count--;	sti();	port->blocked_open++;	while (1) {		cli();		sbus_writeb(port_No(port) & 7,			    &bp->r[chip]->r[CD180_CAR]);		udelay(1);		CD = sbus_readb(&bp->r[chip]->r[CD180_MSVR]) & MSVR_CD;		if (!(port->flags & ASYNC_CALLOUT_ACTIVE))  {			port->MSVR=bp->RTS;			/* auto drops DTR */			sbus_writeb(port->MSVR,				    &bp->r[chip]->r[CD180_MSVR]);		}		sti();		set_current_state(TASK_INTERRUPTIBLE);		if (tty_hung_up_p(filp) ||		    !(port->flags & ASYNC_INITIALIZED)) {			if (port->flags & ASYNC_HUP_NOTIFY)				retval = -EAGAIN;			else				retval = -ERESTARTSYS;				break;		}		if (/*!(port->flags & ASYNC_CALLOUT_ACTIVE) &&*/		    !(port->flags & ASYNC_CLOSING) &&		    (do_clocal || CD))			break;		if (signal_pending(current)) {			retval = -ERESTARTSYS;			break;		}		schedule();	}	current->state = TASK_RUNNING;	remove_wait_queue(&port->open_wait, &wait);	if (!tty_hung_up_p(filp))		port->count++;	port->blocked_open--;	if (retval)		return retval;		port->flags |= ASYNC_NORMAL_ACTIVE;#ifdef AURORA_DEBUG	printk("block_til_ready: end\n");#endif	return 0;}	static int aurora_open(struct tty_struct * tty, struct file * filp){	int board;	int error;	struct Aurora_port * port;	struct Aurora_board * bp;	unsigned long flags;	#ifdef AURORA_DEBUG	printk("aurora_open: start\n");#endif		board = AURORA_BOARD(MINOR(tty->device));	if (board > AURORA_NBOARD ||	    !(aurora_board[board].flags & AURORA_BOARD_PRESENT)) {#ifdef AURORA_DEBUG		printk("aurora_open: error board %d present %d\n",		       board, aurora_board[board].flags & AURORA_BOARD_PRESENT);#endif		return -ENODEV;	}		bp = &aurora_board[board];	port = aurora_port + board * AURORA_NPORT * AURORA_NCD180 + AURORA_PORT(MINOR(tty->device));	if (aurora_paranoia_check(port, tty->device, "aurora_open")) {#ifdef AURORA_DEBUG		printk("aurora_open: error paranoia check\n");#endif		return -ENODEV;	}		port->count++;	tty->driver_data = port;	port->tty = tty;		if ((error = aurora_setup_port(bp, port))) {#ifdef AURORA_DEBUG		printk("aurora_open: error aurora_setup_port ret %d\n",error);#endif		return error;	}	if ((error = block_til_ready(tty, filp, port))) {#ifdef AURORA_DEBUG		printk("aurora_open: error block_til_ready ret %d\n",error);#endif		return error;	}		if ((port->count == 1) && (port->flags & ASYNC_SPLIT_TERMIOS)) {		*tty->termios = port->normal_termios;		save_flags(flags); cli();		aurora_change_speed(bp, port);		restore_flags(flags);

⌨️ 快捷键说明

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