/* The interrupt handler. */ void oeth_interrupt(void) { volatile oeth_regs *regs; regs = (oeth_regs *)(OETH_REG_BASE); uint int_events; int serviced; serviced = 0; /* Get the interrupt events that caused us to be here. */ int_events = regs->int_src; regs->int_src = int_events; /* Handle receive event in its own function. */ if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) { serviced |= 0x1; oeth_rx(); } /* Handle transmit event in its own function. */ if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) { serviced |= 0x2; oeth_tx(); serviced |= 0x2; } /* Check for receive busy, i.e. packets coming but no place to * put them. */ if (int_events & OETH_INT_BUSY) { serviced |= 0x4; if (!(int_events & (OETH_INT_RXF | OETH_INT_RXE))) oeth_rx(); } return; }
/* The interrupt handler. */ static irqreturn_t oeth_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; volatile struct oeth_private *cep; uint int_events; int serviced; serviced = 0; #ifdef DEBUG printk("."); printk("\n=tx_ | %x | %x | %x | %x | %x | %x | %x | %x\n", ((oeth_bd *)(OETH_BD_BASE))->len_status, ((oeth_bd *)(OETH_BD_BASE+8))->len_status, ((oeth_bd *)(OETH_BD_BASE+16))->len_status, ((oeth_bd *)(OETH_BD_BASE+24))->len_status, ((oeth_bd *)(OETH_BD_BASE+32))->len_status, ((oeth_bd *)(OETH_BD_BASE+40))->len_status, ((oeth_bd *)(OETH_BD_BASE+48))->len_status, ((oeth_bd *)(OETH_BD_BASE+56))->len_status); printk("=rx_ | %x | %x | %x | %x | %x | %x | %x | %x\n", ((oeth_bd *)(OETH_BD_BASE+64))->len_status, ((oeth_bd *)(OETH_BD_BASE+64+8))->len_status, ((oeth_bd *)(OETH_BD_BASE+64+16))->len_status, ((oeth_bd *)(OETH_BD_BASE+64+24))->len_status, ((oeth_bd *)(OETH_BD_BASE+64+32))->len_status, ((oeth_bd *)(OETH_BD_BASE+64+40))->len_status, ((oeth_bd *)(OETH_BD_BASE+64+48))->len_status, ((oeth_bd *)(OETH_BD_BASE+64+56))->len_status); #endif cep = (struct oeth_private *)dev->priv; /* Get the interrupt events that caused us to be here. */ int_events = cep->regs->int_src; cep->regs->int_src = int_events; /* Handle receive event in its own function. */ if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) { D(serviced |= 0x1); oeth_rx(dev_id); } /* Handle transmit event in its own function. */ if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) { D(serviced |= 0x2); oeth_tx(dev_id); if (netif_queue_stopped(dev)) { D(printk("n")); netif_wake_queue(dev); } } /* Check for receive busy, i.e. packets coming but no place to * put them. */ if (int_events & OETH_INT_BUSY) { D(serviced |= 0x4); D(printk("b")); if (!(int_events & (OETH_INT_RXF | OETH_INT_RXE))) oeth_rx(dev_id); } #if 0 if (serviced == 0) { void die(const char * str, struct pt_regs * regs, long err); int show_stack(unsigned long *esp); printk("!"); // printk("unserviced irq\n"); // show_stack(NULL); // die("unserviced irq\n", regs, 801); } #endif #ifdef DEBUG if (serviced == 0) printk("\nnot serviced: events 0x%x, irq %d, dev %p\n", int_events, irq, dev_id); else printk(" | serviced 0x%x, events 0x%x, irq %d, dev %p\n", serviced, int_events, irq, dev_id); #endif return IRQ_HANDLED; }