patch-2.1.14 linux/drivers/net/arcnet.c
Next file: linux/drivers/net/wavelan.c
Previous file: linux/drivers/net/3c509.c
Back to the patch index
Back to the overall index
- Lines: 1037
- Date:
Sun Dec 1 09:47:18 1996
- Orig file:
v2.1.13/linux/drivers/net/arcnet.c
- Orig date:
Tue Oct 29 19:58:11 1996
diff -u --recursive --new-file v2.1.13/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c
@@ -17,114 +17,38 @@
**********************
+ v2.60 ALPHA (96/11/23)
+ - Added patch from Vojtech Pavlik <vojtech@atrey.karlin.mff.cuni.cz>
+ and Martin Mares <mj@k332.feld.cvut.cz> to make the driver work
+ with the new Linux 2.1.x memory management. I modified their
+ patch quite a bit though; bugs are my fault. More changes should
+ be made to get eliminate any remaining phys_to_virt calls.
+ - Quietly ignore protocol id's 0, 1, 8, and 243. Thanks to Jake
+ Messinger <jake@ams.com> for reporting these codes and their
+ meanings.
+ - Smarter shmem probe for cards with 4k mirrors. (does it work?)
+ - Initial support for RIM I type cards which use no I/O ports at
+ all. To use this option, you need to compile with RIM_I_MODE
+ enabled. Thanks to Kolja Waschk <kawk@yo.com> for explaining
+ RIM I programming to me. Now, does my RIM I code actually
+ work?
+
v2.56 (96/10/18)
- Turned arc0e/arc0s startup messages back on by default, as most
people will probably not notice the additional devices
- otherwise, and experience more protocol confusion than
- necessary.
+ otherwise. This causes undue confusion.
- Fixed a tiny but noticeable bug in the packet debugging routines
(thanks Tomasz)
- v2.55 (96/08/05)
- - A couple more messages moved to D_EXTRA.
- - SLOW_XMIT_COPY off by default.
- - Some tiny changes.
-
- v2.54 (96/07/05)
- - Under some situations, Stage 5 autoprobe was a little bit too
- picky about the TXACK flag.
- - D_EXTRA removed from default debugging flags. Hey, it's stable,
- right?
- - Removed redundant "unknown protocol ID" messages and made remaining
- ones D_EXTRA.
-
- v2.53 (96/06/06)
- - arc0e and arc0s wouldn't initialize in newer kernels, which
- don't like dev->open==NULL or dev->stop==NULL.
-
- v2.52 (96/04/20)
- - Replaced more decimal node ID's with hex, for consistency.
- - Changed a couple of printk debug levels.
-
- v2.51 (96/02/29)
- - Inserted a rather important missing "volatile" in autoprobe.
- - arc0e and arc0s are now options in drivers/net/Config.in.
-
- v2.50 (96/02/24)
- - Increased IRQ autoprobe delay. Thanks to Andrew J. Kroll for
- noticing the problem, which seems to only affect certain cards.
- - Errors reserving ports and IRQ's now clean up after themselves.
- - We now replace the TESTvalue byte from unused shmem addresses.
- - You can now use "irq=" as well as "irqnum=" to set the IRQ
- during module autoprobe. This doesn't seem to crash insmod
- anymore. (?)
- - You can now define the name of the ARCnet device more easily
- when loading the module: insmod arcnet.o device=test1
- A new option, CONFIG_ARCNET_ETHNAME, allows the kernel to
- choose one of the standard eth?-style device names
- automatically. This currently only works as a module.
- - printk's now try to make some use of the KERN_xxx priority level
- macros (though they may not be perfect yet).
- - Packet and skb dump loops are now separate functions.
- - Removed D_INIT from default debug level, because I am (finally)
- pretty confident that autoprobe shouldn't toast anyone's
- computer.
- - This version is no longer ALPHA.
-
- v2.41 ALPHA (96/02/10)
- - Incorporated changes someone made to arcnet_setup in 1.3.60.
- - Increased reset timeout to 3/10 of a second because some cards
- are too slow.
- - Removed a useless delay from autoprobe stage 4; I wonder
- how that got there! (oops)
- - If FAST_IFCONFIG is defined, don't reset the card during
- arcnet_open; rather, do it in arcnet_close but don't delay.
- This speeds up calls to ifconfig up/down. (Thanks to Vojtech
- for the idea to speed this up.)
- - If FAST_PROBE is defined, don't bother to reset the card in
- autoprobe Stage 5 when there is only one io port and one shmem
- left in the list. They "obviously" correspond to each other.
- Another good idea from Vojtech.
-
- v2.40 ALPHA (96/02/03)
- - Checked the RECON flag last in the interrupt handler (when
- enabled) so the flag will show up in "status" when reporting
- other errors. (I had a cabling problem that was hard to notice
- until I saw the huge RECON count in /proc/net/dev.)
- - Moved "IRQ for unknown device" message to D_DURING.
- - "transmit timed out" and "not acknowledged" messages are
- now D_EXTRA, because they very commonly happen when things
- are working fine. "transmit timed out" due to missed IRQ's
- is still D_NORMAL, because it's probably a bug.
- - "Transmit timed out" messages now include destination station id.
- - The virtual arc0e and arc0s devices can now be disabled.
- Massive (but simple) code rearrangement to support this with
- fewer ifdef's.
- - SLOW_XMIT_COPY option so fast computers don't hog the bus. It's
- weird, but it works.
- - Finally redesigned autoprobe after some discussion with Vojtech
- Pavlik <Vojtech.Pavlik@st.mff.cuni.cz>. It should be much safer
- and more reliable now, I think. We now probe several more io
- ports and many more shmem addresses.
- - Rearranged D_* debugging flags slightly. Watch out! There is
- now a new flag, disabled by default, that will tell you the
- reason a particular port or shmem is discarded from the list.
-
- v2.30 ALPHA (96/01/10)
- - Abandoned support for Linux 1.2 to simplify coding and allow me
- to take advantage of new features in 1.3.
- - Updated cabling/jumpers documentation with MUCH information that
- people have recently (and in some cases, not so recently) sent
- me. I don't mind writing documentation, but the jumpers
- database is REALLY starting to get dull.
- - Autoprobing works as a module now - but ONLY with my fix to
- register_netdev and unregister_netdev. It's also much faster,
- and uses the "new-style" IRQ autoprobe routines. Autoprobe is
- still a horrible mess and will be cleaned up further as time
- passes.
-
The following has been SUMMARIZED. The complete ChangeLog is
- available in the full Linux-ARCnet package.
+ available in the full Linux-ARCnet package at
+ http://www.foxnet.net/~apenwarr/arcnet
+
+ v2.50 (96/02/24)
+ - Massively improved autoprobe routines; they now work even as a
+ module. Thanks to Vojtech Pavlik <Vojtech.Pavlik@st.mff.cuni.cz>
+ for his ideas and help in this area.
+ - Changed printk's around quite a lot.
v2.22 (95/12/08)
- Major cleanups, speedups, and better code-sharing.
@@ -164,17 +88,20 @@
v1.00 (95/02/15)
- Initial non-alpha release.
-
+
TO DO: (semi-prioritized)
+ - Use cleaner "architecture-independent" shared memory access.
+ This is half-done in ARCnet 2.60, but still uses some
+ undocumented i386 stuff. (We shouldn't call phys_to_virt,
+ for example.)
- Support "arpless" mode like NetBSD does, and as recommended
by the (obsoleted) RFC1051.
+ - Some way to make RIM_I_MODE runtime switchable? Yuck...
- Smarter recovery from RECON-during-transmit conditions. (ie.
retransmit immediately)
- Make arcnetE_send_packet use arcnet_prepare_tx for loading the
packet into ARCnet memory.
- - Some cards have shared memory with 4k mirrors instead of just 2k,
- so we (uneventfully) find the "wrong" shmem when probing.
- Probe for multiple devices in one shot (trying to decide whether
to do it the "ugly" way or not).
- Add support for the new 1.3.x IP header cache, and other features.
@@ -210,7 +137,7 @@
*/
static const char *version =
- "arcnet.c: v2.56 96/10/18 Avery Pennarun <apenwarr@foxnet.net>\n";
+ "arcnet.c: v2.60 96/11/23 Avery Pennarun <apenwarr@foxnet.net>\n";
@@ -245,6 +172,12 @@
/**************************************************************************/
+/* Define this if you have a really ancient "RIM I" ARCnet card with no I/O
+ * port at all and _only_ shared memory; this option MAY work for you. It's
+ * untested, though, so good luck and write to me with any results!
+ */
+#undef RIM_I_MODE
+
/* Normally, the ARCnet device needs to be assigned a name (default arc0).
* Ethernet devices have a function to automatically try eth0, eth1, etc
* until a free name is found. To name the ARCnet device using an "eth?"
@@ -367,7 +300,7 @@
#endif
#ifndef ARCNET_DEBUG
-#define ARCNET_DEBUG (D_NORMAL)
+#define ARCNET_DEBUG (D_NORMAL|D_EXTRA)
#endif
int arcnet_debug = ARCNET_DEBUG;
@@ -409,15 +342,33 @@
/* The number of low I/O ports used by the ethercard. */
#define ARCNET_TOTAL_SIZE 16
-
/* Handy defines for ARCnet specific stuff */
/* COM 9026 controller chip --> ARCnet register addresses */
-#define INTMASK (ioaddr+0) /* writable */
-#define STATUS (ioaddr+0) /* readable */
-#define COMMAND (ioaddr+1) /* writable, returns random vals on read (?) */
-#define RESET (ioaddr+8) /* software reset writable */
+#define _INTMASK (ioaddr+0) /* writable */
+#define _STATUS (ioaddr+0) /* readable */
+#define _COMMAND (ioaddr+1) /* writable, returns random vals on read (?) */
+#define _RESET (ioaddr+8) /* software reset (on read) */
+
+/* RIM I (command/status is memory mapped) versus RIM III (standard I/O
+ * mapped) macros. These make things a bit cleaner.
+ */
+#ifdef RIM_I_MODE
+ #define IOADDR (dev->mem_start+0x800)
+ #define ARCSTATUS readb(_STATUS)
+ #define ACOMMAND(cmd) writeb((cmd),_COMMAND)
+ #define ARCRESET writeb(TESTvalue,ioaddr-0x800) /* fake reset */
+ #define AINTMASK(msk) writeb((msk),_INTMASK)
+ #define RELEASE_REGION(x,y) /* nothing */
+#else
+ #define IOADDR (dev->base_addr)
+ #define ARCSTATUS inb(_STATUS)
+ #define ACOMMAND(cmd) outb((cmd),_COMMAND)
+ #define AINTMASK(msk) outb((msk),_INTMASK)
+ #define ARCRESET inb(_RESET)
+ #define RELEASE_REGION(x,y) release_region((x),(y))
+#endif
-#define SETMASK outb(lp->intmask,INTMASK);
+#define SETMASK AINTMASK(lp->intmask)
/* Time needed to reset the card - in jiffies. This works on my SMC
* PC100. I can't find a reference that tells me just how long I
@@ -479,7 +430,7 @@
/* Starts receiving packets into recbuf.
*/
-#define EnableReceiver() outb(RXcmd|(recbuf<<3)|RXbcasts,COMMAND)
+#define EnableReceiver() ACOMMAND(RXcmd|(recbuf<<3)|RXbcasts)
/* RFC1201 Protocol ID's */
#define ARC_P_IP 212 /* 0xD4 */
@@ -496,6 +447,10 @@
#define ARC_P_ETHER 0xE8
/* Unsupported/indirectly supported protocols */
+#define ARC_P_DATAPOINT_BOOT 0 /* very old Datapoint equipment */
+#define ARC_P_DATAPOINT_MOUNT 1
+#define ARC_P_POWERLAN_BEACON 8 /* Probably ATA-Netbios related */
+#define ARC_P_POWERLAN_BEACON2 243
#define ARC_P_LANSOFT 251 /* 0xFB - what is this? */
#define ARC_P_ATALK 0xDD
@@ -750,7 +705,40 @@
* Probe and initialization *
* *
****************************************************************************/
-
+
+#ifdef RIM_I_MODE
+
+/* We cannot probe for a RIM I card; one reason is I don't know how to reset
+ * them. In fact, we can't even get their node ID automatically. So, we
+ * need to be passed a specific shmem address, IRQ, and node ID (stored in
+ * dev->base_addr)
+ */
+int arcnet_probe(struct device *dev)
+{
+ BUGLVL(D_NORMAL) printk(version);
+ BUGMSG(D_NORMAL,"Compiled for ARCnet RIM I (autoprobe disabled)\n");
+ BUGMSG(D_NORMAL,"Given: node %02lXh, shmem %lXh, irq %d\n",
+ dev->base_addr,dev->mem_start,dev->irq);
+
+ if (dev->mem_start<=0 || dev->irq<=0)
+ {
+ BUGMSG(D_NORMAL,"No autoprobe for RIM I; you "
+ "must specify the shmem and irq!\n");
+ return -ENODEV;
+ }
+
+ if (dev->base_addr<=0 || dev->base_addr>255)
+ {
+ BUGMSG(D_NORMAL,"You need to specify your card's station "
+ "ID!\n");
+ return -ENODEV;
+ }
+
+ return arcnet_found(dev,dev->base_addr,dev->irq,dev->mem_start);
+}
+
+#else /* not RIM_I_MODE, so use a real autoprobe */
+
/* 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.
@@ -793,13 +781,13 @@
sizeof(ports)+sizeof(shmems));
-#if 0
+#if 1
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.22) E-mail me if\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");
}
@@ -852,7 +840,7 @@
continue;
}
- if (inb(STATUS) == 0xFF)
+ if (ARCSTATUS == 0xFF)
{
BUGMSG2(D_INIT_REASONS,"(empty)\n");
BUGMSG(D_INIT_REASONS,"Stage 1: ");
@@ -863,7 +851,7 @@
continue;
}
- inb(RESET); /* begin resetting card */
+ ARCRESET; /* begin resetting card */
BUGMSG2(D_INIT_REASONS,"\n");
BUGMSG(D_INIT_REASONS,"Stage 1: ");
@@ -906,8 +894,8 @@
numprint=0;
for (shmem = &shmems[0]; shmem-shmems<numshmems; shmem++)
{
- volatile u_char *cptr;
-
+ u_long ptr;
+
numprint++;
if (numprint>8)
{
@@ -917,12 +905,12 @@
}
BUGMSG2(D_INIT,"%lXh ",*shmem);
- cptr=(u_char *)(*shmem);
+ ptr=(u_long)(*shmem);
- if (*cptr != TESTvalue)
+ if (readb(ptr) != TESTvalue)
{
BUGMSG2(D_INIT_REASONS,"(mem=%02Xh, not %02Xh)\n",
- *cptr,TESTvalue);
+ readb(ptr),TESTvalue);
BUGMSG(D_INIT_REASONS,"Stage 3: ");
BUGLVL(D_INIT_REASONS) numprint=0;
*shmem=shmems[numshmems-1];
@@ -936,8 +924,8 @@
* in another pass through this loop, they will be discarded
* because *cptr != TESTvalue.
*/
- *cptr=0x42;
- if (*cptr != 0x42)
+ writeb(0x42,ptr);
+ if (readb(ptr) != 0x42)
{
BUGMSG2(D_INIT_REASONS,"(read only)\n");
BUGMSG(D_INIT_REASONS,"Stage 3: ");
@@ -999,7 +987,7 @@
BUGMSG2(D_INIT,"%Xh ",*port);
ioaddr=*port;
- status=inb(STATUS);
+ status=ARCSTATUS;
if ((status & 0x9D)
!= (NORXflag|RECONflag|TXFREEflag|RESETflag))
@@ -1013,8 +1001,8 @@
continue;
}
- outb(CFLAGScmd|RESETclear|CONFIGclear,COMMAND);
- status=inb(STATUS);
+ ACOMMAND(CFLAGScmd|RESETclear|CONFIGclear);
+ status=ARCSTATUS;
if (status & RESETflag)
{
BUGMSG2(D_INIT_REASONS," (eternal reset, status=%Xh)\n",
@@ -1037,9 +1025,9 @@
* we tell it to start receiving.
*/
airqmask = probe_irq_on();
- outb(NORXflag,INTMASK);
+ AINTMASK(NORXflag);
udelay(1);
- outb(0,INTMASK);
+ AINTMASK(0);
airq = probe_irq_off(airqmask);
if (airq<=0)
@@ -1070,26 +1058,26 @@
#ifdef FAST_PROBE
if (numports>1 || numshmems>1)
{
- inb(RESET);
+ ARCRESET;
JIFFER(RESETtime);
}
else
{
/* just one shmem and port, assume they match */
- *(u_char *)(shmems[0]) = TESTvalue;
+ writeb(TESTvalue,shmems[0]);
}
#else
- inb(RESET);
+ ARCRESET;
JIFFER(RESETtime);
#endif
for (shmem = &shmems[0]; shmem-shmems<numshmems; shmem++)
{
- u_char *cptr;
- cptr=(u_char *)(*shmem);
+ u_long ptr;
+ ptr=(u_long)(*shmem);
- if (*cptr == TESTvalue) /* found one */
+ if (readb(ptr) == TESTvalue) /* found one */
{
BUGMSG2(D_INIT,"%lXh)\n", *shmem);
openparen=0;
@@ -1106,7 +1094,7 @@
}
else
{
- BUGMSG2(D_INIT_REASONS,"%Xh-", *cptr);
+ BUGMSG2(D_INIT_REASONS,"%Xh-", readb(ptr));
}
}
@@ -1128,48 +1116,67 @@
/* Now put back TESTvalue on all leftover shmems.
*/
for (shmem = &shmems[0]; shmem-shmems<numshmems; shmem++)
- *(u_char *)(*shmem) = TESTvalue;
+ writeb(TESTvalue,*shmem);
if (retval) BUGMSG(D_NORMAL,"Stage 5: No ARCnet cards found.\n");
return retval;
}
+#endif /* !RIM_I_MODE */
+
+
/* Set up the struct device associated with this card. Called after
* probing succeeds.
*/
int arcnet_found(struct device *dev,int port,int airq, u_long shmem)
{
- u_char *first_mirror,*last_mirror;
+ u_long first_mirror,last_mirror;
struct arcnet_local *lp;
+ int mirror_size;
- /* reserve the I/O region */
- request_region(port,ARCNET_TOTAL_SIZE,"arcnet");
- dev->base_addr=port;
-
/* reserve the irq */
if (request_irq(airq,&arcnet_interrupt,0,"arcnet",NULL))
{
BUGMSG(D_NORMAL,"Can't get IRQ %d!\n",airq);
- release_region(port,ARCNET_TOTAL_SIZE);
return -ENODEV;
}
irq2dev_map[airq]=dev;
dev->irq=airq;
+
+#ifdef RIM_I_MODE
+ dev->base_addr=0;
+ writeb(TESTvalue,shmem);
+ writeb(port,shmem+1); /* actually the node ID */
+#else
+ /* reserve the I/O region - guaranteed to work by check_region */
+ request_region(port,ARCNET_TOTAL_SIZE,"arcnet");
+ dev->base_addr=port;
+#endif
/* find the real shared memory start/end points, including mirrors */
#define BUFFER_SIZE (512)
#define MIRROR_SIZE (BUFFER_SIZE*4)
-
- first_mirror=last_mirror=(u_char *)shmem;
- while (*first_mirror==TESTvalue) first_mirror-=MIRROR_SIZE;
- first_mirror+=MIRROR_SIZE;
- while (*last_mirror==TESTvalue) last_mirror+=MIRROR_SIZE;
- last_mirror-=MIRROR_SIZE;
+ /* 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)
+ mirror_size*=2;
+
+ first_mirror=last_mirror=shmem;
+ while (readb(first_mirror)==TESTvalue) first_mirror-=mirror_size;
+ first_mirror+=mirror_size;
+
+ while (readb(last_mirror)==TESTvalue) last_mirror+=mirror_size;
+ last_mirror-=mirror_size;
- dev->mem_start=(u_long)first_mirror;
- dev->mem_end=(u_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;
@@ -1180,7 +1187,7 @@
{
irq2dev_map[airq] = NULL;
free_irq(airq,NULL);
- release_region(port,ARCNET_TOTAL_SIZE);
+ RELEASE_REGION(port,ARCNET_TOTAL_SIZE);
return -ENOMEM;
}
memset(dev->priv,0,sizeof(struct arcnet_local));
@@ -1211,7 +1218,7 @@
sizeof(struct HardHeader));
/* get and check the station ID from offset 1 in shmem */
- lp->stationid = first_mirror[1];
+ lp->stationid = readb(first_mirror+1);
if (lp->stationid==0)
BUGMSG(D_NORMAL,"WARNING! Station address 00 is reserved "
"for broadcasts!\n");
@@ -1221,10 +1228,10 @@
dev->dev_addr[0]=lp->stationid;
BUGMSG(D_NORMAL,"ARCnet station %02Xh found at %03lXh, IRQ %d, "
- "ShMem %lXh (%ld bytes).\n",
+ "ShMem %lXh (%ld*%d bytes).\n",
lp->stationid,
dev->base_addr,dev->irq,dev->mem_start,
- dev->mem_end-dev->mem_start+1);
+ (dev->mem_end-dev->mem_start+1)/mirror_size,mirror_size);
return 0;
}
@@ -1240,30 +1247,28 @@
int arcnet_reset(struct device *dev,int reset_delay)
{
struct arcnet_local *lp=(struct arcnet_local *)dev->priv;
- short ioaddr=dev->base_addr;
+ short ioaddr=IOADDR;
int delayval,recbuf=lp->recbuf;
- u_char *cardmem;
/* no IRQ's, please! */
lp->intmask=0;
SETMASK;
BUGMSG(D_INIT,"Resetting %s (status=%Xh)\n",
- dev->name,inb(STATUS));
+ dev->name,ARCSTATUS);
if (reset_delay)
{
/* reset the card */
- inb(RESET);
+ ARCRESET;
JIFFER(RESETtime);
}
- outb(CFLAGScmd|RESETclear, COMMAND); /* clear flags & end reset */
- outb(CFLAGScmd|CONFIGclear,COMMAND);
+ ACOMMAND(CFLAGScmd|RESETclear); /* clear flags & end reset */
+ ACOMMAND(CFLAGScmd|CONFIGclear);
/* verify that the ARCnet signature byte is present */
- cardmem = (u_char *) dev->mem_start;
- if (cardmem[0] != TESTvalue)
+ if (readb(dev->mem_start) != TESTvalue)
{
BUGMSG(D_NORMAL,"reset failed: TESTvalue not present.\n");
return 1;
@@ -1274,12 +1279,12 @@
lp->txbuf=2;
/* enable extended (512-byte) packets */
- outb(CONFIGcmd|EXTconf,COMMAND);
-
+ ACOMMAND(CONFIGcmd|EXTconf);
+
#ifndef SLOW_XMIT_COPY
/* clean out all the memory to make debugging make more sense :) */
BUGLVL(D_DURING)
- memset((void *)dev->mem_start,0x42,2048);
+ memset_io(dev->mem_start,0x42,2048);
#endif
/* and enable receive of our first packet to the first buffer */
@@ -1346,7 +1351,7 @@
arcnet_open(struct device *dev)
{
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int ioaddr=dev->base_addr;
+ int ioaddr=IOADDR;
if (dev->metric>=1000)
{
@@ -1418,7 +1423,7 @@
* START is set to 1, it could be ignored. So, we turn IRQ's
* off, then on again to clean out the IRQ controller.
*/
- outb(0,INTMASK);
+ AINTMASK(0);
udelay(1); /* give it time to set the mask before
* we reset it again. (may not even be
* necessary)
@@ -1435,7 +1440,7 @@
static int
arcnet_close(struct device *dev)
{
- int ioaddr = dev->base_addr;
+ int ioaddr=IOADDR;
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
TBUSY=1;
@@ -1443,12 +1448,12 @@
/* Shut down the card */
#ifdef FAST_IFCONFIG
- inb(RESET); /* reset IRQ won't run if START=0 */
+ ARCRESET; /* reset IRQ won't run if START=0 */
#else
lp->intmask=0;
SETMASK; /* no IRQ's (except RESET, of course) */
- outb(NOTXcmd,COMMAND); /* stop transmit */
- outb(NORXcmd,COMMAND); /* disable receive */
+ ACOMMAND(NOTXcmd); /* stop transmit */
+ ACOMMAND(NORXcmd); /* disable receive */
#endif
/* reset more flags */
@@ -1497,10 +1502,10 @@
arcnet_send_packet_bad(struct sk_buff *skb, struct device *dev)
{
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int ioaddr=dev->base_addr;
+ int ioaddr=IOADDR;
BUGMSG(D_DURING,"transmit requested (status=%Xh, inTX=%d)\n",
- inb(STATUS),lp->intx);
+ ARCSTATUS,lp->intx);
if (lp->in_txhandler)
{
@@ -1522,7 +1527,7 @@
There should really be a "kick me" function call instead. */
int tickssofar = jiffies - dev->trans_start;
/*int recbuf=lp->recbuf;*/
- int status=inb(STATUS);
+ int status=ARCSTATUS;
if (tickssofar < TX_TIMEOUT)
{
@@ -1549,7 +1554,7 @@
lp->stats.tx_errors++;
lp->stats.tx_aborted_errors++;
- outb(NOTXcmd,COMMAND);
+ ACOMMAND(NOTXcmd);
}
if (lp->outgoing.skb)
@@ -1571,7 +1576,7 @@
itself. */
if (skb == NULL) {
BUGMSG(D_NORMAL,"tx passed null skb (status=%Xh, inTX=%d, tickssofar=%ld)\n",
- inb(STATUS),lp->intx,jiffies-dev->trans_start);
+ ARCSTATUS,lp->intx,jiffies-dev->trans_start);
lp->stats.tx_errors++;
dev_tint(dev);
return 0;
@@ -1580,10 +1585,10 @@
if (lp->txready) /* transmit already in progress! */
{
BUGMSG(D_NORMAL,"trying to start new packet while busy! (status=%Xh)\n",
- inb(STATUS));
+ ARCSTATUS);
lp->intmask &= ~TXFREEflag;
SETMASK;
- outb(NOTXcmd,COMMAND); /* abort current send */
+ ACOMMAND(NOTXcmd); /* abort current send */
arcnet_inthandler(dev); /* fake an interrupt */
lp->stats.tx_errors++;
lp->stats.tx_fifo_errors++;
@@ -1597,7 +1602,7 @@
if (set_bit(0, (void*)&dev->tbusy) != 0)
{
BUGMSG(D_NORMAL,"transmitter called with busy bit set! (status=%Xh, inTX=%d, tickssofar=%ld)\n",
- inb(STATUS),lp->intx,jiffies-dev->trans_start);
+ ARCSTATUS,lp->intx,jiffies-dev->trans_start);
lp->stats.tx_errors++;
lp->stats.tx_fifo_errors++;
return -EBUSY;
@@ -1613,7 +1618,7 @@
arcnetA_send_packet(struct sk_buff *skb, struct device *dev)
{
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int ioaddr=dev->base_addr,bad;
+ int ioaddr=IOADDR,bad;
struct Outgoing *out=&(lp->outgoing);
lp->intx++;
@@ -1723,11 +1728,11 @@
static void arcnetA_continue_tx(struct device *dev)
{
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int ioaddr=dev->base_addr,maxsegsize=XMTU-4;
+ int ioaddr=IOADDR,maxsegsize=XMTU-4;
struct Outgoing *out=&(lp->outgoing);
BUGMSG(D_DURING,"continue_tx called (status=%Xh, intx=%d, intxh=%d, intmask=%Xh\n",
- inb(STATUS),lp->intx,lp->in_txhandler,lp->intmask);
+ ARCSTATUS,lp->intx,lp->in_txhandler,lp->intmask);
if (lp->txready)
{
@@ -1773,7 +1778,7 @@
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
struct ClientData *arcsoft;
union ArcPacket *arcpacket =
- (union ArcPacket *)(dev->mem_start+512*(lp->txbuf^1));
+ (union ArcPacket *)phys_to_virt(dev->mem_start+512*(lp->txbuf^1));
int offset;
#ifdef SLOW_XMIT_COPY
@@ -1790,7 +1795,7 @@
#ifndef SLOW_XMIT_COPY
/* clean out the page to make debugging make more sense :) */
BUGLVL(D_DURING)
- memset((void *)dev->mem_start+lp->txbuf*512,0x42,512);
+ memset_io(dev->mem_start+lp->txbuf*512,0x42,512);
#endif
arcpacket->hardheader.destination=daddr;
@@ -1877,10 +1882,10 @@
arcnet_go_tx(struct device *dev,int enable_irq)
{
struct arcnet_local *lp=(struct arcnet_local *)dev->priv;
- int ioaddr=dev->base_addr;
+ int ioaddr=IOADDR;
BUGMSG(D_DURING,"go_tx: status=%Xh, intmask=%Xh, txready=%d, sending=%d\n",
- inb(STATUS),lp->intmask,lp->txready,lp->sending);
+ ARCSTATUS,lp->intmask,lp->txready,lp->sending);
if (lp->sending || !lp->txready)
{
@@ -1893,7 +1898,7 @@
}
/* start sending */
- outb(TXcmd|(lp->txready<<3),COMMAND);
+ ACOMMAND(TXcmd|(lp->txready<<3));
lp->stats.tx_packets++;
lp->txready=0;
@@ -1940,11 +1945,11 @@
/* RESET flag was enabled - if !dev->start, we must clear it right
* away (but nothing else) since inthandler() is never called.
*/
- ioaddr=dev->base_addr;
+ ioaddr=IOADDR; /* can't do this before checking dev!=NULL */
if (!dev->start)
{
- if (inb(STATUS) & RESETflag)
- outb(CFLAGScmd|RESETclear, COMMAND);
+ if (ARCSTATUS & RESETflag)
+ ACOMMAND(CFLAGScmd|RESETclear);
return;
}
@@ -1960,7 +1965,7 @@
arcnet_inthandler(struct device *dev)
{
struct arcnet_local *lp=(struct arcnet_local *)dev->priv;
- int ioaddr=dev->base_addr, status, boguscount = 3, didsomething;
+ int ioaddr=IOADDR, status, boguscount = 3, didsomething;
if (IF_INTERRUPT)
{
@@ -1968,15 +1973,15 @@
return; /* don't even try. */
}
- outb(0,INTMASK);
+ AINTMASK(0);
INTERRUPT = 1;
BUGMSG(D_DURING,"in arcnet_inthandler (status=%Xh, intmask=%Xh)\n",
- inb(STATUS),lp->intmask);
+ ARCSTATUS,lp->intmask);
do
{
- status = inb(STATUS);
+ status = ARCSTATUS;
didsomething=0;
@@ -2049,7 +2054,7 @@
if (lp->intx)
{
BUGMSG(D_DURING,"TXDONE while intx! (status=%Xh, intx=%d)\n",
- inb(STATUS),lp->intx);
+ ARCSTATUS,lp->intx);
lp->in_txhandler--;
continue;
}
@@ -2108,7 +2113,7 @@
#ifdef DETECT_RECONFIGS
if (status & (lp->intmask) & RECONflag)
{
- outb(CFLAGScmd|CONFIGclear,COMMAND);
+ ACOMMAND(CFLAGScmd|CONFIGclear);
lp->stats.tx_carrier_errors++;
#ifdef SHOW_RECONFIGS
@@ -2179,7 +2184,7 @@
} while (--boguscount && didsomething);
BUGMSG(D_DURING,"net_interrupt complete (status=%Xh, count=%d)\n",
- inb(STATUS),boguscount);
+ ARCSTATUS,boguscount);
BUGMSG(D_DURING,"\n");
SETMASK; /* put back interrupt mask */
@@ -2203,9 +2208,9 @@
arcnet_rx(struct device *dev,int recbuf)
{
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int ioaddr = dev->base_addr;
+ int ioaddr=IOADDR;
union ArcPacket *arcpacket=
- (union ArcPacket *)(dev->mem_start+recbuf*512);
+ (union ArcPacket *)phys_to_virt(dev->mem_start+recbuf*512);
u_char *arcsoft;
short length,offset;
u_char daddr,saddr;
@@ -2219,7 +2224,7 @@
if (saddr==0)
{
BUGMSG(D_NORMAL,"discarding old packet. (status=%Xh)\n",
- inb(STATUS));
+ ARCSTATUS);
lp->stats.rx_errors++;
return;
}
@@ -2263,6 +2268,12 @@
arcnetS_rx(lp->sdev,arcsoft,length,saddr,daddr);
break;
#endif
+ case ARC_P_DATAPOINT_BOOT:
+ case ARC_P_DATAPOINT_MOUNT:
+ break;
+ case ARC_P_POWERLAN_BEACON:
+ case ARC_P_POWERLAN_BEACON2:
+ break;
case ARC_P_LANSOFT: /* don't understand. fall through. */
default:
BUGMSG(D_EXTRA,"received unknown protocol %d (%Xh) from station %d.\n",
@@ -2585,7 +2596,7 @@
return &lp->stats;
}
-#if 0
+#if 0 /* standard ARCnet cards have no promiscuous mode */
/* Set or clear the multicast filter for this adaptor.
* num_addrs == -1 Promiscuous mode, receive all packets
* num_addrs == 0 Normal mode, clear multicast list
@@ -2595,15 +2606,10 @@
static void
set_multicast_list(struct device *dev)
{
-#if 0 /* no promiscuous mode at all on most ARCnet models */
- struct arcnet_local *lp=(struct arcnet_local *)(dev->priv);
-
- short ioaddr = dev->base_addr;
if (num_addrs) {
- outw(69, ioaddr); /* Enable promiscuous mode */
+ /* Enable promiscuous mode */
} else
- outw(99, ioaddr); /* Disable promiscuous mode, use normal mode */
-#endif
+ /* Disable promiscuous mode, use normal mode */
}
#endif
@@ -2809,9 +2815,9 @@
arcnetE_send_packet(struct sk_buff *skb, struct device *dev)
{
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int ioaddr=dev->base_addr,bad;
+ int ioaddr=IOADDR,bad;
union ArcPacket *arcpacket =
- (union ArcPacket *)(dev->mem_start+512*(lp->txbuf^1));
+ (union ArcPacket *)phys_to_virt(dev->mem_start+512*(lp->txbuf^1));
u_char *arcsoft,daddr;
short offset,length=skb->len+1;
@@ -2844,7 +2850,7 @@
#ifndef SLOW_XMIT_COPY
/* clean out the page to make debugging make more sense :) */
BUGLVL(D_DURING)
- memset((void *)dev->mem_start+lp->txbuf*512,0x42,512);
+ memset_io(dev->mem_start+lp->txbuf*512,0x42,512);
#endif
/* broadcasts have address FF:FF:FF:FF:FF:FF in etherspeak */
@@ -2989,7 +2995,7 @@
arcnetS_send_packet(struct sk_buff *skb, struct device *dev)
{
struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int ioaddr=dev->base_addr,bad,length;
+ int ioaddr=IOADDR,bad,length;
struct S_ClientData *hdr=(struct S_ClientData *)skb->data;
lp->intx++;
@@ -3253,61 +3259,67 @@
static int shmem=0;
static char *device = NULL; /* use eg. device="arc1" to change name */
-int
-init_module(void)
+#ifdef RIM_I_MODE
+ static int node=0; /* you must specify the node ID for RIM I cards */
+#endif
+
+int init_module(void)
{
+ struct device *dev=&thiscard;
if (device)
- strcpy(thiscard.name,device);
-#ifndef CONFIG_ARCNET_ETHNAME
- else if (!thiscard.name[0]) strcpy(thiscard.name,"arc0");
-#endif
+ strcpy(dev->name,device);
+ #ifndef CONFIG_ARCNET_ETHNAME
+ else if (!dev->name[0]) strcpy(dev->name,"arc0");
+ #endif
+
+ #ifdef RIM_I_MODE
+ if (node) io=node;
+ #endif
- thiscard.base_addr=io;
+ dev->base_addr=io;
if (irq) irqnum=irq;
-
- thiscard.irq=irqnum;
- if (thiscard.irq==2) thiscard.irq=9;
+ dev->irq=irqnum;
+ if (dev->irq==2) dev->irq=9;
if (shmem)
{
- thiscard.mem_start=shmem;
- thiscard.mem_end=thiscard.mem_start+512*4-1;
- thiscard.rmem_start=thiscard.mem_start+512*0;
- thiscard.rmem_end=thiscard.mem_start+512*2-1;
+ 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;
}
- if (register_netdev(&thiscard) != 0)
+ if (register_netdev(dev) != 0)
return -EIO;
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
- int ioaddr=thiscard.base_addr;
+ struct device *dev=&thiscard;
+ int ioaddr=IOADDR;
- if (thiscard.start) arcnet_close(&thiscard);
+ if (dev->start) arcnet_close(dev);
/* Flush TX and disable RX */
if (ioaddr)
{
- outb(0,INTMASK); /* disable IRQ's */
- outb(NOTXcmd,COMMAND); /* stop transmit */
- outb(NORXcmd,COMMAND); /* disable receive */
+ AINTMASK(0); /* disable IRQ's */
+ ACOMMAND(NOTXcmd); /* stop transmit */
+ ACOMMAND(NORXcmd); /* disable receive */
}
- if (thiscard.irq)
+ if (dev->irq)
{
- irq2dev_map[thiscard.irq] = NULL;
- free_irq(thiscard.irq,NULL);
+ irq2dev_map[dev->irq] = NULL;
+ free_irq(dev->irq,NULL);
}
- if (thiscard.base_addr) release_region(thiscard.base_addr,
- ARCNET_TOTAL_SIZE);
- unregister_netdev(&thiscard);
- kfree(thiscard.priv);
- thiscard.priv = NULL;
+ if (dev->base_addr) RELEASE_REGION(dev->base_addr,ARCNET_TOTAL_SIZE);
+ unregister_netdev(dev);
+ kfree(dev->priv);
+ dev->priv = NULL;
}
#endif /* MODULE */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov