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

📄 aurora.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
			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			schedule_task(&port->tqueue_hangup);	}	/* 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 irqreturn_t 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 IRQ_NONE;/*	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 IRQ_NONE; * 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	return IRQ_HANDLED;}#ifdef AURORA_INT_DEBUGstatic void aurora_timer (unsigned long ignored);static DEFINE_TIMER(aurora_poll_timer, aurora_timer, 0, 0);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);/*	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 = tty_get_baud_rate(tty);		/* Select port on the board */	sbus_writeb(port_No(port) & 7,		    &bp->r[chip]->r[CD180_CAR]);	udelay(1);		if (!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 dependent things. */		/* Set baud rate for port. */	tmp = (((bp->oscfreq + baud/2) / baud +		CD180_TPC/2) / CD180_TPC);/*	tmp = (bp->oscfreq/7)/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 + 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_zeroed_page() */		unsigned long tmp;

⌨️ 快捷键说明

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