Commit 73baed59 authored by Alexander Viro's avatar Alexander Viro Committed by Stephen Hemminger

[arcnet com20020] netdev dynamic alloc; module params; fix bugs

parent 59d27320
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
* ********************** * **********************
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/ioport.h> #include <linux/ioport.h>
...@@ -117,49 +118,43 @@ static int __init com20020isa_probe(struct net_device *dev) ...@@ -117,49 +118,43 @@ static int __init com20020isa_probe(struct net_device *dev)
return err; return err;
} }
#ifdef MODULE
static struct net_device *my_dev;
/* Module parameters */
static int node = 0; static int node = 0;
static int io = 0x0; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */ static int io = 0x0; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
static int irq = 0; /* or use the insmod io= irq= shmem= options */ static int irq = 0; /* or use the insmod io= irq= shmem= options */
static char *device; /* use eg. device="arc1" to change name */ static char device[9]; /* use eg. device="arc1" to change name */
static int timeout = 3; static int timeout = 3;
static int backplane = 0; static int backplane = 0;
static int clockp = 0; static int clockp = 0;
static int clockm = 0; static int clockm = 0;
MODULE_PARM(node, "i"); module_param(node, int, 0);
MODULE_PARM(io, "i"); module_param(io, int, 0);
MODULE_PARM(irq, "i"); module_param(irq, int, 0);
MODULE_PARM(device, "s"); module_param_string(device, device, sizeof(device), 0);
MODULE_PARM(timeout, "i"); module_param(timeout, int, 0);
MODULE_PARM(backplane, "i"); module_param(backplane, int, 0);
MODULE_PARM(clockp, "i"); module_param(clockp, int, 0);
MODULE_PARM(clockm, "i"); module_param(clockm, int, 0);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
int init_module(void) static struct net_device *my_dev;
static int __init com20020_init(void)
{ {
struct net_device *dev; struct net_device *dev;
struct arcnet_local *lp; struct arcnet_local *lp;
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) if (!dev)
return err;
lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
if (!lp)
return -ENOMEM; return -ENOMEM;
memset(lp, 0, sizeof(struct arcnet_local));
if (node && node != 0xff) if (node && node != 0xff)
dev->dev_addr[0] = node; dev->dev_addr[0] = node;
lp = dev->priv;
lp->backplane = backplane; lp->backplane = backplane;
lp->clockp = clockp & 7; lp->clockp = clockp & 7;
lp->clockm = clockm & 3; lp->clockm = clockm & 3;
...@@ -172,21 +167,24 @@ int init_module(void) ...@@ -172,21 +167,24 @@ int init_module(void)
if (dev->irq == 2) if (dev->irq == 2)
dev->irq = 9; dev->irq = 9;
if (com20020isa_probe(dev)) if (com20020isa_probe(dev)) {
free_netdev(dev);
return -EIO; return -EIO;
}
my_dev = dev; my_dev = dev;
return 0; return 0;
} }
void cleanup_module(void) static void __exit com20020_exit(void)
{ {
com20020_remove(my_dev); unregister_netdev(my_dev);
free_irq(my_dev->irq, my_dev);
release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE); release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE);
free_netdev(my_dev);
} }
#else #ifndef MODULE
static int __init com20020isa_setup(char *s) static int __init com20020isa_setup(char *s)
{ {
struct net_device *dev; struct net_device *dev;
...@@ -196,37 +194,31 @@ static int __init com20020isa_setup(char *s) ...@@ -196,37 +194,31 @@ static int __init com20020isa_setup(char *s)
s = get_options(s, 8, ints); s = get_options(s, 8, ints);
if (!ints[0]) if (!ints[0])
return 1; return 1;
dev = alloc_bootmem(sizeof(struct net_device) + sizeof(struct arcnet_local));
memset(dev, 0, sizeof(struct net_device) + sizeof(struct arcnet_local));
lp = dev->priv = (struct arcnet_local *) (dev + 1);
dev->init = com20020isa_probe;
switch (ints[0]) { switch (ints[0]) {
default: /* ERROR */ default: /* ERROR */
printk("com90xx: Too many arguments.\n"); printk("com90xx: Too many arguments.\n");
case 6: /* Timeout */ case 6: /* Timeout */
lp->timeout = ints[6]; timeout = ints[6];
case 5: /* CKP value */ case 5: /* CKP value */
lp->clockp = ints[5]; clockp = ints[5];
case 4: /* Backplane flag */ case 4: /* Backplane flag */
lp->backplane = ints[4]; backplane = ints[4];
case 3: /* Node ID */ case 3: /* Node ID */
dev->dev_addr[0] = ints[3]; node = ints[3];
case 2: /* IRQ */ case 2: /* IRQ */
dev->irq = ints[2]; irq = ints[2];
case 1: /* IO address */ case 1: /* IO address */
dev->base_addr = ints[1]; io = ints[1];
} }
if (*s) if (*s)
strncpy(dev->name, s, 9); snprintf(device, sizeof(device), "%s", s);
else
strcpy(dev->name, "arc%d");
if (register_netdev(dev))
printk(KERN_ERR "com20020: Cannot register arcnet device\n");
return 1; return 1;
} }
__setup("com20020=", com20020isa_setup); __setup("com20020=", com20020isa_setup);
#endif /* MODULE */ #endif /* MODULE */
module_init(com20020_init)
module_exit(com20020_exit)
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
* ********************** * **********************
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/ioport.h> #include <linux/ioport.h>
...@@ -46,18 +47,18 @@ ...@@ -46,18 +47,18 @@
/* Module parameters */ /* Module parameters */
static int node; static int node;
static char *device; /* use eg. device="arc1" to change name */ static char device[9]; /* use eg. device="arc1" to change name */
static int timeout = 3; static int timeout = 3;
static int backplane; static int backplane;
static int clockp; static int clockp;
static int clockm; static int clockm;
MODULE_PARM(node, "i"); module_param(node, int, 0);
MODULE_PARM(device, "s"); module_param_string(device, device, sizeof(device), 0);
MODULE_PARM(timeout, "i"); module_param(timeout, int, 0);
MODULE_PARM(backplane, "i"); module_param(backplane, int, 0);
MODULE_PARM(clockp, "i"); module_param(clockp, int, 0);
MODULE_PARM(clockm, "i"); module_param(clockm, int, 0);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
...@@ -68,15 +69,13 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de ...@@ -68,15 +69,13 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
if (pci_enable_device(pdev)) if (pci_enable_device(pdev))
return -EIO; return -EIO;
dev = dev_alloc(device ? : "arc%d", &err); dev = alloc_netdev(sizeof(struct arcnet_local),
device[0] ? device : "arc%d",
arcdev_setup);
if (!dev) if (!dev)
return err; return -ENOMEM;
lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL); lp = dev->priv;
if (!lp) {
err = -ENOMEM;
goto out_dev;
}
memset(lp, 0, sizeof(struct arcnet_local));
pci_set_drvdata(pdev, dev); pci_set_drvdata(pdev, dev);
// SOHARD needs PCI base addr 4 // SOHARD needs PCI base addr 4
...@@ -89,6 +88,13 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de ...@@ -89,6 +88,13 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
ioaddr = pci_resource_start(pdev, 2); ioaddr = pci_resource_start(pdev, 2);
} }
if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com20020-pci")) {
BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n",
ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
err = -EBUSY;
goto out_dev;
}
// Dummy access after Reset // Dummy access after Reset
// ARCNET controller needs this access to detect bustype // ARCNET controller needs this access to detect bustype
outb(0x00,ioaddr+1); outb(0x00,ioaddr+1);
...@@ -105,12 +111,6 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de ...@@ -105,12 +111,6 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
lp->timeout = timeout; lp->timeout = timeout;
lp->hw.owner = THIS_MODULE; lp->hw.owner = THIS_MODULE;
if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com20020-pci")) {
BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n",
ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
err = -EBUSY;
goto out_priv;
}
if (ASTATUS() == 0xFF) { if (ASTATUS() == 0xFF) {
BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, " BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, "
"but seems empty!\n", ioaddr); "but seems empty!\n", ioaddr);
...@@ -129,18 +129,18 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de ...@@ -129,18 +129,18 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
out_port: out_port:
release_region(ioaddr, ARCNET_TOTAL_SIZE); release_region(ioaddr, ARCNET_TOTAL_SIZE);
out_priv:
kfree(dev->priv);
out_dev: out_dev:
kfree(dev); free_netdev(dev);
return err; return err;
} }
static void __devexit com20020pci_remove(struct pci_dev *pdev) static void __devexit com20020pci_remove(struct pci_dev *pdev)
{ {
struct net_device *dev = pci_get_drvdata(pdev); struct net_device *dev = pci_get_drvdata(pdev);
com20020_remove(dev); unregister_netdev(dev);
free_irq(dev->irq, dev);
release_region(dev->base_addr, ARCNET_TOTAL_SIZE); release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
free_netdev(dev);
} }
static struct pci_device_id com20020pci_id_table[] = { static struct pci_device_id com20020pci_id_table[] = {
......
...@@ -172,11 +172,6 @@ int com20020_found(struct net_device *dev, int shared) ...@@ -172,11 +172,6 @@ int com20020_found(struct net_device *dev, int shared)
dev->set_multicast_list = com20020_set_mc_list; dev->set_multicast_list = com20020_set_mc_list;
/* Fill in the fields of the device structure with generic
* values.
*/
arcdev_setup(dev);
if (!dev->dev_addr[0]) if (!dev->dev_addr[0])
dev->dev_addr[0] = inb(ioaddr + 8); /* FIXME: do this some other way! */ dev->dev_addr[0] = inb(ioaddr + 8); /* FIXME: do this some other way! */
...@@ -221,7 +216,7 @@ int com20020_found(struct net_device *dev, int shared) ...@@ -221,7 +216,7 @@ int com20020_found(struct net_device *dev, int shared)
lp->setup >> 1, lp->setup >> 1,
clockrates[3 - ((lp->setup2 & 0xF0) >> 4) + ((lp->setup & 0x0F) >> 1)]); clockrates[3 - ((lp->setup2 & 0xF0) >> 4) + ((lp->setup & 0x0F) >> 1)]);
if (!dev->init && register_netdev(dev)) { if (register_netdev(dev)) {
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
return -EIO; return -EIO;
} }
...@@ -332,19 +327,10 @@ static void com20020_set_mc_list(struct net_device *dev) ...@@ -332,19 +327,10 @@ static void com20020_set_mc_list(struct net_device *dev)
} }
} }
void com20020_remove(struct net_device *dev)
{
unregister_netdev(dev);
free_irq(dev->irq, dev);
kfree(dev->priv);
free_netdev(dev);
}
#ifdef MODULE #ifdef MODULE
EXPORT_SYMBOL(com20020_check); EXPORT_SYMBOL(com20020_check);
EXPORT_SYMBOL(com20020_found); EXPORT_SYMBOL(com20020_found);
EXPORT_SYMBOL(com20020_remove);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
...@@ -145,20 +145,6 @@ typedef struct com20020_dev_t { ...@@ -145,20 +145,6 @@ typedef struct com20020_dev_t {
dev_node_t node; dev_node_t node;
} com20020_dev_t; } com20020_dev_t;
static void com20020_setup(struct net_device *dev)
{
struct arcnet_local *lp = dev->priv;
lp->timeout = timeout;
lp->backplane = backplane;
lp->clockp = clockp;
lp->clockm = clockm & 3;
lp->hw.owner = THIS_MODULE;
/* fill in our module parameters as defaults */
dev->dev_addr[0] = node;
}
/*====================================================================== /*======================================================================
com20020_attach() creates an "instance" of the driver, allocating com20020_attach() creates an "instance" of the driver, allocating
...@@ -188,13 +174,21 @@ static dev_link_t *com20020_attach(void) ...@@ -188,13 +174,21 @@ static dev_link_t *com20020_attach(void)
goto fail_alloc_info; goto fail_alloc_info;
dev = alloc_netdev(sizeof(struct arcnet_local), "arc%d", dev = alloc_netdev(sizeof(struct arcnet_local), "arc%d",
com20020_setup); arcdev_setup);
if (!dev) if (!dev)
goto fail_alloc_dev; goto fail_alloc_dev;
memset(info, 0, sizeof(struct com20020_dev_t)); memset(info, 0, sizeof(struct com20020_dev_t));
memset(link, 0, sizeof(struct dev_link_t)); memset(link, 0, sizeof(struct dev_link_t));
lp = dev->priv; lp = dev->priv;
lp->timeout = timeout;
lp->backplane = backplane;
lp->clockp = clockp;
lp->clockm = clockm & 3;
lp->hw.owner = THIS_MODULE;
/* fill in our module parameters as defaults */
dev->dev_addr[0] = node;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 16; link->io.NumPorts1 = 16;
...@@ -294,16 +288,15 @@ static void com20020_detach(dev_link_t *link) ...@@ -294,16 +288,15 @@ static void com20020_detach(dev_link_t *link)
if (netif_running(dev)) if (netif_running(dev))
dev->stop(dev); dev->stop(dev);
unregister_netdev(dev);
/* /*
* this is necessary because we register our IRQ separately * this is necessary because we register our IRQ separately
* from card services. * from card services.
*/ */
if (dev->irq) if (dev->irq)
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
/* ...but I/O ports are done automatically by card services */ /* ...but I/O ports are done automatically by card services */
unregister_netdev(dev);
} }
DEBUG(1,"kfree...\n"); DEBUG(1,"kfree...\n");
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
int com20020_check(struct net_device *dev); int com20020_check(struct net_device *dev);
int com20020_found(struct net_device *dev, int shared); int com20020_found(struct net_device *dev, int shared);
void com20020_remove(struct net_device *dev);
/* The number of low I/O ports used by the card. */ /* The number of low I/O ports used by the card. */
#define ARCNET_TOTAL_SIZE 8 #define ARCNET_TOTAL_SIZE 8
......
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