예제 #1
0
/* 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;
}
예제 #2
0
/* 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;
}