int __init elplus_probe(struct net_device *dev) { elp_device *adapter; int i, tries, tries1, timeout, okay; unsigned long cookie = 0; SET_MODULE_OWNER(dev); /* * setup adapter structure */ dev->base_addr = elp_autodetect(dev); if (!(dev->base_addr)) return -ENODEV; /* * setup ptr to adapter specific information */ adapter = (elp_device *) (dev->priv = kmalloc(sizeof(elp_device), GFP_KERNEL)); if (adapter == NULL) { printk("%s: out of memory\n", dev->name); return -ENODEV; } adapter->send_pcb_semaphore = 0; for (tries1 = 0; tries1 < 3; tries1++) { outb_control((adapter->hcr_val | CMDE) & ~DIR, dev); /* First try to write just one byte, to see if the card is * responding at all normally. */ timeout = jiffies + 5*HZ/100; okay = 0; while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE)); if ((inb_status(dev->base_addr) & HCRE)) { outb_command(0, dev->base_addr); /* send a spurious byte */ timeout = jiffies + 5*HZ/100; while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE)); if (inb_status(dev->base_addr) & HCRE) okay = 1; } if (!okay) { /* Nope, it's ignoring the command register. This means that * either it's still booting up, or it's died. */ printk("%s: command register wouldn't drain, ", dev->name); if ((inb_status(dev->base_addr) & 7) == 3) { /* If the adapter status is 3, it *could* still be booting. * Give it the benefit of the doubt for 10 seconds. */ printk("assuming 3c505 still starting\n"); timeout = jiffies + 10*HZ; while (time_before(jiffies, timeout) && (inb_status(dev->base_addr) & 7)); if (inb_status(dev->base_addr) & 7) { printk("%s: 3c505 failed to start\n", dev->name); } else { okay = 1; /* It started */ } } else { /* Otherwise, it must just be in a strange * state. We probably need to kick it. */ printk("3c505 is sulking\n"); } } for (tries = 0; tries < 5 && okay; tries++) { /* * Try to set the Ethernet address, to make sure that the board * is working. */ adapter->tx_pcb.command = CMD_STATION_ADDRESS; adapter->tx_pcb.length = 0; cookie = probe_irq_on(); if (!send_pcb(dev, &adapter->tx_pcb)) { printk("%s: could not send first PCB\n", dev->name); probe_irq_off(cookie); continue; } if (!receive_pcb(dev, &adapter->rx_pcb)) { printk("%s: could not read first PCB\n", dev->name); probe_irq_off(cookie); continue; } if ((adapter->rx_pcb.command != CMD_ADDRESS_RESPONSE) || (adapter->rx_pcb.length != 6)) { printk("%s: first PCB wrong (%d, %d)\n", dev->name, adapter->rx_pcb.command, adapter->rx_pcb.length); probe_irq_off(cookie); continue; } goto okay; } /* It's broken. Do a hard reset to re-initialise the board, * and try again. */ printk(KERN_INFO "%s: resetting adapter\n", dev->name); outb_control(adapter->hcr_val | FLSH | ATTN, dev); outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev); } printk("%s: failed to initialise 3c505\n", dev->name); release_region(dev->base_addr, ELP_IO_EXTENT); return -ENODEV; okay: if (dev->irq) { /* Is there a preset IRQ? */ int rpt = probe_irq_off(cookie); if (dev->irq != rpt) { printk("%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt); } /* if dev->irq == probe_irq_off(cookie), all is well */ } else /* No preset IRQ; just use what we can detect */ dev->irq = probe_irq_off(cookie); switch (dev->irq) { /* Legal, sane? */ case 0: printk("%s: IRQ probe failed: check 3c505 jumpers.\n", dev->name); return -ENODEV; case 1: case 6: case 8: case 13: printk("%s: Impossible IRQ %d reported by probe_irq_off().\n", dev->name, dev->irq); return -ENODEV; } /* * Now we have the IRQ number so we can disable the interrupts from * the board until the board is opened. */ outb_control(adapter->hcr_val & ~CMDE, dev); /* * copy Ethernet address into structure */ for (i = 0; i < 6; i++) dev->dev_addr[i] = adapter->rx_pcb.data.eth_addr[i]; /* find a DMA channel */ if (!dev->dma) { if (dev->mem_start) { dev->dma = dev->mem_start & 7; } else { printk(KERN_WARNING "%s: warning, DMA channel not specified, using default\n", dev->name); dev->dma = ELP_DMA; } } /* * print remainder of startup message */ printk("%s: 3c505 at %#lx, irq %d, dma %d, ", dev->name, dev->base_addr, dev->irq, dev->dma); printk("addr %02x:%02x:%02x:%02x:%02x:%02x, ", dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); /* * read more information from the adapter */ adapter->tx_pcb.command = CMD_ADAPTER_INFO; adapter->tx_pcb.length = 0; if (!send_pcb(dev, &adapter->tx_pcb) || !receive_pcb(dev, &adapter->rx_pcb) || (adapter->rx_pcb.command != CMD_ADAPTER_INFO_RESPONSE) || (adapter->rx_pcb.length != 10)) { printk("not responding to second PCB\n"); } printk("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers, adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz); /* * reconfigure the adapter memory to better suit our purposes */ adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY; adapter->tx_pcb.length = 12; adapter->tx_pcb.data.memconf.cmd_q = 8; adapter->tx_pcb.data.memconf.rcv_q = 8; adapter->tx_pcb.data.memconf.mcast = 10; adapter->tx_pcb.data.memconf.frame = 10; adapter->tx_pcb.data.memconf.rcv_b = 10; adapter->tx_pcb.data.memconf.progs = 0; if (!send_pcb(dev, &adapter->tx_pcb) || !receive_pcb(dev, &adapter->rx_pcb) || (adapter->rx_pcb.command != CMD_CONFIGURE_ADAPTER_RESPONSE) || (adapter->rx_pcb.length != 2)) { printk("%s: could not configure adapter memory\n", dev->name); } if (adapter->rx_pcb.data.configure) { printk("%s: adapter configuration failed\n", dev->name); } /* * initialise the device */ elp_init(dev); return 0; }
int elplus_probe(struct device *dev) { elp_device adapter; int i; CHECK_NULL(dev); /* * setup adapter structure */ adapter.io_addr = dev->base_addr = elp_autodetect(dev); if ( !adapter.io_addr ) return -ENODEV; /* * As we enter here from bootup, the adapter should have IRQs enabled, * but we can as well enable them anyway. */ OUTB(INB(dev->base_addr+PORT_CONTROL) | CONTROL_CMDE, dev->base_addr+PORT_CONTROL); autoirq_setup(0); /* * use ethernet address command to probe for board in polled mode * (this also makes us the IRQ that we need for automatic detection) */ adapter.tx_pcb.command = CMD_STATION_ADDRESS; adapter.tx_pcb.length = 0; if (!send_pcb (&adapter, &adapter.tx_pcb) || !receive_pcb(&adapter, &adapter.rx_pcb) || (adapter.rx_pcb.command != CMD_ADDRESS_RESPONSE) || (adapter.rx_pcb.length != 6)) { printk("%s: not responding to first PCB\n", dev->name); return -ENODEV; } if (dev->irq) { /* Is there a preset IRQ? */ if (dev->irq != autoirq_report(0)) { printk("%s: Detected IRQ doesn't match user-defined one.\n",dev->name); return -ENODEV; } /* if dev->irq == autoirq_report(0), all is well */ } else /* No preset IRQ; just use what we can detect */ dev->irq=autoirq_report(0); switch (dev->irq) { /* Legal, sane? */ case 0: printk("%s: No IRQ reported by autoirq_report().\n",dev->name); printk("%s: Check the jumpers of your 3c505 board.\n",dev->name); return -ENODEV; case 1: case 6: case 8: case 13: printk("%s: Impossible IRQ %d reported by autoirq_report().\n", dev->name, dev->irq); return -ENODEV; } /* * Now we have the IRQ number so we can disable the interrupts from * the board until the board is opened. */ OUTB(INB(dev->base_addr+PORT_CONTROL) & ~CONTROL_CMDE, dev->base_addr+PORT_CONTROL); /* * copy ethernet address into structure */ for (i = 0; i < 6; i++) dev->dev_addr[i] = adapter.rx_pcb.data.eth_addr[i]; /* * print remainder of startup message */ #if (ELP_KERNEL_TYPE < 2) printk("%s: 3c505 card found at I/O 0x%x using IRQ%d has address %s\n", dev->name, dev->base_addr, dev->irq, eth_print(dev->dev_addr)); #else printk("%s: 3c505 card found at I/O 0x%x using IRQ%d has address %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, dev->base_addr, dev->irq, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); #endif /* * initialise the device */ elp_init(dev); return 0; }