Commit 4eb1b94b authored by Stephen Hemminger's avatar Stephen Hemminger

[PATCH] (1/42) ewrk3

Convert ewrk3 to dynamic allocation
	* get rid of private device allocation method
	* fix deeply nested function
parent 5d40d90f
......@@ -56,7 +56,7 @@ extern int at1700_probe(struct net_device *);
extern int fmv18x_probe(struct net_device *);
extern int eth16i_probe(struct net_device *);
extern struct net_device *i82596_probe(int unit);
extern int ewrk3_probe(struct net_device *);
extern struct net_device *ewrk3_probe(int unit);
extern struct net_device *el1_probe(int unit);
extern struct net_device *wavelan_probe(int unit);
extern struct net_device *arlan_probe(int unit);
......@@ -255,14 +255,14 @@ static struct devprobe isa_probes[] __initdata = {
#endif
#ifdef CONFIG_EEXPRESS_PRO /* Intel EtherExpress Pro/10 */
{eepro_probe, 0},
#endif
#ifdef CONFIG_EWRK3 /* DEC EtherWORKS 3 */
{ewrk3_probe, 0},
#endif
{NULL, 0},
};
static struct devprobe2 isa_probes2[] __initdata = {
#ifdef CONFIG_EWRK3 /* DEC EtherWORKS 3 */
{ewrk3_probe, 0},
#endif
#if defined(CONFIG_APRICOT) || defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET) /* Intel I82596 */
{i82596_probe, 0},
#endif
......
......@@ -324,25 +324,14 @@ static int Read_EEPROM(u_long iobase, u_char eaddr);
static int Write_EEPROM(short data, u_long iobase, u_char eaddr);
static u_char get_hw_addr(struct net_device *dev, u_char * eeprom_image, char chipType);
static void isa_probe(struct net_device *dev, u_long iobase);
static void eisa_probe(struct net_device *dev, u_long iobase);
static struct net_device *alloc_device(struct net_device *dev, u_long iobase);
static int ewrk3_dev_index(char *s);
static struct net_device *insert_device(struct net_device *dev, u_long iobase, int (*init) (struct net_device *));
static int ewrk3_probe1(struct net_device *dev, u_long iobase, int irq);
static int isa_probe(struct net_device *dev, u_long iobase);
static int eisa_probe(struct net_device *dev, u_long iobase);
#ifdef MODULE
static int autoprobed = 1, loading_module = 1;
#else
static u_char irq[] =
{5, 0, 10, 3, 11, 9, 15, 12};
static int autoprobed, loading_module;
#endif /* MODULE */
static u_char irq[MAX_NUM_EWRK3S+1] = {5, 0, 10, 3, 11, 9, 15, 12};
static char name[EWRK3_STRLEN + 1];
static int num_ewrk3s, num_eth;
static int num_ewrks3s;
/*
** Miscellaneous defines...
......@@ -352,38 +341,50 @@ static int num_ewrk3s, num_eth;
mdelay(1);\
}
int __init ewrk3_probe(struct net_device *dev)
struct net_device * __init ewrk3_probe(int unit)
{
int tmp = num_ewrk3s, status = -ENODEV;
u_long iobase = dev->base_addr;
struct net_device *dev = alloc_etherdev(sizeof(struct ewrk3_private));
int err;
if (!dev)
return ERR_PTR(-ENOMEM);
if (unit >= 0) {
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
}
SET_MODULE_OWNER(dev);
if ((iobase == 0) && loading_module) {
printk("Autoprobing is not supported when loading a module based driver.\n");
status = -EIO;
} else { /* First probe for the Ethernet */
/* Address PROM pattern */
isa_probe(dev, iobase);
eisa_probe(dev, iobase);
if ((tmp == num_ewrk3s) && (iobase != 0) && loading_module) {
printk("%s: ewrk3_probe() cannot find device at 0x%04lx.\n", dev->name,
iobase);
}
/*
** Walk the device list to check that at least one device
** initialised OK
*/
for (; (dev->priv == NULL) && (dev->next != NULL); dev = dev->next);
err = ewrk3_probe1(dev, dev->base_addr, dev->irq);
if (err)
goto out;
return dev;
out:
free_netdev(dev);
return ERR_PTR(err);
}
if (dev->priv)
status = 0;
if (iobase == 0)
autoprobed = 1;
}
static int __init ewrk3_probe1(struct net_device *dev, u_long iobase, int irq)
{
int err;
return status;
dev->base_addr = iobase;
dev->irq = irq;
/* Address PROM pattern */
err = isa_probe(dev, iobase);
if (err != 0)
err = eisa_probe(dev, iobase);
if (err)
return err;
err = register_netdev(dev);
if (err)
release_region(dev->base_addr, EWRK3_TOTAL_SIZE);
return err;
}
static int __init
......@@ -396,8 +397,8 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
u_char eeprom_image[EEPROM_MAX], chksum, eisa_cr = 0;
/*
** Stop the EWRK3. Enable the DBR ROM. Disable interrupts and remote boot.
** This also disables the EISA_ENABLE bit in the EISA Control Register.
** Stop the EWRK3. Enable the DBR ROM. Disable interrupts and remote boot.
** This also disables the EISA_ENABLE bit in the EISA Control Register.
*/
if (iobase > 0x400)
eisa_cr = inb(EISA_CR);
......@@ -409,232 +410,210 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
icr &= 0x70;
outb(icr, EWRK3_ICR); /* Disable all the IRQs */
if (nicsr == (CSR_TXD | CSR_RXD)) {
if (nicsr == (CSR_TXD | CSR_RXD))
return -ENXIO;
/* Check that the EEPROM is alive and well and not living on Pluto... */
for (chksum = 0, i = 0; i < EEPROM_MAX; i += 2) {
union {
short val;
char c[2];
} tmp;
tmp.val = (short) Read_EEPROM(iobase, (i >> 1));
eeprom_image[i] = tmp.c[0];
eeprom_image[i + 1] = tmp.c[1];
chksum += eeprom_image[i] + eeprom_image[i + 1];
}
/* Check that the EEPROM is alive and well and not living on Pluto... */
for (chksum = 0, i = 0; i < EEPROM_MAX; i += 2) {
union {
short val;
char c[2];
} tmp;
if (chksum != 0) { /* Bad EEPROM Data! */
printk("%s: Device has a bad on-board EEPROM.\n", dev->name);
status = -ENXIO;
} else {
EthwrkSignature(name, eeprom_image);
if (*name != '\0') { /* found a EWRK3 device */
dev->base_addr = iobase;
tmp.val = (short) Read_EEPROM(iobase, (i >> 1));
eeprom_image[i] = tmp.c[0];
eeprom_image[i + 1] = tmp.c[1];
chksum += eeprom_image[i] + eeprom_image[i + 1];
}
if (iobase > 0x400) {
outb(eisa_cr, EISA_CR); /* Rewrite the EISA CR */
}
lemac = eeprom_image[EEPROM_CHIPVER];
cmr = inb(EWRK3_CMR);
if (((lemac == LeMAC) && ((cmr & CMR_NO_EEPROM) != CMR_NO_EEPROM)) ||
((lemac == LeMAC2) && !(cmr & CMR_HS))) {
printk("%s: %s at %#4lx", dev->name, name, iobase);
hard_strapped = 1;
} else if ((iobase & 0x0fff) == EWRK3_EISA_IO_PORTS) {
/* EISA slot address */
printk("%s: %s at %#4lx (EISA slot %ld)",
dev->name, name, iobase, ((iobase >> 12) & 0x0f));
} else { /* ISA port address */
printk("%s: %s at %#4lx", dev->name, name, iobase);
}
if (chksum != 0) { /* Bad EEPROM Data! */
printk("%s: Device has a bad on-board EEPROM.\n", dev->name);
return -ENXIO;
}
EthwrkSignature(name, eeprom_image);
if (*name == '\0')
return -ENXIO;
dev->base_addr = iobase;
if (iobase > 0x400) {
outb(eisa_cr, EISA_CR); /* Rewrite the EISA CR */
}
lemac = eeprom_image[EEPROM_CHIPVER];
cmr = inb(EWRK3_CMR);
if (((lemac == LeMAC) && ((cmr & CMR_NO_EEPROM) != CMR_NO_EEPROM)) ||
((lemac == LeMAC2) && !(cmr & CMR_HS))) {
printk("%s: %s at %#4lx", dev->name, name, iobase);
hard_strapped = 1;
} else if ((iobase & 0x0fff) == EWRK3_EISA_IO_PORTS) {
/* EISA slot address */
printk("%s: %s at %#4lx (EISA slot %ld)",
dev->name, name, iobase, ((iobase >> 12) & 0x0f));
} else { /* ISA port address */
printk("%s: %s at %#4lx", dev->name, name, iobase);
}
if (!status) {
printk(", h/w address ");
if (lemac != LeMAC2)
DevicePresent(iobase); /* need after EWRK3_INIT */
status = get_hw_addr(dev, eeprom_image, lemac);
for (i = 0; i < ETH_ALEN - 1; i++) { /* get the ethernet addr. */
printk("%2.2x:", dev->dev_addr[i]);
}
printk("%2.2x,\n", dev->dev_addr[i]);
printk(", h/w address ");
if (lemac != LeMAC2)
DevicePresent(iobase); /* need after EWRK3_INIT */
status = get_hw_addr(dev, eeprom_image, lemac);
for (i = 0; i < ETH_ALEN - 1; i++) { /* get the ethernet addr. */
printk("%2.2x:", dev->dev_addr[i]);
}
printk("%2.2x,\n", dev->dev_addr[i]);
if (status) {
printk(" which has an EEPROM CRC error.\n");
return -ENXIO;
}
if (status) {
printk(" which has an EEPROM CRC error.\n");
status = -ENXIO;
} else {
if (lemac == LeMAC2) { /* Special LeMAC2 CMR things */
cmr &= ~(CMR_RA | CMR_WB | CMR_LINK | CMR_POLARITY | CMR_0WS);
if (eeprom_image[EEPROM_MISC0] & READ_AHEAD)
cmr |= CMR_RA;
if (eeprom_image[EEPROM_MISC0] & WRITE_BEHIND)
cmr |= CMR_WB;
if (eeprom_image[EEPROM_NETMAN0] & NETMAN_POL)
cmr |= CMR_POLARITY;
if (eeprom_image[EEPROM_NETMAN0] & NETMAN_LINK)
cmr |= CMR_LINK;
if (eeprom_image[EEPROM_MISC0] & _0WS_ENA)
cmr |= CMR_0WS;
}
if (eeprom_image[EEPROM_SETUP] & SETUP_DRAM)
cmr |= CMR_DRAM;
outb(cmr, EWRK3_CMR);
cr = inb(EWRK3_CR); /* Set up the Control Register */
cr |= eeprom_image[EEPROM_SETUP] & SETUP_APD;
if (cr & SETUP_APD)
cr |= eeprom_image[EEPROM_SETUP] & SETUP_PS;
cr |= eeprom_image[EEPROM_MISC0] & FAST_BUS;
cr |= eeprom_image[EEPROM_MISC0] & ENA_16;
outb(cr, EWRK3_CR);
if (lemac == LeMAC2) { /* Special LeMAC2 CMR things */
cmr &= ~(CMR_RA | CMR_WB | CMR_LINK | CMR_POLARITY | CMR_0WS);
if (eeprom_image[EEPROM_MISC0] & READ_AHEAD)
cmr |= CMR_RA;
if (eeprom_image[EEPROM_MISC0] & WRITE_BEHIND)
cmr |= CMR_WB;
if (eeprom_image[EEPROM_NETMAN0] & NETMAN_POL)
cmr |= CMR_POLARITY;
if (eeprom_image[EEPROM_NETMAN0] & NETMAN_LINK)
cmr |= CMR_LINK;
if (eeprom_image[EEPROM_MISC0] & _0WS_ENA)
cmr |= CMR_0WS;
}
if (eeprom_image[EEPROM_SETUP] & SETUP_DRAM)
cmr |= CMR_DRAM;
outb(cmr, EWRK3_CMR);
cr = inb(EWRK3_CR); /* Set up the Control Register */
cr |= eeprom_image[EEPROM_SETUP] & SETUP_APD;
if (cr & SETUP_APD)
cr |= eeprom_image[EEPROM_SETUP] & SETUP_PS;
cr |= eeprom_image[EEPROM_MISC0] & FAST_BUS;
cr |= eeprom_image[EEPROM_MISC0] & ENA_16;
outb(cr, EWRK3_CR);
/*
** Determine the base address and window length for the EWRK3
** RAM from the memory base register.
*/
mem_start = inb(EWRK3_MBR);
shmem_length = 0;
if (mem_start != 0) {
if ((mem_start >= 0x0a) && (mem_start <= 0x0f)) {
mem_start *= SHMEM_64K;
shmem_length = SHMEM_64K;
} else if ((mem_start >= 0x14) && (mem_start <= 0x1f)) {
mem_start *= SHMEM_32K;
shmem_length = SHMEM_32K;
} else if ((mem_start >= 0x40) && (mem_start <= 0xff)) {
mem_start = mem_start * SHMEM_2K + 0x80000;
shmem_length = SHMEM_2K;
} else {
status = -ENXIO;
}
}
/*
** See the top of this source code for comments about
** uncommenting this line.
*/
/*
** Determine the base address and window length for the EWRK3
** RAM from the memory base register.
*/
mem_start = inb(EWRK3_MBR);
shmem_length = 0;
if (mem_start != 0) {
if ((mem_start >= 0x0a) && (mem_start <= 0x0f)) {
mem_start *= SHMEM_64K;
shmem_length = SHMEM_64K;
} else if ((mem_start >= 0x14) && (mem_start <= 0x1f)) {
mem_start *= SHMEM_32K;
shmem_length = SHMEM_32K;
} else if ((mem_start >= 0x40) && (mem_start <= 0xff)) {
mem_start = mem_start * SHMEM_2K + 0x80000;
shmem_length = SHMEM_2K;
} else {
return -ENXIO;
}
}
/*
** See the top of this source code for comments about
** uncommenting this line.
*/
/* FORCE_2K_MODE; */
if (hard_strapped) {
printk(" is hard strapped.\n");
} else if (mem_start) {
printk(" has a %dk RAM window", (int) (shmem_length >> 10));
printk(" at 0x%.5lx", mem_start);
} else {
printk(" is in I/O only mode");
}
if (!status) {
if (hard_strapped) {
printk(" is hard strapped.\n");
} else if (mem_start) {
printk(" has a %dk RAM window", (int) (shmem_length >> 10));
printk(" at 0x%.5lx", mem_start);
} else {
printk(" is in I/O only mode");
}
/* private area & initialise */
dev->priv = (void *) kmalloc(sizeof(struct ewrk3_private),
GFP_KERNEL);
if (dev->priv == NULL) {
return -ENOMEM;
}
lp = (struct ewrk3_private *) dev->priv;
memset(dev->priv, 0, sizeof(struct ewrk3_private));
lp->shmem_base = mem_start;
lp->shmem_length = shmem_length;
lp->lemac = lemac;
lp->hard_strapped = hard_strapped;
lp->led_mask = CR_LED;
spin_lock_init(&lp->hw_lock);
lp->mPage = 64;
if (cmr & CMR_DRAM)
lp->mPage <<= 1; /* 2 DRAMS on module */
sprintf(lp->adapter_name, "%s (%s)", name, dev->name);
request_region(iobase, EWRK3_TOTAL_SIZE, lp->adapter_name);
lp->irq_mask = ICR_TNEM | ICR_TXDM | ICR_RNEM | ICR_RXDM;
if (!hard_strapped) {
/*
** Enable EWRK3 board interrupts for autoprobing
*/
icr |= ICR_IE; /* Enable interrupts */
outb(icr, EWRK3_ICR);
/* The DMA channel may be passed in on this parameter. */
dev->dma = 0;
/* To auto-IRQ we enable the initialization-done and DMA err,
interrupts. For now we will always get a DMA error. */
if (dev->irq < 2) {
lp = (struct ewrk3_private *) dev->priv;
lp->shmem_base = mem_start;
lp->shmem_length = shmem_length;
lp->lemac = lemac;
lp->hard_strapped = hard_strapped;
lp->led_mask = CR_LED;
spin_lock_init(&lp->hw_lock);
lp->mPage = 64;
if (cmr & CMR_DRAM)
lp->mPage <<= 1; /* 2 DRAMS on module */
sprintf(lp->adapter_name, "%s (%s)", name, dev->name);
lp->irq_mask = ICR_TNEM | ICR_TXDM | ICR_RNEM | ICR_RXDM;
if (!hard_strapped) {
/*
** Enable EWRK3 board interrupts for autoprobing
*/
icr |= ICR_IE; /* Enable interrupts */
outb(icr, EWRK3_ICR);
/* The DMA channel may be passed in on this parameter. */
dev->dma = 0;
/* To auto-IRQ we enable the initialization-done and DMA err,
interrupts. For now we will always get a DMA error. */
if (dev->irq < 2) {
#ifndef MODULE
u_char irqnum;
unsigned long irq_mask;
u_char irqnum;
unsigned long irq_mask;
irq_mask = probe_irq_on();
/*
** Trigger a TNE interrupt.
*/
icr |= ICR_TNEM;
outb(1, EWRK3_TDQ); /* Write to the TX done queue */
outb(icr, EWRK3_ICR); /* Unmask the TXD interrupt */
irqnum = irq[((icr & IRQ_SEL) >> 4)];
mdelay(20);
dev->irq = probe_irq_off(irq_mask);
if ((dev->irq) && (irqnum == dev->irq)) {
printk(" and uses IRQ%d.\n", dev->irq);
} else {
if (!dev->irq) {
printk(" and failed to detect IRQ line.\n");
} else if ((irqnum == 1) && (lemac == LeMAC2)) {
printk(" and an illegal IRQ line detected.\n");
} else {
printk(", but incorrect IRQ line detected.\n");
}
status = -ENXIO;
}
DISABLE_IRQs; /* Mask all interrupts */
#endif /* MODULE */
} else {
printk(" and requires IRQ%d.\n", dev->irq);
}
}
if (status)
release_region(iobase, EWRK3_TOTAL_SIZE);
} else {
status = -ENXIO;
}
}
}
irq_mask = probe_irq_on();
/*
** Trigger a TNE interrupt.
*/
icr |= ICR_TNEM;
outb(1, EWRK3_TDQ); /* Write to the TX done queue */
outb(icr, EWRK3_ICR); /* Unmask the TXD interrupt */
irqnum = irq[((icr & IRQ_SEL) >> 4)];
mdelay(20);
dev->irq = probe_irq_off(irq_mask);
if ((dev->irq) && (irqnum == dev->irq)) {
printk(" and uses IRQ%d.\n", dev->irq);
} else {
status = -ENXIO;
if (!dev->irq) {
printk(" and failed to detect IRQ line.\n");
} else if ((irqnum == 1) && (lemac == LeMAC2)) {
printk(" and an illegal IRQ line detected.\n");
} else {
printk(", but incorrect IRQ line detected.\n");
}
return -ENXIO;
}
}
if (!status) {
if (ewrk3_debug > 1) {
printk(version);
}
/* The EWRK3-specific entries in the device structure. */
dev->open = ewrk3_open;
dev->hard_start_xmit = ewrk3_queue_pkt;
dev->stop = ewrk3_close;
dev->get_stats = ewrk3_get_stats;
dev->set_multicast_list = set_multicast_list;
dev->do_ioctl = ewrk3_ioctl;
dev->tx_timeout = ewrk3_timeout;
dev->watchdog_timeo = QUEUE_PKT_TIMEOUT;
dev->mem_start = 0;
/* Fill in the generic field of the device structure. */
ether_setup(dev);
DISABLE_IRQs; /* Mask all interrupts */
#endif /* MODULE */
} else {
printk(" and requires IRQ%d.\n", dev->irq);
}
} else {
status = -ENXIO;
}
return status;
if (ewrk3_debug > 1) {
printk(version);
}
/* The EWRK3-specific entries in the device structure. */
dev->open = ewrk3_open;
dev->hard_start_xmit = ewrk3_queue_pkt;
dev->stop = ewrk3_close;
dev->get_stats = ewrk3_get_stats;
dev->set_multicast_list = set_multicast_list;
dev->do_ioctl = ewrk3_ioctl;
dev->tx_timeout = ewrk3_timeout;
dev->watchdog_timeo = QUEUE_PKT_TIMEOUT;
dev->mem_start = 0;
return 0;
}
......@@ -1269,15 +1248,15 @@ static void SetMulticastFilter(struct net_device *dev)
/*
** ISA bus I/O device probe
*/
static void __init isa_probe(struct net_device *dev, u_long ioaddr)
static int __init isa_probe(struct net_device *dev, u_long ioaddr)
{
int i = num_ewrk3s, maxSlots;
int i = num_ewrks3s, maxSlots;
int ret = -ENODEV;
u_long iobase;
if (!ioaddr && autoprobed)
return; /* Been here before ! */
if (ioaddr >= 0x400)
return; /* Not ISA */
goto out;
if (ioaddr == 0) { /* Autoprobing */
iobase = EWRK3_IO_BASE; /* Get the first slot address */
......@@ -1287,38 +1266,37 @@ static void __init isa_probe(struct net_device *dev, u_long ioaddr)
maxSlots = i + 1;
}
for (; (i < maxSlots) && (dev != NULL); iobase += EWRK3_IOP_INC, i++) {
if (!check_region(iobase, EWRK3_TOTAL_SIZE)) {
for (; (i < maxSlots) && (dev != NULL);
iobase += EWRK3_IOP_INC, i++)
{
if (request_region(iobase, EWRK3_TOTAL_SIZE, dev->name)) {
if (DevicePresent(iobase) == 0) {
if ((dev = alloc_device(dev, iobase)) != NULL) {
if (ewrk3_hw_init(dev, iobase) == 0) {
num_ewrk3s++;
}
num_eth++;
}
int irq = dev->irq;
ret = ewrk3_hw_init(dev, iobase);
if (!ret)
break;
dev->irq = irq;
}
} else if (autoprobed) {
printk("%s: region already allocated at 0x%04lx.\n", dev->name, iobase);
release_region(iobase, EWRK3_TOTAL_SIZE);
}
}
out:
return;
return ret;
}
/*
** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
** the motherboard.
*/
static void __init eisa_probe(struct net_device *dev, u_long ioaddr)
static int __init eisa_probe(struct net_device *dev, u_long ioaddr)
{
int i, maxSlots;
u_long iobase;
char name[EWRK3_STRLEN];
int ret = -ENODEV;
if (!ioaddr && autoprobed)
return; /* Been here before ! */
if (ioaddr < 0x1000)
return; /* Not EISA */
goto out;
if (ioaddr == 0) { /* Autoprobing */
iobase = EISA_SLOT_INC; /* Get the first slot address */
......@@ -1332,114 +1310,22 @@ static void __init eisa_probe(struct net_device *dev, u_long ioaddr)
for (i = 1; (i < maxSlots) && (dev != NULL); i++, iobase += EISA_SLOT_INC) {
if (EISA_signature(name, EISA_ID) == 0) {
if (!check_region(iobase, EWRK3_TOTAL_SIZE)) {
if (DevicePresent(iobase) == 0) {
if ((dev = alloc_device(dev, iobase)) != NULL) {
if (ewrk3_hw_init(dev, iobase) == 0) {
num_ewrk3s++;
}
num_eth++;
}
}
} else if (autoprobed) {
printk("%s: region already allocated at 0x%04lx.\n", dev->name, iobase);
if (request_region(iobase, EWRK3_TOTAL_SIZE, dev->name) &&
DevicePresent(iobase) == 0) {
int irq = dev->irq;
ret = ewrk3_hw_init(dev, iobase);
if (!ret)
break;
dev->irq = irq;
}
release_region(iobase, EWRK3_TOTAL_SIZE);
}
}
return;
out:
return ret;
}
/*
** Search the entire 'eth' device list for a fixed probe. If a match isn't
** found then check for an autoprobe or unused device location. If they
** are not available then insert a new device structure at the end of
** the current list.
*/
static struct net_device * __init alloc_device(struct net_device *dev, u_long iobase)
{
struct net_device *adev = NULL;
int fixed = 0, new_dev = 0;
num_eth = ewrk3_dev_index(dev->name);
if (loading_module)
return dev;
while (1) {
if (((dev->base_addr == EWRK3_NDA) || (dev->base_addr == 0)) && !adev) {
adev = dev;
} else if ((dev->priv == NULL) && (dev->base_addr == iobase)) {
fixed = 1;
} else {
if (dev->next == NULL) {
new_dev = 1;
} else if (strncmp(dev->next->name, "eth", 3) != 0) {
new_dev = 1;
}
}
if ((dev->next == NULL) || new_dev || fixed)
break;
dev = dev->next;
num_eth++;
}
if (adev && !fixed) {
dev = adev;
num_eth = ewrk3_dev_index(dev->name);
new_dev = 0;
}
if (((dev->next == NULL) &&
((dev->base_addr != EWRK3_NDA) && (dev->base_addr != 0)) && !fixed) ||
new_dev) {
num_eth++; /* New device */
dev = insert_device(dev, iobase, ewrk3_probe);
}
return dev;
}
/*
** If at end of eth device list and can't use current entry, malloc
** one up. If memory could not be allocated, print an error message.
*/
static struct net_device * __init
insert_device(struct net_device *dev, u_long iobase, int (*init) (struct net_device *))
{
struct net_device *new;
new = (struct net_device *) kmalloc(sizeof(struct net_device) + 8, GFP_KERNEL);
if (new == NULL) {
printk("eth%d: Device not initialised, insufficient memory\n", num_eth);
return NULL;
} else {
new->next = dev->next;
dev->next = new;
dev = dev->next; /* point to the new device */
if (num_eth > 9999) {
sprintf(dev->name, "eth????"); /* New device name */
} else {
sprintf(dev->name, "eth%d", num_eth); /* New device name */
}
dev->base_addr = iobase; /* assign the io address */
dev->init = init; /* initialisation routine */
}
return dev;
}
static int __init
ewrk3_dev_index(char *s)
{
int i = 0, j = 0;
for (; *s; s++) {
if (isdigit(*s)) {
j = 1;
i = (i * 10) + (*s - '0');
} else if (j)
break;
}
return i;
}
/*
** Read the EWRK3 EEPROM using this routine
......@@ -2074,8 +1960,7 @@ static int ewrk3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
#ifdef MODULE
static struct net_device *ewrk3_devs[MAX_NUM_EWRK3S];
static int ndevs;
static int io[MAX_NUM_EWRK3S+1] = { 0x300, 0, }; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
static int irq[MAX_NUM_EWRK3S+1] = { 5, 0, }; /* or use the insmod io= irq= options */
static int io[MAX_NUM_EWRK3S+1] = { 0x300, 0, };
/* '21' below should really be 'MAX_NUM_EWRK3S' */
MODULE_PARM(io, "0-21i");
......@@ -2083,50 +1968,39 @@ MODULE_PARM(irq, "0-21i");
MODULE_PARM_DESC(io, "EtherWORKS 3 I/O base address(es)");
MODULE_PARM_DESC(irq, "EtherWORKS 3 IRQ number(s)");
static void ewrk3_exit_module(void)
static __exit void ewrk3_exit_module(void)
{
int i;
for( i=0; i<ndevs; i++ ) {
unregister_netdev(ewrk3_devs[i]);
if (ewrk3_devs[i]->priv) {
kfree(ewrk3_devs[i]->priv);
ewrk3_devs[i]->priv = NULL;
}
ewrk3_devs[i]->irq = 0;
release_region(ewrk3_devs[i]->base_addr, EWRK3_TOTAL_SIZE);
free_netdev(ewrk3_devs[i]);
ewrk3_devs[i] = NULL;
}
}
static int ewrk3_init_module(void)
static __init int ewrk3_init_module(void)
{
int i=0;
while( io[i] && irq[i] ) {
ewrk3_devs[ndevs] = kmalloc(sizeof(struct net_device), GFP_KERNEL);
if (!ewrk3_devs[ndevs])
goto error;
memset(ewrk3_devs[ndevs], 0, sizeof(struct net_device));
ewrk3_devs[ndevs]->base_addr = io[i];
ewrk3_devs[ndevs]->irq = irq[i];
ewrk3_devs[ndevs]->init = ewrk3_probe;
if (register_netdev(ewrk3_devs[ndevs]) == 0)
ndevs++;
else
kfree(ewrk3_devs[ndevs]);
struct net_device *dev
= alloc_etherdev(sizeof(struct ewrk3_private));
if (!dev)
break;
if (ewrk3_probe1(dev, io[i], irq[i]) != 0) {
free_netdev(dev);
break;
}
ewrk3_devs[ndevs++] = dev;
i++;
}
return ndevs ? 0 : -EIO;
error:
ewrk3_exit_module();
return -ENOMEM;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment