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 @@
* **********************
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ioport.h>
......@@ -117,49 +118,43 @@ static int __init com20020isa_probe(struct net_device *dev)
return err;
}
#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 char device[9]; /* use eg. device="arc1" to change name */
static int timeout = 3;
static int backplane = 0;
static int clockp = 0;
static int clockm = 0;
MODULE_PARM(node, "i");
MODULE_PARM(io, "i");
MODULE_PARM(irq, "i");
MODULE_PARM(device, "s");
MODULE_PARM(timeout, "i");
MODULE_PARM(backplane, "i");
MODULE_PARM(clockp, "i");
MODULE_PARM(clockm, "i");
module_param(node, int, 0);
module_param(io, int, 0);
module_param(irq, int, 0);
module_param_string(device, device, sizeof(device), 0);
module_param(timeout, int, 0);
module_param(backplane, int, 0);
module_param(clockp, int, 0);
module_param(clockm, int, 0);
MODULE_LICENSE("GPL");
int init_module(void)
static struct net_device *my_dev;
static int __init com20020_init(void)
{
struct net_device *dev;
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)
return err;
lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
if (!lp)
return -ENOMEM;
memset(lp, 0, sizeof(struct arcnet_local));
if (node && node != 0xff)
dev->dev_addr[0] = node;
lp = dev->priv;
lp->backplane = backplane;
lp->clockp = clockp & 7;
lp->clockm = clockm & 3;
......@@ -172,21 +167,24 @@ int init_module(void)
if (dev->irq == 2)
dev->irq = 9;
if (com20020isa_probe(dev))
if (com20020isa_probe(dev)) {
free_netdev(dev);
return -EIO;
}
my_dev = dev;
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);
free_netdev(my_dev);
}
#else
#ifndef MODULE
static int __init com20020isa_setup(char *s)
{
struct net_device *dev;
......@@ -196,37 +194,31 @@ static int __init com20020isa_setup(char *s)
s = get_options(s, 8, ints);
if (!ints[0])
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]) {
default: /* ERROR */
printk("com90xx: Too many arguments.\n");
case 6: /* Timeout */
lp->timeout = ints[6];
timeout = ints[6];
case 5: /* CKP value */
lp->clockp = ints[5];
clockp = ints[5];
case 4: /* Backplane flag */
lp->backplane = ints[4];
backplane = ints[4];
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->base_addr = 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 "com20020: Cannot register arcnet device\n");
snprintf(device, sizeof(device), "%s", s);
return 1;
}
__setup("com20020=", com20020isa_setup);
#endif /* MODULE */
module_init(com20020_init)
module_exit(com20020_exit)
......@@ -27,6 +27,7 @@
* **********************
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ioport.h>
......@@ -46,18 +47,18 @@
/* Module parameters */
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 backplane;
static int clockp;
static int clockm;
MODULE_PARM(node, "i");
MODULE_PARM(device, "s");
MODULE_PARM(timeout, "i");
MODULE_PARM(backplane, "i");
MODULE_PARM(clockp, "i");
MODULE_PARM(clockm, "i");
module_param(node, int, 0);
module_param_string(device, device, sizeof(device), 0);
module_param(timeout, int, 0);
module_param(backplane, int, 0);
module_param(clockp, int, 0);
module_param(clockm, int, 0);
MODULE_LICENSE("GPL");
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
if (pci_enable_device(pdev))
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)
return err;
lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
if (!lp) {
err = -ENOMEM;
goto out_dev;
}
memset(lp, 0, sizeof(struct arcnet_local));
return -ENOMEM;
lp = dev->priv;
pci_set_drvdata(pdev, dev);
// SOHARD needs PCI base addr 4
......@@ -89,6 +88,13 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
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
// ARCNET controller needs this access to detect bustype
outb(0x00,ioaddr+1);
......@@ -105,12 +111,6 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
lp->timeout = timeout;
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) {
BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, "
"but seems empty!\n", ioaddr);
......@@ -129,18 +129,18 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
out_port:
release_region(ioaddr, ARCNET_TOTAL_SIZE);
out_priv:
kfree(dev->priv);
out_dev:
kfree(dev);
free_netdev(dev);
return err;
}
static void __devexit com20020pci_remove(struct pci_dev *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);
free_netdev(dev);
}
static struct pci_device_id com20020pci_id_table[] = {
......
......@@ -172,11 +172,6 @@ int com20020_found(struct net_device *dev, int shared)
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])
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)
lp->setup >> 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);
return -EIO;
}
......@@ -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
EXPORT_SYMBOL(com20020_check);
EXPORT_SYMBOL(com20020_found);
EXPORT_SYMBOL(com20020_remove);
MODULE_LICENSE("GPL");
......
......@@ -145,20 +145,6 @@ typedef struct com20020_dev_t {
dev_node_t node;
} 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
......@@ -188,13 +174,21 @@ static dev_link_t *com20020_attach(void)
goto fail_alloc_info;
dev = alloc_netdev(sizeof(struct arcnet_local), "arc%d",
com20020_setup);
arcdev_setup);
if (!dev)
goto fail_alloc_dev;
memset(info, 0, sizeof(struct com20020_dev_t));
memset(link, 0, sizeof(struct dev_link_t));
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.NumPorts1 = 16;
......@@ -294,16 +288,15 @@ static void com20020_detach(dev_link_t *link)
if (netif_running(dev))
dev->stop(dev);
unregister_netdev(dev);
/*
* this is necessary because we register our IRQ separately
* from card services.
*/
if (dev->irq)
free_irq(dev->irq, dev);
/* ...but I/O ports are done automatically by card services */
unregister_netdev(dev);
}
DEBUG(1,"kfree...\n");
......
......@@ -29,7 +29,6 @@
int com20020_check(struct net_device *dev);
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. */
#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