Esempio n. 1
0
/*
 * The typical workload of the driver:
 * Handle the network interface interrupts.
 */
static void
de600_interrupt(int reg_ptr)
{
	int		irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
	struct device	*dev = irq2dev_map[irq];
	byte		irq_status;
	int		retrig = 0;
	int		boguscount = 0;

	/* This might just as well be deleted now, no crummy drivers present :-) */
	if ((dev == NULL) || (dev->start == 0) || (DE600_IRQ != irq)) {
		printk("%s: bogus interrupt %d\n", dev?dev->name:"DE-600", irq);
		return;
	}

	dev->interrupt = 1;
	select_nic();
	irq_status = de600_read_status(dev);

	do {
		PRINTK(("de600_interrupt (%02X)\n", irq_status));

		if (irq_status & RX_GOOD)
			de600_rx_intr(dev);
		else if (!(irq_status & RX_BUSY))
			de600_put_command(RX_ENABLE);

		/* Any transmission in progress? */
		if (free_tx_pages < TX_PAGES)
			retrig = de600_tx_intr(dev, irq_status);
		else
			retrig = 0;

		irq_status = de600_read_status(dev);
	} while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) );
	/*
	 * Yeah, it _looks_ like busy waiting, smells like busy waiting
	 * and I know it's not PC, but please, it will only occur once
	 * in a while and then only for a loop or so (< 1ms for sure!)
	 */

	/* Enable adapter interrupts */
	dev->interrupt = 0;
	select_prn();

	if (retrig)
		trigger_interrupt(dev);

	sti();
	return;
}
Esempio n. 2
0
static irqreturn_t de600_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
	struct net_device	*dev = dev_id;
	u8		irq_status;
	int		retrig = 0;
	int		boguscount = 0;

	/* This might just as well be deleted now, no crummy drivers present :-) */
	if ((dev == NULL) || (DE600_IRQ != irq)) {
		printk(KERN_ERR "%s: bogus interrupt %d\n", dev?dev->name:"DE-600", irq);
		return IRQ_NONE;
	}

	spin_lock(&de600_lock);
	
	select_nic();
	irq_status = de600_read_status(dev);

	do {
		PRINTK(("de600_interrupt (%02X)\n", irq_status));

		if (irq_status & RX_GOOD)
			de600_rx_intr(dev);
		else if (!(irq_status & RX_BUSY))
			de600_put_command(RX_ENABLE);

		/* Any transmission in progress? */
		if (free_tx_pages < TX_PAGES)
			retrig = de600_tx_intr(dev, irq_status);
		else
			retrig = 0;

		irq_status = de600_read_status(dev);
	} while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) );
	/*
	 * Yeah, it _looks_ like busy waiting, smells like busy waiting
	 * and I know it's not PC, but please, it will only occur once
	 * in a while and then only for a loop or so (< 1ms for sure!)
	 */

	/* Enable adapter interrupts */
	select_prn();
	if (retrig)
		trigger_interrupt(dev);
	spin_unlock(&de600_lock);
	return IRQ_HANDLED;
}
Esempio n. 3
0
static irqreturn_t de600_interrupt(int irq, void *dev_id)
{
	struct net_device	*dev = dev_id;
	u8		irq_status;
	int		retrig = 0;
	int		boguscount = 0;

	spin_lock(&de600_lock);

	select_nic();
	irq_status = de600_read_status(dev);

	do {
		PRINTK(("de600_interrupt (%02X)\n", irq_status));

		if (irq_status & RX_GOOD)
			de600_rx_intr(dev);
		else if (!(irq_status & RX_BUSY))
			de600_put_command(RX_ENABLE);

		/* Any transmission in progress? */
		if (free_tx_pages < TX_PAGES)
			retrig = de600_tx_intr(dev, irq_status);
		else
			retrig = 0;

		irq_status = de600_read_status(dev);
	} while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) );
	/*
	 * Yeah, it _looks_ like busy waiting, smells like busy waiting
	 * and I know it's not PC, but please, it will only occur once
	 * in a while and then only for a loop or so (< 1ms for sure!)
	 */

	/* Enable adapter interrupts */
	select_prn();
	if (retrig)
		trigger_interrupt(dev);
	spin_unlock(&de600_lock);
	return IRQ_HANDLED;
}
Esempio n. 4
0
static irqreturn_t de600_interrupt(int irq, void *dev_id)
{
	struct net_device	*dev = dev_id;
	u8		irq_status;
	int		retrig = 0;
	int		boguscount = 0;

	spin_lock(&de600_lock);

	select_nic();
	irq_status = de600_read_status(dev);

	do {
		pr_debug("de600_interrupt (%02X)\n", irq_status);

		if (irq_status & RX_GOOD)
			de600_rx_intr(dev);
		else if (!(irq_status & RX_BUSY))
			de600_put_command(RX_ENABLE);

		/*                               */
		if (free_tx_pages < TX_PAGES)
			retrig = de600_tx_intr(dev, irq_status);
		else
			retrig = 0;

		irq_status = de600_read_status(dev);
	} while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) );
	/*
                                                                
                                                               
                                                               
  */

	/*                           */
	select_prn();
	if (retrig)
		trigger_interrupt(dev);
	spin_unlock(&de600_lock);
	return IRQ_HANDLED;
}