Commit 59d27320 authored by Alexander Viro's avatar Alexander Viro Committed by Stephen Hemminger

[arcnet arc-rimi] use alloc_netdev; module params; fix bugs on error/cleanup

parent 7661326e
......@@ -26,6 +26,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/delay.h>
......@@ -85,8 +86,6 @@ static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offse
*/
static int __init arcrimi_probe(struct net_device *dev)
{
int retval;
BUGLVL(D_NORMAL) printk(VERSION);
BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n");
......@@ -114,11 +113,7 @@ static int __init arcrimi_probe(struct net_device *dev)
"ID!\n");
return -ENODEV;
}
retval = arcrimi_found(dev);
if (retval < 0) {
release_mem_region(dev->mem_start, BUFFER_SIZE);
}
return retval;
return arcrimi_found(dev);
}
......@@ -129,11 +124,13 @@ static int __init arcrimi_probe(struct net_device *dev)
static int __init arcrimi_found(struct net_device *dev)
{
struct arcnet_local *lp;
u_long first_mirror, last_mirror, shmem;
unsigned long first_mirror, last_mirror, shmem;
int mirror_size;
int err;
/* reserve the irq */
if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev)) {
release_mem_region(dev->mem_start, BUFFER_SIZE);
BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
return -ENODEV;
}
......@@ -168,11 +165,7 @@ static int __init arcrimi_found(struct net_device *dev)
/* initialize the rest of the device structure. */
lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
if (!lp) {
BUGMSG(D_NORMAL, "Can't allocate device data!\n");
goto err_free_irq;
}
lp = dev->priv;
lp->card_name = "RIM I";
lp->hw.command = arcrimi_command;
lp->hw.status = arcrimi_status;
......@@ -181,18 +174,6 @@ static int __init arcrimi_found(struct net_device *dev)
lp->hw.owner = THIS_MODULE;
lp->hw.copy_to_card = arcrimi_copy_to_card;
lp->hw.copy_from_card = arcrimi_copy_from_card;
lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
if (!lp->mem_start) {
BUGMSG(D_NORMAL, "Can't remap device memory!\n");
goto err_free_dev_priv;
}
/* Fill in the fields of the device structure with generic
* values.
*/
arcdev_setup(dev);
/* get and check the station ID from offset 1 in shmem */
dev->dev_addr[0] = readb(lp->mem_start + 1);
/*
* re-reserve the memory region - arcrimi_probe() alloced this reqion
......@@ -200,25 +181,40 @@ static int __init arcrimi_found(struct net_device *dev)
* with the correct size. There is a VERY slim chance this could
* fail.
*/
release_mem_region(dev->mem_start, BUFFER_SIZE);
release_mem_region(shmem, BUFFER_SIZE);
if (!request_mem_region(dev->mem_start,
dev->mem_end - dev->mem_start + 1,
"arcnet (90xx)")) {
BUGMSG(D_NORMAL, "Card memory already allocated\n");
goto err_free_dev_priv;
goto err_free_irq;
}
lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
if (!lp->mem_start) {
BUGMSG(D_NORMAL, "Can't remap device memory!\n");
goto err_release_mem;
}
/* get and check the station ID from offset 1 in shmem */
dev->dev_addr[0] = readb(lp->mem_start + 1);
BUGMSG(D_NORMAL, "ARCnet RIM I: station %02Xh found at IRQ %d, "
"ShMem %lXh (%ld*%d bytes).\n",
dev->dev_addr[0],
dev->irq, dev->mem_start,
(dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
err = register_netdev(dev);
if (err)
goto err_unmap;
return 0;
err_free_dev_priv:
kfree(dev->priv);
err_free_irq:
err_unmap:
iounmap(lp->mem_start);
err_release_mem:
release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
err_free_irq:
free_irq(dev->irq, dev);
return -EIO;
}
......@@ -294,94 +290,81 @@ static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offse
TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
}
#ifdef MODULE
static struct net_device *my_dev;
/* Module parameters */
static int node = 0;
static int io = 0x0; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
static int irq = 0; /* or use the insmod io= irq= shmem= options */
static char *device; /* use eg. device="arc1" to change name */
static int node;
static int io; /* use the insmod io= irq= node= options */
static int irq;
static char device[9]; /* use eg. device=arc1 to change name */
MODULE_PARM(node, "i");
MODULE_PARM(io, "i");
MODULE_PARM(irq, "i");
MODULE_PARM(device, "s");
module_param(node, int, 0);
module_param(io, int, 0);
module_param(irq, int, 0);
module_param_string(device, device, sizeof(device), 0);
MODULE_LICENSE("GPL");
int init_module(void)
static struct net_device *my_dev;
static int __init arc_rimi_init(void)
{
struct net_device *dev;
int err;
dev = dev_alloc(device ? : "arc%d", &err);
dev = alloc_netdev(sizeof(struct arcnet_local),
device[0] ? device : "arc%d",
arcdev_setup);
if (!dev)
return err;
return -ENOMEM;
if (node && node != 0xff)
dev->dev_addr[0] = node;
dev->base_addr = io;
dev->mem_start = io;
dev->irq = irq;
if (dev->irq == 2)
dev->irq = 9;
if (arcrimi_probe(dev))
if (arcrimi_probe(dev)) {
free_netdev(dev);
return -EIO;
}
my_dev = dev;
return 0;
}
void cleanup_module(void)
static void __exit arc_rimi_exit(void)
{
struct net_device *dev = my_dev;
struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
unregister_netdev(dev);
free_irq(dev->irq, dev);
iounmap(lp->mem_start);
release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
kfree(dev->priv);
free_irq(dev->irq, dev);
free_netdev(dev);
}
#else
#ifndef MODULE
static int __init arcrimi_setup(char *s)
{
struct net_device *dev;
int ints[8];
s = get_options(s, 8, ints);
if (!ints[0])
return 1;
dev = alloc_bootmem(sizeof(struct net_device));
memset(dev, 0, sizeof(struct net_device));
dev->init = arcrimi_probe;
switch (ints[0]) {
default: /* ERROR */
printk("arcrimi: Too many arguments.\n");
case 3: /* Node ID */
dev->dev_addr[0] = ints[3];
node = ints[3];
case 2: /* IRQ */
dev->irq = ints[2];
irq = ints[2];
case 1: /* IO address */
dev->mem_start = ints[1];
io = ints[1];
}
if (*s)
strncpy(dev->name, s, 9);
else
strcpy(dev->name, "arc%d");
if (register_netdev(dev))
printk(KERN_ERR "arc-rimi: Cannot register arcnet device\n");
snprintf(device, sizeof(device), "%s", s);
return 1;
}
__setup("arcrimi=", arcrimi_setup);
#endif /* MODULE */
module_init(arc_rimi_init)
module_exit(arc_rimi_exit)
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