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 */
err = ewrk3_probe1(dev, dev->base_addr, dev->irq);
if (err)
goto out;
return dev;
out:
free_netdev(dev);
return ERR_PTR(err);
}
static int __init ewrk3_probe1(struct net_device *dev, u_long iobase, int irq)
{
int err;
dev->base_addr = iobase;
dev->irq = irq;
/* Address PROM pattern */
isa_probe(dev, iobase);
eisa_probe(dev, iobase);
err = isa_probe(dev, iobase);
if (err != 0)
err = 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);
if (err)
return err;
if (dev->priv)
status = 0;
if (iobase == 0)
autoprobed = 1;
}
err = register_netdev(dev);
if (err)
release_region(dev->base_addr, EWRK3_TOTAL_SIZE);
return status;
return err;
}
static int __init
......@@ -409,7 +410,9 @@ 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) {
......@@ -426,10 +429,13 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
if (chksum != 0) { /* Bad EEPROM Data! */
printk("%s: Device has a bad on-board EEPROM.\n", dev->name);
status = -ENXIO;
} else {
return -ENXIO;
}
EthwrkSignature(name, eeprom_image);
if (*name != '\0') { /* found a EWRK3 device */
if (*name == '\0')
return -ENXIO;
dev->base_addr = iobase;
if (iobase > 0x400) {
......@@ -450,7 +456,6 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
printk("%s: %s at %#4lx", dev->name, name, iobase);
}
if (!status) {
printk(", h/w address ");
if (lemac != LeMAC2)
DevicePresent(iobase); /* need after EWRK3_INIT */
......@@ -462,8 +467,9 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
if (status) {
printk(" which has an EEPROM CRC error.\n");
status = -ENXIO;
} else {
return -ENXIO;
}
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)
......@@ -506,7 +512,7 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
mem_start = mem_start * SHMEM_2K + 0x80000;
shmem_length = SHMEM_2K;
} else {
status = -ENXIO;
return -ENXIO;
}
}
/*
......@@ -515,7 +521,6 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
*/
/* FORCE_2K_MODE; */
if (!status) {
if (hard_strapped) {
printk(" is hard strapped.\n");
} else if (mem_start) {
......@@ -525,14 +530,7 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
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;
......@@ -545,7 +543,6 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
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;
......@@ -590,7 +587,7 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
} else {
printk(", but incorrect IRQ line detected.\n");
}
status = -ENXIO;
return -ENXIO;
}
DISABLE_IRQs; /* Mask all interrupts */
......@@ -600,19 +597,7 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
printk(" and requires IRQ%d.\n", dev->irq);
}
}
if (status)
release_region(iobase, EWRK3_TOTAL_SIZE);
} else {
status = -ENXIO;
}
}
}
} else {
status = -ENXIO;
}
}
if (!status) {
if (ewrk3_debug > 1) {
printk(version);
}
......@@ -628,13 +613,7 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
dev->mem_start = 0;
/* Fill in the generic field of the device structure. */
ether_setup(dev);
}
} else {
status = -ENXIO;
}
return status;
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);
}
}
}
return;
}
/*
** 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)
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 = 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);
dev->irq = irq;
}
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 */
release_region(iobase, EWRK3_TOTAL_SIZE);
}
dev->base_addr = iobase; /* assign the io address */
dev->init = init; /* initialisation routine */
}
return dev;
out:
return ret;
}
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