📄 aurora.c
字号:
#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 + -