/* Called from init/main.c to reserve IO ports. */
void reserve_setup(char *str, int *ints)
{
	int i;

	for (i = 1; i < ints[0]; i += 2)
		snarf_region(ints[i], ints[i+1]);
}
Exemple #2
0
unsigned long lance_probe1(short ioaddr, unsigned long mem_start)
{
    struct device *dev;
    struct lance_private *lp;
    int hpJ2405A = 0;
    int i, reset_val;

    hpJ2405A = (inb(ioaddr) == 0x08 && inb(ioaddr+1) == 0x00
		&& inb(ioaddr+2) == 0x09);

    /* Reset the LANCE.  */
    reset_val = inw(ioaddr+LANCE_RESET); /* Reset the LANCE */

    /* The Un-Reset needed is only needed for the real NE2100, and will
       confuse the HP board. */
    if (!hpJ2405A)
	outw(reset_val, ioaddr+LANCE_RESET);

    outw(0x0000, ioaddr+LANCE_ADDR); /* Switch to window 0 */
    if (inw(ioaddr+LANCE_DATA) != 0x0004)
	return mem_start;

	/* 真正的注册网卡 */
    dev = init_etherdev(0, sizeof(struct lance_private)
			+ PKT_BUF_SZ*(RX_RING_SIZE + TX_RING_SIZE),
			&mem_start);

    printk("%s: LANCE at %#3x,", dev->name, ioaddr);

    /* There is a 16 byte station address PROM at the base address.
       The first six bytes are the station address. */
    for (i = 0; i < 6; i++)
	printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));

    dev->base_addr = ioaddr;
    snarf_region(ioaddr, LANCE_TOTAL_SIZE);

    /* Make certain the data structures used by the LANCE are aligned. */
    dev->priv = (void *)(((int)dev->priv + 7) & ~7);
    lp = (struct lance_private *)dev->priv;
    lp->rx_buffs = (long)dev->priv + sizeof(struct lance_private);
    lp->tx_bounce_buffs = (char (*)[PKT_BUF_SZ])
			   (lp->rx_buffs + PKT_BUF_SZ*RX_RING_SIZE);

#ifndef final_version
    /* This should never happen. */
    if ((int)(lp->rx_ring) & 0x07) {
	printk(" **ERROR** LANCE Rx and Tx rings not on even boundary.\n");
	return mem_start;
    }
#endif

    outw(88, ioaddr+LANCE_ADDR);
    lp->old_lance = (inw(ioaddr+LANCE_DATA) != 0x3003);

#if defined(notdef)
    printk(lp->old_lance ? " original LANCE (%04x)" : " PCnet-ISA LANCE (%04x)",
	   inw(ioaddr+LANCE_DATA));
#endif

    lp->init_block.mode = 0x0003;	/* Disable Rx and Tx. */
    for (i = 0; i < 6; i++)
	lp->init_block.phys_addr[i] = dev->dev_addr[i];
    lp->init_block.filter[0] = 0x00000000;
    lp->init_block.filter[1] = 0x00000000;
    lp->init_block.rx_ring = (int)lp->rx_ring | RX_RING_LEN_BITS;
    lp->init_block.tx_ring = (int)lp->tx_ring | TX_RING_LEN_BITS;

    outw(0x0001, ioaddr+LANCE_ADDR);
    outw((short) (int) &lp->init_block, ioaddr+LANCE_DATA);
    outw(0x0002, ioaddr+LANCE_ADDR);
    outw(((int)&lp->init_block) >> 16, ioaddr+LANCE_DATA);
    outw(0x0000, ioaddr+LANCE_ADDR);

    if (hpJ2405A) {
	char dma_tbl[4] = {3, 5, 6, 7};
	char irq_tbl[8] = {3, 4, 5, 9, 10, 11, 12, 15};
	short reset_val = inw(ioaddr+LANCE_RESET);
	dev->dma = dma_tbl[(reset_val >> 2) & 3];
	dev->irq = irq_tbl[(reset_val >> 4) & 7];
	printk(" HP J2405A IRQ %d DMA %d.\n", dev->irq, dev->dma);
    } else {
	/* The DMA channel may be passed in on this parameter. */
	if (dev->mem_start & 0x07)
int netcard_probe1(struct device *dev, short ioaddr)
{
	unsigned char station_addr[6];
	int i;

	/* Read the station address PROM.  */
	for (i = 0; i < 6; i++) {
		station_addr[i] = inb(ioaddr + i);
	}
	/* Check the first three octets of the S.A. for the manufactor's code. */ 
	if (station_addr[0] != SA_ADDR0
		||	 station_addr[1] != SA_ADDR1 || station_addr[2] != SA_ADDR2) {
		return ENODEV;
	}

	printk("%s: %s found at %#3x, IRQ %d.\n", dev->name,
		   "network card", dev->base_addr, dev->irq);

#ifdef jumpered_interrupts
	/* If this board has jumpered interrupts, snarf the interrupt vector
	   now.	 There is no point in waiting since no other device can use
	   the interrupt, and this marks the 'irqaction' as busy. */

	if (dev->irq == -1)
		;			/* Do nothing: a user-level program will set it. */
	else if (dev->irq < 2) {	/* "Auto-IRQ" */
		autoirq_setup(0);
		/* Trigger an interrupt here. */

		dev->irq = autoirq_report(0);
		if (net_debug >= 2)
			printk(" autoirq is %d", dev->irq);
  } else if (dev->irq == 2)
	  /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
	 or don't know which one to set. */
	  dev->irq = 9;

	{	 int irqval = request_irq(dev->irq, &net_interrupt);
		 if (irqval) {
			 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
					 dev->irq, irqval);
			 return EAGAIN;
		 }
	 }
#endif	/* jumpered interrupt */

	/* Grab the region so we can find another board if autoIRQ fails. */
	snarf_region(ioaddr, ETHERCARD_TOTAL_SIZE);

	if (net_debug)
		printk(version);

	/* Initialize the device structure. */
	dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
	memset(dev->priv, 0, sizeof(struct net_local));

	dev->open		= net_open;
	dev->stop		= net_close;
	dev->hard_start_xmit = net_send_packet;
	dev->get_stats	= net_get_stats;
#ifdef HAVE_MULTICAST
	dev->set_multicast_list = &set_multicast_list;
#endif

	/* Fill in the fields of the device structure with ethernet-generic values.
	   This should be in a common file instead of per-driver.  */
	for (i = 0; i < DEV_NUMBUFFS; i++)
		dev->buffs[i] = NULL;

	dev->hard_header	= eth_header;
	dev->add_arp		= eth_add_arp;
	dev->queue_xmit		= dev_queue_xmit;
	dev->rebuild_header	= eth_rebuild_header;
	dev->type_trans		= eth_type_trans;

	dev->type			= ARPHRD_ETHER;
	dev->hard_header_len = ETH_HLEN;
	dev->mtu			= 1500; /* eth_mtu */
	dev->addr_len		= ETH_ALEN;
	for (i = 0; i < ETH_ALEN; i++) {
		dev->broadcast[i]=0xff;
	}

	/* New-style flags. */
	dev->flags			= IFF_BROADCAST;
	dev->family			= AF_INET;
	dev->pa_addr		= 0;
	dev->pa_brdaddr		= 0;
	dev->pa_mask		= 0;
	dev->pa_alen		= sizeof(unsigned long);

	return 0;
}
Exemple #4
0
static int neprobe1(int ioaddr, struct device *dev, int verbose)
{
    int i;
    unsigned char SA_prom[32];
    int wordlength = 2;
    char *name;
    int start_page, stop_page;
    int neX000, ctron, dlink, dfi;
    int reg0 = inb(ioaddr);

    if ( reg0 == 0xFF)
	return 0;

    /* Do a quick preliminary check that we have a 8390. */
    {	int regd;
	outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
	regd = inb_p(ioaddr + 0x0d);
	outb_p(0xff, ioaddr + 0x0d);
	outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
	inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
	if (inb_p(ioaddr + EN0_COUNTER0) != 0) {
	    outb_p(reg0, ioaddr);
	    outb(regd, ioaddr + 0x0d);	/* Restore the old values. */
	    return 0;
	}
    }

    printk("NE*000 ethercard probe at %#3x:", ioaddr);

    /* Read the 16 bytes of station address prom, returning 1 for
       an eight-bit interface and 2 for a 16-bit interface.
       We must first initialize registers, similar to NS8390_init(eifdev, 0).
       We can't reliably read the SAPROM address without this.
       (I learned the hard way!). */
    {
	struct {unsigned char value, offset; } program_seq[] = {
	    {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
	    {0x48,	EN0_DCFG},	/* Set byte-wide (0x48) access. */
	    {0x00,	EN0_RCNTLO},	/* Clear the count regs. */
	    {0x00,	EN0_RCNTHI},
	    {0x00,	EN0_IMR},	/* Mask completion irq. */
	    {0xFF,	EN0_ISR},
	    {E8390_RXOFF, EN0_RXCR},	/* 0x20  Set to monitor */
	    {E8390_TXOFF, EN0_TXCR},	/* 0x02  and loopback mode. */
	    {32,	EN0_RCNTLO},
	    {0x00,	EN0_RCNTHI},
	    {0x00,	EN0_RSARLO},	/* DMA starting at 0x0000. */
	    {0x00,	EN0_RSARHI},
	    {E8390_RREAD+E8390_START, E8390_CMD},
	};
	for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
	    outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
    }
    for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {
	SA_prom[i] = inb(ioaddr + NE_DATAPORT);
	SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
	if (SA_prom[i] != SA_prom[i+1])
	    wordlength = 1;
    }

    if (wordlength == 2) {
	/* We must set the 8390 for word mode. */
	outb_p(0x49, ioaddr + EN0_DCFG);
	/* We used to reset the ethercard here, but it doesn't seem
	   to be necessary. */
	/* Un-double the SA_prom values. */
	for (i = 0; i < 16; i++)
	    SA_prom[i] = SA_prom[i+i];
    }

#if defined(show_all_SAPROM)
    /* If your ethercard isn't detected define this to see the SA_PROM. */
    for(i = 0; i < sizeof(SA_prom); i++)
	printk(" %2.2x", SA_prom[i]);
#else
    for(i = 0; i < ETHER_ADDR_LEN; i++) {
	dev->dev_addr[i] = SA_prom[i];
	printk(" %2.2x", SA_prom[i]);
    }
#endif

    neX000 = (SA_prom[14] == 0x57  &&  SA_prom[15] == 0x57);
    ctron =  (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);
    dlink =  (SA_prom[0] == 0x00 && SA_prom[1] == 0xDE && SA_prom[2] == 0x01);
    dfi   =  (SA_prom[0] == 'D' && SA_prom[1] == 'F' && SA_prom[2] == 'I');

    /* Set up the rest of the parameters. */
    if (neX000 || dlink || dfi) {
	if (wordlength == 2) {
	    name = dlink ? "DE200" : "NE2000";
	    start_page = NESM_START_PG;
	    stop_page = NESM_STOP_PG;
	} else {
	    name = dlink ? "DE100" : "NE1000";
	    start_page = NE1SM_START_PG;
	    stop_page = NE1SM_STOP_PG;
	}
    } else if (ctron) {
	name = "Cabletron";
	start_page = 0x01;
	stop_page = (wordlength == 2) ? 0x40 : 0x20;
    } else {
	printk(" not found.\n");
	return 0;
    }

    if (dev->irq < 2) {
	autoirq_setup(0);
	outb_p(0x50, ioaddr + EN0_IMR);	/* Enable one interrupt. */
	outb_p(0x00, ioaddr + EN0_RCNTLO);
	outb_p(0x00, ioaddr + EN0_RCNTHI);
	outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */
	outb_p(0x00, ioaddr + EN0_IMR); 		/* Mask it again. */
	dev->irq = autoirq_report(0);
	if (ei_debug > 2)
	    printk(" autoirq is %d", dev->irq);
    } else if (dev->irq == 2)
	/* Fixup for users that don't know that IRQ 2 is really IRQ 9,
	   or don't know which one to set. */
	dev->irq = 9;
    
    /* Snarf the interrupt now.  There's no point in waiting since we cannot
       share and the board will usually be enabled. */
    {
	int irqval = irqaction (dev->irq, &ei_sigaction);
	if (irqval) {
	    printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval);
	    return 0;
	}
    }

    dev->base_addr = ioaddr;

#ifdef HAVE_PORTRESERVE
    snarf_region(ioaddr, 32);
#endif

    ethdev_init(dev);
    printk("\n%s: %s found at %#x, using IRQ %d.\n",
	   dev->name, name, ioaddr, dev->irq);

    if (ei_debug > 0)
	printk(version);

    ei_status.name = name;
    ei_status.tx_start_page = start_page;
    ei_status.stop_page = stop_page;
    ei_status.word16 = (wordlength == 2);

    ei_status.rx_start_page = start_page + TX_PAGES;
#ifdef PACKETBUF_MEMSIZE
    /* Allow the packet buffer size to be overridden by know-it-alls. */
    ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
#endif

    ei_status.reset_8390 = &ne_reset_8390;
    ei_status.block_input = &ne_block_input;
    ei_status.block_output = &ne_block_output;
    NS8390_init(dev, 0);
    return dev->base_addr;
}
Exemple #5
0
int
el1_probe(struct device *dev)
{
    int i;
    int ioaddr;
    unsigned char station_addr[6];
    int autoirq = 0;

    eldev = dev;		/* Store for debugging. */
    el_base = dev->base_addr;

    if (el_base < 0x40)		/* Invalid?  Probe for it. */
	el_base = 0x280;

    ioaddr = el_base;

    /* Read the station address PROM data from the special port.  */
    for (i = 0; i < 6; i++) {
	outw(i, ioaddr + EL1_DATAPTR);
	station_addr[i] = inb(ioaddr + EL1_SAPROM);
    }
    /* Check the first three octets of the S.A. for 3Com's code. */ 
    if (station_addr[0] != 0x02  ||  station_addr[1] != 0x60
	|| station_addr[2] != 0x8c) {
	return ENODEV;
    }

#ifdef HAVE_PORTRESERVE
    /* Grab the region so we can find the another board if autoIRQ fails. */
    snarf_region(ioaddr, 16);
#endif

    /* We auto-IRQ by shutting off the interrupt line and letting it float
       high. */
    if (dev->irq < 2) {

	autoirq_setup(2);

	inb(RX_STATUS);		/* Clear pending interrupts. */
	inb(TX_STATUS);
	outb(AX_LOOP + 1, AX_CMD);

	outb(0x00, AX_CMD);

	autoirq = autoirq_report(1);

	if (autoirq == 0) {
	    printk("%s: 3c501 probe failed to detect IRQ line.\n", dev->name);
	    return EAGAIN;
	}
	dev->irq = autoirq;
    }

    outb(AX_RESET+AX_LOOP, AX_CMD);			/* Loopback mode. */

    dev->base_addr = el_base;
    memcpy(dev->dev_addr, station_addr, ETH_ALEN);
    if (dev->mem_start & 0xf)
	el_debug = dev->mem_start & 0x7;

    printk("%s: 3c501 EtherLink at %#x, using %sIRQ %d, melting ethernet.\n",
	   dev->name, dev->base_addr, autoirq ? "auto":"assigned ", dev->irq);

    if (el_debug)
	printk("%s", version);

    /* The EL1-specific entries in the device structure. */
    dev->open = &el_open;
    dev->hard_start_xmit = &el_start_xmit;
    dev->stop = &el1_close;
    dev->get_stats = &el1_get_stats;
#ifdef HAVE_MULTICAST
    dev->set_multicast_list = &set_multicast_list;
#endif

    /* Fill in the generic field of the device structure. */
    for (i = 0; i < DEV_NUMBUFFS; i++)
	dev->buffs[i] = NULL;

    dev->hard_header	= eth_header;
    dev->add_arp	= eth_add_arp;
    dev->queue_xmit	= dev_queue_xmit;
    dev->rebuild_header	= eth_rebuild_header;
    dev->type_trans	= eth_type_trans;

    dev->type		= ARPHRD_ETHER;
    dev->hard_header_len = ETH_HLEN;
    dev->mtu		= 1500; /* eth_mtu */
    dev->addr_len	= ETH_ALEN;
    for (i = 0; i < ETH_ALEN; i++) {
	dev->broadcast[i]=0xff;
    }

    /* New-style flags. */
    dev->flags		= IFF_BROADCAST;
    dev->family		= AF_INET;
    dev->pa_addr	= 0;
    dev->pa_brdaddr	= 0;
    dev->pa_mask	= 0;
    dev->pa_alen	= sizeof(unsigned long);

    return 0;
}
int eexp_probe1(struct device *dev, short ioaddr)
{
	unsigned short station_addr[3];
	int i;

	printk("%s: EtherExpress at %#x,", dev->name, ioaddr);

	/* The station address is stored !backwards! in the EEPROM, reverse
	   after reading.  (Hmmm, a little brain-damage there at Intel, eh?) */
	station_addr[0] = read_eeprom(ioaddr, 2);
	station_addr[1] = read_eeprom(ioaddr, 3);
	station_addr[2] = read_eeprom(ioaddr, 4);

	/* Check the first three octets of the S.A. for the manufacturer's code. */
	if (station_addr[2] != 0x00aa || (station_addr[1] & 0xff00) != 0x0000) {
		printk(" rejected (invalid address %04x%04x%04x).\n",
			   station_addr[2], station_addr[1], station_addr[0]);
		return ENODEV;
	}

	/* We've committed to using the board, and can start filling in *dev. */
	snarf_region(ioaddr, 16);
	dev->base_addr = ioaddr;

	for (i = 0; i < 6; i++) {
		dev->dev_addr[i] = ((unsigned char*)station_addr)[5-i];
		printk(" %02x", dev->dev_addr[i]);
	}

	/* There is no reason for the driver to care, but I print out the
	   interface to minimize bogus bug reports. */
	{
		char irqmap[] = {0, 9, 3, 4, 5, 10, 11, 0};
		char *ifmap[] = {"AUI", "BNC", "10baseT"};
		enum iftype {AUI=0, BNC=1, TP=2};
		unsigned short setupval = read_eeprom(ioaddr, 0);

		dev->irq = irqmap[setupval >> 13];
		dev->if_port = (setupval & 0x1000) == 0 ? AUI :
			read_eeprom(ioaddr, 5) & 0x1 ? TP : BNC;
		printk(", IRQ %d, Interface %s.\n", dev->irq, ifmap[dev->if_port]);
		/* Release the IRQ line so that it can be shared if we don't use the
		   ethercard. */
		outb(0x00, ioaddr + SET_IRQ);
	}

	/* It's now OK to leave the board in reset, pending the open(). */
	outb(ASIC_RESET, ioaddr + EEPROM_Ctrl);

	if ((dev->mem_start & 0xf) > 0)
		net_debug = dev->mem_start & 7;

	if (net_debug)
		printk(version);

	/* Initialize the device structure. */
	dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
	memset(dev->priv, 0, sizeof(struct net_local));

	dev->open		= eexp_open;
	dev->stop		= eexp_close;
	dev->hard_start_xmit = eexp_send_packet;
	dev->get_stats	= eexp_get_stats;
	dev->set_multicast_list = &set_multicast_list;

	/* Fill in the fields of the device structure with ethernet-generic values. */
	
	ether_setup(dev);
	
	return 0;
}
Exemple #7
0
static int ni52_probe1(struct device *dev,int ioaddr)
{
  long memaddrs[] = { 0xd0000,0xd2000,0xd4000,0xd6000,0xd8000, 0 };
  int i,size;

  for(i=0;i<ETH_ALEN;i++)
    dev->dev_addr[i] = inb(dev->base_addr+i);

  if(dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1
                                    || dev->dev_addr[2] != NI52_ADDR2)
    return ENODEV;

  printk("%s: Ni52 found at %#3x, ",dev->name,dev->base_addr);

  snarf_region(ioaddr,NI52_TOTAL_SIZE);

  dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL); 
                                  /* warning: we don't free it on errors */
  memset((char *) dev->priv,0,sizeof(struct priv));

  /* 
   * check (or search) IO-Memory, 8K and 16K
   */
  if(dev->mem_start != 0) /* no auto-mem-probe */
  {
    size = 0x4000;
    if(!check586(dev,(char *) dev->mem_start,size)) {
      size = 0x2000;
      if(!check586(dev,(char *) dev->mem_start,size)) {
        printk("?memprobe, Can't find memory at 0x%lx!\n",dev->mem_start);
        return ENODEV;
      }
    }
  }
  else  
  {
    for(i=0;;i++)
    {
      if(!memaddrs[i]) {
        printk("?memprobe, Can't find io-memory!\n");
        return ENODEV;
      }
      dev->mem_start = memaddrs[i];
      size = 0x2000;
      if(check586(dev,(char *)dev->mem_start,size)) /* 8K-check */
        break;
      size = 0x4000;
      if(check586(dev,(char *)dev->mem_start,size)) /* 16K-check */
        break;
    }
  }

  ((struct priv *) (dev->priv))->base =  dev->mem_start + size - 0x01000000;
  alloc586(dev);

  printk("Memaddr: 0x%lx, Memsize: %d, ",dev->mem_start,size);

  if(dev->irq < 2)
  {
    autoirq_setup(0);
    ni_reset586();
    ni_attn586();
    if(!(dev->irq = autoirq_report(2)))
    {
      printk("?autoirq, Failed to detect IRQ line!\n"); 
      return 1;
    }
  }
  else if(dev->irq == 2) 
    dev->irq = 9;

  printk("IRQ %d.\n",dev->irq);

  dev->open            = &ni52_open;
  dev->stop            = &ni52_close;
  dev->get_stats       = &ni52_get_stats;
  dev->hard_start_xmit = &ni52_send_packet;
  dev->set_multicast_list = &set_multicast_list;

  dev->if_port 	       = 0;

  ether_setup(dev);

  dev->tbusy = 0;
  dev->interrupt = 0;
  dev->start = 0;
  
  return 0;
}
Exemple #8
0
int hpprobe1(struct device *dev, int ioaddr)
{
    int i, board_id, wordmode;
    char *name;
    unsigned char *station_addr = dev->dev_addr;

    /* Check for the HP physical address, 08 00 09 xx xx xx. */
    /* This really isn't good enough: we may pick up HP LANCE boards
       also!  Avoid the lance 0x5757 signature. */
    if (inb(ioaddr) != 0x08
            || inb(ioaddr+1) != 0x00
            || inb(ioaddr+2) != 0x09
            || inb(ioaddr+14) == 0x57)
        return ENODEV;

    /* Set up the parameters based on the board ID.
       If you have additional mappings, please mail them to [email protected]. */
    if ((board_id = inb(ioaddr + HP_ID)) & 0x80) {
        name = "HP27247";
        wordmode = 1;
    } else {
        name = "HP27250";
        wordmode = 0;
    }

    /* Grab the region so we can find another board if something fails. */
    snarf_region(ioaddr, HP_IO_EXTENT);

    printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr);

    for(i = 0; i < ETHER_ADDR_LEN; i++)
        printk(" %2.2x", station_addr[i] = inb(ioaddr + i));

    /* Snarf the interrupt now.  Someday this could be moved to open(). */
    if (dev->irq < 2) {
        int irq_16list[] = { 11, 10, 5, 3, 4, 7, 9, 0};
        int irq_8list[] = { 7, 5, 3, 4, 9, 0};
        int *irqp = wordmode ? irq_16list : irq_8list;
        do {
            int irq = *irqp;
            if (request_irq (irq, NULL) != -EBUSY) {
                autoirq_setup(0);
                /* Twinkle the interrupt, and check if it's seen. */
                outb_p(irqmap[irq] | HP_RUN, ioaddr + HP_CONFIGURE);
                outb_p( 0x00 | HP_RUN, ioaddr + HP_CONFIGURE);
                if (irq == autoirq_report(0)		 /* It's a good IRQ line! */
                        && request_irq (irq, &ei_interrupt) == 0) {
                    printk(" selecting IRQ %d.\n", irq);
                    dev->irq = *irqp;
                    break;
                }
            }
        } while (*++irqp);
        if (*irqp == 0) {
            printk(" no free IRQ lines.\n");
            return EBUSY;
        }
    } else {
        if (dev->irq == 2)
            dev->irq = 9;
        if (irqaction(dev->irq, &ei_sigaction)) {
            printk (" unable to get IRQ %d.\n", dev->irq);
            return EBUSY;
        }
    }

    if (ei_debug > 1)
        printk(version);

    /* Set the base address to point to the NIC, not the "real" base! */
    dev->base_addr = ioaddr + NIC_OFFSET;

    ethdev_init(dev);

    ei_status.name = name;
    ei_status.word16 = wordmode;
    ei_status.tx_start_page = HP_START_PG;
    ei_status.rx_start_page = HP_START_PG + TX_PAGES;
    ei_status.stop_page = wordmode ? HP_16BSTOP_PG : HP_8BSTOP_PG;

    ei_status.reset_8390 = &hp_reset_8390;
    ei_status.block_input = &hp_block_input;
    ei_status.block_output = &hp_block_output;
    hp_init_card(dev);

    return 0;
}