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

📄 aurora.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#else		status = sbus_readb(&bp->r[chip]->r[CD180_RCSR]) & port->mark_mask;#endif		ch = sbus_readb(&bp->r[chip]->r[CD180_RDR]);	if (!status)		return;	if (status & RCSR_TOUT)  {/*		printk("aurora%d: port %d: Receiver timeout. Hardware problems ?\n",		       board_No(bp), port_No(port));*/		return;			} else if (status & RCSR_BREAK)  {		printk(KERN_DEBUG "aurora%d: port %d: Handling break...\n",		       board_No(bp), port_No(port));		*tty->flip.flag_buf_ptr++ = TTY_BREAK;		if (port->flags & ASYNC_SAK)			do_SAK(tty);			} else if (status & RCSR_PE) 		*tty->flip.flag_buf_ptr++ = TTY_PARITY;		else if (status & RCSR_FE) 		*tty->flip.flag_buf_ptr++ = TTY_FRAME;	        else if (status & RCSR_OE)		*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;		else		*tty->flip.flag_buf_ptr++ = 0;		*tty->flip.char_buf_ptr++ = ch;	tty->flip.count++;	queue_task(&tty->flip.tqueue, &tq_timer);}static void aurora_receive(struct Aurora_board const * bp, int chip){	struct Aurora_port *port;	struct tty_struct *tty;	unsigned char count,cnt;	if (!(port = aurora_get_port(bp, chip, "Receive")))		return;		tty = port->tty;		count = sbus_readb(&bp->r[chip]->r[CD180_RDCR]);#ifdef AURORA_REPORT_FIFO	port->hits[count > 8 ? 9 : count]++;#endif	while (count--)  {		if (tty->flip.count >= TTY_FLIPBUF_SIZE)  {#ifdef AURORA_INTNORM			printk("aurora%d: port %d: Working around flip buffer overflow.\n",			       board_No(bp), port_No(port));#endif			break;		}		cnt = sbus_readb(&bp->r[chip]->r[CD180_RDR]);		*tty->flip.char_buf_ptr++ = cnt;		*tty->flip.flag_buf_ptr++ = 0;		tty->flip.count++;	}	queue_task(&tty->flip.tqueue, &tq_timer);}static void aurora_transmit(struct Aurora_board const * bp, int chip){	struct Aurora_port *port;	struct tty_struct *tty;	unsigned char count;		if (!(port = aurora_get_port(bp, chip, "Transmit")))		return;			tty = port->tty;		if (port->SRER & SRER_TXEMPTY)  {		/* FIFO drained */		sbus_writeb(port_No(port) & 7,			    &bp->r[chip]->r[CD180_CAR]);		udelay(1);		port->SRER &= ~SRER_TXEMPTY;		sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);		return;	}		if ((port->xmit_cnt <= 0 && !port->break_length)	    || tty->stopped || tty->hw_stopped)  {		sbus_writeb(port_No(port) & 7,			    &bp->r[chip]->r[CD180_CAR]);		udelay(1);		port->SRER &= ~SRER_TXRDY;		sbus_writeb(port->SRER,			    &bp->r[chip]->r[CD180_SRER]);		return;	}		if (port->break_length)  {		if (port->break_length > 0)  {			if (port->COR2 & COR2_ETC)  {				sbus_writeb(CD180_C_ESC,					    &bp->r[chip]->r[CD180_TDR]);				sbus_writeb(CD180_C_SBRK,					    &bp->r[chip]->r[CD180_TDR]);				port->COR2 &= ~COR2_ETC;			}			count = MIN(port->break_length, 0xff);			sbus_writeb(CD180_C_ESC,				    &bp->r[chip]->r[CD180_TDR]);			sbus_writeb(CD180_C_DELAY,				    &bp->r[chip]->r[CD180_TDR]);			sbus_writeb(count,				    &bp->r[chip]->r[CD180_TDR]);			if (!(port->break_length -= count))				port->break_length--;		} else  {			sbus_writeb(CD180_C_ESC,				    &bp->r[chip]->r[CD180_TDR]);			sbus_writeb(CD180_C_EBRK,				    &bp->r[chip]->r[CD180_TDR]);			sbus_writeb(port->COR2,				    &bp->r[chip]->r[CD180_COR2]);			aurora_wait_CCR(bp->r[chip]);			sbus_writeb(CCR_CORCHG2,				    &bp->r[chip]->r[CD180_CCR]);			port->break_length = 0;		}		return;	}		count = CD180_NFIFO;	do {		u8 byte = port->xmit_buf[port->xmit_tail++];		sbus_writeb(byte, &bp->r[chip]->r[CD180_TDR]);		port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);		if (--port->xmit_cnt <= 0)			break;	} while (--count > 0);		if (port->xmit_cnt <= 0)  {		sbus_writeb(port_No(port) & 7,			    &bp->r[chip]->r[CD180_CAR]);		udelay(1);		port->SRER &= ~SRER_TXRDY;		sbus_writeb(port->SRER,			    &bp->r[chip]->r[CD180_SRER]);	}	if (port->xmit_cnt <= port->wakeup_chars)		aurora_mark_event(port, RS_EVENT_WRITE_WAKEUP);}static void aurora_check_modem(struct Aurora_board const * bp, int chip){	struct Aurora_port *port;	struct tty_struct *tty;	unsigned char mcr;		if (!(port = aurora_get_port(bp, chip, "Modem")))		return;			tty = port->tty;		mcr = sbus_readb(&bp->r[chip]->r[CD180_MCR]);	if (mcr & MCR_CDCHG)  {		if (sbus_readb(&bp->r[chip]->r[CD180_MSVR]) & MSVR_CD) 			wake_up_interruptible(&port->open_wait);		else if (!((port->flags & ASYNC_CALLOUT_ACTIVE) &&			   (port->flags & ASYNC_CALLOUT_NOHUP))) {			MOD_INC_USE_COUNT;			if (schedule_task(&port->tqueue_hangup) == 0)				MOD_DEC_USE_COUNT;		}	}	/* We don't have such things yet. My aurora board has DTR and RTS swapped, but that doesn't count in this driver. Let's hope * Aurora didn't made any boards with CTS or DSR broken... *//* #ifdef AURORA_BRAIN_DAMAGED_CTS	if (mcr & MCR_CTSCHG)  {		if (aurora_in(bp, CD180_MSVR) & MSVR_CTS)  {			tty->hw_stopped = 0;			port->SRER |= SRER_TXRDY;			if (port->xmit_cnt <= port->wakeup_chars)				aurora_mark_event(port, RS_EVENT_WRITE_WAKEUP);		} else  {			tty->hw_stopped = 1;			port->SRER &= ~SRER_TXRDY;		}		sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);	}	if (mcr & MCR_DSRCHG)  {		if (aurora_in(bp, CD180_MSVR) & MSVR_DSR)  {			tty->hw_stopped = 0;			port->SRER |= SRER_TXRDY;			if (port->xmit_cnt <= port->wakeup_chars)				aurora_mark_event(port, RS_EVENT_WRITE_WAKEUP);		} else  {			tty->hw_stopped = 1;			port->SRER &= ~SRER_TXRDY;		}		sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);	}#endif AURORA_BRAIN_DAMAGED_CTS */		/* Clear change bits */	sbus_writeb(0, &bp->r[chip]->r[CD180_MCR]);}/* The main interrupt processing routine */static void aurora_interrupt(int irq, void * dev_id, struct pt_regs * regs){	unsigned char status;	unsigned char ack,chip/*,chip_id*/;	struct Aurora_board * bp = (struct Aurora_board *) dev_id;	unsigned long loop = 0;#ifdef AURORA_INT_DEBUG	printk("IRQ%d %d\n",irq,++irqhit);#ifdef AURORA_FLOODPRO	if (irqhit>=AURORA_FLOODPRO)		sbus_writeb(8, &bp->r0->r);#endif#endif	/* old	bp = IRQ_to_board[irq&0x0f];*/		if (!bp || !(bp->flags & AURORA_BOARD_ACTIVE))		return;/*	The while() below takes care of this.	status = sbus_readb(&bp->r[0]->r[CD180_SRSR]);#ifdef AURORA_INT_DEBUG	printk("mumu: %02x\n", status);#endif	if (!(status&SRSR_ANYINT))		return; * Nobody has anything to say, so exit **/	while ((loop++ < 48) &&	       (status = sbus_readb(&bp->r[0]->r[CD180_SRSR]) & SRSR_ANYINT)){#ifdef AURORA_INT_DEBUG		printk("SRSR: %02x\n", status);#endif		if (status & SRSR_REXT) {			ack = sbus_readb(&bp->r3->r[bp->ACK_RINT]);#ifdef AURORA_INT_DEBUG			printk("R-ACK %02x\n", ack);#endif			if ((ack >> 5) == board_No(bp)) {				if ((chip=((ack>>3)&3)-1) < AURORA_NCD180) {					if ((ack&GSVR_ITMASK)==GSVR_IT_RGD) {						aurora_receive(bp,chip);						sbus_writeb(0,							 &bp->r[chip]->r[CD180_EOSRR]);					} else if ((ack & GSVR_ITMASK) == GSVR_IT_REXC) {						aurora_receive_exc(bp,chip);						sbus_writeb(0,							 &bp->r[chip]->r[CD180_EOSRR]);					}				}			}		} else if (status & SRSR_TEXT) {			ack = sbus_readb(&bp->r3->r[bp->ACK_TINT]);#ifdef AURORA_INT_DEBUG			printk("T-ACK %02x\n", ack);#endif			if ((ack >> 5) == board_No(bp)) {				if ((chip=((ack>>3)&3)-1) < AURORA_NCD180) {					if ((ack&GSVR_ITMASK)==GSVR_IT_TX) {						aurora_transmit(bp,chip);						sbus_writeb(0,							 &bp->r[chip]->r[CD180_EOSRR]);					}				}			}		} else if (status & SRSR_MEXT) {			ack = sbus_readb(&bp->r3->r[bp->ACK_MINT]);#ifdef AURORA_INT_DEBUG			printk("M-ACK %02x\n", ack);#endif			if ((ack >> 5) == board_No(bp)) {				if ((chip = ((ack>>3)&3)-1) < AURORA_NCD180) {					if ((ack&GSVR_ITMASK)==GSVR_IT_MDM) {						aurora_check_modem(bp,chip);						sbus_writeb(0,							 &bp->r[chip]->r[CD180_EOSRR]);					}				}			}		}	}/* I guess this faster code can be used with CD1865, using AUROPRI and GLOBPRI. */#if 0	while ((loop++ < 48)&&(status=bp->r[0]->r[CD180_SRSR]&SRSR_ANYINT)){#ifdef AURORA_INT_DEBUG		printk("SRSR: %02x\n",status);#endif		ack = sbus_readb(&bp->r3->r[0]);#ifdef AURORA_INT_DEBUG		printk("ACK: %02x\n",ack);#endif		if ((ack>>5)==board_No(bp)) {			if ((chip=((ack>>3)&3)-1) < AURORA_NCD180) {				ack&=GSVR_ITMASK;				if (ack==GSVR_IT_RGD) {					aurora_receive(bp,chip);					sbus_writeb(0,						    &bp->r[chip]->r[CD180_EOSRR]);				} else if (ack==GSVR_IT_REXC) {					aurora_receive_exc(bp,chip);					sbus_writeb(0,						    &bp->r[chip]->r[CD180_EOSRR]);				} else if (ack==GSVR_IT_TX) {					aurora_transmit(bp,chip);					sbus_writeb(0,						    &bp->r[chip]->r[CD180_EOSRR]);				} else if (ack==GSVR_IT_MDM) {					aurora_check_modem(bp,chip);					sbus_writeb(0,						    &bp->r[chip]->r[CD180_EOSRR]);				}			}		}	}#endif/* This is the old handling routine, used in riscom8 for only one CD180. I keep it here for reference. */#if 0	for(chip=0;chip<AURORA_NCD180;chip++){		chip_id=(board_No(bp)<<5)|((chip+1)<<3);		loop=0;		while ((loop++ < 1) &&		       ((status = sbus_readb(&bp->r[chip]->r[CD180_SRSR])) &			(SRSR_TEXT | SRSR_MEXT | SRSR_REXT))) {			if (status & SRSR_REXT) {				ack = sbus_readb(&bp->r3->r[bp->ACK_RINT]);				if (ack == (chip_id | GSVR_IT_RGD)) {#ifdef AURORA_INTMSG					printk("RX ACK\n");#endif					aurora_receive(bp,chip);				} else if (ack == (chip_id | GSVR_IT_REXC)) {#ifdef AURORA_INTMSG					printk("RXC ACK\n");#endif					aurora_receive_exc(bp,chip);				} else {#ifdef AURORA_INTNORM					printk("aurora%d-%d: Bad receive ack 0x%02x.\n",					       board_No(bp), chip, ack);#endif				}			} else if (status & SRSR_TEXT) {				ack = sbus_readb(&bp->r3->r[bp->ACK_TINT]);				if (ack == (chip_id | GSVR_IT_TX)){#ifdef AURORA_INTMSG					printk("TX ACK\n");#endif					aurora_transmit(bp,chip);				} else {#ifdef AURORA_INTNORM					printk("aurora%d-%d: Bad transmit ack 0x%02x.\n",					       board_No(bp), chip, ack);#endif				}			} else  if (status & SRSR_MEXT)  {				ack = sbus_readb(&bp->r3->r[bp->ACK_MINT]);				if (ack == (chip_id | GSVR_IT_MDM)){#ifdef AURORA_INTMSG					printk("MDM ACK\n");#endif					aurora_check_modem(bp,chip);				} else {#ifdef AURORA_INTNORM					printk("aurora%d-%d: Bad modem ack 0x%02x.\n",					       board_No(bp), chip, ack);#endif				}			}			sbus_writeb(0, &bp->r[chip]->r[CD180_EOSRR]);		}	}#endif}#ifdef AURORA_INT_DEBUGstatic void aurora_timer (unsigned long ignored);static struct timer_listaurora_poll_timer = { NULL, NULL, 0, 0, aurora_timer };static voidaurora_timer (unsigned long ignored){	unsigned long flags;	int i;	save_flags(flags); cli();	printk("SRSR: %02x,%02x - ",	       sbus_readb(&aurora_board[0].r[0]->r[CD180_SRSR]),	       sbus_readb(&aurora_board[0].r[1]->r[CD180_SRSR]));	for (i = 0; i < 4; i++) {		udelay(1);		printk("%02x ",		       sbus_readb(&aurora_board[0].r3->r[i]));	}	printk("\n");	aurora_poll_timer.expires = jiffies + 300;	add_timer (&aurora_poll_timer);	restore_flags(flags);}#endif/* *  Routines for open & close processing. *//* Called with disabled interrupts */static int aurora_setup_board(struct Aurora_board * bp){	int error;	#ifdef AURORA_ALLIRQ	int i;	for (i = 0; i < AURORA_ALLIRQ; i++) {		error = request_irq(allirq[i]|0x30, aurora_interrupt, SA_SHIRQ,				    "sio16", bp);		if (error)			printk(KERN_ERR "IRQ%d request error %d\n",			       allirq[i], error);	}#else	error = request_irq(bp->irq|0x30, aurora_interrupt, SA_SHIRQ,			    "sio16", bp);	if (error) {		printk(KERN_ERR "IRQ request error %d\n", error);		return error;	}#endif	/* Board reset */	sbus_writeb(0, &bp->r0->r);	udelay(1);	if (bp->flags & AURORA_BOARD_TYPE_2) {		/* unknown yet */	} else {		sbus_writeb((AURORA_CFG_ENABLE_IO | AURORA_CFG_ENABLE_IRQ |			     (((bp->irq)&0x0f)>>2)),			    &bp->r0->r);	}	udelay(10000);	if (aurora_init_CD180(bp,0))error=1;error=0;	if (aurora_init_CD180(bp,1))error++;	if (error == AURORA_NCD180) {		printk(KERN_ERR "Both chips failed initialisation.\n");		return -EIO;	}#ifdef AURORA_INT_DEBUG	aurora_poll_timer.expires= jiffies + 1;	add_timer(&aurora_poll_timer);#endif#ifdef AURORA_DEBUG	printk("aurora_setup_board: end\n");#endif	return 0;}/* Called with disabled interrupts */static void aurora_shutdown_board(struct Aurora_board *bp){	int i;#ifdef AURORA_DEBUG	printk("aurora_shutdown_board: start\n");#endif#ifdef AURORA_INT_DEBUG	del_timer(&aurora_poll_timer);#endif#ifdef AURORA_ALLIRQ	for(i=0;i<AURORA_ALLIRQ;i++){		free_irq(allirq[i]|0x30, bp);/*		IRQ_to_board[allirq[i]&0xf] = NULL;*/	}#else	free_irq(bp->irq|0x30, bp);

⌨️ 快捷键说明

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