Arcnet patch for 2.3.33

Martin Mares (mj@suse.cz)
Wed, 15 Dec 1999 00:35:44 +0100


Hello, world!\n

This is my experimental patch to the Arcnet driver in 2.3.33.

Changes:

o Rewrote probing. Static device number limits and kludgy manipulation
with device lists are forever gone.
o Adapted to new ISA addressing and resource management in 2.3 kernels.
o phys_to_virt() calls are gone as well.

I've tested in on my local Arcnet network, but the patch needs more testing.
If you have any Arcnet hardware, please try it and send me the result -- both
positive and negative test reports are welcome.

Currently, only the com90xx cards work. I'll modify the remaining sub-drivers
soon, but I don't have any such cards around to play -- if you do, I'll be
happy to hear that.

Martin

--- include/linux/arcdevice.h.mj Mon Dec 13 14:02:38 1999
+++ include/linux/arcdevice.h Tue Dec 14 23:25:32 1999
@@ -29,8 +29,6 @@
#define ARC_90xx 3
#define ARC_90xx_IO 4

-#define MAX_ARCNET_DEVS 8
-

/* The card sends the reconfiguration signal when it loses the connection to
* the rest of its network. It is a 'Hello, is anybody there?' cry. This
@@ -72,11 +70,6 @@
#define TX_TIMEOUT (20*HZ/100)


-/* Display warnings about the driver being an ALPHA version.
- */
-#undef ALPHA_WARNING
-
-
/* New debugging bitflags: each option can be enabled individually.
*
* These can be set while the driver is running by typing:
@@ -321,6 +314,8 @@
#ifdef CONFIG_ARCNET_1051
struct net_device *sdev; /* RFC1051 protocol device */
#endif
+
+ void *mem_start; /* ioremap'ped base address */
};

/* Functions exported by arcnet.c
@@ -341,7 +336,6 @@
#endif

extern void arcnet_tx_done(struct net_device *dev, struct arcnet_local *lp);
-extern void arcnet_makename(char *device);
extern void arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs);
extern void arcnet_setup(struct net_device *dev);
extern int arcnet_go_tx(struct net_device *dev,int enable_irq);
@@ -349,6 +343,7 @@
extern void arcnet_rx(struct arcnet_local *lp, u_char *arcsoft, short length, int saddr, int daddr);
extern void arcnet_use_count(int open);

+extern int arc90xx_probe(struct net_device *);

#endif /* __KERNEL__ */
#endif /* _LINUX_ARCDEVICE_H */
--- drivers/net/arcnet.c.mj Mon Dec 13 14:02:38 1999
+++ drivers/net/arcnet.c Wed Dec 15 00:22:21 1999
@@ -15,6 +15,11 @@

**********************

+ v3.10 (99/12/13) by Martin Mares <mj@suse.cz>
+ - Rewrote probing. Static device number limits and kludgy manipulation
+ with device lists are gone.
+ - Adapted to new ISA addressing and resource management.
+
v3.02 (98/06/07)
- Use register_netdevice() instead of register_netdev() to create
new devices for RFC1051 and Ethernet encapsulation in arcnet_open.
@@ -177,8 +182,17 @@
<jojo@repas.de>
*/

-static const char *version =
-"arcnet.c: v3.02 98/06/07 Avery Pennarun <apenwarr@worldvisions.ca> et al.\n";
+static const char * version_message =
+"arcnet.c: v3.10 99/12/13 Avery Pennarun <apenwarr@worldvisions.ca> et al.\n"
+"Available protocols: ARCnet RFC1201"
+#ifdef CONFIG_ARCNET_ETH
+ ", Ethernet-Encap"
+#endif
+#ifdef CONFIG_ARCNET_1051
+ ", ARCnet RFC1051"
+#endif
+".\n";
+

#include <linux/module.h>
#include <linux/config.h>
@@ -234,22 +248,9 @@

/* Exported function prototypes */

-#ifdef MODULE
-int init_module(void);
-void cleanup_module(void);
-#else
-int arcnet_init(void);
-static int init_module(void);
-#ifdef CONFIG_ARCNET_COM90xx
-extern char com90xx_explicit;
-extern int arc90xx_probe(struct net_device *dev);
-#endif
-#endif
-
void arcnet_tx_done(struct net_device *dev, struct arcnet_local *lp);
void arcnet_use_count(int open);
void arcnet_setup(struct net_device *dev);
-void arcnet_makename(char *device);
void arcnetA_continue_tx(struct net_device *dev);
int arcnet_go_tx(struct net_device *dev, int enable_irq);
void arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs);
@@ -259,7 +260,6 @@
EXPORT_SYMBOL(arcnet_tx_done);
EXPORT_SYMBOL(arcnet_use_count);
EXPORT_SYMBOL(arcnet_setup);
-EXPORT_SYMBOL(arcnet_makename);
EXPORT_SYMBOL(arcnetA_continue_tx);
EXPORT_SYMBOL(arcnet_go_tx);
EXPORT_SYMBOL(arcnet_interrupt);
@@ -1855,15 +1855,21 @@

/****************************************************************************
* *
- * Kernel Loadable Module Support *
+ * Kernel Loadable Module Support and Initialization *
* *
****************************************************************************/

#ifdef MODULE

+int init_module(void)
+{
+ printk("%sarcnet: Don't forget to load the chipset driver.\n", version_message);
+ return 0;
+}
+
void cleanup_module(void)
{
- printk("Generic arcnet support removed.\n");
+ printk("arcnet: Generic arcnet support removed.\n");
}

void arcnet_use_count(int open)
@@ -1880,102 +1886,16 @@
{
}

-struct net_device arcnet_devs[MAX_ARCNET_DEVS];
-int arcnet_num_devs = 0;
-char arcnet_dev_names[MAX_ARCNET_DEVS][10];
-
int __init arcnet_init(void)
{
- int c;
-
- init_module();
-
- /* Don't register_netdev here. The chain hasn't been initialised. */
-
+ printk(version_message);
#ifdef CONFIG_ARCNET_COM90xx
- if ((!com90xx_explicit) && arcnet_num_devs < MAX_ARCNET_DEVS) {
- arcnet_devs[arcnet_num_devs].init = arc90xx_probe;
- arcnet_devs[arcnet_num_devs].name =
- (char *) &arcnet_dev_names[arcnet_num_devs];
- arcnet_num_devs++;
- }
-#endif
-
- if (!arcnet_num_devs) {
- printk("Don't forget to load the chipset driver.\n");
- return 0;
- }
- /* Link into the device chain */
-
- /* Q: Should we put ourselves at the beginning or the end of the chain? */
- /* Probably the end, because we're not so fast, but... */
-
- for (c = 0; c < (arcnet_num_devs - 1); c++)
- arcnet_devs[c].next = &arcnet_devs[c + 1];
-
- write_lock_bh(&dev_base_lock);
- arcnet_devs[c].next = dev_base;
- dev_base = &arcnet_devs[0];
- write_unlock_bh(&dev_base_lock);
-
- /* Give names to those without them */
-
- for (c = 0; c < arcnet_num_devs; c++)
- if (!arcnet_dev_names[c][0])
- arcnet_makename((char *) &arcnet_dev_names[c]);
- return 0;
-}
-
-#endif /* MODULE */
-
-
-#ifdef MODULE
-int init_module(void)
-#else
-static int __init init_module(void)
-#endif
-{
-#ifdef ALPHA_WARNING
- BUGLVL(D_EXTRA) {
- printk("arcnet: ***\n");
- printk("arcnet: * Read arcnet.txt for important release notes!\n");
- printk("arcnet: *\n");
- printk("arcnet: * This is an ALPHA version! (Last stable release: v2.56) E-mail me if\n");
- printk("arcnet: * you have any questions, comments, or bug reports.\n");
- printk("arcnet: ***\n");
- }
+ arc90xx_probe(NULL);
#endif
-
- printk("%sAvailable protocols: ARCnet RFC1201"
-#ifdef CONFIG_ARCNET_ETH
- ", Ethernet-Encap"
-#endif
-#ifdef CONFIG_ARCNET_1051
- ", ARCnet RFC1051"
-#endif
-#ifdef MODULE
- ".\nDon't forget to load the chipset driver"
+#if !defined(CONFIG_ARCNET_COM90xx) && !defined(CONFIG_ARCNET_COM90xxIO) && !defined(CONFIG_ARCNET_RIM_I) && !defined(CONFIG_ARCNET_COM20020)
+ printk("arcnet: Don't forget to load chipset driver.\n");
#endif
- ".\n", version);
return 0;
}

-
-void arcnet_makename(char *device)
-{
- struct net_device *dev;
- int arcnum;
-
- arcnum = 0;
- for (;;) {
- sprintf(device, "arc%d", arcnum);
- read_lock_bh(&dev_base_lock);
- for (dev = dev_base; dev; dev = dev->next)
- if (dev->name != device && !strcmp(dev->name, device))
- break;
- read_unlock_bh(&dev_base_lock);
- if (!dev)
- return;
- arcnum++;
- }
-}
+#endif /* MODULE */
--- drivers/net/com90xx.c.mj Mon Dec 13 14:02:38 1999
+++ drivers/net/com90xx.c Wed Dec 15 00:16:40 1999
@@ -45,6 +45,7 @@
#include <linux/init.h>
#include <linux/if_arcnet.h>
#include <linux/arcdevice.h>
+#include <linux/bootmem.h>

#include <asm/system.h>
#include <asm/bitops.h>
@@ -88,12 +89,8 @@


/* Internal function declarations */
-#ifdef MODULE
-static
-#endif
-int arc90xx_probe(struct net_device *dev);
static void arc90xx_rx(struct net_device *dev, int recbuf);
-static int arc90xx_found(struct net_device *dev, int ioaddr, int airq, void * shmem, int more);
+static int arc90xx_found(struct net_device *dev, int ioaddr, int airq, unsigned int shmem);
static void arc90xx_inthandler(struct net_device *dev);
static int arc90xx_reset(struct net_device *dev, int reset_delay);
static void arc90xx_setmask(struct net_device *dev, u_char mask);
@@ -103,34 +100,15 @@
char *data, int length, int daddr, int exceptA, int offset);
static void arc90xx_openclose(int open);

-
-/* Module parameters */
-
-#ifdef MODULE
-static int io = 0x0; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
-static int irq = 0; /* or use the insmod io= irq= shmem= options */
-static int shmem = 0;
-static char *device; /* use eg. device="arc1" to change name */
-
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(shmem, "i");
-MODULE_PARM(device, "s");
-#else
-void __init com90xx_setup(char *str, int *ints);
-char __initdata com90xx_explicit = 0;
-
-extern struct net_device arcnet_devs[];
-extern char arcnet_dev_names[][10];
-extern int arcnet_num_devs;
-#endif
-
-
/* Handy defines for ARCnet specific stuff */

-/* 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 16

+/* Amount of I/O memory used by the card */
+#define BUFFER_SIZE (512)
+#define MIRROR_SIZE (BUFFER_SIZE*4)
+
/* COM 9026 controller chip --> ARCnet register addresses */
#define _INTMASK (ioaddr+0) /* writable */
#define _STATUS (ioaddr+0) /* readable */
@@ -150,7 +128,7 @@
#define ARCRESET inb(_RESET)

static const char *version =
-"com90xx.c: v3.00 97/11/09 Avery Pennarun <apenwarr@worldvisions.ca> et al.\n";
+"com90xx.c: v3.10 99/12/13 Avery Pennarun <apenwarr@worldvisions.ca> et al.\n";


/****************************************************************************
@@ -159,61 +137,37 @@
* *
****************************************************************************/

-/* Check for an ARCnet network adaptor, and return '0' if one exists.
- * If dev->base_addr == 0, probe all likely locations.
- * If dev->base_addr == 1, always return failure.
- * If dev->base_addr == 2, allocate space for the device and return success
- * (detachable devices only).
- *
- * NOTE: the list of possible ports/shmems is static, so it is retained
- * across calls to arcnet_probe. So, if more than one ARCnet probe is made,
- * values that were discarded once will not even be tried again.
- *
- * FIXME: grab all devices in one shot and eliminate the big static array.
- */
-
-static int ports[(0x3f0 - 0x200) / 16 + 1] __initdata = {
- 0
-};
-static void * shmems[(0xFF800 - 0xA0000) / 2048 + 1] __initdata = {
- 0
-};
+static int arc90xx_skip_probe __initdata = 0;

int __init arc90xx_probe(struct net_device *dev)
{
- static int init_once = 0;
- static int numports = sizeof(ports) / sizeof(ports[0]), numshmems = sizeof(shmems) / sizeof(shmems[0]);
+ int ports[(0x3f0 - 0x200) / 16 + 1];
+ unsigned int shmems[(0xFF800 - 0xA0000) / 2048 + 1];
+ int numports, numshmems;
int count, status, delayval, ioaddr, numprint, airq, retval = -ENODEV,
openparen = 0;
unsigned long airqmask;
int *port;
- void **shmem;
+ unsigned int *shmem;
+ static int arc90xx_inited __initdata = 0;

- if (!init_once) {
+ if (!arc90xx_inited++)
+ BUGLVL(D_NORMAL) printk(version);
+ if (!dev && arc90xx_skip_probe)
+ return -ENODEV;
+
+ numports = numshmems = 0;
+ if (dev && dev->base_addr)
+ ports[numports++] = dev->base_addr;
+ else
for (count = 0x200; count <= 0x3f0; count += 16)
- ports[(count - 0x200) / 16] = count;
+ ports[numports++] = count;
+ if (dev && dev->mem_start)
+ shmems[numshmems++] = dev->mem_start;
+ else
for (count = 0xA0000; count <= 0xFF800; count += 2048)
- shmems[(count - 0xA0000) / 2048] = ioremap(count, 2048);
- BUGLVL(D_NORMAL) printk(version);
- BUGMSG(D_DURING, "space used for probe buffers: %d+%d=%d bytes\n",
- sizeof(ports), sizeof(shmems),
- sizeof(ports) + sizeof(shmems));
- }
- init_once++;
-
- BUGMSG(D_INIT, "given: base %lXh, IRQ %d, shmem %lXh\n",
- dev->base_addr, dev->irq, dev->mem_start);
-
- if (dev->base_addr > 0x1ff) { /* Check a single specified port */
- ports[0] = dev->base_addr;
- numports = 1;
- } else if (dev->base_addr > 0) /* Don't probe at all. */
- return -ENXIO;
-
- if (dev->mem_start) {
- shmems[0] = ioremap(dev->mem_start, 2048);
- numshmems = 1;
- }
+ shmems[numshmems++] = count;
+
/* Stage 1: abandon any reserved ports, or ones with status==0xFF
* (empty), and reset any others by reading the reset port.
*/
@@ -284,7 +238,7 @@
BUGMSG(D_INIT, "Stage 3: ");
numprint = 0;
for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
- void * ptr;
+ void *ptr;

numprint++;
if (numprint > 8) {
@@ -292,10 +246,19 @@
BUGMSG(D_INIT, "Stage 3: ");
numprint = 1;
}
- BUGMSG2(D_INIT, "%ph ", *shmem);
+ BUGMSG2(D_INIT, "%Xh ", *shmem);

- ptr = *shmem;
+ if (check_mem_region(*shmem, BUFFER_SIZE)) {
+ BUGMSG2(D_INIT_REASONS, "(check_mem_region)\n");
+ BUGMSG(D_INIT_REASONS, "Stage 3: ");
+ BUGLVL(D_INIT_REASONS) numprint = 0;
+ *shmem = shmems[numshmems - 1];
+ numshmems--;
+ shmem--;
+ continue;
+ }

+ ptr = ioremap(*shmem, 2048);
if (readb(ptr) != TESTvalue) {
BUGMSG2(D_INIT_REASONS, "(mem=%02Xh, not %02Xh)\n",
readb(ptr), TESTvalue);
@@ -342,7 +305,7 @@
BUGMSG(D_INIT, "Stage 4: ");
numprint = 1;
}
- BUGMSG2(D_INIT, "%ph ", *shmem);
+ BUGMSG2(D_INIT, "%Xh ", *shmem);
}
BUGMSG2(D_INIT, "\n");

@@ -392,7 +355,7 @@
/* skip this completely if an IRQ was given, because maybe
* we're on a machine that locks during autoirq!
*/
- if (!dev->irq) {
+ if (!dev || !dev->irq) {
/* if we do this, we're sure to get an IRQ since the
* card has just reset and the NORXflag is on until
* we tell it to start receiving.
@@ -431,7 +394,7 @@
JIFFER(RESETtime);
} else {
/* just one shmem and port, assume they match */
- writeb(TESTvalue, shmems[0]);
+ isa_writeb(TESTvalue, shmems[0]);
}
#else
ARCRESET;
@@ -439,20 +402,12 @@
#endif

for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
- void * ptr;
- ptr = *shmem;
-
- if (readb(ptr) == TESTvalue) { /* found one */
- int probe_more;
- BUGMSG2(D_INIT, "%ph)\n", *shmem);
+ if (isa_readb(*shmem) == TESTvalue) { /* found one */
+ BUGMSG2(D_INIT, "%Xh)\n", *shmem);
openparen = 0;

/* register the card */
- if (init_once == 1 && numshmems > 1)
- probe_more = numshmems - 1;
- else
- probe_more = 0;
- retval = arc90xx_found(dev, *port, airq, *shmem, probe_more);
+ retval = arc90xx_found(dev, *port, airq, *shmem);
if (retval)
openparen = 0;

@@ -462,7 +417,7 @@

break;
} else {
- BUGMSG2(D_INIT_REASONS, "%Xh-", readb(ptr));
+ BUGMSG2(D_INIT_REASONS, "%Xh-", isa_readb(*shmem));
}
}

@@ -474,16 +429,13 @@
*port = ports[numports - 1];
numports--;
port--;
-
- if (!retval)
- break;
}
BUGMSG(D_INIT_REASONS, "\n");

/* Now put back TESTvalue on all leftover shmems.
*/
for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++)
- writeb(TESTvalue, *shmem);
+ isa_writeb(TESTvalue, *shmem);

if (retval)
BUGMSG(D_NORMAL, "Stage 5: No ARCnet cards found.\n");
@@ -493,57 +445,65 @@
/* Set up the struct net_device associated with this card. Called after
* probing succeeds.
*/
-static int __init arc90xx_found(struct net_device *dev, int ioaddr, int airq, void * shmem, int more)
+static int __init arc90xx_found(struct net_device *dev0, int ioaddr, int airq, unsigned int shmem)
{
+ struct net_device *dev = dev0;
struct arcnet_local *lp;
- void *first_mirror, *last_mirror;
- int mirror_size;
+ unsigned int first_mirror, last_mirror;
+ int mirror_size, err;
+
+ /* allocate struct net_device if we don't have one yet */
+ if (!dev && !(dev = dev_alloc("arc%d", &err))) {
+ BUGMSG(D_NORMAL, "Can't allocate device!\n");
+ return err;
+ }

/* reserve the irq */
- if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
+ if (request_irq(airq, &arcnet_interrupt, 0, dev->name, dev)) {
BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
return -ENODEV;
}
dev->irq = airq;

/* reserve the I/O region - guaranteed to work by check_region */
- request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (90xx)");
+ request_region(ioaddr, ARCNET_TOTAL_SIZE, dev->name);
dev->base_addr = ioaddr;

/* find the real shared memory start/end points, including mirrors */
-#define BUFFER_SIZE (512)
-#define MIRROR_SIZE (BUFFER_SIZE*4)

/* guess the actual size of one "memory mirror" - the number of
* bytes between copies of the shared memory. On most cards, it's
* 2k (or there are no mirrors at all) but on some, it's 4k.
*/
mirror_size = MIRROR_SIZE;
- if (readb(shmem) == TESTvalue
- && readb(shmem - mirror_size) != TESTvalue
- && readb(shmem - 2 * mirror_size) == TESTvalue)
+ if (isa_readb(shmem) == TESTvalue
+ && isa_readb(shmem - mirror_size) != TESTvalue
+ && isa_readb(shmem - 2 * mirror_size) == TESTvalue)
mirror_size *= 2;

first_mirror = last_mirror = shmem;
- while (readb(first_mirror) == TESTvalue)
+ while (isa_readb(first_mirror) == TESTvalue)
first_mirror -= mirror_size;
first_mirror += mirror_size;

- while (readb(last_mirror) == TESTvalue)
+ while (isa_readb(last_mirror) == TESTvalue)
last_mirror += mirror_size;
last_mirror -= mirror_size;

- dev->mem_start = (unsigned long) first_mirror;
- dev->mem_end = (unsigned long) last_mirror + MIRROR_SIZE - 1;
+ dev->mem_start = first_mirror;
+ dev->mem_end = last_mirror + MIRROR_SIZE - 1;
dev->rmem_start = dev->mem_start + BUFFER_SIZE * 0;
dev->rmem_end = dev->mem_start + BUFFER_SIZE * 2 - 1;

+ request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, dev->name);
+
/* Initialize the rest of the device structure. */

dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
if (dev->priv == NULL) {
free_irq(airq, dev);
release_region(ioaddr, ARCNET_TOTAL_SIZE);
+ release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
return -ENOMEM;
}
memset(dev->priv, 0, sizeof(struct arcnet_local));
@@ -557,6 +517,7 @@
lp->openclose_device = arc90xx_openclose;
lp->prepare_tx = arc90xx_prepare_tx;
lp->inthandler = arc90xx_inthandler;
+ lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);

/* Fill in the fields of the device structure with generic
* values.
@@ -575,7 +536,7 @@
sizeof(struct archdr));

/* get and check the station ID from offset 1 in shmem */
- lp->stationid = readb(first_mirror + 1);
+ lp->stationid = readb(lp->mem_start + 1);

if (lp->stationid == 0)
BUGMSG(D_NORMAL, "WARNING! Station address 00 is reserved "
@@ -591,27 +552,8 @@
dev->base_addr, dev->irq, dev->mem_start,
(dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);

- /* OK. We're finished. If there are probably other cards, add other
- * COM90xx drivers to the device chain, so they get probed later.
- */
-
-#ifndef MODULE
- while (!com90xx_explicit && more--) {
- if (arcnet_num_devs < MAX_ARCNET_DEVS) {
- arcnet_devs[arcnet_num_devs].next = dev->next;
- dev->next = &arcnet_devs[arcnet_num_devs];
- dev = dev->next;
- dev->name = (char *) &arcnet_dev_names[arcnet_num_devs];
- arcnet_num_devs++;
- } else {
- BUGMSG(D_NORMAL, "Too many arcnet devices - no more will be probed for.\n");
- return 0;
- }
- arcnet_makename(dev->name);
- dev->init = arc90xx_probe;
- }
-#endif
-
+ if (!dev0)
+ register_netdev(dev);
return 0;
}

@@ -649,7 +591,7 @@
ACOMMAND(CFLAGScmd | CONFIGclear);

/* verify that the ARCnet signature byte is present */
- if (readb(dev->mem_start) != TESTvalue) {
+ if (readb(lp->mem_start) != TESTvalue) {
BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
return 1;
}
@@ -663,7 +605,7 @@
#ifndef SLOW_XMIT_COPY
/* clean out all the memory to make debugging make more sense :) */
BUGLVL(D_DURING)
- memset_io(dev->mem_start, 0x42, 2048);
+ memset_io(lp->mem_start, 0x42, 2048);
#endif

/* and enable receive of our first packet to the first buffer */
@@ -914,7 +856,7 @@
struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
int ioaddr = dev->base_addr;
union ArcPacket *arcpacket =
- (union ArcPacket *) phys_to_virt(dev->mem_start + recbuf * 512);
+ (union ArcPacket *) (lp->mem_start + recbuf * 512);
u_char *arcsoft;
short length, offset;
u_char daddr, saddr;
@@ -967,7 +909,7 @@
{
struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
union ArcPacket *arcpacket =
- (union ArcPacket *) phys_to_virt(dev->mem_start + 512 * (lp->txbuf ^ 1));
+ (union ArcPacket *) (lp->mem_start + 512 * (lp->txbuf ^ 1));

#ifdef SLOW_XMIT_COPY
char *iptr, *iend, *optr;
@@ -983,7 +925,7 @@
#ifndef SLOW_XMIT_COPY
/* clean out the page to make debugging make more sense :) */
BUGLVL(D_DURING)
- memset_io(dev->mem_start + lp->txbuf * 512, 0x42, 512);
+ memset_io(lp->mem_start + lp->txbuf * 512, 0x42, 512);
#endif

arcpacket->hardheader.destination = daddr;
@@ -1045,30 +987,37 @@

/****************************************************************************
* *
- * Kernel Loadable Module Support *
+ * Kernel Loadable Module Support and Setup *
* *
****************************************************************************/


#ifdef MODULE

-static char devicename[9] = "";
-static struct net_device thiscard =
-{
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0, 0, /* I/O address, IRQ */
- 0, 0, 0, NULL, arc90xx_probe
-};
+/* Module parameters */
+
+static int io = 0x0; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
+static int irq = 0; /* or use the insmod io= irq= shmem= options */
+static int shmem = 0;
+static char *device; /* use eg. device="arc1" to change name */

+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(shmem, "i");
+MODULE_PARM(device, "s");
+
+static struct net_device *thiscard;

int init_module(void)
{
- struct net_device *dev = &thiscard;
+ struct net_device *dev;
+ int err;
+
+ thiscard = dev = dev_alloc("arc%d", &err);
+ if (!dev)
+ return err;
if (device)
strcpy(dev->name, device);
- else
- arcnet_makename(dev->name);

dev->base_addr = io;

@@ -1076,12 +1025,10 @@
if (dev->irq == 2)
dev->irq = 9;

- if (shmem) {
+ if (shmem)
dev->mem_start = shmem;
- dev->mem_end = thiscard.mem_start + 512 * 4 - 1;
- dev->rmem_start = thiscard.mem_start + 512 * 0;
- dev->rmem_end = thiscard.mem_start + 512 * 2 - 1;
- }
+
+ dev->init = arc90xx_probe;
if (register_netdev(dev) != 0)
return -EIO;
arcnet_use_count(1);
@@ -1090,7 +1037,7 @@

void cleanup_module(void)
{
- struct net_device *dev = &thiscard;
+ struct net_device *dev = thiscard;
int ioaddr = dev->mem_start;

if (dev->start)
@@ -1098,7 +1045,7 @@

/* Flush TX and disable RX */
if (ioaddr) {
- AINTMASK(0); /* disable IRQ's */
+ AINTMASK(0); /* disable IRQ's */
ACOMMAND(NOTXcmd); /* stop transmit */
ACOMMAND(NORXcmd); /* disable receive */

@@ -1108,11 +1055,12 @@
outb((inb(_CONFIG) & ~IOMAPflag), _CONFIG);
#endif
}
- if (dev->irq) {
+ if (dev->irq)
free_irq(dev->irq, dev);
- }
- if (dev->base_addr)
+ if (dev->base_addr) {
release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+ release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+ }
unregister_netdev(dev);
kfree(dev->priv);
dev->priv = NULL;
@@ -1121,28 +1069,27 @@

#else

-void __init com90xx_setup(char *str, int *ints)
+static int __init arc90xx_setup(char *s)
{
struct net_device *dev;
+ int ints[8];

- if (arcnet_num_devs == MAX_ARCNET_DEVS) {
- printk("com90xx: Too many ARCnet devices registered (max %d).\n",
- MAX_ARCNET_DEVS);
- return;
- }
- if (!ints[0] && (!str || !*str)) {
+ arc90xx_skip_probe = 1;
+
+ s = get_options(s, 8, ints);
+ if (!ints[0] && !*s) {
printk("com90xx: Disabled.\n");
- com90xx_explicit++;
- return;
+ return 1;
}
- dev = &arcnet_devs[arcnet_num_devs];

- dev->dev_addr[3] = 3;
+ dev = alloc_bootmem(sizeof(struct net_device) + 10);
+ memset(dev, 0, sizeof(struct net_device) + 10);
+ dev->name = (char *) (dev+1);
dev->init = arc90xx_probe;

switch (ints[0]) {
case 4: /* ERROR */
- printk("com20020: Too many arguments.\n");
+ printk("com90xx: Too many arguments.\n");

case 3: /* Mem address */
dev->mem_start = ints[3];
@@ -1153,12 +1100,16 @@
case 1: /* IO address */
dev->base_addr = ints[1];
}
+ if (*s)
+ strncpy(dev->name, s, 9);
+ else
+ strcpy(dev->name, "arc%d");
+ if (register_netdev(dev))
+ printk(KERN_ERR "com90xx: Cannot register arcnet device\n");

- dev->name = (char *) &arcnet_dev_names[arcnet_num_devs];
+ return 1;
+}

- if (str)
- strncpy(dev->name, str, 9);
+__setup("com90xx=", arc90xx_setup);

- arcnet_num_devs++;
-}
#endif /* MODULE */

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/