예제 #1
0
파일: sb1000.c 프로젝트: wxlong/Test
/* SB1000 interrupt handler. */
static irqreturn_t sb1000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	char *name;
	unsigned char st;
	int ioaddr[2];
	struct net_device *dev = (struct net_device *) dev_id;
	struct sb1000_private *lp = netdev_priv(dev);

	const unsigned char Command0[6] = {0x80, 0x2c, 0x00, 0x00, 0x00, 0x00};
	const unsigned char Command1[6] = {0x80, 0x2e, 0x00, 0x00, 0x00, 0x00};
	const int MaxRxErrorCount = 6;

	if (dev == NULL) {
		printk(KERN_ERR "sb1000_interrupt(): irq %d for unknown device.\n",
			irq);
		return IRQ_NONE;
	}

	ioaddr[0] = dev->base_addr;
	/* mem_start holds the second I/O address */
	ioaddr[1] = dev->mem_start;
	name = dev->name;

	/* is it a good interrupt? */
	st = inb(ioaddr[1] + 6);
	if (!(st & 0x08 && st & 0x20)) {
		return IRQ_NONE;
	}

	if (sb1000_debug > 3)
		printk(KERN_DEBUG "%s: entering interrupt\n", dev->name);

	st = inb(ioaddr[0] + 7);
	if (sb1000_rx(dev))
		lp->rx_error_count++;
#ifdef SB1000_DELAY
	udelay(SB1000_DELAY);
#endif /* SB1000_DELAY */
	sb1000_issue_read_command(ioaddr, name);
	if (st & 0x01) {
		sb1000_error_dpc(dev);
		sb1000_issue_read_command(ioaddr, name);
	}
	if (lp->rx_error_dpc_count && !(--lp->rx_error_dpc_count)) {
		sb1000_wait_for_ready_clear(ioaddr, name);
		sb1000_send_command(ioaddr, name, Command0);
		sb1000_wait_for_ready(ioaddr, name);
		sb1000_issue_read_command(ioaddr, name);
	}
	if (lp->rx_error_count >= MaxRxErrorCount) {
		sb1000_wait_for_ready_clear(ioaddr, name);
		sb1000_send_command(ioaddr, name, Command1);
		sb1000_wait_for_ready(ioaddr, name);
		sb1000_issue_read_command(ioaddr, name);
		lp->rx_error_count = 0;
	}

	return IRQ_HANDLED;
}
예제 #2
0
static irqreturn_t sb1000_interrupt(int irq, void *dev_id)
{
	static const unsigned char Command0[6] = {0x80, 0x2c, 0x00, 0x00, 0x00, 0x00};
	static const unsigned char Command1[6] = {0x80, 0x2e, 0x00, 0x00, 0x00, 0x00};

	char *name;
	unsigned char st;
	int ioaddr[2];
	struct net_device *dev = dev_id;
	struct sb1000_private *lp = netdev_priv(dev);

	const int MaxRxErrorCount = 6;

	ioaddr[0] = dev->base_addr;
	
	ioaddr[1] = dev->mem_start;
	name = dev->name;

	
	st = inb(ioaddr[1] + 6);
	if (!(st & 0x08 && st & 0x20)) {
		return IRQ_NONE;
	}

	if (sb1000_debug > 3)
		printk(KERN_DEBUG "%s: entering interrupt\n", dev->name);

	st = inb(ioaddr[0] + 7);
	if (sb1000_rx(dev))
		lp->rx_error_count++;
#ifdef SB1000_DELAY
	udelay(SB1000_DELAY);
#endif 
	sb1000_issue_read_command(ioaddr, name);
	if (st & 0x01) {
		sb1000_error_dpc(dev);
		sb1000_issue_read_command(ioaddr, name);
	}
	if (lp->rx_error_dpc_count && !(--lp->rx_error_dpc_count)) {
		sb1000_wait_for_ready_clear(ioaddr, name);
		sb1000_send_command(ioaddr, name, Command0);
		sb1000_wait_for_ready(ioaddr, name);
		sb1000_issue_read_command(ioaddr, name);
	}
	if (lp->rx_error_count >= MaxRxErrorCount) {
		sb1000_wait_for_ready_clear(ioaddr, name);
		sb1000_send_command(ioaddr, name, Command1);
		sb1000_wait_for_ready(ioaddr, name);
		sb1000_issue_read_command(ioaddr, name);
		lp->rx_error_count = 0;
	}

	return IRQ_HANDLED;
}