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

📄 aurora.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
				if (!(tmp = get_zeroed_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) && ((++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;	}		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))) {		port->flags |= ASYNC_NORMAL_ACTIVE;		return 0;	}	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;		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_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(tty->index);	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(tty->index);	if ((aurora_paranoia_check(port, tty->name, "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;	}	#ifdef AURORA_DEBUG	printk("aurora_open: end\n");#endif	return 0;}static void aurora_close(struct tty_struct * tty, struct file * filp){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	struct Aurora_board *bp;	unsigned long flags;	unsigned long timeout;	unsigned char chip;	#ifdef AURORA_DEBUG	printk("aurora_close: start\n");#endif		if (!port || (aurora_paranoia_check(port, tty->name, "close"))		return;		chip = AURORA_CD180(port_No(port));	save_flags(flags); cli();	if (tty_hung_up_p(filp))  {		restore_flags(flags);		return;	}		bp = port_Board(port);	if ((tty->count == 1) && (port->count != 1))  {		printk(KERN_DEBUG "aurora%d: aurora_close: bad port count; "		       "tty->count is 1, port count is %d\n",		       board_No(bp), port->count);		port->count = 1;	}	if (--port->count < 0)  {		printk(KERN_DEBUG "aurora%d: aurora_close: bad port "		       "count for tty%d: %d\n",		       board_No(bp), port_No(port), port->count);		port->count = 0;	}	if (port->count)  {		restore_flags(flags);		return;	}	port->flags |= ASYNC_CLOSING;	/* 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 (port->closing_wait != ASYNC_CLOSING_WAIT_NONE){#ifdef AURORA_DEBUG		printk("aurora_close: waiting to flush...\n");#endif		tty_wait_until_sent(tty, port->closing_wait);	}	/* At this point we stop accepting input.  To do this, we	 * disable the receive line status interrupts, and tell the	 * interrupt driver to stop checking the data ready bit in the	 * line status register.	 */	port->SRER &= ~SRER_RXD;	if (port->flags & ASYNC_INITIALIZED) {		port->SRER &= ~SRER_TXRDY;		port->SRER |= SRER_TXEMPTY;		sbus_writeb(port_No(port) & 7,			    &bp->r[chip]->r[CD180_CAR]);		udelay(1);		sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);		/*		 * Before we drop DTR, make sure the UART transmitter		 * has completely drained; this is especially		 * important if there is a transmit FIFO!		 */		timeout = jiffies+HZ;		while(port->SRER & SRER_TXEMPTY)  {			msleep_interruptible(jiffies_to_msecs(port->timeout));			if (time_after(jiffies, timeout))				break;		}	}#ifdef AURORA_DEBUG	printk("aurora_close: shutdown_port\n");#endif	aurora_shutdown_port(bp, port);	if (tty->driver->flush_buffer)		tty->driver->flush_buffer(tty);	tty_ldisc_flush(tty);	tty->closing = 0;	port->event = 0;	port->tty = 0;	if (port->blocked_open) {		if (port->close_delay) {			msleep_interruptible(jiffies_to_msecs(port->close_delay));		}		wake_up_interruptible(&port->open_wait);	}	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);	wake_up_interruptible(&port->close_wait);	restore_flags(flags);#ifdef AURORA_DEBUG	printk("aurora_close: end\n");#endif}static int aurora_write(struct tty_struct * tty, 			const unsigned char *buf, int count){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	struct Aurora_board *bp;	int c, total = 0;	unsigned long flags;	unsigned char chip;#ifdef AURORA_DEBUG	printk("aurora_write: start %d\n",count);#endif	if ((aurora_paranoia_check(port, tty->name, "aurora_write"))		return 0;			chip = AURORA_CD180(port_No(port));		bp = port_Board(port);	if (!tty || !port->xmit_buf || !tmp_buf)		return 0;	save_flags(flags);	while (1) {		cli();		c = min(count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,				   SERIAL_XMIT_SIZE - port->xmit_head));		if (c <= 0) {			restore_flags(flags);			break;		}		memcpy(port->xmit_buf + port->xmit_head, buf, c);		port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);		port->xmit_cnt += c;		restore_flags(flags);		buf += c;		count -= c;		total += c;	}	cli();	if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&	    !(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_write: end %d\n",total);#endif	return total;}static void aurora_put_char(struct tty_struct * tty, unsigned char ch){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	unsigned long flags;#ifdef AURORA_DEBUG	printk("aurora_put_char: start %c\n",ch);#endif	if ((aurora_paranoia_check(port, tty->name, "aurora_put_char"))		return;	if (!tty || !port->xmit_buf)		return;	save_flags(flags); cli();		if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {		restore_flags(flags);		return;	}	port->xmit_buf[port->xmit_head++] = ch;	port->xmit_head &= SERIAL_XMIT_SIZE - 1;	port->xmit_cnt++;	restore_flags(flags);#ifdef AURORA_DEBUG	printk("aurora_put_char: end\n");#endif}static void aurora_flush_chars(struct tty_struct * tty){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	unsigned long flags;	unsigned char chip;/*#ifdef AURORA_DEBUG	printk("aurora_flush_chars: start\n");#endif*/	if ((aurora_paranoia_check(port, tty->name, "aurora_flush_chars"))		return;			chip = AURORA_CD180(port_No(port));		if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||	    !port->xmit_buf)		return;	save_flags(flags); cli();	port->SRER |= SRER_TXRDY;	sbus_writeb(port_No(port) & 7,		    &port_Board(port)->r[chip]->r[CD180_CAR]);	udelay(1);	sbus_writeb(port->SRER,		    &port_Board(port)->r[chip]->r[CD180_SRER]);	restore_flags(flags);/*#ifdef AURORA_DEBUG	printk("aurora_flush_chars: end\n");#endif*/}static int aurora_write_room(struct tty_struct * tty){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	int	ret;#ifdef AURORA_DEBUG	printk("aurora_write_room: start\n");#endif	if ((aurora_paranoia_check(port, tty->name, "aurora_write_room"))		return 0;	ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;	if (ret < 0)		ret = 0;#ifdef AURORA_DEBUG	printk("aurora_write_room: end\n");#endif	return ret;}static int aurora_chars_in_buffer(struct tty_struct *tty){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;					if ((aurora_paranoia_check(port, tty->name, "aurora_chars_in_buffer"))		return 0;		return port->xmit_cnt;}static void aurora_flush_buffer(struct tty_struct *tty){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	unsigned long flags;#ifdef AURORA_DEBUG	printk("aurora_flush_buffer: start\n");#endif	if ((aurora_paranoia_check(port, tty->name, "aurora_flush_buffer"))		return;	save_flags(flags); cli();	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;	restore_flags(flags);		tty_wakeup(tty);#ifdef AURORA_DEBUG	printk("aurora_flush_buffer: end\n");#endif}static int aurora_tiocmget(struct tty_struct *tty, struct file *file){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	struct Aurora_board * bp;	unsigned char status,chip;	unsigned int result;	unsigned long flags;#ifdef AURORA_DEBUG	printk("aurora_get_modem_info: start\n");#endif	if ((aurora_paranoia_check(port, tty->name, __FUNCTION__))		return -ENODEV;	chip = AURORA_CD180(port_No(port));	bp = port_Board(port);	save_flags(flags); cli();	sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);	udelay(1);	status = sbus_readb(&bp->r[chip]->r[CD180_MSVR]);	result = 0/*bp->r[chip]->r[AURORA_RI] & (1u << port_No(port)) ? 0 : TIOCM_RNG*/;	restore_flags(flags);	result |= ((status & bp->RTS) ? TIOCM_RTS : 0)		| ((status & bp->DTR) ? TIOCM_DTR : 0)		| ((status & MSVR_CD)  ? TIOCM_CAR : 0)		| ((status & MSVR_DSR) ? TIOCM_DSR : 0)		| ((status & MSVR_CTS) ? TIOCM_CTS : 0);#ifdef AURORA_DEBUG	printk("aurora_get_modem_info: end\n");#endif	return result;}static int aurora_tiocmset(struct tty_struct *tty, struct file *file,			   unsigned int set, unsigned int clear){	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;	unsigned int arg;	unsigned long flags;	struct Aurora_board *bp = port_Board(port);	unsigned char chip;#ifdef AURORA_DEBUG	printk("aurora_set_modem_info: start\n");#endif	if ((aurora_paranoia_check(port, tty->name, __FUNCTION__))		return -ENODEV;	chip = AURORA_CD180(port_No(port));	save_flags(flags); cli();	if (set & TIOCM_RTS)		port->MSVR |= bp->RTS;	if (set & TIOCM_DTR)		port->MSVR |= bp->DTR;

⌨️ 快捷键说明

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