Commit 93b40e80 authored by Stephen Hemminger's avatar Stephen Hemminger

[PATCH] (30/42) jazzsonic

NE55-jazzsonic
	* switched jazzsonic to dynamic allocation
	* jazzsonic: fixed resource leaks on failure exits
parent b87c82c3
...@@ -70,7 +70,7 @@ extern struct net_device *e2100_probe(int unit); ...@@ -70,7 +70,7 @@ extern struct net_device *e2100_probe(int unit);
extern struct net_device *ni5010_probe(int unit); extern struct net_device *ni5010_probe(int unit);
extern struct net_device *ni52_probe(int unit); extern struct net_device *ni52_probe(int unit);
extern struct net_device *ni65_probe(int unit); extern struct net_device *ni65_probe(int unit);
extern int sonic_probe(struct net_device *); extern struct net_device *sonic_probe(int unit);
extern struct net_device *SK_init(int unit); extern struct net_device *SK_init(int unit);
extern struct net_device *seeq8005_probe(int unit); extern struct net_device *seeq8005_probe(int unit);
extern struct net_device *smc_init(int unit); extern struct net_device *smc_init(int unit);
...@@ -335,14 +335,10 @@ static struct devprobe m68k_probes[] __initdata = { ...@@ -335,14 +335,10 @@ static struct devprobe m68k_probes[] __initdata = {
{NULL, 0}, {NULL, 0},
}; };
static struct devprobe mips_probes[] __initdata = { static struct devprobe2 mips_probes[] __initdata = {
#ifdef CONFIG_MIPS_JAZZ_SONIC #ifdef CONFIG_MIPS_JAZZ_SONIC
{sonic_probe, 0}, {sonic_probe, 0},
#endif #endif
{NULL, 0},
};
static struct devprobe2 mips_probes2[] __initdata = {
#ifdef CONFIG_BAGETLANCE /* Lance-based Baget ethernet boards */ #ifdef CONFIG_BAGETLANCE /* Lance-based Baget ethernet boards */
{bagetlance_probe, 0}, {bagetlance_probe, 0},
#endif #endif
...@@ -379,8 +375,7 @@ static int __init ethif_probe(int unit) ...@@ -379,8 +375,7 @@ static int __init ethif_probe(int unit)
* The arch specific probes are 1st so that any on-board ethernet * The arch specific probes are 1st so that any on-board ethernet
* will be probed before other ISA/EISA/MCA/PCI bus cards. * will be probed before other ISA/EISA/MCA/PCI bus cards.
*/ */
if (probe_list(dev, m68k_probes) == 0 || if (probe_list(dev, m68k_probes) == 0)
probe_list(dev, mips_probes) == 0)
err = register_netdev(dev); err = register_netdev(dev);
if (err) if (err)
...@@ -396,7 +391,7 @@ static void __init ethif_probe2(int unit) ...@@ -396,7 +391,7 @@ static void __init ethif_probe2(int unit)
if (base_addr == 1) if (base_addr == 1)
return; return;
probe_list2(unit, mips_probes2, base_addr == 0) && probe_list2(unit, mips_probes, base_addr == 0) &&
probe_list2(unit, eisa_probes, base_addr == 0) && probe_list2(unit, eisa_probes, base_addr == 0) &&
probe_list2(unit, mca_probes, base_addr == 0) && probe_list2(unit, mca_probes, base_addr == 0) &&
probe_list2(unit, isa_probes, base_addr == 0) && probe_list2(unit, isa_probes, base_addr == 0) &&
......
...@@ -80,7 +80,6 @@ static unsigned short known_revisions[] = ...@@ -80,7 +80,6 @@ static unsigned short known_revisions[] =
/* Index to functions, as function prototypes. */ /* Index to functions, as function prototypes. */
extern int sonic_probe(struct net_device *dev);
static int sonic_probe1(struct net_device *dev, unsigned int base_addr, static int sonic_probe1(struct net_device *dev, unsigned int base_addr,
unsigned int irq); unsigned int irq);
...@@ -89,29 +88,57 @@ static int sonic_probe1(struct net_device *dev, unsigned int base_addr, ...@@ -89,29 +88,57 @@ static int sonic_probe1(struct net_device *dev, unsigned int base_addr,
* Probe for a SONIC ethernet controller on a Mips Jazz board. * Probe for a SONIC ethernet controller on a Mips Jazz board.
* Actually probing is superfluous but we're paranoid. * Actually probing is superfluous but we're paranoid.
*/ */
int __init sonic_probe(struct net_device *dev) struct net_device * __init sonic_probe(int unit)
{ {
unsigned int base_addr = dev ? dev->base_addr : 0; struct net_device *dev;
struct sonic_local *lp;
unsigned int base_addr;
int err = 0;
int i; int i;
/* /*
* Don't probe if we're not running on a Jazz board. * Don't probe if we're not running on a Jazz board.
*/ */
if (mips_machgroup != MACH_GROUP_JAZZ) if (mips_machgroup != MACH_GROUP_JAZZ)
return -ENODEV; return ERR_PTR(-ENODEV);
if (base_addr >= KSEG0) /* Check a single specified location. */
return sonic_probe1(dev, base_addr, dev->irq); dev = alloc_etherdev(0);
else if (base_addr != 0) /* Don't probe at all. */ if (!dev)
return -ENXIO; return ERR_PTR(-ENOMEM);
for (i = 0; sonic_portlist[i].port; i++) { sprintf(dev->name, "eth%d", unit);
int base_addr = sonic_portlist[i].port; netdev_boot_setup_check(dev);
if (check_region(base_addr, 0x100)) base_addr = dev->base_addr;
continue;
if (sonic_probe1(dev, base_addr, sonic_portlist[i].irq) == 0) if (base_addr >= KSEG0) { /* Check a single specified location. */
return 0; err = sonic_probe1(dev, base_addr, dev->irq);
} else if (base_addr != 0) { /* Don't probe at all. */
err = -ENXIO;
} else {
for (i = 0; sonic_portlist[i].port; i++) {
int io = sonic_portlist[i].port;
if (sonic_probe1(dev, io, sonic_portlist[i].irq) == 0)
break;
}
if (!sonic_portlist[i].port)
err = -ENODEV;
} }
return -ENODEV; if (err)
goto out;
err = register_netdev(dev);
if (err)
goto out1;
return dev;
out1:
lp = dev->priv;
vdma_free(lp->rba_laddr);
kfree(lp->rba);
vdma_free(lp->cda_laddr);
kfree(lp);
release_region(dev->base_addr, 0x100);
out:
free_netdev(dev);
return ERR_PTR(err);
} }
static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr, static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
...@@ -121,8 +148,11 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr, ...@@ -121,8 +148,11 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
unsigned int silicon_revision; unsigned int silicon_revision;
unsigned int val; unsigned int val;
struct sonic_local *lp; struct sonic_local *lp;
int err = -ENODEV;
int i; int i;
if (!request_region(base_addr, 0x100, dev->name))
return -EBUSY;
/* /*
* get the Silicon Revision ID. If this is one of the known * get the Silicon Revision ID. If this is one of the known
* one assume that we found a SONIC ethernet controller at * one assume that we found a SONIC ethernet controller at
...@@ -140,12 +170,9 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr, ...@@ -140,12 +170,9 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
if (known_revisions[i] == 0xffff) { if (known_revisions[i] == 0xffff) {
printk("SONIC ethernet controller not found (0x%4x)\n", printk("SONIC ethernet controller not found (0x%4x)\n",
silicon_revision); silicon_revision);
return -ENODEV; goto out;
} }
if (!request_region(base_addr, 0x100, dev->name))
return -EBUSY;
if (sonic_debug && version_printed++ == 0) if (sonic_debug && version_printed++ == 0)
printk(version); printk(version);
...@@ -175,6 +202,8 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr, ...@@ -175,6 +202,8 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
} }
printk(" IRQ %d\n", irq); printk(" IRQ %d\n", irq);
err = -ENOMEM;
/* Initialize the device structure. */ /* Initialize the device structure. */
if (dev->priv == NULL) { if (dev->priv == NULL) {
...@@ -196,7 +225,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr, ...@@ -196,7 +225,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
if (lp == NULL) { if (lp == NULL) {
printk("%s: couldn't allocate memory for descriptors\n", printk("%s: couldn't allocate memory for descriptors\n",
dev->name); dev->name);
return -ENOMEM; goto out;
} }
memset(lp, 0, sizeof(struct sonic_local)); memset(lp, 0, sizeof(struct sonic_local));
...@@ -206,7 +235,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr, ...@@ -206,7 +235,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
if (lp->cda_laddr == ~0UL) { if (lp->cda_laddr == ~0UL) {
printk("%s: couldn't get DMA page entry for " printk("%s: couldn't get DMA page entry for "
"descriptors\n", dev->name); "descriptors\n", dev->name);
return -ENOMEM; goto out1;
} }
lp->tda_laddr = lp->cda_laddr + sizeof (lp->cda); lp->tda_laddr = lp->cda_laddr + sizeof (lp->cda);
...@@ -219,7 +248,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr, ...@@ -219,7 +248,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
if (!lp->rba) { if (!lp->rba) {
printk("%s: couldn't allocate receive buffers\n", printk("%s: couldn't allocate receive buffers\n",
dev->name); dev->name);
return -ENOMEM; goto out2;
} }
/* get virtual dma address */ /* get virtual dma address */
...@@ -228,7 +257,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr, ...@@ -228,7 +257,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
if (lp->rba_laddr == ~0UL) { if (lp->rba_laddr == ~0UL) {
printk("%s: couldn't get DMA page entry for receive " printk("%s: couldn't get DMA page entry for receive "
"buffers\n",dev->name); "buffers\n",dev->name);
return -ENOMEM; goto out3;
} }
/* now convert pointer to KSEG1 pointer */ /* now convert pointer to KSEG1 pointer */
...@@ -252,9 +281,16 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr, ...@@ -252,9 +281,16 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
SONIC_WRITE(SONIC_FAET,0xffff); SONIC_WRITE(SONIC_FAET,0xffff);
SONIC_WRITE(SONIC_MPT,0xffff); SONIC_WRITE(SONIC_MPT,0xffff);
/* Fill in the fields of the device structure with ethernet values. */
ether_setup(dev);
return 0; return 0;
out3:
kfree(lp->rba);
out2:
vdma_free(lp->cda_laddr);
out1:
kfree(lp);
out:
release_region(base_addr, 0x100);
return err;
} }
/* /*
......
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