diff -u --recursive --new-file v2.4.6/linux/CREDITS linux/CREDITS
--- v2.4.6/linux/CREDITS	Tue Jul  3 17:08:18 2001
+++ linux/CREDITS	Wed Jul  4 11:50:38 2001
@@ -957,6 +957,12 @@
 S: New South Wales, 2121
 S: Australia
 
+N: Carlos E. Gorges 
+E: carlos@techlinux.com.br
+D: fix smp support on cmpci driver
+P: 2048G/EA3C4B19 FF31 33A6 0362 4915 B7EB  E541 17D0 0379 EA3C 4B19
+S: Brazil
+
 N: Dmitry S. Gorodchanin
 E: pgmdsg@ibi.com
 D: RISCom/8 driver, misc kernel fixes.
diff -u --recursive --new-file v2.4.6/linux/Documentation/README.nsp_cs.eng linux/Documentation/README.nsp_cs.eng
--- v2.4.6/linux/Documentation/README.nsp_cs.eng	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/README.nsp_cs.eng	Wed Jul  4 11:50:38 2001
@@ -0,0 +1,127 @@
+
+         WorkBiT NinjaSCSI-3/32Bi driver for Linux
+
+1. Comment
+ This is Workbit corp.'s(http://www.workbit.co.jp/) NinjaSCSI-3
+(http://www.workbit.co.jp/ts/z_nj3r.html) and NinjaSCSI-32Bi
+(http://www.workbit.co.jp/ts/z_njsc32bi.html) PCMCIA card driver module
+for Linux.
+
+2. My Linux environment
+Linux kernel: 2.4.0 / 2.2.18
+pcmcia-cs:    3.1.24
+gcc:          gcc-2.95.2
+PC card:      I-O data PCSC-F (NinjaSCSI-3)
+              I-O data CBSC-II in 16 bit mode (NinjaSCSI-32Bi)
+SCSI device:  I-O data CDPS-PX24 (CD-ROM drive)
+              Media Intelligent MMO-640GT (Optical disk drive)
+
+3. Install
+[1] Check your PC card is true "NinjaSCSI-3" card.
+    If you installed pcmcia-cs already, pcmcia reports your card as UNKNOWN
+    card, and write ["WBT", "NinjaSCSI-3", "R1.0"] or some other string to
+    your console or log file.
+    You can also use "cardctl" program (this program is in pcmcia-cs source
+    code) to get more info.
+
+# cat /var/log/messgaes
+...
+Jan  2 03:45:06 lindberg cardmgr[78]: unsupported card in socket 1
+Jan  2 03:45:06 lindberg cardmgr[78]:   product info: "WBT", "NinjaSCSI-3", "R1.0"
+...
+# cardctl ident
+Socket 0:
+  no product info available
+Socket 1:
+  product info: "IO DATA", "CBSC16       ", "1"
+
+
+[2] Get Linux kernel source, and extract it to /usr/src.
+    Because NinjaSCSI driver requiers some SCSI header files in Linux kernel
+    source.
+    I recomend rebuilding your kernel. This eliminate some versioning problem.
+$ cd /usr/src
+$ tar -zxvf linux-x.x.x.tar.gz
+$ cd linux
+$ make config
+...
+
+[3] If you use this driver with Kernel 2.2, Unpack pcmcia-cs in some directory
+    and make & install. This driver requies pcmcia-cs header file.
+$ cd /usr/src
+$ tar zxvf cs-pcmcia-cs-3.x.x.tar.gz
+...
+
+[4] Extract this driver's archive somewhere, and edit Makefile, then do make.
+$ tar -zxvf nsp_cs-x.x.tar.gz
+$ cd nsp_cs-x.x
+$ make
+
+[5] Copy nsp_cs.o to suitable plase, like /lib/modules/<Kernel version>/pcmcia/ .
+
+[6] Add these lines to /etc/pcmcia/config .
+    If you yse pcmcia-cs-3.1.8 or later, we can use "nsp_cs.conf" file.
+    So, you don't need to edit file. Just copy to /etc/pcmcia/ .
+
+-------------------------------------
+device "nsp_cs"
+  class "scsi" module "nsp_cs"
+
+card "WorkBit NinjaSCSI-3"
+  version "WBT", "NinjaSCSI-3", "R1.0"
+  bind "nsp_cs"
+
+card "WorkBit NinjaSCSI-32Bi (16bit)"
+  version "WORKBIT", "UltraNinja-16", "1"
+  bind "nsp_cs"
+
+# OEM
+card "WorkBit NinjaSCSI-32Bi (16bit) / IO-DATA"
+  version "IO DATA", "CBSC16       ", "1"
+  bind "nsp_cs"
+
+# OEM
+card "WorkBit NinjaSCSI-32Bi (16bit) / KME-1"
+  version "KME    ", "SCSI-CARD-001", "1"
+  bind "nsp_cs"
+card "WorkBit NinjaSCSI-32Bi (16bit) / KME-2"
+  version "KME    ", "SCSI-CARD-002", "1"
+  bind "nsp_cs"
+card "WorkBit NinjaSCSI-32Bi (16bit) / KME-3"
+  version "KME    ", "SCSI-CARD-003", "1"
+  bind "nsp_cs"
+card "WorkBit NinjaSCSI-32Bi (16bit) / KME-4"
+  version "KME    ", "SCSI-CARD-004", "1"
+  bind "nsp_cs"
+-------------------------------------
+
+[7] Boot (or reboot) pcmcia-cs.
+# /etc/rc.d/rc.pcmcia start        (BSD style)
+or
+# /etc/init.d/pcmcia start         (SYSV style)
+
+
+4. History
+See README.nin_cs .
+
+5. Caution
+ If you eject card when doing some operation for your SCSI device or suspend
+your computer, you encount some *BAD* error like disk crash.
+ It works good when I using this driver right way. But I'm not guarantee
+your data. Please backup your data when you use this driver.
+
+6. Known Bugs
+ Some write error occurs when you use slow device.
+
+7. Testing
+ Please send me some reports(bug reports etc..) of this software.
+When you send report, please tell me these or more.
+	card name
+	kernel version
+	your SCSI device name(hard drive, CD-ROM, etc...)
+
+8. Copyright
+ See GPL.
+
+
+2001/02/01 yokota@netlab.is.tsukuba.ac.jp <YOKOTA Hiroshi>
diff -u --recursive --new-file v2.4.6/linux/Documentation/networking/multicast.txt linux/Documentation/networking/multicast.txt
--- v2.4.6/linux/Documentation/networking/multicast.txt	Mon Aug  9 10:23:09 1999
+++ linux/Documentation/networking/multicast.txt	Wed Jul  4 11:50:38 2001
@@ -39,11 +39,13 @@
 hp		YES		YES		YES		Hardware
 hp100		YES		YES		YES		Hardware
 ibmtr		NO		NO		NO		N/A
+ioc3-eth	YES		YES		YES		Hardware
 lance		YES		YES		YES		Software(#)
 ne		YES		YES		YES		Hardware
 ni52		<------------------ Buggy ------------------>
 ni65		YES		YES		YES		Software(#)
 seeq		NO		NO		NO		N/A
+sgiseek		<------------------ Buggy ------------------>
 sk_g16		NO		NO		YES		N/A
 smc-ultra	YES		YES		YES		Hardware
 sunlance	YES		YES		YES		Hardware
diff -u --recursive --new-file v2.4.6/linux/Documentation/sound/CMI8338 linux/Documentation/sound/CMI8338
--- v2.4.6/linux/Documentation/sound/CMI8338	Fri Jul 28 12:50:52 2000
+++ linux/Documentation/sound/CMI8338	Wed Jul  4 11:50:38 2001
@@ -8,59 +8,80 @@
 On-board C-Media chips
 
 
-WHAT'S NEW
+STEPS TO BUILD DRIVER
 ================================================================================
 
-  1. Support modem interface for 8738. (select in kernel configuration)
-  2. Enable S/PDIF-in to S/PDIF-out (S/PDIF loop).
-  3. Enable 4 channels analog duplicate mode on 3 jack or 4 jack
-     configuration.
+  1. Backup the Config.in and Makefile in the sound driver directory
+     (/usr/src/linux/driver/sound).
+     The Configure.help provide help when you config driver in step
+     4, please backup the original one (/usr/src/linux/Document) and
+     copy this file.
+     The cmpci is document for the driver in detail, please copy it
+     to /usr/src/linux/Document/sound so you can refer it. Backup if
+     there is already one.
 
+  2. Extract the tar file by 'tar xvzf cmpci-xx.tar.gz' in the above
+     directory.
 
-   Be aware: C-Media Electronics Inc. is basically an IC design house,
-   and whose development of software drivers is mainly for use by its OEM
-   customers in their products. C-Media Electronics Inc. itself does not
-   manufacture end-user products, such as PC or sound cards, so it can
-   not fully control the drivers provided to consumers. Drivers provided
-   at this site, therefore, MAY NOT BE APPLICABLE to all sound cards.
-   Drivers you download from this site may function well at certain
-   situation, but C-Media Electronics Inc. does not give any guarantee or
-   assurances. Please be aware that these drivers might cause some
-   technical difficulties when installed
+  3. Change directory to /usr/src/linux
 
+  4. Config cm8338 driver by 'make menuconfig', 'make config' or
+     'make xconfig' command.
 
-1. Config cm8338 driver by 'make menuconfig' or 'make config' command.
+  5. Please select Sound Card (CONFIG_SOUND=m) support and CMPCI
+     driver (CONFIG_SOUND_CMPCI=m) as modules. Resident mode not tested.
+     For driver option, please refer 'DRIVER PARAMETER'
 
-2. Please select Sound Card (CONFIG_SOUND=m) support and CMPCI driver (CONFIG_SOUND_CMPCI=m) as modules. Resident mode not tested.
+  6. Compile the kernel if necessary.
 
-3. Compile the kernel if necessary.
+  7. Compile the modules by 'make modules'.
 
-4. Compile the modules by 'make modules'.
+  8. Install the modules by 'make modules_install'
 
-5. Install the modules by 'make modules_install'
 
-6. Before first time to run the driver, create module dependency by 'depmod -a'
+INSTALL DRIVER
+================================================================================
+
+  1. Before first time to run the driver, create module dependency by
+     'depmod -a'
+
+  2. To install the driver manually, enter 'modprobe cmpci'.
+
+  3. Driver installation for various distributions:
 
-7. To install the driver, enter 'modprobe cmpci'.
+    a. Slackware 4.0
+       Add the 'modprobe cmpci' command in your /etc/rc.d/rc.modules
+       file.so you can start the driver automatically each time booting.
 
+    b. Caldera OpenLinux 2.2
+       Use LISA to load the cmpci module.
 
-DRIVER PARAMETERS
+    c. RedHat 6.0 and S.u.S.E. 6.1
+       Add following command in /etc/conf.modules:
+
+       alias sound cmpci
+
+	also visit http://www.cmedia.com.tw for installation instruction.
+
+DRIVER PARAMETER
 ================================================================================
 
   Some functions for the cm8738 can be configured in Kernel Configuration
   or modules parameters. Set these parameters to 1 to enable.
 
+  mpu_io:	I/O ports base for MPU-401, 0 if disabled.
+  fm_io:	I/O ports base for OPL-3, 0 if disabled.
+  spdif_inverse:Inverse the S/PDIF-in signal, this depends on your
+		CD-ROM or DVD-ROM.
   spdif_loop:   Enable S/PDIF loop, this route S/PDIF-in to S/PDIF-out
                 directly.
-  four_ch:      Enable 4 channels mode, rear-out or line-in will output
-                the same as line-out.
-  rear_out:     Enable this if you have independent rear-out jacket on
-                your sound card, otherwise line-in will be used as
+  speakers:     Number of speakers used.
+  use_line_as_rear:Enable this if you want to use line-in as
                 rear-out.
+  use_line_as_bass:Enable this if you want to use line-in as
+                bass-out.
   modem:	You will need to set this parameter if you want to use
 		the HSP modem. You need install the pctel.o, the modem
 		driver itself.
-
-  (You will need to get the pctel driver (binary only) and the support for
-  this option from the CMI site. It is not included in the Linux kernel 
-  proper as it is non-free).
+  joystick:	Enable joystick. You will need to install Linux joystick
+		driver.
diff -u --recursive --new-file v2.4.6/linux/Documentation/usb/philips.txt linux/Documentation/usb/philips.txt
--- v2.4.6/linux/Documentation/usb/philips.txt	Tue May 22 10:25:36 2001
+++ linux/Documentation/usb/philips.txt	Wed Jul  4 11:50:38 2001
@@ -34,6 +34,10 @@
    specificly, red and blue are swapped), try palette=bgr24 or
    palette=rgb24.
 
+   Only the native yuv420/yuv420p format is supported by the in kernel driver. 
+   If you want to use other formats with in-kernel conversion download the
+   driver from the URL given. [Alan]
+
 fbufs
    This paramter specifies the number of internal buffers to use for storing 
    frames from the cam. This will help if the process that reads images from 
diff -u --recursive --new-file v2.4.6/linux/Makefile linux/Makefile
--- v2.4.6/linux/Makefile	Tue Jul  3 17:08:18 2001
+++ linux/Makefile	Wed Jul  4 11:53:23 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 6
-EXTRAVERSION =
+SUBLEVEL = 7
+EXTRAVERSION =-pre1
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -u --recursive --new-file v2.4.6/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c
--- v2.4.6/linux/arch/alpha/kernel/time.c	Sun Nov 12 19:27:11 2000
+++ linux/arch/alpha/kernel/time.c	Wed Jul  4 11:50:46 2001
@@ -169,6 +169,77 @@
 	init_rtc_irq();
 }
 
+/*
+ * Calibrate CPU clock using legacy 8254 timer/counter. Stolen from
+ * arch/i386/time.c.
+ */
+
+#define CALIBRATE_LATCH	(52 * LATCH)
+#define CALIBRATE_TIME	(52 * 1000020 / HZ)
+
+static unsigned long __init
+calibrate_cc_with_pic(void)
+{
+	int cc;
+	unsigned long count = 0;
+
+	/* Set the Gate high, disable speaker */
+	outb((inb(0x61) & ~0x02) | 0x01, 0x61);
+
+	/*
+	 * Now let's take care of CTC channel 2
+	 *
+	 * Set the Gate high, program CTC channel 2 for mode 0,
+	 * (interrupt on terminal count mode), binary count,
+	 * load 5 * LATCH count, (LSB and MSB) to begin countdown.
+	 */
+	outb(0xb0, 0x43);		/* binary, mode 0, LSB/MSB, Ch 2 */
+	outb(CALIBRATE_LATCH & 0xff, 0x42);	/* LSB of count */
+	outb(CALIBRATE_LATCH >> 8, 0x42);	/* MSB of count */
+
+	cc = rpcc();
+	do {
+		count++;
+	} while ((inb(0x61) & 0x20) == 0);
+	cc = rpcc() - cc;
+
+	/* Error: ECTCNEVERSET */
+	if (count <= 1)
+		goto bad_ctc;
+
+	/* Error: ECPUTOOFAST */
+	if (count >> 32)
+		goto bad_ctc;
+
+	/* Error: ECPUTOOSLOW */
+	if (cc <= CALIBRATE_TIME)
+		goto bad_ctc;
+
+	return ((long)cc * 1000000) / CALIBRATE_TIME;
+
+	/*
+	 * The CTC wasn't reliable: we got a hit on the very first read,
+	 * or the CPU was so fast/slow that the quotient wouldn't fit in
+	 * 32 bits..
+	 */
+ bad_ctc:
+	return 0;
+}
+
+/* The Linux interpretation of the CMOS clock register contents:
+   When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+   RTC registers show the second which has precisely just started.
+   Let's hope other operating systems interpret the RTC the same way.  */
+
+static unsigned long __init
+rpcc_after_update_in_progress(void)
+{
+	do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
+	do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
+
+	return rpcc();
+}
+
 void __init
 time_init(void)
 {
@@ -176,24 +247,15 @@
 	unsigned long cycle_freq, one_percent;
 	long diff;
 
-	/*
-	 * The Linux interpretation of the CMOS clock register contents:
-	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-	 * RTC registers show the second which has precisely just started.
-	 * Let's hope other operating systems interpret the RTC the same way.
-	 */
-	do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
-	do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
+	/* Calibrate CPU clock -- attempt #1.  */
+	if (!est_cycle_freq)
+		est_cycle_freq = calibrate_cc_with_pic();
 
-	/* Read cycle counter exactly on falling edge of update flag */
-	cc1 = rpcc();
+	cc1 = rpcc_after_update_in_progress();
 
+	/* Calibrate CPU clock -- attempt #2.  */
 	if (!est_cycle_freq) {
-		/* Sometimes the hwrpb->cycle_freq value is bogus. 
-		   Go another round to check up on it and see.  */
-		do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
-		do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
-		cc2 = rpcc();
+		cc2 = rpcc_after_update_in_progress();
 		est_cycle_freq = cc2 - cc1;
 		cc1 = cc2;
 	}
diff -u --recursive --new-file v2.4.6/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- v2.4.6/linux/arch/alpha/kernel/traps.c	Thu May 24 15:24:37 2001
+++ linux/arch/alpha/kernel/traps.c	Wed Jul  4 11:50:38 2001
@@ -61,202 +61,6 @@
 			   "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
 			   "t10", "t11", "ra", "pv", "at", "gp", "sp", "zero"};
 
-static char * inst_name[] = {"call_pal", "", "", "", "", "", "", "",
-	"lda", "ldah", "ldbu", "ldq_u", "ldwu", "stw", "stb", "stq_u",
-	"ALU", "ALU", "ALU", "ALU", "SQRT", "FVAX", "FIEEE", "FLOAT",
-	"MISC", "PAL19", "JMP", "PAL1B", "GRAPH", "PAL1D", "PAL1E", "PAL1F",
-	"ldf", "ldg", "lds", "ldt", "stf", "stg", "sts", "stt",
-	"ldl", "ldq", "ldl_l", "ldq_l", "stl", "stq", "stl_c", "stq_c",
-	"br", "fbeq", "fblt", "fble", "bsr", "fbne", "fbge", "fbgt"
-	"blbc", "beq", "blt", "ble", "blbs", "bne", "bge", "bgt"
-};
-
-static char * jump_name[] = {"jmp", "jsr", "ret", "jsr_coroutine"};
-
-typedef struct {int func; char * text;} alist;
-
-static alist inta_name[] = {{0, "addl"}, {2, "s4addl"}, {9, "subl"},
-	{0xb, "s4subl"}, {0xf, "cmpbge"}, {0x12, "s8addl"}, {0x1b, "s8subl"},
-	{0x1d, "cmpult"}, {0x20, "addq"}, {0x22, "s4addq"}, {0x29, "subq"},
-	{0x2b, "s4subq"}, {0x2d, "cmpeq"}, {0x32, "s8addq"}, {0x3b, "s8subq"},
-	{0x3d, "cmpule"}, {0x40, "addl/v"}, {0x49, "subl/v"}, {0x4d, "cmplt"},
-	{0x60, "addq/v"}, {0x69, "subq/v"}, {0x6d, "cmple"}, {-1, 0}};
-
-static alist intl_name[] = {{0, "and"}, {8, "andnot"}, {0x14, "cmovlbs"},
-	{0x16, "cmovlbc"}, {0x20, "or"}, {0x24, "cmoveq"}, {0x26, "cmovne"},
-	{0x28, "ornot"}, {0x40, "xor"}, {0x44, "cmovlt"}, {0x46, "cmovge"},
-	{0x48, "eqv"}, {0x61, "amask"}, {0x64, "cmovle"}, {0x66, "cmovgt"},
-	{0x6c, "implver"}, {-1, 0}};
-
-static alist ints_name[] = {{2, "mskbl"}, {6, "extbl"}, {0xb, "insbl"},
-	{0x12, "mskwl"}, {0x16, "extwl"}, {0x1b, "inswl"}, {0x22, "mskll"},
-	{0x26, "extll"}, {0x2b, "insll"}, {0x30, "zap"}, {0x31, "zapnot"},
-	{0x32, "mskql"}, {0x34, "srl"}, {0x36, "extql"}, {0x39, "sll"},
-	{0x3b, "insql"}, {0x3c, "sra"}, {0x52, "mskwh"}, {0x57, "inswh"},
-	{0x5a, "extwh"}, {0x62, "msklh"}, {0x67, "inslh"}, {0x6a, "extlh"},
-	{0x72, "mskqh"}, {0x77, "insqh"}, {0x7a, "extqh"}, {-1, 0}};
-
-static alist intm_name[] = {{0, "mull"}, {0x20, "mulq"}, {0x30, "umulh"},
-	{0x40, "mull/v"}, {0x60, "mulq/v"}, {-1, 0}};
-
-static alist * int_name[] = {inta_name, intl_name, ints_name, intm_name};
-
-static char *
-assoc(int fcode, alist * a)
-{
-	while ((fcode != a->func) && (a->func != -1))
-		++a;
-	return a->text;
-}
-
-static char *
-iname(unsigned int instr)
-{
-	int opcode = instr >> 26;
-	char * name = inst_name[opcode];
-
-	switch (opcode) {
-		default:
-			break;
-
-		case 0x10:
-		case 0x11:
-		case 0x12:
-		case 0x13: {
-			char * specific_name
-			  = assoc((instr >> 5) & 0x3f, int_name[opcode - 0x10]);
-			if (specific_name)
-				name = specific_name;
-			break;
-		}
-
-		case 0x1a:
-			name = jump_name[(instr >> 14) & 3];
-			break;
-	}
-	
-	return name;
-}
-
-static enum {NOT_INST, PAL, BRANCH, MEMORY, JUMP, OPERATE, FOPERATE, MISC}
-iformat(int opcode)
-{
-	if (opcode >= 0x30)
-		return BRANCH;
-	if (opcode >= 0x20)
-		return MEMORY;
-	if (opcode == 0)
-		return PAL;
-	if (opcode < 8)
-		return NOT_INST;
-	if (opcode < 0x10)
-		return MEMORY;
-	if (opcode < 0x14)
-		return OPERATE;
-	if (opcode < 0x18)
-		return FOPERATE;
-	switch (opcode) {
-		case 0x18:
-			return MISC;
-		case 0x1A:
-			return JUMP;
-		case 0x1C:
-			return OPERATE;
-		default:
-			return NOT_INST;
-	}
-}
-
-/*
- * The purpose here is to provide useful clues about a kernel crash, so
- * less likely instructions, e.g. floating point, aren't fully decoded.
- */
-static void
-disassemble(unsigned int instr)
-{
-	int optype = instr >> 26;
-	char buf[40], *s = buf;
-
-	s += sprintf(buf, "%08x  %s ", instr, iname(instr));
-	switch (iformat(optype)) {
-		default:
-		case NOT_INST:
-		case MISC:
-			break;
-
-		case PAL:
-			s += sprintf(s, "%d", instr);
-			break;
-
-		case BRANCH: {
-			int reg = (instr >> 21) & 0x1f;
-			int offset = instr & 0x1fffff;
-
-			if (offset >= 0x100000)
-				offset -= 0x200000;
-			if (((optype & 3) == 0) || (optype >= 0x38)) {
-				if ((optype != 0x30) || (reg != 0x1f))
-					s += sprintf(s, "%s,", ireg_name[reg]);
-			} else
-				s += sprintf(s, "f%d,", reg);
-			s += sprintf(s, ".%+d", (offset + 1) << 2);
-			break;
-		}
-
-		case MEMORY: {
-			int addr_reg = (instr >> 16) & 0x1f;
-			int value_reg = (instr >> 21) & 0x1f;
-			int offset = instr & 0xffff;
-
-			if (offset >= 0x8000)
-				offset -= 0x10000;
-			if ((optype >= 0x20) && (optype < 0x28))
-				s += sprintf(s, "f%d", value_reg);
-			else
-				s += sprintf(s, "%s", ireg_name[value_reg]);
-
-			s += sprintf(s, ",%d(%s)", offset, ireg_name[addr_reg]);
-			break;
-		}
-
-		case JUMP: {
-			int target_reg = (instr >> 16) & 0x1f;
-			int return_reg = (instr >> 21) & 0x1f;
-
-			s += sprintf(s, "%s,", ireg_name[return_reg]);
-			s += sprintf(s, "(%s)", ireg_name[target_reg]);
-			break;
-		}
-
-		case OPERATE: {
-			int areg = (instr >> 21) & 0x1f;
-			int breg = (instr >> 16) & 0x1f;
-			int creg = instr & 0x1f;
-			int litflag = instr & (1<<12);
-			int lit = (instr >> 13) & 0xff;
-
-			s += sprintf(s, "%s,", ireg_name[areg]);
-			if (litflag)
-				s += sprintf(s, "%d", lit);
-			else
-				s += sprintf(s, "%s", ireg_name[breg]);
-			s += sprintf(s, ",%s", ireg_name[creg]);
-			break;
-		}
-
-		case FOPERATE: {
-			int areg = (instr >> 21) & 0x1f;
-			int breg = (instr >> 16) & 0x1f;
-			int creg = instr & 0x1f;
-
-			s += sprintf(s, "f%d,f%d,f%d", areg, breg, creg);
-			break;
-		}
-	}
-	buf[s-buf] = 0;
-	printk("%s\n", buf);
-}
-
 static void
 dik_show_code(unsigned int *pc)
 {
@@ -267,8 +71,7 @@
 		unsigned int insn;
 		if (__get_user(insn, pc+i))
 			break;
-		printk("%c", i ? ' ' : '*');
-		disassemble(insn);
+		printk("%c%08x%c", i ? ' ' : '<', insn, i ? ' ' : '>');
 	}
 	printk("\n");
 }
@@ -286,17 +89,11 @@
 			continue;
 		if (tmp >= (unsigned long) &_etext)
 			continue;
-		/*
-		 * Assume that only the low 24-bits of a kernel text address
-		 * is interesting.
-		 */
-		printk("%6x%c", (int)tmp & 0xffffff, (++i % 11) ? ' ' : '\n');
-#if 0
+		printk("%lx%c", tmp, ' ');
 		if (i > 40) {
 			printk(" ...");
 			break;
 		}
-#endif
 	}
 	printk("\n");
 }
@@ -337,8 +134,8 @@
 #endif
 	printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
 	dik_show_regs(regs, r9_15);
-	dik_show_code((unsigned int *)regs->pc);
 	dik_show_trace((unsigned long *)(regs+1));
+	dik_show_code((unsigned int *)regs->pc);
 
 	if (current->thread.flags & (1UL << 63)) {
 		printk("die_if_kernel recursion detected.\n");
diff -u --recursive --new-file v2.4.6/linux/arch/cris/Makefile linux/arch/cris/Makefile
--- v2.4.6/linux/arch/cris/Makefile	Tue May  1 16:04:56 2001
+++ linux/arch/cris/Makefile	Wed Jul  4 11:50:38 2001
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.18 2001/04/17 13:58:38 orjanf Exp $
+# $Id: Makefile,v 1.19 2001/06/11 12:06:40 bjornw Exp $
 # cris/Makefile
 #
 # This file is included by the global makefile so that you can add your own
@@ -49,7 +49,12 @@
 
 HEAD := arch/cris/kernel/head.o
 
-SUBDIRS += arch/cris/kernel arch/cris/mm arch/cris/lib arch/cris/drivers arch/cris/boot/rescue
+SUBDIRS += arch/cris/kernel arch/cris/mm arch/cris/lib arch/cris/drivers
+ifdef CONFIG_ETRAX_AXISFLASHMAP
+# only build this if axis flash map is used, because they depend on
+# each others config options
+SUBDIRS += arch/cris/boot/rescue
+endif
 CORE_FILES += arch/cris/kernel/kernel.o arch/cris/mm/mm.o arch/cris/drivers/drivers.o
 LIBGCC = $(shell $(CC) $(CFLAGS) -print-file-name=libgcc.a)
 LIBS := $(TOPDIR)/arch/cris/lib/lib.a $(LIBS) $(TOPDIR)/arch/cris/lib/lib.a $(LIBGCC)
diff -u --recursive --new-file v2.4.6/linux/arch/cris/config.in linux/arch/cris/config.in
--- v2.4.6/linux/arch/cris/config.in	Tue May  1 16:04:56 2001
+++ linux/arch/cris/config.in	Wed Jul  4 11:50:38 2001
@@ -18,11 +18,10 @@
 
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'Sysctl support' CONFIG_SYSCTL
 
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-  tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
-fi
 
 bool 'Use kernel gdb debugger' CONFIG_ETRAX_KGDB
 
@@ -38,9 +37,9 @@
 	 Etrax-100-LX-v2	CONFIG_ETRAX100LX_V2	\
 	 Etrax-100-LX-for-xsim-simulator   CONFIG_SVINTO_SIM" Etrax-100-LX-v1
 
-# For both LX version 1 and the current simulator we enable the low VM mapping
+# Etrax100 LX v1 has a MMU "feature" requiring a low mapping
 
-if [ "$CONFIG_ETRAX100LX" = "y" -o "$CONFIG_SVINTO_SIM" = "y" ]; then
+if [ "$CONFIG_ETRAX100LX" = "y" ]; then
 	define_bool CONFIG_CRIS_LOW_MAP y
 	define_hex  CONFIG_ETRAX_DRAM_VIRTUAL_BASE 60000000
 else
@@ -98,7 +97,7 @@
 hex 'R_WAITSTATES' CONFIG_ETRAX_DEF_R_WAITSTATES 95a6
 hex 'R_BUS_CONFIG' CONFIG_ETRAX_DEF_R_BUS_CONFIG 104
 
-bool 'SDRAM support' CONFIG_ETRAX_SDRAM n
+bool 'SDRAM support' CONFIG_ETRAX_SDRAM
 if [ "$CONFIG_ETRAX_SDRAM" = "n" ]; then
 	hex 'R_DRAM_CONFIG' CONFIG_ETRAX_DEF_R_DRAM_CONFIG 1a200040
 	hex 'R_DRAM_TIMING' CONFIG_ETRAX_DEF_R_DRAM_TIMING 5611
@@ -115,6 +114,12 @@
 hex 'R_PORT_PB_DIR' CONFIG_ETRAX_DEF_R_PORT_PB_DIR 00
 hex 'R_PORT_PB_DATA' CONFIG_ETRAX_DEF_R_PORT_PB_DATA ff
 
+bool 'Software Shutdown Support' CONFIG_ETRAX_SOFT_SHUTDOWN
+if [ "$CONFIG_ETRAX_SOFT_SHUTDOWN" = "y" ]; then
+   int 'Shutdown bit on port CSP0' CONFIG_ETRAX_SHUTDOWN_BIT 12
+   int 'Power button bit on port G' CONFIG_ETRAX_POWERBUTTON_BIT 25
+fi
+
 endmenu
 
 # bring in Etrax built-in drivers
@@ -164,7 +169,7 @@
 
 source drivers/ieee1394/Config.in
 
-source drivers/i2o/Config.in
+source drivers/message/i2o/Config.in
 
 if [ "$CONFIG_NET" = "y" ]; then
   mainmenu_option next_comment
@@ -214,8 +219,6 @@
 source drivers/media/Config.in
 
 source fs/Config.in
-
-source drivers/char/Config.in
 
 mainmenu_option next_comment
 comment 'Sound'
diff -u --recursive --new-file v2.4.6/linux/arch/cris/defconfig linux/arch/cris/defconfig
--- v2.4.6/linux/arch/cris/defconfig	Tue May  1 16:04:56 2001
+++ linux/arch/cris/defconfig	Wed Jul  4 11:50:38 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 
 #
 # Code maturity level options
@@ -13,8 +15,9 @@
 #
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
 CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_JAVA is not set
 # CONFIG_ETRAX_KGDB is not set
 # CONFIG_ETRAX_WATCHDOG is not set
 
@@ -27,16 +30,30 @@
 CONFIG_CRIS_LOW_MAP=y
 CONFIG_ETRAX_DRAM_VIRTUAL_BASE=60000000
 CONFIG_ETRAX_DRAM_SIZE=8
-CONFIG_ETRAX_FLASH_LENGTH=2
 CONFIG_ETRAX_FLASH_BUSWIDTH=2
 CONFIG_ETRAX_PA_LEDS=y
 # CONFIG_ETRAX_PB_LEDS is not set
-# CONFIG_ETRAX_90000000_LEDS is not set
+# CONFIG_ETRAX_CSP0_LEDS is not set
 # CONFIG_ETRAX_NO_LEDS is not set
 CONFIG_ETRAX_LED1G=2
 CONFIG_ETRAX_LED1R=2
 CONFIG_ETRAX_LED2G=2
 CONFIG_ETRAX_LED2R=2
+CONFIG_ETRAX_LED3R=2
+CONFIG_ETRAX_LED3G=2
+CONFIG_ETRAX_LED4R=2
+CONFIG_ETRAX_LED4G=2
+CONFIG_ETRAX_LED5R=2
+CONFIG_ETRAX_LED5G=2
+CONFIG_ETRAX_LED6R=2
+CONFIG_ETRAX_LED6G=2
+CONFIG_ETRAX_LED7R=2
+CONFIG_ETRAX_LED7G=2
+CONFIG_ETRAX_LED8Y=2
+CONFIG_ETRAX_LED9Y=2
+CONFIG_ETRAX_LED10Y=2
+CONFIG_ETRAX_LED11Y=2
+CONFIG_ETRAX_LED12R=2
 CONFIG_ETRAX_DEBUG_PORT0=y
 # CONFIG_ETRAX_DEBUG_PORT1 is not set
 # CONFIG_ETRAX_DEBUG_PORT2 is not set
@@ -55,13 +72,17 @@
 CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG=00
 CONFIG_ETRAX_DEF_R_PORT_PB_DIR=1e
 CONFIG_ETRAX_DEF_R_PORT_PB_DATA=f3
+# CONFIG_ETRAX_SOFT_SHUTDOWN is not set
 
 #
-# Drivers for Etrax built-in interfaces
+# Drivers for ETRAX 100LX built-in interfaces
 #
 CONFIG_ETRAX_ETHERNET=y
 CONFIG_NET_ETHERNET=y
-CONFIG_ETRAX_SERIAL=y
+# CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK is not set
+CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY=y
+C# CONFIG_ETRAX_ETHERNET_LPSLAVE is not set
+ONFIG_ETRAX_SERIAL=y
 # CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB is not set
 CONFIG_ETRAX_SERIAL_PORT1=y
 # CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PB is not set
@@ -71,6 +92,7 @@
 # CONFIG_ETRAX_SYNCHRONOUS_SERIAL is not set
 # CONFIG_ETRAX_IDE is not set
 CONFIG_ETRAX_AXISFLASHMAP=y
+CONFIG_ETRAX_PTABLE_SECTOR=65536
 CONFIG_MTD=y
 CONFIG_MTD_CFI=y
 # CONFIG_MTD_CFI_INTELEXT is not set
@@ -80,6 +102,7 @@
 CONFIG_MTD_BLOCK=y
 CONFIG_ETRAX_I2C=y
 CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C=y
+# CONFIG_ETRAX_I2C_EEPROM is not set
 CONFIG_ETRAX_GPIO=y
 CONFIG_ETRAX_PA_BUTTON_BITMASK=02
 CONFIG_ETRAX_PA_CHANGEABLE_DIR=00
@@ -87,21 +110,35 @@
 CONFIG_ETRAX_PB_CHANGEABLE_DIR=00
 CONFIG_ETRAX_PB_CHANGEABLE_BITS=FF
 # CONFIG_ETRAX_USB_HOST is not set
+# CONFIG_USB is not set
+# CONFIG_ETRAX_DS1302 is not set
 
 #
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
 # CONFIG_MTD_DOC1000 is not set
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOCPROBE is not set
+
+#
+# RAM/ROM Device Drivers
+#
 # CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_MTDRAM is not set
+
+#
+# Linearly Mapped Flash Device Drivers
+#
 CONFIG_MTD_CFI=y
 # CONFIG_MTD_CFI_GEOMETRY is not set
 # CONFIG_MTD_CFI_INTELEXT is not set
@@ -112,6 +149,7 @@
 # CONFIG_MTD_NORA is not set
 # CONFIG_MTD_PNC2000 is not set
 # CONFIG_MTD_RPXLITE is not set
+# CONFIG_MTD_SC520CDP is not set
 # CONFIG_MTD_SBC_MEDIAGX is not set
 # CONFIG_MTD_ELAN_104NC is not set
 # CONFIG_MTD_SA1100 is not set
@@ -121,8 +159,16 @@
 # CONFIG_MTD_MIXMEM is not set
 # CONFIG_MTD_OCTAGON is not set
 # CONFIG_MTD_VMAX is not set
+
+#
+# NAND Flash Device Drivers
+#
 # CONFIG_MTD_NAND is not set
 # CONFIG_MTD_NAND_SPIA is not set
+
+#
+# User Modules And Translation Layers
+#
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/Config.in linux/arch/cris/drivers/Config.in
--- v2.4.6/linux/arch/cris/drivers/Config.in	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/Config.in	Wed Jul  4 11:50:38 2001
@@ -6,10 +6,21 @@
 # this is just so that the user does not have to go into the
 # normal ethernet driver section just to enable ethernetworking
   define_bool CONFIG_NET_ETHERNET y
+  
+  choice 'Network LED behavior' \
+  "LED_on_when_link      CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK    \
+   LED_on_when_activity  CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY" \
+     LED_on_when_activity
+
 else
   define_bool CONFIG_NET_ETHERNET n
 fi
 
+bool 'Etrax Ethernet slave support (over lp0/1)' CONFIG_ETRAX_ETHERNET_LPSLAVE
+if [ "$CONFIG_ETRAX_ETHERNET_LPSLAVE" = "y" ]; then
+  bool '  Slave has its own LEDs' CONFIG_ETRAX_ETHERNET_LPSLAVE_HAS_LEDS
+fi 
+
 bool 'Serial-port support' CONFIG_ETRAX_SERIAL
 if [ "$CONFIG_ETRAX_SERIAL" = "y" ]; then
   comment '  Port 0 is always enabled'
@@ -99,7 +110,7 @@
 	define_bool CONFIG_BLK_DEV_IDEDMA y
 	define_bool CONFIG_DMA_NONPCI y
 	
-	int 'Delay for drives to regain consciousness' CONFIG_IDE_DELAY 15
+	int 'Delay for drives to regain consciousness' CONFIG_ETRAX_IDE_DELAY 15
 	
 	choice 'IDE reset pin' \
   	"Port_PB_Bit_7  CONFIG_ETRAX_IDE_PB7_RESET\
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/Makefile linux/arch/cris/drivers/Makefile
--- v2.4.6/linux/arch/cris/drivers/Makefile	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/Makefile	Wed Jul  4 11:50:38 2001
@@ -7,18 +7,21 @@
 obj-y :=
 
 
-obj-$(CONFIG_ETRAX_ETHERNET)           += ethernet.o
-obj-$(CONFIG_ETRAX_SERIAL)             += serial.o
-obj-$(CONFIG_ETRAX_IDE)                += ide.o
-obj-$(CONFIG_ETRAX_AXISFLASHMAP)       += axisflashmap.o
-obj-$(CONFIG_ETRAX_I2C) 	       += i2c.o
-obj-$(CONFIG_ETRAX_I2C_EEPROM)         += eeprom.o
-obj-$(CONFIG_ETRAX_GPIO) 	       += gpio.o
-obj-$(CONFIG_ETRAX_USB_HOST)           += usb-host.o
-obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o
-obj-$(CONFIG_ETRAX_PARPORT)            += parport.o
-obj-$(CONFIG_ETRAX_DS1302)             += ds1302.o
+obj-$(CONFIG_ETRAX_ETHERNET)            += ethernet.o
+obj-$(CONFIG_ETRAX_SERIAL)              += serial.o
+obj-$(CONFIG_ETRAX_IDE)                 += ide.o
+obj-$(CONFIG_ETRAX_AXISFLASHMAP)        += axisflashmap.o
+obj-$(CONFIG_ETRAX_I2C) 	        += i2c.o
+obj-$(CONFIG_ETRAX_I2C_EEPROM)          += eeprom.o
+obj-$(CONFIG_ETRAX_GPIO) 	        += gpio.o
+obj-$(CONFIG_ETRAX_USB_HOST)            += usb-host.o
+obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL)  += sync_serial.o
+obj-$(CONFIG_ETRAX_PARPORT)             += parport.o
+obj-$(CONFIG_ETRAX_DS1302)              += ds1302.o
 
 
+obj-$(CONFIG_ETRAX_ETHERNET_LPSLAVE)    += lpslave/lpslavedrivers.o
+subdir-$(CONFIG_ETRAX_ETHERNET_LPSLAVE) += lpslave
 
 include $(TOPDIR)/Rules.make
+
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/axisflashmap.c linux/arch/cris/drivers/axisflashmap.c
--- v2.4.6/linux/arch/cris/drivers/axisflashmap.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/axisflashmap.c	Wed Jul  4 11:50:38 2001
@@ -11,6 +11,23 @@
  * partition split defined below.
  *
  * $Log: axisflashmap.c,v $
+ * Revision 1.12  2001/06/11 09:50:30  jonashg
+ * Oops, 2MB is 0x200000 bytes.
+ *
+ * Revision 1.11  2001/06/08 11:39:44  jonashg
+ * Changed sizes and offsets in axis_default_partitions to use
+ * CONFIG_ETRAX_PTABLE_SECTOR.
+ *
+ * Revision 1.10  2001/05/29 09:42:03  jonashg
+ * Use macro for end marker length instead of sizeof.
+ *
+ * Revision 1.9  2001/05/29 08:52:52  jonashg
+ * Gave names to the magic fours (size of the ptable end marker).
+ *
+ * Revision 1.8  2001/05/28 15:36:20  jonashg
+ * * Removed old comment about ptable location in flash (it's a CONFIG_ option).
+ * * Variable ptable was initialized twice to the same value.
+ *
  * Revision 1.7  2001/04/05 13:41:46  markusl
  * Updated according to review remarks
  *
@@ -130,6 +147,10 @@
 #define MAX_PARTITIONS         7  
 #define NUM_DEFAULT_PARTITIONS 3
 
+/* Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the
+ * size of one flash block and "filesystem"-partition needs 5 blocks to be able
+ * to use JFFS.
+ */
 static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
 	{
 		name: "boot firmware",
@@ -138,13 +159,13 @@
 	},
 	{
 		name: "kernel",
-		size: 0x1a0000,
+		size: 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR),
 		offset: CONFIG_ETRAX_PTABLE_SECTOR
 	},
 	{
 		name: "filesystem",
-		size: 0x50000,
-		offset: (0x1a0000 + CONFIG_ETRAX_PTABLE_SECTOR)
+		size: 5 * CONFIG_ETRAX_PTABLE_SECTOR,
+		offset: 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR)
 	}
 };
 
@@ -223,21 +244,17 @@
 
 	mymtd->module = THIS_MODULE;
 
-	/* The partition-table is at an offset within the second 
-	 * sector of the flash. We _define_ this to be at offset 64k
-	 * even if the actual sector-size in the flash changes.. for
-	 * now at least.
-	 */
-
 	ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR +
 		CONFIG_ETRAX_PTABLE_SECTOR + PARTITION_TABLE_OFFSET);
 	pidx++;  /* first partition is always set to the default */
 
 	if ((ptable_head->magic == PARTITION_TABLE_MAGIC)
 	    && (ptable_head->size <
-		(MAX_PARTITIONS * sizeof(struct partitiontable_entry) + 4))
+		(MAX_PARTITIONS * sizeof(struct partitiontable_entry) +
+		PARTITIONTABLE_END_MARKER_SIZE))
 	    && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) +
-				  ptable_head->size - 4)
+				  ptable_head->size -
+				  PARTITIONTABLE_END_MARKER_SIZE)
 		== PARTITIONTABLE_END_MARKER)) {
 		/* Looks like a start, sane length and end of a
 		 * partition table, lets check csum etc.
@@ -268,9 +285,6 @@
 		ptable_ok = (csum == ptable_head->checksum);
 
 		/* Read the entries and use/show the info.  */
-		ptable = (struct partitiontable_entry *)
-			((unsigned long)ptable_head + sizeof(*ptable_head));
-		
 		printk(" Found %s partition table at 0x%08lX-0x%08lX.\n",
 		       (ptable_ok ? "valid" : "invalid"),
 		       (unsigned long)ptable_head,
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/ds1302.c linux/arch/cris/drivers/ds1302.c
--- v2.4.6/linux/arch/cris/drivers/ds1302.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/ds1302.c	Wed Jul  4 11:50:38 2001
@@ -7,6 +7,32 @@
 *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init, get_rtc_status
 *!
 *! $Log: ds1302.c,v $
+*! Revision 1.11  2001/06/14 12:35:52  jonashg
+*! The ATA hack is back. It is unfortunately the only way to set g27 to output.
+*!
+*! Revision 1.9  2001/06/14 10:00:14  jonashg
+*! No need for tempudelay to be inline anymore (had to adjust the usec to
+*! loops conversion because of this to make it slow enough to be a udelay).
+*!
+*! Revision 1.8  2001/06/14 08:06:32  jonashg
+*! Made tempudelay delay usecs (well, just a tad more).
+*!
+*! Revision 1.7  2001/06/13 14:18:11  jonashg
+*! Only allow processes with SYS_TIME capability to set time and charge.
+*!
+*! Revision 1.6  2001/06/12 15:22:07  jonashg
+*! * Made init function __init.
+*! * Parameter to out_byte() is unsigned char.
+*! * The magic number 42 has got a name.
+*! * Removed comment about /proc (nothing is exported there).
+*!
+*! Revision 1.5  2001/06/12 14:35:13  jonashg
+*! Gave the module a name and added it to printk's.
+*!
+*! Revision 1.4  2001/05/31 14:53:40  jonashg
+*! Made tempudelay() inline so that the watchdog doesn't reset (see
+*! function comment).
+*!
 *! Revision 1.3  2001/03/26 16:03:06  bjornw
 *! Needs linux/config.h
 *!
@@ -56,13 +82,14 @@
 *!
 *! (C) Copyright 1999, 2000, 2001  Axis Communications AB, LUND, SWEDEN
 *!
-*! $Id: ds1302.c,v 1.3 2001/03/26 16:03:06 bjornw Exp $
+*! $Id: ds1302.c,v 1.11 2001/06/14 12:35:52 jonashg Exp $
 *!
 *!***************************************************************************/
 
 #include <linux/config.h>
 
 #include <linux/fs.h>
+#include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/miscdevice.h>
@@ -76,13 +103,15 @@
 
 #define RTC_MAJOR_NR 121 /* local major, change later */
 
+static const char ds1302_name[] = "ds1302";
+
 /* The DS1302 might be connected to different bits on different products. 
  * It has three signals - SDA, SCL and RST. RST and SCL are always outputs,
  * but SDA can have a selected direction.
  * For now, only PORT_PB is hardcoded.
  */
 
-/* The RST bit may be on either the Generic Port or Port PB */
+/* The RST bit may be on either the Generic Port or Port PB. */
 #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
 #define TK_RST_OUT(x) REG_SHADOW_SET(R_PORT_G_DATA,  port_g_data_shadow,  CONFIG_ETRAX_DS1302_RSTBIT, x)
 #define TK_RST_DIR(x)
@@ -106,21 +135,23 @@
  * (used in udelay) is not set when functions here are called from time.c 
  */
 
-static void tempudelay(int time) 
+static void tempudelay(int usecs) 
 {
-	int i;
-	for(i = 0; i < time * 10000; i++);	
+	volatile int loops;
+
+	for(loops = usecs * 12; loops > 0; loops--)
+		/* nothing */;	
 }
 
 
-/* send 8 bits */
+/* Send 8 bits. */
 static void
-out_byte(int x) 
+out_byte(unsigned char x) 
 {
 	int i;
 	TK_SDA_DIR(1);
 	for (i = 8; i--;) {
-		/* the chip latches incoming bits on the rising edge of SCL */
+		/* The chip latches incoming bits on the rising edge of SCL. */
 		TK_SCL_OUT(0);
 		TK_SDA_OUT(x & 1);
 		tempudelay(1);
@@ -138,7 +169,7 @@
 	int i;
 
 	/* Read byte. Bits come LSB first, on the falling edge of SCL.
-	 * Assume SDA is in input direction already
+	 * Assume SDA is in input direction already.
 	 */
 	TK_SDA_DIR(0);
 
@@ -154,7 +185,7 @@
 	return x;
 }
 
-/* prepares for a transaction by de-activating RST (active-low) */
+/* Prepares for a transaction by de-activating RST (active-low). */
 
 static void
 start(void) 
@@ -166,7 +197,7 @@
 	TK_RST_OUT(1);	
 }
 
-/* ends a transaction by taking RST active again */
+/* Ends a transaction by taking RST active again. */
 
 static void
 stop(void) 
@@ -175,7 +206,7 @@
 	TK_RST_OUT(0);
 }
 
-/* enable writing */
+/* Enable writing. */
 
 static void
 ds1302_wenable(void) 
@@ -186,7 +217,7 @@
 	stop();
 }
 
-/* disable writing */
+/* Disable writing. */
 
 static void
 ds1302_wdisable(void) 
@@ -197,7 +228,9 @@
 	stop();
 }
 
-/* probe for the chip by writing something to its RAM and try reading it back */
+/* Probe for the chip by writing something to its RAM and try reading it back. */
+
+#define MAGIC_PATTERN 0x42
 
 static int
 ds1302_probe(void) 
@@ -208,36 +241,36 @@
 	TK_SCL_DIR(1);
 	TK_SDA_DIR(0);
 	
-	/* try to talk to timekeeper */
+	/* Try to talk to timekeeper. */
 
 	ds1302_wenable();  
 	start();
 	out_byte(0xc0); /* write RAM byte 0 */	
-	out_byte(0x42); /* write something magic */
+	out_byte(MAGIC_PATTERN); /* write something magic */
 	start();
 	out_byte(0xc1); /* read RAM byte 0 */
 
-	if((res = in_byte()) == 0x42) {
+	if((res = in_byte()) == MAGIC_PATTERN) {
 		char buf[100];
 		stop();
 		ds1302_wdisable();
-		printk("DS1302 RTC found.\n");
-                printk("SDA, SCL, RST on PB%i, PB%i, %s%i\n",
-                       CONFIG_ETRAX_DS1302_SDABIT,
-                       CONFIG_ETRAX_DS1302_SCLBIT,
+		printk("%s: RTC found.\n", ds1302_name);
+		printk("%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n",
+		       ds1302_name,
+		       CONFIG_ETRAX_DS1302_SDABIT,
+		       CONFIG_ETRAX_DS1302_SCLBIT,
 #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
-                       "GENIO",
+		       "GENIO",
 #else
-                       "PB",
+		       "PB",
 #endif
-                       CONFIG_ETRAX_DS1302_RSTBIT
-                       );
+		       CONFIG_ETRAX_DS1302_RSTBIT);
                 get_rtc_status(buf);
                 printk(buf);
 		retval = 1;
 	} else {
 		stop();
-		printk("DS1302 RTC not found.\n");
+		printk("%s: RTC not found.\n", ds1302_name);
 		retval = 0;
 	}
 
@@ -245,7 +278,7 @@
 }
 
 
-/* read a byte from the selected register in the DS1302 */
+/* Read a byte from the selected register in the DS1302. */
 
 unsigned char
 ds1302_readreg(int reg) 
@@ -253,21 +286,21 @@
 	unsigned char x;
 
 	start();
-	out_byte(0x81 | (reg << 1)); /* Read register */
+	out_byte(0x81 | (reg << 1)); /* read register */
 	x = in_byte();
 	stop();
 
 	return x;
 }
 
-/* write a byte to the selected register */
+/* Write a byte to the selected register. */
 
 void
 ds1302_writereg(int reg, unsigned char val) 
 {
 	ds1302_wenable();
 	start();
-	out_byte(0x80 | (reg << 1)); /* Write register */
+	out_byte(0x80 | (reg << 1)); /* write register */
 	out_byte(val);
 	stop();
 	ds1302_wdisable();
@@ -311,7 +344,7 @@
 static unsigned char days_in_mo[] = 
     {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
-/* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date) */
+/* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date). */
 
 static int
 rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
@@ -320,7 +353,7 @@
         unsigned long flags;
 
 	switch(cmd) {
-		case RTC_RD_TIME:	/* Read the time/date from RTC	*/
+		case RTC_RD_TIME:	/* read the time/date from RTC	*/
 		{
 			struct rtc_time rtc_tm;
 						
@@ -330,16 +363,16 @@
 			return 0;
 		}
 
-		case RTC_SET_TIME:	/* Set the RTC */
+		case RTC_SET_TIME:	/* set the RTC */
 		{
 			struct rtc_time rtc_tm;
 			unsigned char mon, day, hrs, min, sec, leap_yr;
 			unsigned char save_control, save_freq_select;
 			unsigned int yrs;
-#if 0
-			if (!suser())
-				return -EACCES;
-#endif			
+
+			if (!capable(CAP_SYS_TIME))
+				return -EPERM;
+
 			if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
 				return -EFAULT;    	
 
@@ -387,21 +420,21 @@
 			CMOS_WRITE(sec, RTC_SECONDS);
 			restore_flags(flags);
 
-			/* notice that at this point, the RTC is updated but the kernel
-			 * is still running with the old time. you need to set that
-			 * separately with settimeofday or adjtimex.
+			/* Notice that at this point, the RTC is updated but
+			 * the kernel is still running with the old time.
+			 * You need to set that separately with settimeofday
+			 * or adjtimex.
 			 */
 			return 0;
 		}
 
-		case RTC_SET_CHARGE: /* Set the RTC TRICKLE CHARGE register */
+		case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */
 		{
 			int tcs_val;                        
 			unsigned char save_control, save_freq_select;
-#if 0
-			if (!suser())
-				return -EACCES;
-#endif
+
+			if (!capable(CAP_SYS_TIME))
+				return -EPERM;
 			
 			if(copy_from_user(&tcs_val, (int*)arg, sizeof(int)))
 				return -EFAULT;
@@ -415,10 +448,6 @@
 	}
 }
 
-/*
- *	Info exported via "/proc/rtc".
- */
-
 int
 get_rtc_status(char *buf) 
 {
@@ -444,45 +473,41 @@
 }
 
 
-/*
- *	The various file operations we support.
- */
+/* The various file operations we support. */
 
 static struct file_operations rtc_fops = {
         owner:          THIS_MODULE,
         ioctl:          rtc_ioctl,	
 }; 
 
-/* just probe for the RTC and register the device to handle the ioctl needed */
+/* Just probe for the RTC and register the device to handle the ioctl needed. */
 
-int
+int __init
 ds1302_init(void) 
 { 
-  
- /* Ugly hack to handle both 2100 and 2400 hardware.
-    Remove...
- */
-	if(!ds1302_probe()) {
+	if (!ds1302_probe()) {
 #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
-    	/*
-     	* Make sure that R_GEN_CONFIG is 
-     	* setup correct.
-     	*/
-    		genconfig_shadow = ( (genconfig_shadow & ~IO_MASK(R_GEN_CONFIG, ata) ) | 
-                           ( IO_STATE( R_GEN_CONFIG, ata, select ) ) );    
+		/*
+		 * The only way to set g27 to output is to enable ATA.
+		 *
+		 * Make sure that R_GEN_CONFIG is setup correct.
+		 */
+    		genconfig_shadow = ((genconfig_shadow &
+				     ~IO_MASK(R_GEN_CONFIG, ata))
+				   | 
+				   (IO_STATE(R_GEN_CONFIG, ata, select)));    
     		*R_GEN_CONFIG = genconfig_shadow;
-    		if(!ds1302_probe())
+    		if (!ds1302_probe())
       			return -1;
 #else
     		return -1;
 #endif
   	}
   
-	if (register_chrdev(RTC_MAJOR_NR, "rtc", &rtc_fops)) {
-		printk("unable to get major %d for rtc\n", RTC_MAJOR_NR);
+	if (register_chrdev(RTC_MAJOR_NR, ds1302_name, &rtc_fops)) {
+		printk(KERN_INFO "%s: unable to get major %d for rtc\n", 
+		       ds1302_name, RTC_MAJOR_NR);
 		return -1;
 	}
 	return 0;
 }
-
-
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/eeprom.c linux/arch/cris/drivers/eeprom.c
--- v2.4.6/linux/arch/cris/drivers/eeprom.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/eeprom.c	Wed Jul  4 11:50:38 2001
@@ -1,32 +1,12 @@
-/*!**************************************************************************
+/*!*****************************************************************************
 *!
-*!  FILE NAME:      e100eeprom.c
-*!
-*!  DESCRIPTION:    Implements an interface for i2c compatible eeproms to run
-*!                  under linux.
-*!                  Supports 2k, 8k(?) and 16k
-*!                  Uses adaptive timing adjustents by Johan.Adolfsson@axis.com
-*!                  Probing results:
-*!                    8k or not is detected (the assumes 2k or 16k)
-*!                    2k or 16k detected using test reads and writes.
-*!
-*!  FUNCTIONS:
-*!
-*!  (Exported)
-*!              eeprom_init()
-*!
-*!  (Local)
-*!
-*!              eeprom_open()
-*!              eeprom_lseek()
-*!              eeprom_read()
-*!              eeprom_write()
-*!              eeprom_close()
-*!              eeprom_address()
-*!              eeprom_disable_write_protect()
-*!
-*!
-*!  $Id: eeprom.c,v 1.3 2001/03/19 16:04:46 markusl Exp $
+*!  Implements an interface for i2c compatible eeproms to run under linux.
+*!  Supports 2k, 8k(?) and 16k. Uses adaptive timing adjustents by
+*!  Johan.Adolfsson@axis.com
+*!
+*!  Probing results:
+*!    8k or not is detected (the assumes 2k or 16k)
+*!    2k or 16k detected using test reads and writes.
 *!
 *!------------------------------------------------------------------------
 *!  HISTORY
@@ -40,6 +20,13 @@
 *!                                  in the spin-lock.
 *!
 *!  $Log: eeprom.c,v $
+*!  Revision 1.5  2001/06/14 14:39:51  jonashg
+*!  Forgot to use name when registering the driver.
+*!
+*!  Revision 1.4  2001/06/14 14:35:47  jonashg
+*!  * Gave driver a name and used it in printk's.
+*!  * Cleanup.
+*!
 *!  Revision 1.3  2001/03/19 16:04:46  markusl
 *!  Fixed init of fops struct
 *!
@@ -64,9 +51,7 @@
 *!
 *!
 *!        (c) 1999 Axis Communications AB, Lund, Sweden
-*!**************************************************************************/
-
-/********************** INCLUDE FILES SECTION ******************************/
+*!*****************************************************************************/
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -76,7 +61,6 @@
 #include <linux/delay.h>
 #include "i2c.h"
 
-/********************** CONSTANT AND MACRO SECTION *************************/
 #define D(x) 
 
 /* If we should use adaptive timing or not: */
@@ -86,9 +70,8 @@
 #define EEPROM_MINOR_NR 0
 
 #define MAX_WRITEDELAY_US 10000 /* 10 ms according to spec for 2KB EEPROM */
-/*
- *  this one defines how many times to try when eeprom fails.
- */
+
+/* This one defines how many times to try when eeprom fails. */
 #define EEPROM_RETRIES 10
 
 #define EEPROM_2KB (2 * 1024)
@@ -98,8 +81,6 @@
 
 #define i2c_delay(x) udelay(x)
 
-/********************** TYPE DEFINITION SECTION ****************************/
-
 /*
  *  This structure describes the attached eeprom chip.
  *  The values are probed for.
@@ -110,51 +91,42 @@
   unsigned long size;
   unsigned long sequential_write_pagesize;
   unsigned char select_cmd;
-  unsigned long usec_delay_writecycles; /* Min time between write cycles (up to 10ms for some models) */
-  unsigned long int usec_delay_step; /* For adaptive algorithm */
+  unsigned long usec_delay_writecycles; /* Min time between write cycles
+					   (up to 10ms for some models) */
+  unsigned long usec_delay_step; /* For adaptive algorithm */
   int adapt_state; /* 1 = To high , 0 = Even, -1 = To low */
   
   /* this one is to keep the read/write operations atomic */
   wait_queue_head_t wait_q;
   int busy;
   int retry_cnt_addr; /* Used to keep track of number of retries for
-                     adaptive timing adjustments */
+                         adaptive timing adjustments */
   int retry_cnt_read;
-
-  
-  
 };
 
-/********************** LOCAL FUNCTION DECLARATION SECTION *****************/
-
-static int  eeprom_open (struct inode * inode, struct file * file);
+static int  eeprom_open(struct inode * inode, struct file * file);
 static loff_t  eeprom_lseek(struct file * file, loff_t offset, int orig);
-static ssize_t  eeprom_read (struct file * file, char * buf, size_t count, loff_t *off);
-static ssize_t  eeprom_write(struct file * file, const char * buf, size_t count, loff_t *off);
+static ssize_t  eeprom_read(struct file * file, char * buf, size_t count,
+                            loff_t *off);
+static ssize_t  eeprom_write(struct file * file, const char * buf, size_t count,
+                             loff_t *off);
 static int eeprom_close(struct inode * inode, struct file * file);
 
 static int  eeprom_address(unsigned long addr);
 static int  read_from_eeprom(char * buf, int count);
-static int eeprom_write_buf(unsigned long int addr,
-                            const char * buf, int count);
+static int eeprom_write_buf(unsigned long addr, const char * buf, int count);
 static int eeprom_read_buf(unsigned long addr,
                            char * buf, int count);
 
 static void eeprom_disable_write_protect(void);
 
 
-/********************** GLOBAL VARIABLE DECLARATION SECTION ****************/
-
-/********************** LOCAL VARIABLE DECLARATION SECTION *****************/
+static const char eeprom_name[] = "eeprom";
 
 /* chip description */
 static struct eeprom_type eeprom;
 
-/*
- *  This is the exported file-operations structure
- *  for this device.
- */
-
+/* This is the exported file-operations structure for this device. */
 struct file_operations eeprom_fops =
 {
   llseek:  eeprom_lseek,
@@ -164,29 +136,7 @@
   release: eeprom_close
 };
 
-/********************** FUNCTION DEFINITION SECTION ************************/
-
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_init
-*#                                                            
-*# PARAMETERS   : none
-*#                                                            
-*# RETURNS      : 0 if OK
-*#                                                            
-*# SIDE EFFECTS : 
-*#                                                            
-*# DESCRIPTION  : eeprom init call. Probes for different eeprom models.
-*#                                                            
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#                                                            
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Aug 28 1999  Edgar Iglesias  Initial version               
-*# Sep 03 1999  Edgar Iglesias  Updated probing. Added forced values.
-*#
-*#**************************************************************************/
+/* eeprom init call. Probes for different eeprom models. */
 
 int __init eeprom_init(void)
 {
@@ -198,9 +148,10 @@
 #else
 #define EETEXT "Assuming"
 #endif
-  if (register_chrdev(EEPROM_MAJOR_NR, "mem", &eeprom_fops))
+  if (register_chrdev(EEPROM_MAJOR_NR, eeprom_name, &eeprom_fops))
   {
-    printk("unable to get major %d for eeprom device\n", EEPROM_MAJOR_NR);
+    printk(KERN_INFO "%s: unable to get major %d for eeprom device\n",
+           eeprom_name, EEPROM_MAJOR_NR);
     return -1;
   }
   
@@ -213,7 +164,6 @@
    *        for all models. If you encounter problems the easiest way
    *        is probably to define your model within #ifdef's, and hard-
    *        code it.
-   *
    */
 
   eeprom.size = 0;
@@ -240,7 +190,6 @@
      * 2. if it doesn't differ - write diferent value to one of the locations,
      *    check the other - if content still is the same it's a 2k EEPROM,
      *    restore original data.
-     *    
      */
 #define LOC1 8
 #define LOC2 (0x1fb) /*1fb, 3ed, 5df, 7d1 */
@@ -256,7 +205,7 @@
     }
     else
     {
-      printk("Failed to read in 2k mode!\n");  
+      printk(KERN_INFO "%s: Failed to read in 2k mode!\n", eeprom_name);  
     }
     
     /* 16k settings */
@@ -276,7 +225,7 @@
           if (memcmp(loc1, loc2, 4) != 0 )
           {
             /* It's 16k */
-            printk("16k detected in step 1\n");
+            printk(KERN_INFO "%s: 16k detected in step 1\n", eeprom_name);
             eeprom.size = EEPROM_16KB;     
             success = 1;
           }
@@ -299,7 +248,8 @@
                          LOC1, loc1, tmp));
                 if (memcmp(loc1, tmp, 4) != 0 )
                 {
-                  printk("read and write differs! Not 16kB\n");
+                  printk(KERN_INFO "%s: read and write differs! Not 16kB\n",
+                         eeprom_name);
                   loc1[0] = ~loc1[0];
                   
                   if (eeprom_write_buf(LOC1, loc1, 1) == 1)
@@ -308,7 +258,8 @@
                   }
                   else
                   {
-                    printk("eeprom: Restore 2k failed during probe EEPROM might be corrupt!\n");
+                    printk(KERN_INFO "%s: Restore 2k failed during probe,"
+                           " EEPROM might be corrupt!\n", eeprom_name);
                     
                   }
                   i2c_stop();
@@ -321,7 +272,8 @@
                   }
                   else
                   {
-                    printk("Failed to write back 2k start!\n");
+                    printk(KERN_INFO "%s: Failed to write back 2k start!\n",
+                           eeprom_name);
                   }
                   
                   eeprom.size = EEPROM_2KB;
@@ -338,7 +290,7 @@
                   {
                     /* Data the same, must be mirrored -> 2k */
                     /* Restore data */
-                    printk("2k detected in step 2\n");
+                    printk(KERN_INFO "%s: 2k detected in step 2\n", eeprom_name);
                     loc1[0] = ~loc1[0];
                     if (eeprom_write_buf(LOC1, loc1, 1) == 1)
                     {
@@ -346,7 +298,8 @@
                     }
                     else
                     {
-                      printk("eeprom: Restore 2k failed during probe EEPROM might be corrupt!\n");
+                      printk(KERN_INFO "%s: Restore 2k failed during probe,"
+                             " EEPROM might be corrupt!\n", eeprom_name);
                       
                     }
                     
@@ -354,7 +307,8 @@
                   }
                   else
                   {
-                    printk("16k detected in step 2\n");
+                    printk(KERN_INFO "%s: 16k detected in step 2\n",
+                           eeprom_name);
                     loc1[0] = ~loc1[0];
                     /* Data differs, assume 16k */
                     /* Restore data */
@@ -364,7 +318,8 @@
                     }
                     else
                     {
-                      printk("eeprom: Restore 16k failed during probe EEPROM might be corrupt!\n");
+                      printk(KERN_INFO "%s: Restore 16k failed during probe,"
+                             " EEPROM might be corrupt!\n", eeprom_name);
                     }
                     
                     eeprom.size = EEPROM_16KB;
@@ -376,7 +331,7 @@
         } /* address LOC1 */
         if (!success)
         {
-          printk("eeprom: Probing failed!, using 2KB!\n");
+          printk(KERN_INFO "%s: Probing failed!, using 2KB!\n", eeprom_name);
           eeprom.size = EEPROM_2KB;               
         }
       } /* read */
@@ -418,23 +373,23 @@
   switch(eeprom.size)
   {
    case (EEPROM_2KB):
-     printk("e100eeprom: " EETEXT " i2c compatible 2Kb eeprom.\n");
+     printk("%s: " EETEXT " i2c compatible 2Kb eeprom.\n", eeprom_name);
      eeprom.sequential_write_pagesize = 16;
      eeprom.select_cmd = 0xA0;
      break;
    case (EEPROM_8KB):
-     printk("e100eeprom: " EETEXT " i2c compatible 8Kb eeprom.\n");
+     printk("%s: " EETEXT " i2c compatible 8Kb eeprom.\n", eeprom_name);
      eeprom.sequential_write_pagesize = 16;
      eeprom.select_cmd = 0x80;
      break;
    case (EEPROM_16KB):
-     printk("e100eeprom: " EETEXT " i2c compatible 16Kb eeprom.\n");
+     printk("%s: " EETEXT " i2c compatible 16Kb eeprom.\n", eeprom_name);
      eeprom.sequential_write_pagesize = 64;
      eeprom.select_cmd = 0xA0;     
      break;
    default:
      eeprom.size = 0;
-     printk("e100eeprom: Did not find a supported eeprom\n");
+     printk("%s: Did not find a supported eeprom\n", eeprom_name);
      break;
   }
 
@@ -445,28 +400,7 @@
   return 0;
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_open
-*#                                                            
-*# PARAMETERS   : inode    : Pointer to the inode
-*#                file     : Pointer to the file
-*#                                                            
-*# RETURNS      : 0 if OK
-*#                                                            
-*# SIDE EFFECTS : 
-*#                                                            
-*# DESCRIPTION  : Opens the device.
-*#                                                            
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#                                                            
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Aug 28 1999  Edgar Iglesias  Initial version               
-*# Sep 03 1999  Edgar Iglesias  Removed users check.
-*#
-*#**************************************************************************/
+/* Opens the device. */
 
 static int eeprom_open(struct inode * inode, struct file * file)
 {
@@ -486,29 +420,7 @@
   return -EFAULT;
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_lseek
-*#                                                            
-*# PARAMETERS   : file     : Pointer to the file
-*#                offset   : The offset (in bytes)
-*#                orig     : look at the note
-*#                                                            
-*# RETURNS      : 0 if OK
-*#                                                            
-*# SIDE EFFECTS : 
-*#                                                            
-*# DESCRIPTION  : Changes the current file position.
-*#                                                            
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#                                                            
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Aug 28 1999  Edgar Iglesias  Initial version
-*# Sep 03 1999  Edgar Iglesias  Return -EOVERFLOW when beyond eeprom size.
-*#
-*#**************************************************************************/
+/* Changes the current file position. */
 
 static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig)
 {
@@ -549,29 +461,8 @@
   return ( file->f_pos );
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_read
-*#                                                            
-*# PARAMETERS   : inode    : Pointer to the inode
-*#                file     : Pointer to the file
-*#                buf      : Destination buffer
-*#                count    : max nr bytes to read
-*#                                                            
-*# RETURNS      : number of read bytes.
-*#                                                            
-*# SIDE EFFECTS : updates file->f_pos
-*#                                                            
-*# DESCRIPTION  : Reads data from eeprom.
-*#                                                            
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#                                                            
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Jan 17 2000  Johan Adolfsson Initial version
-*#
-*#**************************************************************************/
+/* Reads data from eeprom. */
+
 static int eeprom_read_buf(unsigned long addr,
                            char * buf, int count)
 {
@@ -583,31 +474,7 @@
 
 
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_read
-*#                                                            
-*# PARAMETERS   : file     : Pointer to the file
-*#                buf      : Destination buffer
-*#                count    : max nr bytes to read
-*#                                                            
-*# RETURNS      : number of read bytes.
-*#                                                            
-*# SIDE EFFECTS : updates file->f_pos
-*#                                                            
-*# DESCRIPTION  : Reads data from eeprom.
-*#                                                            
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#                                                            
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Aug 28 1999  Edgar Iglesias  Initial version               
-*# Aug 31 1999  Edgar Iglesias  Made operation atomic with wait queues
-*# Sep 03 1999  Edgar Iglesias  Added bail-out stuff if we get interrupted
-*#                              in the spin-lock.
-*#
-*#**************************************************************************/
+/* Reads data from eeprom. */
 
 static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off)
 {
@@ -636,8 +503,8 @@
   
   if(!eeprom_address(p))
   {
-    printk("eeprom: Read failed to address the eeprom: "
-           "0x%08X (%i) page: %i\n", p, p, page);
+    printk(KERN_INFO "%s: Read failed to address the eeprom: "
+           "0x%08X (%i) page: %i\n", eeprom_name, p, p, page);
     i2c_stop();
     
     /* don't forget to wake them up */
@@ -674,30 +541,9 @@
   return read;
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_write_buf
-*#                                                            
-*# PARAMETERS   : addr     : Address to write to
-*#                buf      : Data buffer to write from
-*#                count    : number bytes to write
-*#                                                            
-*# RETURNS      : number of bytes actualy written.
-*#                                                            
-*# SIDE EFFECTS : None
-*#             
-*# DESCRIPTION  : Writes data to eeprom.
-*#                                                            
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#                                                            
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Jan 17 2000  Johan Adolfsson Initial vesion
-*#
-*#**************************************************************************/
-static int eeprom_write_buf(unsigned long int addr,
-                            const char * buf, int count)
+/* Writes data to eeprom. */
+
+static int eeprom_write_buf(unsigned long addr, const char * buf, int count)
 {
   struct file f;
 
@@ -707,33 +553,7 @@
 }
 
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_write
-*#                                                            
-*# PARAMETERS   : file     : Pointer to the file
-*#                buf      : Data buffer to write from
-*#                count    : number bytes to write
-*#                                                            
-*# RETURNS      : number of bytes actualy written.
-*#                                                            
-*# SIDE EFFECTS : updates file->f_pos
-*#             
-*# DESCRIPTION  : Writes data to eeprom.
-*#                                                            
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#                                                            
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Aug 28 1999  Edgar Iglesias  Initial version               
-*# Aug 31 1999  Edgar Iglesias  Made operation atomic with wait queues
-*# Sep 03 1999  Edgar Iglesias  Moved the actual reading to read_from_eeprom
-*# Sep 03 1999  Edgar Iglesias  Added bail-out stuff if we get interrupted
-*#                              in the spin-lock.
-*# May 18 2000  Edgar Iglesias  Make sure to end write cycle after every write.
-*#
-*#**************************************************************************/
+/* Writes data to eeprom. */
 
 static ssize_t eeprom_write(struct file * file, const char * buf, size_t count,
                             loff_t *off)
@@ -761,8 +581,8 @@
       /* address the eeprom */
       if(!eeprom_address(p))
       {
-        printk("eeprom: Write failed to address the eeprom: 0x%08X (%i) \n", 
-               p, p);
+        printk(KERN_INFO "%s: Write failed to address the eeprom: "
+               "0x%08X (%i) \n", eeprom_name, p, p);
         i2c_stop();
         
         /* don't forget to wake them up */
@@ -868,7 +688,7 @@
         if(!i2c_getack())
         {
           restart=1;
-          printk("eeprom: write error, retrying. %d\n", i);
+          printk(KERN_INFO "%s: write error, retrying. %d\n", eeprom_name, i);
           i2c_stop();
           break;
         }
@@ -891,28 +711,7 @@
   return written;
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_close
-*#                                                            
-*# PARAMETERS   : inode    : Pointer to the inode
-*#                file     : Pointer to the file
-*#
-*# RETURNS      : nothing
-*#
-*# SIDE EFFECTS :
-*#
-*# DESCRIPTION  : Closes the device.
-*#
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Aug 28 1999  Edgar Iglesias  Initial version               
-*# Sep 03 1999  Edgar Iglesias  Removed eeprom.users stuff.
-*#
-*#**************************************************************************/
+/* Closes the device. */
 
 static int eeprom_close(struct inode * inode, struct file * file)
 {
@@ -920,27 +719,7 @@
   return 0;
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_address
-*#                                                            
-*# PARAMETERS   : addr     : Address to be given to eeprom
-*#
-*# RETURNS      : 1 if OK, 0 if failure.
-*#
-*# SIDE EFFECTS :
-*#
-*# DESCRIPTION  : Sets the current address of the eeprom.
-*#
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Aug 28 1999  Edgar Iglesias  Initial version               
-*# Sep 03 1999  Edgar Iglesias  Corrected typo.
-*#
-*#**************************************************************************/
+/* Sets the current address of the eeprom. */
 
 static int eeprom_address(unsigned long addr)
 {
@@ -999,27 +778,7 @@
   return 1;
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: read_from_eeprom
-*#                                                            
-*# PARAMETERS   : buf      : Destination buffer.
-*#                count    : Number of bytes to read.
-*#
-*# RETURNS      : number of read bytes or -EFAULT.
-*#
-*# SIDE EFFECTS :
-*#
-*# DESCRIPTION  : Reads from current adress.
-*#
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Sep 03 1999  Edgar Iglesias  Initial version               
-*#
-*#**************************************************************************/
+/* Reads from current adress. */
 
 static int read_from_eeprom(char * buf, int count)
 {
@@ -1040,7 +799,7 @@
   
   if(i == EEPROM_RETRIES)
   {
-    printk("eeprom: failed to read from eeprom\n");
+    printk(KERN_INFO "%s: failed to read from eeprom\n", eeprom_name);
     i2c_stop();
     
     return -EFAULT;
@@ -1066,26 +825,8 @@
   return read;
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_disable_write_protect
-*#                                                            
-*# PARAMETERS   : None
-*#
-*# RETURNS      : Nothing
-*#
-*# SIDE EFFECTS :
-*#
-*# DESCRIPTION  : Disables write protection if applicable
-*#
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Jan 14 2000  Johan Adolfsson Initial version (from PS pareerom.c)
-*#
-*#**************************************************************************/
+/* Disables write protection if applicable. */
+
 #define DBP_SAVE(x)
 #define ax_printf printk
 static void eeprom_disable_write_protect(void)
@@ -1133,7 +874,7 @@
     }
     i2c_stop();
     
-    /* Step 3 Set BP1, BP0, and/or WPEN bits (write 00000110 to address 1FFFh*/
+    /* Step 3 Set BP1, BP0, and/or WPEN bits (write 00000110 to address 1FFFh */
     i2c_start();
     i2c_outbyte(0xbe);
     if(!i2c_getack())
@@ -1157,5 +898,3 @@
 }
 
 module_init(eeprom_init);
-
-/********************** END OF FILE e100eeprom.c *****************************/
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/ethernet.c linux/arch/cris/drivers/ethernet.c
--- v2.4.6/linux/arch/cris/drivers/ethernet.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/ethernet.c	Wed Jul  4 11:50:38 2001
@@ -1,4 +1,4 @@
-/* $Id: ethernet.c,v 1.12 2001/04/05 11:43:11 tobiasa Exp $
+/* $Id: ethernet.c,v 1.17 2001/06/11 12:43:46 olof Exp $
  *
  * e100net.c: A network driver for the ETRAX 100LX network controller.
  *
@@ -7,6 +7,23 @@
  * The outline of this driver comes from skeleton.c.
  *
  * $Log: ethernet.c,v $
+ * Revision 1.17  2001/06/11 12:43:46  olof
+ * Modified defines for network LED behavior
+ *
+ * Revision 1.16  2001/05/30 06:12:46  markusl
+ * TxDesc.next should not be set to NULL
+ *
+ * Revision 1.15  2001/05/29 10:27:04  markusl
+ * Updated after review remarks:
+ * +Use IO_EXTRACT
+ * +Handle underrun
+ *
+ * Revision 1.14  2001/05/29 09:20:14  jonashg
+ * Use driver name on printk output so one can tell which driver that complains.
+ *
+ * Revision 1.13  2001/05/09 12:35:59  johana
+ * Use DMA_NBR and IRQ_NBR defines from dma.h and irq.h
+ *
  * Revision 1.12  2001/04/05 11:43:11  tobiasa
  * Check dev before panic.
  *
@@ -80,6 +97,7 @@
 
 #include <asm/svinto.h>     /* DMA and register descriptions */
 #include <asm/io.h>         /* LED_* I/O functions */
+#include <asm/irq.h>
 #include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -87,8 +105,6 @@
 //#define ETHDEBUG
 #define D(x)
 
-#define ETH_TX_DMA 0
-#define ETH_RX_DMA 1
 
 /*
  * The name of the card. Is used for messages and in the requests for
@@ -116,9 +132,6 @@
 	spinlock_t lock;
 };
 
-#define NETWORK_DMARX_IRQ 17  /* irq 17 is the DMA1 irq */
-#define NETWORK_DMATX_IRQ 16  /* irq 16 is the DMA0 irq */
-#define NETWORK_STATUS_IRQ 6  /* irq 6 is the network irq */
 
 /* Dma descriptors etc. */
 
@@ -231,7 +244,8 @@
 	/* make Linux aware of the new hardware  */
 
 	if (!dev) {
-		printk("dev == NULL. Should this happen?\n");
+		printk(KERN_WARNING "%s: dev == NULL. Should this happen?\n",
+		       cardname);
 		dev = init_etherdev(dev, sizeof(struct net_local));
 		if (!dev)
 			panic("init_etherdev failed\n");
@@ -250,8 +264,8 @@
 
 	/* now setup our etrax specific stuff */
 
-	dev->irq = NETWORK_DMARX_IRQ; /* we really use DMATX as well... */
-	dev->dma = 1;
+	dev->irq = NETWORK_DMA_RX_IRQ_NBR; /* we really use DMATX as well... */
+	dev->dma = NETWORK_RX_DMA_NBR;
 
 	/* fill in our handlers so the network layer can talk to us in the future */
 
@@ -381,30 +395,30 @@
 
 	/* Reset and wait for the DMA channels */
 
-	RESET_DMA(0);
-	RESET_DMA(1);
-	WAIT_DMA(0);
-	WAIT_DMA(1);
+	RESET_DMA(NETWORK_TX_DMA_NBR);
+	RESET_DMA(NETWORK_RX_DMA_NBR);
+	WAIT_DMA(NETWORK_TX_DMA_NBR);
+	WAIT_DMA(NETWORK_RX_DMA_NBR);
 
 	/* Initialise the etrax network controller */
 
 	/* allocate the irq corresponding to the receiving DMA */
 
-	if (request_irq(NETWORK_DMARX_IRQ, e100rx_interrupt, 0,
+	if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rx_interrupt, 0,
 			cardname, (void *)dev)) {
 		goto grace_exit;
 	}
 
 	/* allocate the irq corresponding to the transmitting DMA */
 
-	if (request_irq(NETWORK_DMATX_IRQ, e100tx_interrupt, 0,
+	if (request_irq(NETWORK_DMA_TX_IRQ_NBR, e100tx_interrupt, 0,
 			cardname, (void *)dev)) {
 		goto grace_exit;
 	}
 
 	/* allocate the irq corresponding to the network errors etc */
 
-	if (request_irq(NETWORK_STATUS_IRQ, e100nw_interrupt, 0,
+	if (request_irq(NETWORK_STATUS_IRQ_NBR, e100nw_interrupt, 0,
 			cardname, (void *)dev)) {
 		goto grace_exit;
 	}
@@ -414,17 +428,17 @@
 	 * and clean up on failure.
 	 */
 
-	if(request_dma(ETH_TX_DMA, cardname)) {
+	if(request_dma(NETWORK_TX_DMA_NBR, cardname)) {
 		goto grace_exit;
 	}
 
-	if(request_dma(ETH_RX_DMA, cardname)) {
+	if(request_dma(NETWORK_RX_DMA_NBR, cardname)) {
 	grace_exit:
 		/* this will cause some 'trying to free free irq' but what the heck... */
-		free_dma(ETH_TX_DMA);
-		free_irq(NETWORK_DMARX_IRQ, (void *)dev);
-		free_irq(NETWORK_DMATX_IRQ, (void *)dev);
-		free_irq(NETWORK_STATUS_IRQ, (void *)dev);
+		free_dma(NETWORK_TX_DMA_NBR);
+		free_irq(NETWORK_DMA_RX_IRQ_NBR, (void *)dev);
+		free_irq(NETWORK_DMA_TX_IRQ_NBR, (void *)dev);
+		free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev);
 		return -EAGAIN;
 	}
 
@@ -625,8 +639,8 @@
 	
 	/* reset the TX DMA in case it has hung on something */
 	
-	RESET_DMA(0);
-	WAIT_DMA(0);
+	RESET_DMA(NETWORK_TX_DMA_NBR);
+	WAIT_DMA(NETWORK_TX_DMA_NBR);
 	
 	/* Reset the tranceiver. */
 	
@@ -751,7 +765,8 @@
 			tx_skb = 0;
 			netif_wake_queue(dev);
 		} else {
-			printk("tx weird interrupt\n");
+			printk(KERN_WARNING "%s: tx weird interrupt\n",
+			       cardname);
 		}
 
 		spin_unlock(&np->lock);
@@ -765,6 +780,13 @@
 	struct net_local *np = (struct net_local *)dev->priv;
 	unsigned long irqbits = *R_IRQ_MASK0_RD;
 
+	/* check for underrun irq */
+	if(irqbits & IO_STATE(R_IRQ_MASK0_RD, underrun, active)) { 
+		*R_NETWORK_TR_CTRL = IO_STATE(R_NETWORK_TR_CTRL, clr_error, clr);
+		np->stats.tx_errors++;
+		D(printk("ethernet receiver underrun!\n"));
+	}
+
 	/* check for overrun irq */
 	if(irqbits & IO_STATE(R_IRQ_MASK0_RD, overrun, active)) { 
 		update_rx_stats(&np->stats); /* this will ack the irq */
@@ -900,17 +922,17 @@
 
 	/* Stop the receiver and the transmitter */
 
-	RESET_DMA(0);
-	RESET_DMA(1);
+	RESET_DMA(NETWORK_TX_DMA_NBR);
+	RESET_DMA(NETWORK_RX_DMA_NBR);
 
 	/* Flush the Tx and disable Rx here. */
 
-	free_irq(NETWORK_DMARX_IRQ, (void *)dev);
-	free_irq(NETWORK_DMATX_IRQ, (void *)dev);
-	free_irq(NETWORK_STATUS_IRQ, (void *)dev);
+	free_irq(NETWORK_DMA_RX_IRQ_NBR, (void *)dev);
+	free_irq(NETWORK_DMA_TX_IRQ_NBR, (void *)dev);
+	free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev);
 
-	free_dma(ETH_TX_DMA);
-	free_dma(ETH_RX_DMA);
+	free_dma(NETWORK_TX_DMA_NBR);
+	free_dma(NETWORK_RX_DMA_NBR);
 
 	/* Update the statistics here. */
 
@@ -925,10 +947,10 @@
 {
 	unsigned long r = *R_REC_COUNTERS;
 	/* update stats relevant to reception errors */
-	es->rx_fifo_errors += r >> 24;            /* fifo overrun */
-	es->rx_crc_errors += r & 0xff;            /* crc error */
-	es->rx_frame_errors += (r >> 8) & 0xff;   /* alignment error */
-	es->rx_length_errors += (r >> 16) & 0xff; /* oversized frames */
+	es->rx_fifo_errors += IO_EXTRACT(R_REC_COUNTERS, congestion, r);
+	es->rx_crc_errors += IO_EXTRACT(R_REC_COUNTERS, crc_error, r);
+	es->rx_frame_errors += IO_EXTRACT(R_REC_COUNTERS, alignment_error, r);
+	es->rx_length_errors += IO_EXTRACT(R_REC_COUNTERS, oversize, r);
 }
 
 static void
@@ -936,8 +958,10 @@
 {
 	unsigned long r = *R_TR_COUNTERS;
 	/* update stats relevant to transmission errors */
-	es->collisions += (r & 0xff) + ((r >> 8) & 0xff); /* single_col + multiple_col */
-	es->tx_errors += (r >> 24) & 0xff; /* deferred transmit frames */
+	es->collisions +=
+		IO_EXTRACT(R_TR_COUNTERS, single_col, r) +
+		IO_EXTRACT(R_TR_COUNTERS, multiple_col, r);
+	es->tx_errors += IO_EXTRACT(R_TR_COUNTERS, deferred, r);
 }
 
 /*
@@ -1082,10 +1106,12 @@
 static void
 e100_set_network_leds(int active)
 {
-#ifdef CONFIG_LED_OFF_DURING_ACTIVITY
+#if defined(CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK)
 	int light_leds = (active == NO_NETWORK_ACTIVITY);
-#else
+#elif defined(CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY)
 	int light_leds = (active == NETWORK_ACTIVITY);
+#else
+#error "Define either CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK or CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY"
 #endif
 
 	if (!current_speed) {
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/gpio.c linux/arch/cris/drivers/gpio.c
--- v2.4.6/linux/arch/cris/drivers/gpio.c	Sat May 19 17:43:05 2001
+++ linux/arch/cris/drivers/gpio.c	Wed Jul  4 11:50:38 2001
@@ -1,4 +1,4 @@
-/* $Id: gpio.c,v 1.7 2001/04/04 13:30:08 matsfg Exp $
+/* $Id: gpio.c,v 1.9 2001/05/04 14:16:07 matsfg Exp $
  *
  * Etrax general port I/O device
  *
@@ -9,6 +9,14 @@
  *             Johan Adolfsson  (read/set directions)
  *
  * $Log: gpio.c,v $
+ * Revision 1.9  2001/05/04 14:16:07  matsfg
+ * Corrected spelling error
+ *
+ * Revision 1.8  2001/04/27 13:55:26  matsfg
+ * Moved initioremap.
+ * Turns off all LEDS on init.
+ * Added support for shutdown and powerbutton.
+ *
  * Revision 1.7  2001/04/04 13:30:08  matsfg
  * Added bitset and bitclear for leds. Calls init_ioremap to set up memmapping
  *
@@ -247,6 +255,16 @@
 			*priv->dir = *priv->dir_shadow |= 
 			  ((unsigned char)arg & priv->changeable_dir);
 			return *priv->dir_shadow;
+                case IO_SHUTDOWN:
+                       SOFT_SHUTDOWN();
+                       break;
+                case IO_GET_PWR_BT:
+#if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
+                       return (*R_PORT_G_DATA & 
+                               ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
+#else
+                       return 0;
+#endif
 		default:
 			if(priv->minor == LEDS)
 				return gpio_leds_ioctl(cmd, arg);
@@ -262,12 +280,6 @@
 {
 	unsigned char green;
 	unsigned char red;
-        static int initialized = 0;
-        if(!initialized)
-        {
-          initialized = 1;
-          init_ioremap();
-        }
 	switch (_IOC_NR(cmd)) {
 		case IO_LEDACTIVE_SET:
 			green = ((unsigned char) arg) & 1;
@@ -298,7 +310,7 @@
 static __init int
 gpio_init(void)
 {
-	int res;
+	int res,i;
 
 	/* do the formalities */
 
@@ -307,6 +319,24 @@
 		printk(KERN_ERR "gpio: couldn't get a major number.\n");
 		return res;
 	}
+
+        /* Clear all leds */
+#if defined (CONFIG_ETRAX_CSP0_LEDS) ||  defined (CONFIG_ETRAX_PA_LEDS)         || defined (CONFIG_ETRAX_PB_LEDS) 
+
+        init_ioremap();
+        LED_NETWORK_SET(0);
+        LED_ACTIVE_SET(0);
+        LED_DISK_READ(0);
+        LED_DISK_WRITE(0);        
+
+#if defined (CONFIG_ETRAX_CSP0_LEDS)
+        for( i = 0; i < 32; i ++)
+        {
+            LED_BIT_SET(i);
+        }
+#endif
+
+#endif
 	
 	printk("ETRAX 100LX GPIO driver v2.1, (c) 2001 Axis Communications AB\n");
 
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/ide.c linux/arch/cris/drivers/ide.c
--- v2.4.6/linux/arch/cris/drivers/ide.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/cris/drivers/ide.c	Wed Jul  4 11:50:38 2001
@@ -1,4 +1,4 @@
-/* $Id: ide.c,v 1.16 2001/04/05 08:30:07 matsfg Exp $
+/* $Id: ide.c,v 1.19 2001/05/09 12:53:16 johana Exp $
  *
  * Etrax specific IDE functions, like init and PIO-mode setting etc.
  * Almost the entire ide.c is used for the rest of the Etrax ATA driver.
@@ -8,6 +8,15 @@
  *             Mikael Starvik     (pio setup stuff)
  *
  * $Log: ide.c,v $
+ * Revision 1.19  2001/05/09 12:53:16  johana
+ * Added #include <asm/dma.h>
+ *
+ * Revision 1.18  2001/05/09 12:37:00  johana
+ * Use DMA_NBR macros from dma.h.
+ *
+ * Revision 1.17  2001/04/23 13:36:30  matsfg
+ * Changed CONFIG_IDE_DELAY to CONFIG_ETRAX_IDE_DELAY
+ *
  * Revision 1.16  2001/04/05 08:30:07  matsfg
  * Corrected cse1 and csp0 reset.
  *
@@ -98,6 +107,7 @@
 
 #include <asm/io.h>
 #include <asm/svinto.h>
+#include <asm/dma.h>
 
 /* number of Etrax DMA descriptors */
 #define MAX_DMA_DESCRS 64
@@ -341,17 +351,17 @@
 			     IO_STATE( R_IRQ_MASK0_SET, ata_irq2, set ) |
 			     IO_STATE( R_IRQ_MASK0_SET, ata_irq3, set ) );
 
-	printk("ide: waiting %d seconds for drives to regain consciousness\n", CONFIG_IDE_DELAY);
+	printk("ide: waiting %d seconds for drives to regain consciousness\n", CONFIG_ETRAX_IDE_DELAY);
 
-	h = jiffies + (CONFIG_IDE_DELAY * HZ);
+	h = jiffies + (CONFIG_ETRAX_IDE_DELAY * HZ);
 	while(jiffies < h) ;
 
   /* reset the dma channels we will use */
 
-	RESET_DMA(2);
-	RESET_DMA(3);
-	WAIT_DMA(2);
-	WAIT_DMA(3);
+	RESET_DMA(ATA_TX_DMA_NBR);
+	RESET_DMA(ATA_RX_DMA_NBR);
+	WAIT_DMA(ATA_TX_DMA_NBR);
+	WAIT_DMA(ATA_RX_DMA_NBR);
 
 }
 
@@ -378,8 +388,8 @@
 	}
 	
 	/* make sure the DMA channel is available */
-	RESET_DMA(3);
-	WAIT_DMA(3); 
+	RESET_DMA(ATA_RX_DMA_NBR);
+	WAIT_DMA(ATA_RX_DMA_NBR); 
 	
 	/* setup DMA descriptor */
 	
@@ -406,7 +416,7 @@
 	/* wait for completion */
 	
 	LED_DISK_READ(1);
-	WAIT_DMA(3);
+	WAIT_DMA(ATA_RX_DMA_NBR);
 	LED_DISK_READ(0);
 
 #if 0
@@ -457,8 +467,8 @@
 	}
 
 	/* make sure the DMA channel is available */
-	RESET_DMA(2);
-	WAIT_DMA(2); 
+	RESET_DMA(ATA_TX_DMA_NBR);
+	WAIT_DMA(ATA_TX_DMA_NBR); 
 	
 	/* setup DMA descriptor */
 	
@@ -485,7 +495,7 @@
 	/* wait for completion */
 	
 	LED_DISK_WRITE(1);
-	WAIT_DMA(2);
+	WAIT_DMA(ATA_TX_DMA_NBR);
 	LED_DISK_WRITE(0);
 
 #if 0
@@ -794,8 +804,8 @@
 
 	if(reading) {
 
-		RESET_DMA(3); /* sometimes the DMA channel get stuck so we need to do this */
-		WAIT_DMA(3);
+		RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
+		WAIT_DMA(ATA_RX_DMA_NBR);
 
 		/* set up the Etrax DMA descriptors */
 		
@@ -837,8 +847,8 @@
 	} else {
 		/* writing */
 
-		RESET_DMA(2); /* sometimes the DMA channel get stuck so we need to do this */
-		WAIT_DMA(2);
+		RESET_DMA(ATA_TX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
+		WAIT_DMA(ATA_TX_DMA_NBR);
 
 		/* set up the Etrax DMA descriptors */
 
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/lpslave/Makefile linux/arch/cris/drivers/lpslave/Makefile
--- v2.4.6/linux/arch/cris/drivers/lpslave/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/lpslave/Makefile	Wed Jul  4 11:50:38 2001
@@ -0,0 +1,20 @@
+#
+# Makefile for parallel port slave drivers
+#
+
+O_TARGET := lpslavedrivers.o
+
+obj-y = e100lpslavenet.o e100lpslave_code.o
+
+
+include $(TOPDIR)/Rules.make
+
+e100lpslave_code.o:	e100lpslave.o e100lpslaveld 
+	$(CROSS_COMPILE)ld -qmagic -Te100lpslaveld e100lpslave.o -o e100lpslave
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.data --remove-section=.bss e100lpslave e100lpslave.text
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.text --remove-section=.bss e100lpslave e100lpslave.data
+	cat e100lpslave.text e100lpslave.data |\
+	./bintocarr.pl e100lpslaveprog |\
+	$(CC) $(CFLAGS) -pipe -o e100lpslave_code.o -c -x c -
+	ls -l e100lpslave.text e100lpslave.data
+	rm -f e100lpslave e100lpslave.text e100lpslave.data
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/lpslave/bintocarr.pl linux/arch/cris/drivers/lpslave/bintocarr.pl
--- v2.4.6/linux/arch/cris/drivers/lpslave/bintocarr.pl	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/lpslave/bintocarr.pl	Wed Jul  4 11:50:38 2001
@@ -0,0 +1,29 @@
+#!/usr/bin/perl -w
+# $Id: bintocarr.pl,v 1.3 2001/06/08 08:46:50 olof Exp $
+# Copy of mkjulbin.pl made by Olof
+# convert a binary stdin to a C-file containing a char array of the input
+# first argument is the symbol name
+
+$symbol = shift @ARGV;
+
+print "#include <linux/init.h>\n\n";
+print "unsigned char $symbol", "[] __initdata = {\n";
+
+my $char;
+
+$bcount = 0;
+
+while(read STDIN, $char, 1) {
+    printf("0x%x, ", ord($char));
+    $bcount++;
+    if(!($bcount % 16)) {
+	print "\n";
+    }
+}
+
+print "\n};\n";
+
+$lensymb = ("_" . ($symbol . "_length"));
+
+print "__asm__(\"\\t.globl $lensymb\\n$lensymb = $bcount\\n\");\n";
+  
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslave.README linux/arch/cris/drivers/lpslave/e100lpslave.README
--- v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslave.README	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/lpslave/e100lpslave.README	Wed Jul  4 11:50:38 2001
@@ -0,0 +1,54 @@
+***** MODIFICATIONS
+To use a 5600 as a slave device it has to somewhat modified.
+This has to be done on a 5600 (art no 16144 R2) to automatically set it to parallel port boot mode:
+
+1)
+Close to the LPT1 connector there are two resistors, between the "Pulse" inductor and
+the LS245. The one closest to the LS245 is a 4k7 pull up (R105). Remove it.
+
+2)
+Between the other "Pulse" inductor and Etrax there is a black 5-pin inverter
+(D15). Short connectors 2 and 3 with a solder blob.
+
+
+***** PINOUT
+To use this driver use cables connected like this:
+DSUB25-Male                DSUB25Male
+
+1	10
+2-9	2-9
+10 	1
+11	14
+12	18
+13	NC
+14	11
+15	NC
+16	NC	
+17	NC
+18	12
+19	NC
+20-25	20-25
+
+Thus the cables are symmetrical with most cables straight through,
+some crossed (1-10, 11-14 and 12-18) 
+and some Not connected (NC 13,15,16,17 and 19).
+
+
+******* Only for reference
+To ease the use of flat-cable connectors, here are the notes of wich wires to cross and cut with pin 1 being cable 1:
+Cross:
+1	19
+2	21
+10	23
+Cut:
+4
+6
+8
+12
+25
+
+jonas.dellenvall@axis.com
+
+
+
+
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslave.S linux/arch/cris/drivers/lpslave/e100lpslave.S
--- v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslave.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/lpslave/e100lpslave.S	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,429 @@
+	;; $Id: e100lpslave.S,v 1.2 2001/06/11 12:50:01 olof Exp $
+	;;
+	;; Etrax100 slave network<->parport forwarder
+	;;
+	;; Copyright (c) 1999 Bjorn Wesen, Axis Communications AB
+	;;
+	;; We got 784 bytes (par loader size) to do DMA forwarding
+	;; between DMA0/1 (ethernet) and DMA3/4 (par port 0 RX/1 TX)
+	;;
+
+#include <linux/config.h>
+#if 0
+#define ASSEMBLER_MACROS_ONLY
+#endif
+#include <asm/sv_addr_ag.h>
+
+#define BUFSIZE 0x600
+
+	;; R_IRQ_READ2
+
+#define DMA1EOPBIT 3
+#define DMA0EOPBIT 1
+#define DMA3EOPBIT 7
+#define DMA4DESCBIT 8
+
+	;; R_IRQ_READ0
+
+#define PAR0ECPCMDBIT 11
+
+	;; get host CMDs
+
+#include "e100lpslave.h"
+
+start:
+	;; disable interrupts. we are not going to use them at all.
+
+	di
+
+	;; setup DMA connections and port configuration
+
+	movu.w	0x84, r0	; DMA2/3/4/5 to par ports
+	move.d	r0, [R_GEN_CONFIG]
+
+	;; setup port PA dirs and turn on the LED to show were alive
+
+	movu.w	0x0cfb, r0	; PA2-PA3 out, PA2 inactive
+	move.d	r0, [R_PORT_PA_SET]
+
+	;; enable MDIO output pin
+	moveq IO_STATE(R_NETWORK_MGM_CTRL, mdoe, enable), r0
+	move.d	r0, [R_NETWORK_MGM_CTRL]
+
+	;; accept broadcast frames, and enable station address 0
+	moveq	IO_STATE(R_NETWORK_REC_CONFIG, broadcast, receive) | \
+		IO_STATE(R_NETWORK_REC_CONFIG, ma0, enable), r0
+	move.d	r0, [R_NETWORK_REC_CONFIG]
+
+	;; use MII CLK mode, and enable the controller
+	moveq	IO_STATE(R_NETWORK_GEN_CONFIG, phy, mii_clk) | \
+		IO_STATE(R_NETWORK_GEN_CONFIG, enable, on), r0
+	move.d	r0, [R_NETWORK_GEN_CONFIG]
+
+	move.d	IO_STATE(R_PAR0_CONFIG, ioe,     noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, iseli,   noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, iautofd, noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, istrb,   noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, iinit,   noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, iperr,   noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, iack,    noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, ibusy,   noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, ifault,  noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, isel,    noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, dma, enable)        |  \
+		IO_STATE(R_PAR0_CONFIG, rle_in, disable)    |  \
+		IO_STATE(R_PAR0_CONFIG, rle_out, disable)   |  \
+		IO_STATE(R_PAR0_CONFIG, enable, on)         |  \
+		IO_STATE(R_PAR0_CONFIG, force, on)          |  \
+		IO_STATE(R_PAR0_CONFIG, mode, ecp_rev), r0	; Reverse ECP - PAR0 is RX
+
+	move.d	r0, [R_PAR0_CONFIG]
+
+	move.d	IO_STATE(R_PAR1_CONFIG, ioe,     noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, iseli,   noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, iautofd, noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, istrb,   noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, iinit,   noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, iperr,   inv)       |  \
+		IO_STATE(R_PAR1_CONFIG, iack,    noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, ibusy,   noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, ifault,  noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, isel,    noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, dma, enable)        |  \
+		IO_STATE(R_PAR1_CONFIG, rle_in, disable)    |  \
+		IO_STATE(R_PAR1_CONFIG, rle_out, disable)   |  \
+		IO_STATE(R_PAR1_CONFIG, enable, on)         |  \
+		IO_STATE(R_PAR1_CONFIG, force, on)          |  \
+		IO_STATE(R_PAR1_CONFIG, mode, ecp_fwd), r0	; Forward ECP - PAR1 is TX
+
+	move.d	r0, [R_PAR1_CONFIG]
+
+	moveq	IO_FIELD(R_PAR1_DELAY, setup, 1), r0    ; setup time of value * 160 + 20
+	move.d	r0, [R_PAR1_DELAY]
+
+	;; we got four descriptors, that can be active at the same time:
+	;; 1) from network
+	;; 2) to parport
+	;; 3) from parport
+	;; 4) to network
+	;;
+	;; we got four buffers, each can hold a max packet (we use 1536 bytes)
+	;; buffers 1 and 2 are used from network to parport, while
+	;; buffers 3 and 4 are used from parport to network.
+	;; 
+	;; a double buffering scheme is used, so that new data can be read
+	;; into a buffer pair while the last data is written out from the
+	;; last buffer. if the read buffer is done before the write buffer,
+	;; the reading will halt until the writing is done, at which point
+	;; writing starts from the newly read and reading can start with
+	;; the newly written.
+	;; 
+
+	move.d	R_DMA_CH0_FIRST, r1   ; we use this as base for subsequent DMA ops
+	moveq	IO_STATE(R_DMA_CH1_CMD, cmd, start), r6
+	move.d	FN1desc, r7
+	move.d	R_IRQ_READ0, r9
+
+	;; start receiving from network
+
+	jsr	startdmaFPTN
+	jsr	startdmaFNTP
+
+	
+
+	;; ------------------- MAIN LOOP
+
+	;; IRQ bits:	parport rcv is par0_ecp_cmd, then dma3_eop
+	;;              network rcv is dma1_eop
+	;;              parport tx  is dma4_desc
+	;;              network tx  is dma0_eop
+
+mainloop:
+
+	;; ------- first handle the parport -> network link
+
+	;; check if we got something from the parport
+
+	move.d	[r9], r0	; r0 <- *R_IRQ_READ0
+	btstq	PAR0ECPCMDBIT, r0
+	bpl	noparecp
+	nop
+
+	;; ack it by reading PAR0_STATUS_DATA
+
+	move.d	[R_PAR0_STATUS_DATA], r0
+
+	;; trigger EOP on DMA3 (par0 incoming channel)
+
+	moveq	IO_STATE(R_SET_EOP, ch3_eop, set), r0
+	move.d	r0, [R_SET_EOP]
+
+noparecp:
+
+	;; if we simultaneously have parport rx EOP and
+	;; network TX eop, we can swap buffers and start a new RX/TX
+
+	move.d	[r9 + (R_IRQ_READ2 - R_IRQ_READ0)], r0
+	btstq	DMA3EOPBIT, r0	; check parport rx
+	bpl	noswap1
+	btstq	DMA0EOPBIT, r0	; check network tx
+	bpl	noswap1
+	nop
+
+	;; prepare to swap buffer ptrs (FN3b <-> TN4b)
+
+	move.d	[r4 = r7 + 56], r0; FP3b
+	move.d	[r3 = r7 + 72], r2; TN4b
+
+	;; but first check if this was a Host Command Packet
+
+	move.d	[r0], r5	; r5 <- first 4 bytes in PAR-received packet
+	bne	handle_command	; if non-zero, it was a host command
+	addq	4, r0		; skip command (in delay slot - handle_command requires this)
+	move.d	r0, [r3]	; write to To Network descriptor
+	subq	4, r2		; undo the skipping done last swap
+	move.d	r2, [r4]	; write to From Parport descriptor
+
+	;; clear the interrupts
+
+	moveq	IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do), r0
+	move.b	r0, [r1 + (R_DMA_CH0_CLR_INTR - R_DMA_CH0_FIRST)]
+	move.b	r0, [r1 + (R_DMA_CH3_CLR_INTR - R_DMA_CH0_FIRST)]
+
+	;; copy received length to outgoing network length
+
+	move.w	[r7 + 60], r0	; FPhlen
+	subq	4, r0		; skip command
+	move.w	r0, [r7 + 64]	; TN4desc
+
+	;; restart DMAs
+
+	jsr	startdmaFPTN
+
+#ifdef CONFIG_ETRAX_ETHERNET_LPSLAVE_HAS_LEDS
+#if defined(CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK)
+	;; Turn off the LED signaling an outgoing network packet
+	movu.b	[LEDOff], r0
+#elif defined(CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY)
+	;; Light the LED signaling an outgoing network packet
+	movu.b	[LEDAmber], r0
+#else
+#error "Define either CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK or CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY"	
+#endif 
+	move.b	r0, [R_PORT_PA_DATA]
+	move.d	0x00011000, r0
+	move.d	r0,[LEDCount]
+#endif
+
+noswap1:
+	;; ----- now check the network -> parport link
+
+
+	;; if we simultaneously have network rx EOP and
+	;; parport TX desc, we can swap buffers and start a new RX/TX
+
+	move.d	[r9 + (R_IRQ_READ2 - R_IRQ_READ0)], r0
+	btstq	DMA1EOPBIT, r0	; check network rx
+	bpl	noswap2
+	btstq	DMA4DESCBIT, r0	; check parport tx
+	bpl	noswap2
+	nop
+
+	;; prepare to swap buffer ptrs (FP1b <-> TP2b)
+
+	move.d	[r4 = r7 +  8], r0; FN1b
+	move.d	[r3 = r7 + 24], r2; TP2b
+	move.d	r0, [r3]	; write to To Parport descriptor
+	move.d	r2, [r4]	; write to From Network descriptor
+
+	;; clear the interrupts
+
+	moveq	IO_STATE(R_DMA_CH1_CLR_INTR, clr_eop, do) | \
+		IO_STATE(R_DMA_CH1_CLR_INTR, clr_descr, do), r0
+	move.b	r0, [r1 + (R_DMA_CH1_CLR_INTR - R_DMA_CH0_FIRST)]
+	move.b	r0, [r1 + (R_DMA_CH4_CLR_INTR - R_DMA_CH0_FIRST)]
+
+	;; copy received network length to outgoing parport length
+
+	move.w	[r7 + 12], r0	; FNhlen
+	move.w	r0, [r7 + 16]	; TP2desc
+
+	;; restart DMAs
+
+	jsr	startdmaFNTP
+#if 0
+#ifdef CONFIG_ETRAX_ETHERNET_LPSLAVE_HAS_LEDS
+	;; Light the LED signaling an incoming networkpacket
+	movu.b	0xFB, r0
+	move.b	r0, [R_PORT_PA_DATA]
+	move.d	0x00010000, r0
+	move.d	r0,[LEDCount]
+#endif
+#endif
+
+noswap2:
+#ifdef CONFIG_ETRAX_ETHERNET_LPSLAVE_HAS_LEDS
+
+	;; Count down LED counter, and turn off the network LED if required
+	move.d	[LEDCount], r0
+	beq	mainloop
+	nop
+
+	subq	1, r0
+	move.d	r0, [LEDCount]	
+	bne	mainloop
+	nop
+
+#if defined(CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK)	
+	;; Light the network LED , and start over the main loop
+	movu.b	[LEDAmber], r0
+#elif defined(CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY)		
+	;; Turn off the network LED, and start over the main loop
+	movu.b	[LEDOff], r0
+#else
+#error "Define either CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK or CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY"	
+#endif
+	move.b	r0, [R_PORT_PA_DATA]
+#endif
+
+	ba	mainloop
+	nop
+
+	;; --- some useful subroutines.
+
+handle_command:
+	;; handle command. we also need to clear the PAR0 RX EOP IRQ, and 
+	;; restart the PAR0 dma. command is in R5, packet after cmd is in R0
+
+	moveq	IO_STATE(R_DMA_CH3_CLR_INTR, clr_eop, do), r2
+	move.b	r2, [r1 + (R_DMA_CH3_CLR_INTR - R_DMA_CH0_FIRST)]
+
+	cmpq	HOST_CMD_SETMAC, r5
+	bne	no_setmac
+	nop
+
+	;; copy station address (6 bytes) from packet to hardware
+
+	move.d	[r0+], r2
+	move.d	R_NETWORK_SA_0, r3
+	move.d	r2, [r3]
+	move.w	[r0], r2
+	move.w	r2, [r3 + 4] 
+
+no_setmac:
+	move	noswap1, SRP
+	ba	startdmaFP
+	nop
+
+	;; start DMAs, from parport and to network
+
+startdmaFPTN:
+
+	;; start transmitting to the network (CH0)
+
+	move.d	TN4desc, r8
+	move.d	r8, [r1]					; TN4desc -> FIRST0
+	move.b	r6, [r1 + (R_DMA_CH0_CMD - R_DMA_CH0_FIRST)]	; start -> CMD0
+
+startdmaFP:
+
+	;; start receiving from parport (CH3)
+
+	move.d	FP3desc, r8
+	move.d	r8, [r1 + (R_DMA_CH3_FIRST - R_DMA_CH0_FIRST)]  ; FP3desc -> FIRST3
+	move.b	r6, [r1 + (R_DMA_CH3_CMD - R_DMA_CH0_FIRST)]	; start -> CMD3
+
+	ret
+	nop
+
+	;; start DMAs, from network and to parport
+
+startdmaFNTP:
+
+	;; start transmitting to the parport (CH4)
+
+	move.d	TP2desc, r8
+	move.d	r8, [r1 + (R_DMA_CH4_FIRST - R_DMA_CH0_FIRST)]	; TP2desc -> FIRST4
+	move.b	r6, [r1 + (R_DMA_CH4_CMD - R_DMA_CH0_FIRST)]	; start -> CMD4
+
+	;; start receiving from network (CH1) (r7 already contains FN1desc)
+
+	move.d	r7, [r1 + (R_DMA_CH1_FIRST - R_DMA_CH0_FIRST)]  ; FN1desc -> FIRST1
+	move.b	r6, [r1 + (R_DMA_CH1_CMD - R_DMA_CH0_FIRST)]	; start -> CMD1
+
+	ret
+	nop
+
+	;; --- DMA descriptors - each descriptor is 4 longwords (16 bytes)
+	;; DONT MOVE THESE AROUND. Due to the as/ld "hole-in-the-head",
+	;; we cant write stuff like (TP2b - TP2desc) but the offsets
+	;; have to be hardcoded.
+
+	.data
+
+	;; 0 from network
+FN1desc:
+	.word	BUFSIZE		; sw_len
+	.word	0x0001		; ctrl, d_eol is only flag we need
+	.dword	0		; next
+FN1b:	.dword	buffers		; buffer 1 8
+	.word	0		; hw_len
+	.word	0		; status
+
+	;; 16 to parport
+TP2desc:
+	.word	2		; sw_len, filled in by code 
+	.word	0x0004		; ctrl, d_wait because ecp cmd in next
+	.dword	TP2desc2	; next
+TP2b:	.dword	buffers + BUFSIZE ; buffer 2 24
+	.word	0		; hw_len
+	.word	0		; status
+
+	;; 32 to parport second descriptor, for the ECP command
+TP2desc2:
+	.word	0x0001		; sw_len, 1 byte (ecp command) 
+	.word	0x0019		; ctrl, d_ecp | d_eol | d_int
+	.dword	0		; next
+	.dword	TP2desc2	; buffer, dont care
+	.word	0		; hw_len
+	.word	0		; status
+
+	;; 48 from parport
+FP3desc:
+	.word	BUFSIZE		; sw_len
+	.word	0x0001		; ctrl, d_eol is only flag we need
+	.dword	0		; next
+FP3b:	.dword	buffers + BUFSIZE * 2 ; 56 buffer 3
+FPhlen:	.word	0		; 60 hw_len
+	.word	0		; status
+
+	;; 64 to network
+TN4desc:
+	.word	2		; sw_len, filled in by code 
+	.word	0x0007		; ctrl, d_eop | d_eol | d_wait
+	.dword	0		; next
+TN4b:	.dword	buffers + BUFSIZE * 3 + 4	; 72 buffer 4 (the +4 is to offset the anti-skipping)
+	.word	0		; hw_len
+	.word	0		; status
+
+#ifdef CONFIG_ETRAX_ETHERNET_LPSLAVE_HAS_LEDS
+LEDCount:
+	.dword	0
+LEDOff:	
+	.word	0xff
+LEDGreen:
+	.word	0xfb
+LEDRed:
+	.word	0xf7
+LEDAmber:
+	.word	0xf3
+LED:
+	.word	0xf7
+#endif
+
+	;; after the prog we put the buffers. not in the asm program, we just use
+	;; the address generated
+
+buffers:
+
+	;; END
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslave.h linux/arch/cris/drivers/lpslave/e100lpslave.h
--- v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslave.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/lpslave/e100lpslave.h	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,2 @@
+#define HOST_CMD_SENDPACK 0
+#define HOST_CMD_SETMAC 1
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslaveld linux/arch/cris/drivers/lpslave/e100lpslaveld
--- v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslaveld	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/lpslave/e100lpslaveld	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,22 @@
+MEMORY 
+	{
+	cache : ORIGIN = 0x380000f0,
+	       	LENGTH = 784
+	}
+
+SECTIONS
+{
+	.text :
+	{
+		*(.text)
+	} > cache
+	.data :
+	{
+		*(.data)
+		*(COMMON)
+	} > cache
+	.bss :
+	{
+		*(.bss)
+	} > cache
+}
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslavenet.c linux/arch/cris/drivers/lpslave/e100lpslavenet.c
--- v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslavenet.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/lpslave/e100lpslavenet.c	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,1031 @@
+/* $Id: e100lpslavenet.c,v 1.2 2001/06/11 15:39:52 olof Exp $
+ *
+ * e100lpslavenet.c: A network driver for the ETRAX 100LX slave controller.
+ *
+ * Copyright (c) 1998-2001 Axis Communications AB.
+ *
+ * The outline of this driver comes from skeleton.c.
+ *
+ * $Log: e100lpslavenet.c,v $
+ * Revision 1.2  2001/06/11 15:39:52  olof
+ * Clean up and sync with ethernet.c rev 1.16. Increased reset time of slave.
+ *
+ * Revision 1.1  2001/06/06 08:56:26  olof
+ * Added support for slave Etrax defined by CONFIG_ETRAX_ETHERNET_LPSLAVE
+ *
+ */
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/svinto.h>     /* DMA and register descriptions */
+#include <asm/io.h>         /* LED_* I/O functions */
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include "e100lpslave.h"
+
+/* #define ETHDEBUG */
+#define D(x)
+
+/*
+ * The name of the card. Is used for messages and in the requests for
+ * io regions, irqs and dma channels
+ */
+
+static const char* cardname = "Etrax 100LX ethernet slave controller";
+
+/* A default ethernet address. Highlevel SW will set the real one later */
+
+static struct sockaddr default_mac = {
+	0,
+        { 0x00, 0x40, 0x8C, 0xCD, 0x00, 0x00 }
+};
+
+/* Information that need to be kept for each board. */
+struct net_local {
+	struct net_device_stats stats;
+
+	/* Tx control lock.  This protects the transmit buffer ring
+	 * state along with the "tx full" state of the driver.  This
+	 * means all netif_queue flow control actions are protected
+	 * by this lock as well.
+	 */
+	spinlock_t lock;
+};
+
+/* Dma descriptors etc. */
+
+#define RX_BUF_SIZE 32768
+#define ETHER_HEAD_LEN      14
+
+#define PAR0_ECP_IRQ_NBR    4
+
+#define RX_DESC_BUF_SIZE   256
+#define NBR_OF_RX_DESC     (RX_BUF_SIZE / \
+			    RX_DESC_BUF_SIZE)
+
+/* Size of slave etrax boot image */
+#define ETRAX_PAR_BOOT_LENGTH 784
+
+static etrax_dma_descr *myNextRxDesc;  /* Points to the next descriptor to
+					  to be processed */
+static etrax_dma_descr *myLastRxDesc;  /* The last processed descriptor */
+static etrax_dma_descr *myPrevRxDesc;  /* The descriptor right before myNextRxDesc */
+
+static unsigned char RxBuf[RX_BUF_SIZE];
+
+static etrax_dma_descr RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned(4)));
+static etrax_dma_descr TxDescList[3] __attribute__ ((aligned(4)));
+                       /* host command, data, bogus ECP command */
+
+static struct sk_buff *tx_skb;
+
+/* Index to functions, as function prototypes. */
+
+static int etrax_ethernet_lpslave_init(struct net_device *dev);
+
+static int e100_open(struct net_device *dev);
+static int e100_set_mac_address(struct net_device *dev, void *addr);
+static int e100_send_packet(struct sk_buff *skb, struct net_device *dev);
+static void e100rx_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void e100tx_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void ecp_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void e100_rx(struct net_device *dev);
+static int e100_close(struct net_device *dev);
+static struct net_device_stats *e100_get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+static void e100_hardware_send_packet(unsigned long hostcmd, char *buf, int length);
+static void update_rx_stats(struct net_device_stats *);
+static void update_tx_stats(struct net_device_stats *);
+static void e100_reset_tranceiver(void);
+
+static void boot_slave(unsigned char *code);
+
+#ifdef ETHDEBUG
+static void dump_parport_status(void);
+#endif
+
+#define tx_done(dev) (*R_DMA_CH0_CMD == 0)
+
+static unsigned long host_command;
+extern unsigned char e100lpslaveprog;
+
+/*
+ * This driver uses PAR0 to recevice data from slave ETRAX and PAR1 to boot
+ * and send data to slave ETRAX.
+ * Used ETRAX100 DMAchannels with corresponding IRQ:
+ * PAR0 RX : DMA3 - IRQ 19
+ * PAR1 TX : DMA4 - IRQ 20
+ * IRQ 4 is used to detect ECP commands from slave ETRAX
+ *
+ * NOTE! PAR0 and PAR1 shares DMA and IRQ numbers with SER2 and SER3 
+ */
+
+
+/*
+ * Check for a network adaptor of this type, 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).
+ */
+static int __init
+etrax_ethernet_lpslave_init(struct net_device *dev)
+{
+	int i;
+	int anOffset = 0;
+
+	printk("Etrax/100 lpslave ethernet driver v0.3, (c) 1999 Axis Communications AB\n");
+
+	dev->base_addr = 2;
+
+	printk("%s initialized\n", dev->name);
+
+	/* make Linux aware of the new hardware  */
+
+	if (!dev) {
+		printk(KERN_WARNING "%s: dev == NULL. Should this happen?\n",
+                       cardname);
+		dev = init_etherdev(dev, sizeof(struct net_local));
+		if (!dev)
+			panic("init_etherdev failed\n");
+	}
+
+	/* setup generic handlers and stuff in the dev struct */
+
+	ether_setup(dev);
+
+	/* make room for the local structure containing stats etc */
+
+	dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+	if (dev->priv == NULL)
+		return -ENOMEM;
+	memset(dev->priv, 0, sizeof(struct net_local));
+
+	/* now setup our etrax specific stuff */
+
+	dev->irq = DMA3_RX_IRQ_NBR; /* we really use DMATX as well... */
+        dev->dma = PAR0_RX_DMA_NBR;
+
+	/* fill in our handlers so the network layer can talk to us in the future */
+
+	dev->open               = e100_open;
+	dev->hard_start_xmit    = e100_send_packet;
+	dev->stop               = e100_close;
+	dev->get_stats          = e100_get_stats;
+	dev->set_multicast_list = set_multicast_list;
+	dev->set_mac_address    = e100_set_mac_address;
+        
+        /* set the default MAC address */
+
+	e100_set_mac_address(dev, &default_mac);
+
+	/* Initialise the list of Etrax DMA-descriptors */
+
+	/* Initialise receive descriptors */
+
+	for(i = 0; i < (NBR_OF_RX_DESC - 1); i++) {
+		RxDescList[i].ctrl   = 0;
+		RxDescList[i].sw_len = RX_DESC_BUF_SIZE;
+		RxDescList[i].next   = virt_to_phys(&RxDescList[i + 1]);
+		RxDescList[i].buf    = virt_to_phys(RxBuf + anOffset);
+		RxDescList[i].status = 0;
+		RxDescList[i].hw_len = 0;
+		anOffset += RX_DESC_BUF_SIZE;
+	}
+
+	RxDescList[i].ctrl   = d_eol;
+	RxDescList[i].sw_len = RX_DESC_BUF_SIZE;
+	RxDescList[i].next   = virt_to_phys(&RxDescList[0]);
+	RxDescList[i].buf    = virt_to_phys(RxBuf + anOffset);
+	RxDescList[i].status = 0;
+	RxDescList[i].hw_len = 0;
+
+	/* Initialise initial pointers */
+
+	myNextRxDesc = &RxDescList[0];
+	myLastRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
+	myPrevRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
+
+        /* setup some TX descriptor data */
+
+	TxDescList[0].sw_len = 4;
+	TxDescList[0].ctrl = 0;
+	TxDescList[0].buf = virt_to_phys(&host_command);
+	TxDescList[0].next = virt_to_phys(&TxDescList[1]);
+
+	return 0;
+}
+
+/* set MAC address of the interface. called from the core after a
+ * SIOCSIFADDR ioctl, and from the bootup above.
+ */
+
+static int
+e100_set_mac_address(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+	int i;
+
+	/* remember it */
+
+        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	/* Write it to the hardware.
+	 * Note the way the address is wrapped:
+	 * *R_NETWORK_SA_0 = a0_0 | (a0_1 << 8) | (a0_2 << 16) | (a0_3 << 24);
+	 * *R_NETWORK_SA_1 = a0_4 | (a0_5 << 8);
+	 */
+
+        tx_skb = 0;
+	e100_hardware_send_packet(HOST_CMD_SETMAC, dev->dev_addr, 6);
+
+	/* show it in the log as well */
+
+	printk("%s: changed MAC to ", dev->name);
+
+	for (i = 0; i < 5; i++)
+		printk("%02X:", dev->dev_addr[i]);
+
+	printk("%02X\n", dev->dev_addr[i]);
+
+	return 0;
+}
+
+/*
+ * Open/initialize the board. This is called (in the current kernel)
+ * sometime after booting when the 'ifconfig' program is run.
+ *
+ * This routine should set everything up anew at each open, even
+ * registers that "should" only need to be set once at boot, so that
+ * there is non-reboot way to recover if something goes wrong.
+ */
+
+static int
+e100_open(struct net_device *dev)
+{
+	unsigned long flags;
+
+	/* configure the PAR0 (RX) and PAR1 (TX) ports
+	 *
+	 * perror is nAckReverse, which must be 1 at the TX side,
+         * and 0 at the RX side
+         *
+	 * select is XFlag, which must be 1 at both sides
+	 */
+#ifdef ETHDEBUG        
+        printk("Setting up PAR ports\n");
+#endif
+        *R_PAR0_CONFIG =
+          /* We do not have an external buffer, don't care */
+		IO_STATE(R_PAR0_CONFIG, ioe,     noninv)    |
+          /* Not connected, don't care */
+		IO_STATE(R_PAR0_CONFIG, iseli,   noninv)    |
+          /* iautofd is not inverted, noninv */
+		IO_STATE(R_PAR0_CONFIG, iautofd, noninv)    |
+          /* Not used in reverse direction, don't care */
+		IO_STATE(R_PAR0_CONFIG, istrb,   noninv)    |
+          /* Not connected, don't care /
+		IO_STATE(R_PAR0_CONFIG, iinit,   noninv)    |
+          /* perror is GND and reverse wants 0, noninv */
+		IO_STATE(R_PAR0_CONFIG, iperr,   noninv)    |
+          /* ack is not inverted, noninv */
+		IO_STATE(R_PAR0_CONFIG, iack,    noninv)    |
+          /* busy is not inverted, noninv */
+		IO_STATE(R_PAR0_CONFIG, ibusy,   noninv)    |
+          /* fault is not inverted, noninv */
+		IO_STATE(R_PAR0_CONFIG, ifault,  noninv)    |
+          /* select is Vcc and we want 1, noninv */
+		IO_STATE(R_PAR0_CONFIG, isel,    noninv)    |
+          /* We will run dma, enable */
+		IO_STATE(R_PAR0_CONFIG, dma, enable)        |
+          /* No run length encoding, disable */
+		IO_STATE(R_PAR0_CONFIG, rle_in, disable)    |
+          /* No run length encoding, disable */
+		IO_STATE(R_PAR0_CONFIG, rle_out, disable)   |
+          /* Enable parallel port */
+		IO_STATE(R_PAR0_CONFIG, enable, on)         |
+          /* Force mode regardless of pin status */
+		IO_STATE(R_PAR0_CONFIG, force, on)          |
+          /* We want ECP forward mode since PAR0 is RX */
+		IO_STATE(R_PAR0_CONFIG, mode, ecp_rev);       
+
+        *R_PAR1_CONFIG =
+          /* We do not have an external buffer, don't care */
+		IO_STATE(R_PAR1_CONFIG, ioe,     noninv)    |
+          
+          /* Not connected, don't care */
+		IO_STATE(R_PAR1_CONFIG, iseli,   noninv)    |
+          
+          /* HostAck must indicate data cycle, noninv */
+		IO_STATE(R_PAR1_CONFIG, iautofd, noninv)    |
+          
+          /* HostClk has no external inverter, noninv */
+		IO_STATE(R_PAR1_CONFIG, istrb,   noninv)    |
+          
+          /* Not connected, don't care */
+		IO_STATE(R_PAR1_CONFIG, iinit,   noninv)    |
+          
+          /* nAckReverse must be 1 in forward mode but is grounded, inv */ 
+		IO_STATE(R_PAR1_CONFIG, iperr,   inv)       |
+          
+          /* PeriphClk must be 1 in forward mode, noninv */
+		IO_STATE(R_PAR1_CONFIG, iack,    noninv)    |
+          
+          /* PeriphAck has no external inverter, noninv */
+		IO_STATE(R_PAR1_CONFIG, ibusy,   noninv)    |
+          
+          /* nPerihpRequest has no external inverter, noniv */
+		IO_STATE(R_PAR1_CONFIG, ifault,  noninv)    |
+          
+          /* Select is VCC and we want 1, noninv */
+		IO_STATE(R_PAR1_CONFIG, isel,    noninv)    |
+          
+          /* No EPP mode, disable */
+                IO_STATE(R_PAR1_CONFIG, ext_mode, disable)  |
+          
+          /* We will run dma, enable */
+                IO_STATE(R_PAR1_CONFIG, dma, enable)        |
+          
+          /* No run length encoding, disable */
+		IO_STATE(R_PAR1_CONFIG, rle_in, disable)    |
+          
+          /* No run length encoding, disable */
+		IO_STATE(R_PAR1_CONFIG, rle_out, disable)   |
+          
+          /* Enable parallel port */
+		IO_STATE(R_PAR1_CONFIG, enable, on)         |
+          
+          /* Force mode regardless of pin status */
+		IO_STATE(R_PAR1_CONFIG, force, on)          |
+          
+          /* We want ECP forward mode since PAR1 is TX */
+	 	IO_STATE(R_PAR1_CONFIG, mode, ecp_fwd);        
+
+        /* Setup time of value * 160 + 20 ns == 180 ns below */
+        *R_PAR1_DELAY = IO_FIELD(R_PAR1_DELAY, setup, 1);  
+
+        *R_PAR1_CTRL = 0;
+
+        while ((((*R_PAR1_STATUS)&0xE000) >> 13) != 5); /* Wait for ECP_FWD mode */
+#ifdef ETHDEBUG
+        dump_parport_status();
+#endif
+        
+        /* make sure ECP irq is acked when we enable it below */
+
+	(void)*R_PAR0_STATUS_DATA;
+	(void)*R_PAR1_STATUS_DATA;
+
+	/* Reset and wait for the DMA channels */
+
+        RESET_DMA(4); /* PAR1_TX_DMA_NBR */
+	RESET_DMA(3); /* PAR0_RX_DMA_NBR */
+	WAIT_DMA(4);  
+	WAIT_DMA(3);
+        
+        /* boot the slave Etrax, by sending code on PAR1.
+	 * do this before we start up the IRQ handlers and stuff,
+	 * beacuse we simply poll for completion in boot_slave.
+	 */
+        
+	boot_slave(&e100lpslaveprog);
+
+	/* allocate the irq corresponding to the receiving DMA */
+
+	if (request_irq(DMA3_RX_IRQ_NBR, e100rx_interrupt, 0,
+			cardname, (void *)dev)) {
+          printk("Failed to allocate DMA3_RX_IRQ_NBR\n");
+		goto grace_exit;
+	}
+
+	/* allocate the irq corresponding to the transmitting DMA */
+
+	if (request_irq(DMA4_TX_IRQ_NBR, e100tx_interrupt, 0,
+			cardname, (void *)dev)) {
+          printk("Failed to allocate DMA4_TX_IRQ_NBR\n");
+          goto grace_exit;
+	}
+        
+        /* allocate the irq used for detecting ECP commands on the RX port (PAR0) */
+
+	if (request_irq(PAR0_ECP_IRQ_NBR, ecp_interrupt, 0,
+			cardname, (void *)dev)) {
+          printk("Failed to allocate PAR0_ECP_IRQ_NBR\n");
+          grace_exit:          
+                free_irq(PAR0_ECP_IRQ_NBR, (void *)dev);
+                free_irq(DMA4_TX_IRQ_NBR, (void *)dev);
+		free_irq(DMA3_RX_IRQ_NBR, (void *)dev);
+                
+		return -EAGAIN;
+	}
+
+#if 0
+        /* We are not allocating DMA since DMA4 is reserved for 'cascading'
+         * and will always fail with the current dma.c
+         */
+        
+	/*
+	 * Always allocate the DMA channels after the IRQ,
+	 * and clean up on failure.
+	 */
+
+	if(request_dma(PAR0_RX_DMA_NBR, cardname)) {
+          printk("Failed to allocate PAR0_RX_DMA_NBR\n");
+		goto grace_exit;
+	}
+
+	if(request_dma(PAR1_TX_DMA_NBR, cardname)) {
+          printk("Failed to allocate PAR1_TX_DMA_NBR\n");
+	grace_exit:
+		/* this will cause some 'trying to free free irq' but what the heck... */
+
+		free_dma(PAR1_TX_DMA_NBR);
+                free_dma(PAR0_RX_DMA_NBR);
+                free_irq(PAR0_ECP_IRQ_NBR, (void *)dev);
+                free_irq(DMA4_TX_IRQ_NBR, (void *)dev);
+		free_irq(DMA3_RX_IRQ_NBR, (void *)dev);
+		
+		return -EAGAIN;
+	}
+#endif
+        
+#ifdef ETHDEBUG
+        printk("Par port IRQ and DMA allocated\n");
+#endif
+	save_flags(flags);
+	cli();
+
+	/* enable the irq's for PAR0/1 DMA */
+
+	*R_IRQ_MASK2_SET =
+		IO_STATE(R_IRQ_MASK2_SET, dma3_eop, set) |
+		IO_STATE(R_IRQ_MASK2_SET, dma4_descr, set);
+
+        *R_IRQ_MASK0_SET =
+		IO_STATE(R_IRQ_MASK0_SET, par0_ecp_cmd, set);
+
+	tx_skb = 0;
+
+	/* make sure the irqs are cleared */
+
+	*R_DMA_CH3_CLR_INTR = IO_STATE(R_DMA_CH3_CLR_INTR, clr_eop, do);
+	*R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do);
+
+        /* Write the MAC address to the slave HW */
+	udelay(5000);
+	e100_hardware_send_packet(HOST_CMD_SETMAC, dev->dev_addr, 6);
+        
+	/* make sure the rec and transmit error counters are cleared */
+
+	(void)*R_REC_COUNTERS;  /* dummy read */
+	(void)*R_TR_COUNTERS;   /* dummy read */
+
+	/* start the receiving DMA channel so we can receive packets from now on */
+
+	*R_DMA_CH3_FIRST = virt_to_phys(myNextRxDesc);
+	*R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, start);
+
+	restore_flags(flags);
+	
+	/* We are now ready to accept transmit requeusts from
+	 * the queueing layer of the networking.
+	 */
+#ifdef ETHDEBUG
+        printk("Starting slave network transmit queue\n");
+#endif
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+static void 
+e100_reset_tranceiver(void)
+{
+  /* To do: Reboot and setup slave Etrax */
+}
+
+/* Called by upper layers if they decide it took too long to complete
+ * sending a packet - we need to reset and stuff.
+ */
+
+static void
+e100_tx_timeout(struct net_device *dev)
+{
+	struct net_local *np = (struct net_local *)dev->priv;
+
+	printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
+	       tx_done(dev) ? "IRQ problem" : "network cable problem");
+	
+	/* remember we got an error */
+	
+	np->stats.tx_errors++; 
+	
+	/* reset the TX DMA in case it has hung on something */
+	
+	RESET_DMA(4);
+	WAIT_DMA(4);
+	
+	/* Reset the tranceiver. */
+	
+	e100_reset_tranceiver();
+	
+	/* and get rid of the packet that never got an interrupt */
+	
+	dev_kfree_skb(tx_skb);
+	tx_skb = 0;
+	
+	/* tell the upper layers we're ok again */
+	
+	netif_wake_queue(dev);
+}
+
+
+/* This will only be invoked if the driver is _not_ in XOFF state.
+ * What this means is that we need not check it, and that this
+ * invariant will hold if we make sure that the netif_*_queue()
+ * calls are done at the proper times.
+ */
+
+static int
+e100_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+	struct net_local *np = (struct net_local *)dev->priv;
+	int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+	unsigned char *buf = skb->data;
+	
+#ifdef ETHDEBUG
+        unsigned char *temp_data_ptr = buf;
+        int i;
+        
+	printk("Sending a packet of length %d:\n", length);
+	/* dump the first bytes in the packet */
+	for(i = 0; i < 8; i++) {
+		printk("%d: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", i * 8,
+		       temp_data_ptr[0],temp_data_ptr[1],temp_data_ptr[2],
+                       temp_data_ptr[3],temp_data_ptr[4],temp_data_ptr[5],
+                       temp_data_ptr[6],temp_data_ptr[7]);
+		temp_data_ptr += 8;
+	}
+#endif
+	spin_lock_irq(&np->lock);  /* protect from tx_interrupt */
+
+	tx_skb = skb; /* remember it so we can free it in the tx irq handler later */
+	dev->trans_start = jiffies;
+	
+	e100_hardware_send_packet(HOST_CMD_SENDPACK, buf, length);
+
+	/* this simple TX driver has only one send-descriptor so we're full
+	 * directly. If this had a send-ring instead, we would only do this if
+	 * the ring got full.
+	 */
+
+	netif_stop_queue(dev);
+        
+	spin_unlock_irq(&np->lock);
+
+	return 0;
+}
+
+/*
+ * The typical workload of the driver:
+ *   Handle the network interface interrupts.
+ */
+
+static void
+e100rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	unsigned long irqbits = *R_IRQ_MASK2_RD;
+        
+	if(irqbits & IO_STATE(R_IRQ_MASK2_RD, dma3_eop, active)) {
+
+		/* acknowledge the eop interrupt */
+
+		*R_DMA_CH3_CLR_INTR = IO_STATE(R_DMA_CH3_CLR_INTR, clr_eop, do);
+
+		/* check if one or more complete packets were indeed received */
+
+		while(*R_DMA_CH3_FIRST != virt_to_phys(myNextRxDesc)) {
+			/* Take out the buffer and give it to the OS, then
+			 * allocate a new buffer to put a packet in.
+			 */
+			e100_rx(dev);
+			((struct net_local *)dev->priv)->stats.rx_packets++;
+			/* restart/continue on the channel, for safety */
+			*R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, restart);
+			/* clear dma channel 3 eop/descr irq bits */
+			*R_DMA_CH3_CLR_INTR =
+				IO_STATE(R_DMA_CH3_CLR_INTR, clr_eop, do) |
+				IO_STATE(R_DMA_CH3_CLR_INTR, clr_descr, do);
+			
+			/* now, we might have gotten another packet
+			   so we have to loop back and check if so */
+		}
+	}
+}
+
+/* the transmit dma channel interrupt
+ *
+ * this is supposed to free the skbuff which was pending during transmission,
+ * and inform the kernel that we can send one more buffer
+ */
+
+static void
+e100tx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	unsigned long irqbits = *R_IRQ_MASK2_RD;
+	struct net_local *np = (struct net_local *)dev->priv;
+
+#ifdef ETHDEBUG
+        printk("We got tx interrupt\n");
+#endif
+	/* check for a dma4_eop interrupt */
+	if(irqbits & IO_STATE(R_IRQ_MASK2_RD, dma4_descr, active)) {
+		/* This protects us from concurrent execution of
+		 * our dev->hard_start_xmit function above.
+		 */
+
+		spin_lock(&np->lock);
+		
+		/* acknowledge the eop interrupt */
+                
+		*R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do);
+
+                /* skip *R_DMA_CH4_FIRST == 0 test since we use d_wait... */
+		if(tx_skb) {
+
+			np->stats.tx_bytes += tx_skb->len;
+			np->stats.tx_packets++;
+			/* dma is ready with the transmission of the data in tx_skb, so now we can release the skb memory */
+			dev_kfree_skb_irq(tx_skb);
+			tx_skb = 0;
+			netif_wake_queue(dev);
+		} else {
+			printk(KERN_WARNING "%s: tx weird interrupt\n",
+                               cardname);
+		}
+
+		spin_unlock(&np->lock);
+	}
+}
+
+static void
+ecp_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct net_local *lp = (struct net_local *)dev->priv;
+	unsigned long temp, irqbits = *R_IRQ_MASK0_RD;
+
+        /* check for ecp irq */
+	if(irqbits & IO_MASK(R_IRQ_MASK0_RD, par0_ecp_cmd)) { 
+		/* acknowledge by reading the bit */
+		temp = *R_PAR0_STATUS_DATA;
+		/* force an EOP on the incoming channel, so we'll get an rx interrupt */
+		*R_SET_EOP = IO_STATE(R_SET_EOP, ch3_eop, set);
+	}
+}
+
+/* We have a good packet(s), get it/them out of the buffers. */
+static void
+e100_rx(struct net_device *dev)
+{
+	struct sk_buff *skb;
+	int length=0;
+	int i;
+	struct net_local *np = (struct net_local *)dev->priv;
+	struct etrax_dma_descr *mySaveRxDesc = myNextRxDesc;
+	unsigned char *skb_data_ptr;
+
+	/* If the packet is broken down in many small packages then merge
+	 * count how much space we will need to alloc with skb_alloc() for
+	 * it to fit.
+	 */
+
+	while (!(myNextRxDesc->status & d_eop)) {
+		length += myNextRxDesc->sw_len; /* use sw_len for the first descs */
+		myNextRxDesc->status = 0;
+		myNextRxDesc = phys_to_virt(myNextRxDesc->next);
+	}
+
+	length += myNextRxDesc->hw_len; /* use hw_len for the last descr */
+
+#ifdef ETHDEBUG
+	printk("Got a packet of length %d:\n", length);
+	/* dump the first bytes in the packet */
+	skb_data_ptr = (unsigned char *)phys_to_virt(mySaveRxDesc->buf);
+	for(i = 0; i < 8; i++) {
+		printk("%d: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", i * 8,
+		       skb_data_ptr[0],skb_data_ptr[1],skb_data_ptr[2],skb_data_ptr[3],
+		       skb_data_ptr[4],skb_data_ptr[5],skb_data_ptr[6],skb_data_ptr[7]);
+		skb_data_ptr += 8;
+	}
+#endif
+
+	skb = dev_alloc_skb(length - ETHER_HEAD_LEN);
+	if (!skb) {
+		np->stats.rx_errors++;
+		printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
+		       dev->name);
+		return;
+	}
+
+	skb_put(skb, length - ETHER_HEAD_LEN);        /* allocate room for the packet body */
+	skb_data_ptr = skb_push(skb, ETHER_HEAD_LEN); /* allocate room for the header */
+
+#ifdef ETHDEBUG
+	printk("head = 0x%x, data = 0x%x, tail = 0x%x, end = 0x%x\n",
+	       skb->head, skb->data, skb->tail, skb->end);
+	printk("copying packet to 0x%x.\n", skb_data_ptr);
+#endif
+
+	/* this loop can be made using max two memcpy's if optimized */
+
+	while(mySaveRxDesc != myNextRxDesc) {
+		memcpy(skb_data_ptr, phys_to_virt(mySaveRxDesc->buf),
+		       mySaveRxDesc->sw_len);
+		skb_data_ptr += mySaveRxDesc->sw_len;
+		mySaveRxDesc = phys_to_virt(mySaveRxDesc->next);
+	}
+
+	memcpy(skb_data_ptr, phys_to_virt(mySaveRxDesc->buf),
+	       mySaveRxDesc->hw_len);
+
+	skb->dev = dev;
+	skb->protocol = eth_type_trans(skb, dev);
+
+	/* Send the packet to the upper layers */
+
+	netif_rx(skb);
+
+	/* Prepare for next packet */
+
+	myNextRxDesc->status = 0;
+	myPrevRxDesc = myNextRxDesc;
+	myNextRxDesc = phys_to_virt(myNextRxDesc->next);
+
+	myPrevRxDesc->ctrl |= d_eol;
+	myLastRxDesc->ctrl &= ~d_eol;
+	myLastRxDesc = myPrevRxDesc;
+
+	return;
+}
+
+/* The inverse routine to net_open(). */
+static int
+e100_close(struct net_device *dev)
+{
+	struct net_local *np = (struct net_local *)dev->priv;
+
+	printk("Closing %s.\n", dev->name);
+
+	netif_stop_queue(dev);
+
+	*R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, par0_ecp_cmd, clr);
+
+	*R_IRQ_MASK2_CLR =
+		IO_STATE(R_IRQ_MASK2_CLR, dma3_eop, clr) |
+		IO_STATE(R_IRQ_MASK2_CLR, dma4_descr, clr);	
+
+	/* Stop the receiver and the transmitter */
+
+	RESET_DMA(3);
+	RESET_DMA(4);
+
+	/* Flush the Tx and disable Rx here. */
+
+	free_irq(DMA3_RX_IRQ_NBR, (void *)dev);
+	free_irq(DMA4_TX_IRQ_NBR, (void *)dev);
+	free_irq(PAR0_ECP_IRQ_NBR, (void *)dev);
+
+	free_dma(PAR1_TX_DMA_NBR);
+	free_dma(PAR0_RX_DMA_NBR);
+
+	/* Update the statistics here. */
+
+	update_rx_stats(&np->stats);
+	update_tx_stats(&np->stats);
+
+	return 0;
+}
+
+static void
+update_rx_stats(struct net_device_stats *es)
+{
+	unsigned long r = *R_REC_COUNTERS;
+	/* update stats relevant to reception errors */
+	es->rx_fifo_errors += r >> 24;            /* fifo overrun */
+	es->rx_crc_errors += r & 0xff;            /* crc error */
+	es->rx_frame_errors += (r >> 8) & 0xff;   /* alignment error */
+	es->rx_length_errors += (r >> 16) & 0xff; /* oversized frames */
+}
+
+static void
+update_tx_stats(struct net_device_stats *es)
+{
+	unsigned long r = *R_TR_COUNTERS;
+	/* update stats relevant to transmission errors */
+	es->collisions += (r & 0xff) + ((r >> 8) & 0xff); /* single_col + multiple_col */
+	es->tx_errors += (r >> 24) & 0xff; /* deferred transmit frames */
+}
+
+/*
+ * Get the current statistics.
+ * This may be called with the card open or closed.
+ */
+static struct net_device_stats *
+e100_get_stats(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *)dev->priv;
+
+	update_rx_stats(&lp->stats);
+	update_tx_stats(&lp->stats);
+
+	return &lp->stats;
+}
+
+/*
+ * 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
+ * num_addrs > 0	Multicast mode, receive normal and MC packets,
+ *			and do best-effort filtering.
+ */
+static void
+set_multicast_list(struct net_device *dev)
+{
+  /* To do */
+}
+
+void
+e100_hardware_send_packet(unsigned long hostcmd, char *buf, int length)
+{
+  static char bogus_ecp[] = { 42, 42 };
+  int i;
+  
+
+#ifdef ETHDEBUG
+	printk("e100 send pack, buf 0x%x len %d\n", buf, length);
+#endif
+        
+        host_command = hostcmd;
+
+	/* Configure the tx dma descriptor. Desc 0 is already configured.*/
+
+        TxDescList[1].sw_len = length;
+	/* bug workaround - etrax100 needs d_wait on the descriptor _before_
+	 * a descriptor containing an ECP command
+	 */
+	TxDescList[1].ctrl = d_wait;
+	TxDescList[1].buf = virt_to_phys(buf);
+	TxDescList[1].next = virt_to_phys(&TxDescList[2]);
+
+        /* append the ecp dummy descriptor - its only purpose is to 
+	 * make the receiver generate an irq due to the ecp command
+	 * so the receiver knows where packets end
+	 */
+
+	TxDescList[2].sw_len = 1;
+	TxDescList[2].ctrl = d_ecp | d_eol | d_int;
+	TxDescList[2].buf = virt_to_phys(bogus_ecp);
+        
+
+	/* setup the dma channel and start it */
+
+        *R_DMA_CH4_FIRST = virt_to_phys(TxDescList);
+	*R_DMA_CH4_CMD = IO_STATE(R_DMA_CH4_CMD, cmd, start);
+        
+#ifdef ETHDEBUG         
+         printk("done\n");
+#endif
+}
+
+/* send a chunk of code to the slave chip to boot it. */
+
+static void
+boot_slave(unsigned char *code)
+{
+  int i;
+
+#ifdef ETHDEBUG
+	printk("  booting slave ETRAX...\n");
+#endif
+        *R_PORT_PB_DATA = 0x7F; /* Reset slave */
+        udelay(15); /* Time enough to reset WAN tranciever */
+        *R_PORT_PB_DATA = 0xFF; /* Reset slave */
+
+	/* configure the tx dma data descriptor */
+
+	TxDescList[1].sw_len = ETRAX_PAR_BOOT_LENGTH;
+	TxDescList[1].ctrl = d_eol | d_int; 
+                                                      
+	TxDescList[1].buf = virt_to_phys(code);
+        /*TxDescList[1].buf = code;*/
+	TxDescList[1].next = 0;
+        
+        /* setup the dma channel and start it */
+ 	*R_DMA_CH4_FIRST = virt_to_phys(&TxDescList[1]);
+	*R_DMA_CH4_CMD = IO_STATE(R_DMA_CH4_CMD, cmd, start);
+
+	/* wait for completion */
+	while(!(*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma4_descr)));
+
+	/* ack the irq */
+
+	*R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do);
+
+#if 0
+        /* manual transfer of boot code - requires dma turned off */
+        for (i=0; i<ETRAX_PAR_BOOT_LENGTH; i++)
+        {
+          printk("  sending byte: %u value: %x\n",i,code[i]);
+          while (((*R_PAR1_STATUS)&0x02) == 0); /* Wait while tr_rdy is busy*/
+          *R_PAR1_CTRL_DATA = code[i];
+        }
+#endif
+
+#ifdef ETHDEBUG
+	printk("  done\n");
+#endif
+}
+
+#ifdef ETHDEBUG
+/* debug code to check the current status of PAR1 */
+static void
+dump_parport_status(void)
+{
+  unsigned long temp;
+  
+  printk("Parport1 status:\n");
+  
+  temp = (*R_PAR1_STATUS)&0xE000;
+  temp = temp >> 13;
+  printk("Reg mode: %u (ecp_fwd(5), ecp_rev(6))\n", temp);
+  
+  temp = (*R_PAR1_STATUS)&0x1000;
+  temp = temp >> 12;
+  printk("Reg perr: %u (ecp_rev(0))\n", temp);
+  
+  temp = (*R_PAR1_STATUS)&0x0800;
+  temp = temp >> 11;
+  printk("Reg ack: %u (inactive (1), active (0))\n", temp);
+  
+  temp = (*R_PAR1_STATUS)&0x0400;
+  temp = temp >> 10;
+  printk("Reg busy: %u (inactive (0), active (1))\n", temp);
+  
+  temp = (*R_PAR1_STATUS)&0x0200;
+  temp = temp >> 9;
+  printk("Reg fault: %u (inactive (1), active (0))\n", temp);
+  
+  temp = (*R_PAR1_STATUS)&0x0100;
+  temp = temp >> 8;
+  printk("Reg sel: %u (inactive (0), active (1), xflag(1))\n", temp);
+
+  temp = (*R_PAR1_STATUS)&0x02;
+  temp = temp >> 1;
+  printk("Reg tr_rdy: %u (busy (0), ready (1))\n", temp);
+
+}
+#endif /* ETHDEBUG */
+
+static struct net_device dev_etrax_slave_ethernet;
+
+static int
+etrax_init_module(void)
+{
+	struct net_device *d = &dev_etrax_slave_ethernet;
+
+	d->init = etrax_ethernet_lpslave_init;
+
+	if(register_netdev(d) == 0)
+		return 0;
+	else
+		return -ENODEV;
+}
+
+module_init(etrax_init_module);
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/parport.c linux/arch/cris/drivers/parport.c
--- v2.4.6/linux/arch/cris/drivers/parport.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/parport.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: parport.c,v 1.4 2001/04/06 13:04:02 hugo Exp $
+/* $Id: parport.c,v 1.5 2001/05/09 12:38:42 johana Exp $
  * 
  * Elinux parallel port driver
  * NOTE!
@@ -501,8 +501,8 @@
 
 #ifdef CONFIG_ETRAX_PARALLEL_PORT0
 #ifdef CONFIG_ETRAX_PAR0_DMA
-	RESET_DMA(2);
-	WAIT_DMA(2);
+	RESET_DMA(PAR0_TX_DMA_NBR);
+	WAIT_DMA(PAR0_TX_DMA_NBR);
 #ifdef CONFIG_ETRAX_SERIAL_PORT2
 	printk(" Warning - DMA clash with ser2!\n");
 #endif /* SERIAL_PORT2 */
@@ -511,8 +511,8 @@
 
 #ifdef CONFIG_ETRAX_PARALLEL_PORT1
 #ifdef CONFIG_ETRAX_PAR1_DMA
-	RESET_DMA(4);
-	WAIT_DMA(4);
+	RESET_DMA(PAR1_TX_DMA_NBR);
+	WAIT_DMA(PAR1_TX_DMA_NBR);
 #ifdef CONFIG_ETRAX_SERIAL_PORT3
 	printk(" Warning - DMA clash with ser3!\n");
 #endif /* SERIAL_PORT3 */
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/serial.c linux/arch/cris/drivers/serial.c
--- v2.4.6/linux/arch/cris/drivers/serial.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/serial.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: serial.c,v 1.12 2001/04/19 12:23:07 bjornw Exp $
+/* $Id: serial.c,v 1.13 2001/05/09 12:40:31 johana Exp $
  *
  * Serial port driver for the ETRAX 100LX chip
  *
@@ -7,6 +7,9 @@
  *      Many, many authors. Based once upon a time on serial.c for 16x50.
  *
  * $Log: serial.c,v $
+ * Revision 1.13  2001/05/09 12:40:31  johana
+ * Use DMA_NBR and IRQ_NBR defines from dma.h and irq.h
+ *
  * Revision 1.12  2001/04/19 12:23:07  bjornw
  * CONFIG_RS485 -> CONFIG_ETRAX_RS485
  *
@@ -199,7 +202,7 @@
  *
  */
 
-static char *serial_version = "$Revision: 1.12 $";
+static char *serial_version = "$Revision: 1.13 $";
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -495,7 +498,6 @@
 #endif
 
 #ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
-#define TIMER1_IRQ_NBR 3
 
 /* clock select 10 for timer 1 gives 230400 Hz */
 #define FASTTIMER_SELECT (10)
@@ -3049,32 +3051,32 @@
 #ifndef CONFIG_SVINTO_SIM
 	/* Not needed in simulator.  May only complicate stuff. */
 	/* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */
-	if(request_irq(22, tr_interrupt, SA_INTERRUPT, "serial 0 dma tr", NULL))
+	if(request_irq(SER0_DMA_TX_IRQ_NBR, tr_interrupt, SA_INTERRUPT, "serial 0 dma tr", NULL))
 		panic("irq22");
-	if(request_irq(23, rec_interrupt, SA_INTERRUPT, "serial 0 dma rec", NULL))
+	if(request_irq(SER0_DMA_RX_IRQ_NBR, rec_interrupt, SA_INTERRUPT, "serial 0 dma rec", NULL))
 		panic("irq23");
 #ifdef SERIAL_HANDLE_EARLY_ERRORS
-	if(request_irq(8, ser_interrupt, SA_INTERRUPT, "serial ", NULL))
+	if(request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_INTERRUPT, "serial ", NULL))
 		panic("irq8");
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT1
-	if(request_irq(24, tr_interrupt, SA_INTERRUPT, "serial 1 dma tr", NULL))
+	if(request_irq(SER1_DMA_TX_IRQ_NBR, tr_interrupt, SA_INTERRUPT, "serial 1 dma tr", NULL))
 		panic("irq24");
-	if(request_irq(25, rec_interrupt, SA_INTERRUPT, "serial 1 dma rec", NULL))
+	if(request_irq(SER1_DMA_RX_IRQ_NBR, rec_interrupt, SA_INTERRUPT, "serial 1 dma rec", NULL))
 		panic("irq25");
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT2
 	/* DMA Shared with par0 (and SCSI0 and ATA) */
-	if(request_irq(18, tr_interrupt, SA_SHIRQ, "serial 2 dma tr", NULL))
+	if(request_irq(SER2_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ, "serial 2 dma tr", NULL))
 		panic("irq18");
-	if(request_irq(19, rec_interrupt, SA_SHIRQ, "serial 2 dma rec", NULL))
+	if(request_irq(SER2_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ, "serial 2 dma rec", NULL))
 		panic("irq19");
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT3
 	/* DMA Shared with par1 (and SCSI1 and Extern DMA 0) */
-	if(request_irq(20, tr_interrupt, SA_SHIRQ, "serial 3 dma tr", NULL))
+	if(request_irq(SER3_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ, "serial 3 dma tr", NULL))
 		panic("irq20");
-	if(request_irq(21, rec_interrupt, SA_SHIRQ, "serial 3 dma rec", NULL))
+	if(request_irq(SER3_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ, "serial 3 dma rec", NULL))
 		panic("irq21");
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/usb-host.c linux/arch/cris/drivers/usb-host.c
--- v2.4.6/linux/arch/cris/drivers/usb-host.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/usb-host.c	Wed Jul  4 11:50:39 2001
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2001 Axis Communications AB.
  *
- * $Id: usb-host.c,v 1.8 2001/02/27 13:52:48 bjornw Exp $
+ * $Id: usb-host.c,v 1.9 2001/05/09 12:54:12 johana Exp $
  *
  */
 
@@ -23,17 +23,18 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/svinto.h>
 
 #include <linux/usb.h>
 #include "usb-host.h"
 
-#define ETRAX_USB_HC_IRQ 31
-#define ETRAX_USB_RX_IRQ 25
-#define ETRAX_USB_TX_IRQ 24
+#define ETRAX_USB_HC_IRQ USB_HC_IRQ_NBR
+#define ETRAX_USB_RX_IRQ USB_DMA_RX_IRQ_NBR
+#define ETRAX_USB_TX_IRQ USB_DMA_TX_IRQ_NBR
 
-static const char *usb_hcd_version = "$Revision: 1.8 $";
+static const char *usb_hcd_version = "$Revision: 1.9 $";
 
 #undef KERN_DEBUG
 #define KERN_DEBUG ""
@@ -2034,21 +2035,21 @@
 		OK (4);		/* hub power ** */
 		
 	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
-                if (wIndex == 1) {
+		if (wIndex == 1) {
 			*((__u16*)data) = cpu_to_le16(hc->rh.prev_wPortStatus_1);
 			*((__u16*)data + 1) = cpu_to_le16(hc->rh.wPortChange_1);
-                }
-                else if (wIndex == 2) {
+		}
+		else if (wIndex == 2) {
 			*((__u16*)data) = cpu_to_le16(hc->rh.prev_wPortStatus_2);
 			*((__u16*)data + 1) = cpu_to_le16(hc->rh.wPortChange_2);
-                }
-                else {
+		}
+		else {
 			dbg_rh("RH_GET_STATUS whith invalid wIndex !!");
 			OK(0);
-                }
+		}
 		
-                OK(4);
-                
+		OK(4);
+
 	case RH_CLEAR_FEATURE | RH_ENDPOINT:
 		switch (wValue) {
 		case (RH_ENDPOINT_STALL):
@@ -2114,16 +2115,16 @@
 			OK (0);	/* port power ** */
 		case (RH_C_PORT_CONNECTION):
 			
-                        if (wIndex == 1) {
+			if (wIndex == 1) {
 				hc->rh.wPortChange_1 &= ~(1 << RH_PORT_CONNECTION);
-                        }
-                        else if (wIndex == 2) {
+			}
+			else if (wIndex == 2) {
 				hc->rh.wPortChange_2 &= ~(1 << RH_PORT_CONNECTION);
-                        }
-                        else {
+			}
+			else {
 				dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_CONNECTION "
 				       "with invalid wIndex == %d!!", wIndex);
-                        }
+			}
 
 			OK (0);
 		case (RH_C_PORT_ENABLE):
@@ -2182,7 +2183,7 @@
 
 			OK (0);
 		case (RH_PORT_RESET):
-                        if (wIndex == 1) {
+			if (wIndex == 1) {
 				int port1_retry;
 				
 			port1_redo:
@@ -2205,8 +2206,8 @@
 				   not even schedule() works !!! WHY ?? */
 
 				udelay(15000);
-                        }
-                        else if (wIndex == 2) {
+			}
+			else if (wIndex == 2) {
 				int port2_retry;
 				
 			port2_redo:
@@ -2229,7 +2230,7 @@
 				   not even schedule() works !!! WHY ?? */
 
 				udelay(15000);
-                        }
+			}
 
 			/* Try to bring the HC into running state */
 			*R_USB_COMMAND =
@@ -2237,21 +2238,21 @@
 			
 			nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
 			
-                        dbg_rh("...Done");
-                        OK(0);
-                        
+			dbg_rh("...Done");
+			OK(0);
+
 		case (RH_PORT_POWER):
 			OK (0);	/* port power ** */
 		case (RH_PORT_ENABLE):
 			/* There is no rh port enable command in the Etrax USB interface!!!! */
 			OK (0);
-                        
+
 		}
 		break;
 		
 	case RH_SET_ADDRESS:
 		hc->rh.devnum = wValue;
-                dbg_rh("RH address set to: %d", hc->rh.devnum);
+		dbg_rh("RH address set to: %d", hc->rh.devnum);
 		OK (0);
 		
 	case RH_GET_DESCRIPTOR:
@@ -2324,7 +2325,7 @@
 	etrax_usb_bus = bus = usb_alloc_bus(&etrax_usb_device_operations);
 	hc->bus = bus;
 	bus->hcpriv = hc;
-        
+
 	/* Initalize RH to the default address.
 	   And make sure that we have no status change indication */
 	hc->rh.numports = 2;  /* The RH has two ports */
@@ -2339,7 +2340,7 @@
 	/* Initialize the intr-traffic flags */
 	hc->intr.sleeping = 0;
 	hc->intr.wq = NULL;
-        
+
 	/* Initially all ep's are free except ep 0 */
 	ep_usage_bitmask = 0;
 	set_bit(0, (void *)&ep_usage_bitmask);
@@ -2349,20 +2350,20 @@
 
 	/* This code should really be moved */
 
-        if (request_dma(8, "ETRAX 100LX built-in USB (Tx)")) {
+	if (request_dma(USB_TX_DMA_NBR, "ETRAX 100LX built-in USB (Tx)")) {
 		err("Could not allocate DMA ch 8 for USB");
 		etrax_usb_hc_cleanup();
 		DBFEXIT;
 		return -1;
 	}
 	
-	if (request_dma(9, "ETRAX 100LX built-in USB (Rx)")) {
+	if (request_dma(USB_RX_DMA_NBR, "ETRAX 100LX built-in USB (Rx)")) {
 		err("Could not allocate DMA ch 9 for USB");
 		etrax_usb_hc_cleanup();
 		DBFEXIT;
 		return -1;
 	}	
-#if 0  /* Moved to head.S */        
+#if 0  /* Moved to head.S */
 	*R_GEN_CONFIG = genconfig_shadow =
 		(genconfig_shadow & ~(IO_MASK(R_GEN_CONFIG, usb1) |
 				      IO_MASK(R_GEN_CONFIG, usb2) |
@@ -2490,8 +2491,8 @@
 	free_irq(ETRAX_USB_RX_IRQ, NULL);
 	free_irq(ETRAX_USB_TX_IRQ, NULL);
 
-	free_dma(8);
-	free_dma(9);
+	free_dma(USB_TX_DMA_NBR);
+	free_dma(USB_RX_DMA_NBR);
 	usb_deregister_bus(etrax_usb_bus);
 
 	DBFEXIT;
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/Makefile linux/arch/cris/kernel/Makefile
--- v2.4.6/linux/arch/cris/kernel/Makefile	Tue May  1 16:04:56 2001
+++ linux/arch/cris/kernel/Makefile	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.4 2001/04/17 13:58:39 orjanf Exp $
+# $Id: Makefile,v 1.5 2001/05/15 05:10:00 hp Exp $
 #
 # Makefile for the linux kernel.
 #
@@ -19,6 +19,11 @@
 	   debugport.o semaphore.o
 
 obj-$(CONFIG_ETRAX_KGDB) += kgdb.o
+
+entry.o: entryoffsets.s
+
+entryoffsets.s: entryoffsets.c
+	$(CC) $(CFLAGS) -S -c $<
 
 clean:
 
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/entry.S linux/arch/cris/kernel/entry.S
--- v2.4.6/linux/arch/cris/kernel/entry.S	Sun May 20 12:11:38 2001
+++ linux/arch/cris/kernel/entry.S	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.22 2001/04/17 13:58:39 orjanf Exp $
+/* $Id: entry.S,v 1.27 2001/05/29 11:25:27 markusl Exp $
  *
  *  linux/arch/cris/entry.S
  *
@@ -7,6 +7,21 @@
  *  Authors:	Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: entry.S,v $
+ *  Revision 1.27  2001/05/29 11:25:27  markusl
+ *  In case of "spurious_interrupt", do hard_reset instead of hanging system in a loop...
+ *
+ *  Revision 1.26  2001/05/15 15:46:03  bjornw
+ *  Include config.h now that we use some CONFIG_ options
+ *
+ *  Revision 1.25  2001/05/15 05:38:47  hp
+ *  Tweaked code in _ret_from_sys_call
+ *
+ *  Revision 1.24  2001/05/15 05:27:49  hp
+ *  Save r9 in r1 over function call rather than on stack.
+ *
+ *  Revision 1.23  2001/05/15 05:10:00  hp
+ *  Generate entry.S structure offsets from C
+ *
  *  Revision 1.22  2001/04/17 13:58:39  orjanf
  *  * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.
  *
@@ -140,39 +155,21 @@
 	
 LENOSYS = 38
 
-	;; offsets into the task_struct (found at sp aligned to THREAD_SIZE, 8192)
-	;; linux/sched.h
-	
-LTASK_SIGPENDING  =  8
-LTASK_NEEDRESCHED = 20
-LTASK_PTRACE      = 24
-LTASK_PID         = 105
+	;; Get offsets into various structs.
+	.include "entryoffsets.s"
 
-	;; process bits for ptrace
+	;; process bits for ptrace.  FIXME: Should be in a header file.
 
 PT_TRACESYS_BIT	  = 1
 
-	;; some pt_regs offsets (from ptrace.h)
-	
-LORIG_R10	= 4
-LR13		= 8
-LR12		= 12
-LR11		= 16
-LR10		= 20
-LR9		= 24
-LMOF		= 64
-LDCCR		= 68
-LSRP		= 72
-LIRP		= 76
-
 	;; below are various parts of system_call which are not in the fast-path
 	
 	;; handle software irqs
 				
 handle_softirq:
-	push	r9
+	move.d	r9,r1
 	jsr	_do_softirq		; call the C routine for softirq handling
-	pop	r9
+	move.d	r1,r9
 
 	;; fall-through
 	
@@ -188,11 +185,10 @@
 
 reschedule:
 	;; keep r9 intact
-	push	r9
+	move.d	r9,r1
 	jsr	_schedule
-	pop	r9
 	ba	_ret_from_sys_call
-	nop
+	move.d	r1,r9
 
 	;; return but call do_signal first
 signal_return:
@@ -275,8 +271,9 @@
 		
 	;; check if any bottom halves need service
 	
-	move.d	[_irq_stat],r0	       ; softirq_active
-	and.d	[_irq_stat+4],r0       ; softirq_mask
+	move.d	_irq_stat,r10
+	move.d	[r10+],r0	       ; softirq_active
+	and.d	[r10],r0	       ; softirq_mask
 	bne	handle_softirq
 	nop
 
@@ -378,12 +375,6 @@
 	ba	_ret_from_sys_call
 	nop
 		
-	;; from asm/processor.h, the thread_struct
-	
-LTHREAD_KSP	= 0
-LTHREAD_USP	= 4
-LTHREAD_DCCR	= 8
-	
 	;; _resume performs the actual task-switching, by switching stack pointers
 	;; input arguments: r10 = prev, r11 = next, r12 = thread offset in task struct
 	;; returns old current in r10
@@ -495,7 +486,7 @@
 _IRQ1_interrupt:
 _spurious_interrupt:	
 	di
-basse2:	ba	basse2
+	jsr _hard_reset_now
 	nop
 
 	;; this handles the case when multiple interrupts arrive at the same time
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/entryoffsets.c linux/arch/cris/kernel/entryoffsets.c
--- v2.4.6/linux/arch/cris/kernel/entryoffsets.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/entryoffsets.c	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,54 @@
+/* linux/arch/cris/entryoffsets.c
+ *
+ * Copyright (C) 2001 Axis Communications AB
+ *
+ * Generate structure offsets for use in entry.S.  No extra processing
+ * needed more than compiling this file to assembly code.  Horrendous
+ * assembly code will be generated, so don't look at that.
+ *
+ * Authors:	Hans-Peter Nilsson (hp@axis.com)
+ */
+
+/* There can be string constants fallout from inline functions, so we'd
+   better make sure we don't assemble anything emitted from inclusions.  */
+__asm__ (".if 0");
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <asm/processor.h>
+
+/* Exclude everything except the assembly by wrapping it in ".if 0".  */
+#undef OF
+#define OF(NAME, TYPE, MEMBER)			\
+void NAME ## _fun (void)			\
+ {						\
+  __asm__ (".endif \n"				\
+	   #NAME " = %0 \n"			\
+	   ".if 0\n"				\
+	   : : "i" (offsetof (TYPE, MEMBER)));	\
+ }
+
+/* task_struct offsets.  */
+OF (LTASK_SIGPENDING, struct task_struct, sigpending)
+OF (LTASK_NEEDRESCHED, struct task_struct, need_resched)
+OF (LTASK_PTRACE, struct task_struct, ptrace)
+OF (LTASK_PID, struct task_struct, pid)
+
+/* pt_regs offsets.  */
+OF (LORIG_R10, struct pt_regs, orig_r10)
+OF (LR13, struct pt_regs, r13)
+OF (LR12, struct pt_regs, r12)
+OF (LR11, struct pt_regs, r11)
+OF (LR10, struct pt_regs, r10)
+OF (LR9, struct pt_regs, r9)
+OF (LMOF, struct pt_regs, mof)
+OF (LDCCR, struct pt_regs, dccr)
+OF (LSRP, struct pt_regs, srp)
+OF (LIRP, struct pt_regs, irp)
+
+/* thread_struct offsets.  */
+OF (LTHREAD_KSP, struct thread_struct, ksp)
+OF (LTHREAD_USP, struct thread_struct, usp)
+OF (LTHREAD_DCCR, struct thread_struct, dccr)
+
+__asm__ (".endif");
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/head.S linux/arch/cris/kernel/head.S
--- v2.4.6/linux/arch/cris/kernel/head.S	Tue May  1 16:04:56 2001
+++ linux/arch/cris/kernel/head.S	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.29 2001/04/18 12:51:59 orjanf Exp $
+/* $Id: head.S,v 1.34 2001/05/15 07:08:14 hp Exp $
  * 
  * Head of the kernel - alter with care
  *
@@ -7,6 +7,21 @@
  * Authors:	Bjorn Wesen (bjornw@axis.com)
  * 
  * $Log: head.S,v $
+ * Revision 1.34  2001/05/15 07:08:14  hp
+ * Tweak "notice" to reflect that both r8 r9 are used
+ *
+ * Revision 1.33  2001/05/15 06:40:05  hp
+ * Put bulk of code in .text.init, data in .data.init
+ *
+ * Revision 1.32  2001/05/15 06:18:56  hp
+ * Execute review comment: s/bcc/bhs/g; s/bcs/blo/g
+ *
+ * Revision 1.31  2001/05/15 06:08:40  hp
+ * Add sentence about autodetecting the bit31-MMU-bug
+ *
+ * Revision 1.30  2001/05/15 06:00:05  hp
+ * Update comment: LOW_MAP is not forced on xsim anymore.
+ *
  * Revision 1.29  2001/04/18 12:51:59  orjanf
  * * Reverted review change regarding the use of bcs/bcc.
  * * Removed non-working LED-clearing code.
@@ -127,9 +142,9 @@
 	;; since etrax actually starts at address 2 when booting from flash, we
 	;; put a nop (2 bytes) here first so we dont accidentally skip the di
 	;;
-	;; NOTICE! The registers r8 and r9 are used as a parameter carrying
+	;; NOTICE! The registers r8 and r9 are used as parameters carrying
 	;; information from the decompressor (if the kernel was compressed). 
-	;; They should not be used in the code below until it is read.
+	;; They should not be used in the code below until read.
 	
 	nop	
 	di
@@ -143,8 +158,11 @@
 	;; temporarily map those segments linearily.
 	;;
 	;; Due to a bug in Etrax-100 LX version 1 we need to map the memory
-	;; slightly different. We also let the simulator get this mapping for now.
-	;; (The bug is that you can't remap bit 31.)
+	;; slightly different.  The bug is that you can't remap bit 31 of
+	;; an address.  Though we can check the version register for
+	;; whether the bug is present, some constants would then have to
+	;; be variables, so we don't.  The drawback is that you can "only" map
+	;; 1G per process with CONFIG_CRIS_LOW_MAP.
 
 #ifdef CONFIG_CRIS_LOW_MAP
 	move.d	0x0004b098, r0	; kseg mappings, temporary map of 0xc0->0x40
@@ -190,11 +208,18 @@
 	move.d	pc,r0
 	and.d	0x7fffffff,r0	; get rid of the non-cache bit
 	cmp.d	0x10000,r0	; arbitrary... just something above this code
-	bcs	inflash
+	blo	inflash0
 	nop
 
 	jump	inram		; enter cached ram
-	
+
+	;; Jumpgate for branches.
+inflash0:
+	jump	inflash
+
+	;; Put this in a suitable section where we can reclaim storage
+	;; after init.
+	.section ".text.init"
 inflash:
 	;; We need to initialze DRAM registers before we start using the DRAM
 
@@ -225,7 +250,7 @@
 1:	move.w	[r0+], r3
 	move.w	r3, [r1+]
 	cmp.d	r2, r1
-	bcs	1b
+	blo	1b
 	nop
 
 	;; We keep the cramfs in the flash.
@@ -271,7 +296,7 @@
 	;;  to a cramfs magic is small.. )
 	
 	cmp.d	0x0ffffff8, r9
-	bcc	no_romfs_in_flash	; r9 points outside the flash area
+	bhs	no_romfs_in_flash	; r9 points outside the flash area
 	nop
 	move.d	[r9], r0	; cramfs_super.magic
 	cmp.d	CRAMFS_MAGIC, r0
@@ -353,7 +378,7 @@
 	move.d	_end, r1
 1:	clear.d	[r0+]
 	cmp.d	r1, r0
-	bcs	1b
+	blo	1b
 	nop
 	
 #ifdef CONFIG_BLK_DEV_ETRAXIDE
@@ -575,5 +600,6 @@
 #else	
 _swapper_pg_dir = 0xc0002000
 #endif
-	
+
+	.section ".data.init"
 #include "../lib/hw_settings.S"
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/irq.c linux/arch/cris/kernel/irq.c
--- v2.4.6/linux/arch/cris/kernel/irq.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/kernel/irq.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.14 2001/04/17 13:58:39 orjanf Exp $
+/* $Id: irq.c,v 1.15 2001/06/10 11:18:46 bjornw Exp $
  *
  *	linux/arch/cris/kernel/irq.c
  *
@@ -485,3 +485,10 @@
 #endif
 
 }
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
+/* Used by other archs to show/control IRQ steering during SMP */
+void init_irq_proc(void)
+{
+}
+#endif
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/process.c linux/arch/cris/kernel/process.c
--- v2.4.6/linux/arch/cris/kernel/process.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/kernel/process.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.13 2001/03/20 19:44:06 bjornw Exp $
+/* $Id: process.c,v 1.14 2001/05/29 11:27:59 markusl Exp $
  * 
  *  linux/arch/cris/kernel/process.c
  *
@@ -8,6 +8,9 @@
  *  Authors:   Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: process.c,v $
+ *  Revision 1.14  2001/05/29 11:27:59  markusl
+ *  Fixed so that hard_reset_now will do reset even if watchdog wasn't enabled
+ *
  *  Revision 1.13  2001/03/20 19:44:06  bjornw
  *  Use the 7th syscall argument for regs instead of current_regs
  *
@@ -90,12 +93,21 @@
 
 /* if the watchdog is enabled, we can simply disable interrupts and go
  * into an eternal loop, and the watchdog will reset the CPU after 0.1s
+ * if on the other hand the watchdog wasn't enabled, we just enable it and wait
  */
 
 void hard_reset_now (void)
 {
 	printk("*** HARD RESET ***\n");
 	cli();
+
+#ifndef CONFIG_ETRAX_WATCHDOG
+	/* Since we dont plan to keep on reseting the watchdog,
+	   the key can be arbitrary hence three */
+	*R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, 3) |
+		IO_STATE(R_WATCHDOG, enable, start);
+#endif
+
 	while(1) /* waiting for RETRIBUTION! */ ;
 }
 
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/setup.c linux/arch/cris/kernel/setup.c
--- v2.4.6/linux/arch/cris/kernel/setup.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/kernel/setup.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.14 2001/04/03 12:54:12 starvik Exp $
+/* $Id: setup.c,v 1.16 2001/05/15 01:23:13 hp Exp $
  *
  *  linux/arch/cris/kernel/setup.c
  *
@@ -190,14 +190,10 @@
 	unsigned short cache;
 	unsigned short flags;
 } cpu_info[] = {
+	/* The first four models will never ever run this code and are
+	   only here for display.  */
 	{ "ETRAX 1",   0, 0 },
-	{ "ETRAX 2",   0, 0 },	/* Don't say it HAS_TOKENRING - there are
-				   lethal bugs in that chip that
-				   prevents T-R from ever working.
-				   Never go there, and never lead anyone
-				   into believing it can work.  BTW:
-				   Anyone working on a T-R network
-				   driver? :-) :-) :-) :-/ */
+	{ "ETRAX 2",   0, 0 },
 	{ "ETRAX 3",   0, HAS_TOKENRING },
 	{ "ETRAX 4",   0, HAS_TOKENRING | HAS_SCSI },
 	{ "Unknown",   0, 0 },
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/signal.c linux/arch/cris/kernel/signal.c
--- v2.4.6/linux/arch/cris/kernel/signal.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/kernel/signal.c	Wed Jul  4 11:50:39 2001
@@ -7,7 +7,7 @@
  *
  *  Ideas also taken from arch/arm.
  *
- *  Copyright (C) 2000 Axis Communications AB
+ *  Copyright (C) 2000, 2001 Axis Communications AB
  *
  *  Authors:  Bjorn Wesen (bjornw@axis.com)
  *
@@ -101,7 +101,14 @@
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
 		if (do_signal(0, &saveset, regs))
-			return -EINTR;
+			/* We will get here twice: once to call the signal
+			   handler, then again to return from the
+			   sigsuspend system call.  When calling the
+			   signal handler, R10 holds the signal number as
+			   set through do_signal.  The sigsuspend call
+			   will return with the restored value set above;
+			   always -EINTR.  */
+			return regs->r10;
 	}
 }
 
@@ -133,7 +140,14 @@
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
 		if (do_signal(0, &saveset, regs))
-			return -EINTR;
+			/* We will get here twice: once to call the signal
+			   handler, then again to return from the
+			   sigsuspend system call.  When calling the
+			   signal handler, R10 holds the signal number as
+			   set through do_signal.  The sigsuspend call
+			   will return with the restored value set above;
+			   always -EINTR.  */
+			return regs->r10;
 	}
 }
 
@@ -413,6 +427,7 @@
 
 	regs->irp = (unsigned long) ka->sa.sa_handler;  /* what we enter NOW   */
 	regs->srp = return_ip;                          /* what we enter LATER */
+	regs->r10 = sig;                                /* first argument is signo */
 
 	/* actually move the usp to reflect the stacked frame */
 
@@ -462,7 +477,6 @@
 		/* trampoline - the desired return ip is the retcode itself */
 		return_ip = (unsigned long)&frame->retcode;
 		/* This is movu.w __NR_sigreturn, r9; break 13; */
-		/* TODO: check byteorder */
 		err |= __put_user(0x9c5f,         (short *)(frame->retcode+0));
 		err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2));
 		err |= __put_user(0xe93d,         (short *)(frame->retcode+4));
@@ -477,6 +491,7 @@
 
 	regs->irp = (unsigned long) ka->sa.sa_handler;  /* what we enter NOW   */
 	regs->srp = return_ip;                          /* what we enter LATER */
+	regs->r10 = sig;                                /* first argument is signo */
 
 	/* actually move the usp to reflect the stacked frame */
 
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/sys_cris.c linux/arch/cris/kernel/sys_cris.c
--- v2.4.6/linux/arch/cris/kernel/sys_cris.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/kernel/sys_cris.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: sys_cris.c,v 1.7 2001/04/17 11:52:15 orjanf Exp $
+/* $Id: sys_cris.c,v 1.9 2001/05/30 06:20:26 markusl Exp $
  *
  * linux/arch/cris/kernel/sys_cris.c
  *
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/time.c linux/arch/cris/kernel/time.c
--- v2.4.6/linux/arch/cris/kernel/time.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/kernel/time.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.4 2000/10/17 14:44:58 bjornw Exp $
+/* $Id: time.c,v 1.6 2001/05/29 11:29:42 markusl Exp $
  *
  *  linux/arch/cris/kernel/time.c
  *
@@ -83,12 +83,9 @@
 	 * avoiding timer inconsistencies (they are rare, but they happen)...
 	 * there are three kinds of problems that must be avoided here:
 	 *  1. the timer counter underflows
-	 *  2. hardware problem with the timer, not giving us continuous time,
-	 *     the counter does small "jumps" upwards on some Pentium systems,
-	 *     thus causes time warps
-	 *  3. we are after the timer interrupt, but the bottom half handler
+	 *  2. we are after the timer interrupt, but the bottom half handler
 	 *     hasn't executed yet.
-	 */
+ */
 	if( jiffies_t == jiffies_p ) {
 		if( count > count_p ) {
 		}
@@ -195,7 +192,7 @@
 	return retval;
 }
 
-/* Except from the Etrax100 HSDD about the built-in watchdog:
+/* Excerpt from the Etrax100 HSDD about the built-in watchdog:
  *
  * 3.10.4 Watchdog timer
 
@@ -231,14 +228,12 @@
 
 #define WATCHDOG_MIN_FREE_PAGES 8
 
-extern int nr_free_pages;
-
 static inline void
 reset_watchdog(void)
 {
 #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
 	/* only keep watchdog happy as long as we have memory left! */
-	if(nr_free_pages > WATCHDOG_MIN_FREE_PAGES) {
+	if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) {
 		/* reset the watchdog with the inverse of the old key */
 		watchdog_key ^= 0x7; /* invert key, which is 3 bits */
 		*R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, watchdog_key) |
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/traps.c linux/arch/cris/kernel/traps.c
--- v2.4.6/linux/arch/cris/kernel/traps.c	Sun May 20 12:11:38 2001
+++ linux/arch/cris/kernel/traps.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.11 2001/04/04 09:43:31 orjanf Exp $
+/* $Id: traps.c,v 1.12 2001/05/15 15:46:40 bjornw Exp $
  *
  *  linux/arch/cris/traps.c
  *
diff -u --recursive --new-file v2.4.6/linux/arch/cris/lib/checksum.S linux/arch/cris/lib/checksum.S
--- v2.4.6/linux/arch/cris/lib/checksum.S	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/lib/checksum.S	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: checksum.S,v 1.4 2001/02/19 11:11:33 bjornw Exp $
+/* $Id: checksum.S,v 1.5 2001/05/29 11:40:14 markusl Exp $
  * A fast checksum routine using movem
  * Copyright (c) 1998-2001 Axis Communications AB
  *
@@ -13,6 +13,8 @@
 	;; r12 - checksum
 
 	;; check for breakeven length between movem and normal word looping versions
+	;; we also do _NOT_ want to compute a checksum over more than the 
+	;; actual length when length < 40
 	
 	cmpu.w	80,r11
 	blo	word_loop
@@ -20,6 +22,8 @@
 
 	;; need to save the registers we use below in the movem loop
 	;; this overhead is why we have a check above for breakeven length
+	;; only r0 - r8 have to be saved, the other ones are clobber-able
+	;; according to the ABI
 	
 	subq	9*4,sp
 	movem	r8,[sp]
diff -u --recursive --new-file v2.4.6/linux/arch/cris/lib/checksumcopy.S linux/arch/cris/lib/checksumcopy.S
--- v2.4.6/linux/arch/cris/lib/checksumcopy.S	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/lib/checksumcopy.S	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: checksumcopy.S,v 1.4 2001/02/19 11:11:34 bjornw Exp $
+/* $Id: checksumcopy.S,v 1.5 2001/05/29 11:40:14 markusl Exp $
  * A fast checksum+copy routine using movem
  * Copyright (c) 1998, 2001 Axis Communications AB
  *
@@ -17,6 +17,8 @@
 	;; r13 - checksum
 
 	;; check for breakeven length between movem and normal word looping versions
+	;; we also do _NOT_ want to compute a checksum over more than the 
+	;; actual length when length < 40
 	
 	cmpu.w	80,r12
 	blo	word_loop
@@ -24,6 +26,8 @@
 
 	;; need to save the registers we use below in the movem loop
 	;; this overhead is why we have a check above for breakeven length
+	;; only r0 - r8 have to be saved, the other ones are clobber-able
+	;; according to the ABI
 	
 	subq	9*4,sp
 	movem	r8,[sp]
diff -u --recursive --new-file v2.4.6/linux/arch/cris/lib/dram_init.S linux/arch/cris/lib/dram_init.S
--- v2.4.6/linux/arch/cris/lib/dram_init.S	Tue May  1 16:04:56 2001
+++ linux/arch/cris/lib/dram_init.S	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: dram_init.S,v 1.7 2001/04/18 12:05:39 bjornw Exp $
+/* $Id: dram_init.S,v 1.8 2001/05/15 07:12:45 hp Exp $
  * 
  * DRAM/SDRAM initialization - alter with care
  * This file is intended to be included from other assembler files
@@ -11,6 +11,9 @@
  * Authors:  Mikael Starvik (starvik@axis.com)	
  * 
  * $Log: dram_init.S,v $
+ * Revision 1.8  2001/05/15 07:12:45  hp
+ * Copy warning from head.S about r8 and r9
+ *
  * Revision 1.7  2001/04/18 12:05:39  bjornw
  * Fixed comments, and explicitely include config.h to be sure its there
  *
@@ -44,6 +47,9 @@
 
 #include <linux/config.h>
 
+	;; WARNING! The registers r8 and r9 are used as parameters carrying
+	;; information from the decompressor (if the kernel was compressed). 
+	;; They should not be used in the code below.
 
 #ifndef CONFIG_SVINTO_SIM	
 	move.d   CONFIG_ETRAX_DEF_R_WAITSTATES, r0
diff -u --recursive --new-file v2.4.6/linux/arch/cris/lib/hw_settings.S linux/arch/cris/lib/hw_settings.S
--- v2.4.6/linux/arch/cris/lib/hw_settings.S	Sun May 20 12:11:38 2001
+++ linux/arch/cris/lib/hw_settings.S	Wed Jul  4 11:50:39 2001
@@ -1,14 +1,15 @@
-	;; $Id: hw_settings.S,v 1.2 2001/04/03 11:11:09 starvik Exp $
-	;; 
-	;; This table is used by some tools to extract hardware parameters.
-	;; The table should be included in the kernel and the decompressor.
-	;; Don't forget to update the tools if you change this table.
-	;;
-	;; Copyright (C) 2001 Axis Communications AB
-	;;
-	;; Authors:  Mikael Starvik (starvik@axis.com)	
+/*
+ * $Id: hw_settings.S,v 1.3 2001/04/21 17:02:46 bjornw Exp $
+ * 
+ * This table is used by some tools to extract hardware parameters.
+ * The table should be included in the kernel and the decompressor.
+ * Don't forget to update the tools if you change this table.
+ *
+ * Copyright (C) 2001 Axis Communications AB
+ *
+ * Authors:  Mikael Starvik (starvik@axis.com)	
+ */
 
-	
 #define PA_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PA_DIR << 8) | \
 		(CONFIG_ETRAX_DEF_R_PORT_PA_DATA))
 #define PB_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG << 16) | \
diff -u --recursive --new-file v2.4.6/linux/arch/cris/lib/usercopy.c linux/arch/cris/lib/usercopy.c
--- v2.4.6/linux/arch/cris/lib/usercopy.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/lib/usercopy.c	Wed Jul  4 11:50:39 2001
@@ -273,20 +273,27 @@
 	movem	r10,[r13+]
 
 	addq   44,r12  ;; compensate for last loop underflowing n
-
+8:
 	;; Restore registers from stack
 	movem [sp+],r10
 
 	.section .fixup,\"ax\"
 
-; To provide a correct count in r10 of bytes that failed to be copied,
-; we jump back into the loop if the loop-branch was taken.
-;  There is no performance penalty; the program will segfault soon
-; enough.
+;; Do not jump back into the loop if we fail.  For some uses, we get a
+;; page fault but for performance reasons we care to not get further
+;; faults.  For example, fs/super.c at one time did
+;;  i = size - copy_from_user((void *)page, data, size);
+;; which would cause repeated faults while clearing the remainder of
+;; the SIZE bytes at PAGE after the first fault.
 
 3:
 	move.d [sp],r10
+
+;; Number of remaining bytes, cleared but not copied, is r12 + 44.
+
+	add.d r12,r10
 	addq 44,r10
+
 	move.d r10,[sp]
 	clear.d r0
 	clear.d r1
@@ -299,7 +306,40 @@
 	clear.d r8
 	clear.d r9
 	clear.d r10
-	jump 1b
+
+;; Perform clear similar to the copy-loop.
+
+4:
+	subq 44,r12
+	bge 4b
+	movem r10,[r13+]
+
+;; Clear by four for the remaining multiples.
+
+	addq 40,r12
+	bmi 6f
+	nop
+5:
+	subq 4,r12
+	bpl 5b
+	clear.d [r13+]
+6:
+	addq 4,r12
+	beq 7f
+	nop
+
+	subq 1,r12
+	beq 7f
+	clear.b [r13+]
+
+	subq 1,r12
+	beq 7f
+	clear.b [r13+]
+
+	clear.d r12
+	clear.b [r13+]
+7:
+	jump 8b
 
 	.previous
 	.section __ex_table,\"a\"
diff -u --recursive --new-file v2.4.6/linux/arch/cris/mm/fault.c linux/arch/cris/mm/fault.c
--- v2.4.6/linux/arch/cris/mm/fault.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/mm/fault.c	Wed Jul  4 11:50:39 2001
@@ -6,6 +6,19 @@
  *  Authors:  Bjorn Wesen 
  * 
  *  $Log: fault.c,v $
+ *  Revision 1.16  2001/06/13 00:06:08  bjornw
+ *  current_pgd should be volatile
+ *
+ *  Revision 1.15  2001/06/13 00:02:23  bjornw
+ *  Use a separate variable to store the current pgd to avoid races in schedule
+ *
+ *  Revision 1.14  2001/05/16 17:41:07  hp
+ *  Last comment tweak further tweaked.
+ *
+ *  Revision 1.13  2001/05/15 00:58:44  hp
+ *  Expand a bit on the comment why we compare address >= TASK_SIZE rather
+ *  than >= VMALLOC_START.
+ *
  *  Revision 1.12  2001/04/04 10:51:14  bjornw
  *  mmap_sem is grabbed for reading
  *
@@ -59,6 +72,10 @@
 /* debug of higher-level faults */
 #define DPG(x)
 
+/* current active page directory */
+
+volatile pgd_t *current_pgd;
+
 /* fast TLB-fill fault handler */
 
 void
@@ -94,9 +111,11 @@
 
 	if(miss) {
 
-		/* see if the pte exists at all */
+		/* see if the pte exists at all
+		 * refer through current_pgd, dont use mm->pgd
+		 */
 		
-		pmd = (pmd_t *)pgd_offset(mm, address);
+		pmd = (pmd_t *)(current_pgd + pgd_index(address));
 		if(pmd_none(*pmd))
 			goto dofault;
 		if(pmd_bad(*pmd)) {
@@ -206,7 +225,9 @@
 	 * should really be >= VMALLOC_START, however, kernel fixup errors
 	 * will be handled more quickly by going through vmalloc_fault and then
 	 * into bad_area_nosemaphore than falling through the find_vma user-mode
-	 * tests.
+	 * tests.  As an aside can be mentioned that the difference in
+	 * compiled code is neglibible; the instruction is the same, just a
+	 * comparison with a different address of the same size.
          */
 
         if (address >= TASK_SIZE)
@@ -384,12 +405,17 @@
                 /*
                  * Synchronize this task's top level page-table
                  * with the 'reference' page table.
+		 *
+		 * Use current_pgd instead of tsk->active_mm->pgd
+		 * since the latter might be unavailable if this
+		 * code is executed in a misfortunately run irq
                  */
+
                 int offset = pgd_index(address);
                 pgd_t *pgd, *pgd_k;
                 pmd_t *pmd, *pmd_k;
 
-                pgd = tsk->active_mm->pgd + offset;
+                pgd = current_pgd + offset;
                 pgd_k = init_mm.pgd + offset;
 
                 if (!pgd_present(*pgd)) {
diff -u --recursive --new-file v2.4.6/linux/arch/cris/mm/init.c linux/arch/cris/mm/init.c
--- v2.4.6/linux/arch/cris/mm/init.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/mm/init.c	Wed Jul  4 11:50:39 2001
@@ -7,6 +7,12 @@
  *  Authors:  Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: init.c,v $
+ *  Revision 1.25  2001/06/13 00:02:23  bjornw
+ *  Use a separate variable to store the current pgd to avoid races in schedule
+ *
+ *  Revision 1.24  2001/05/15 00:52:20  hp
+ *  Only map segment 0xa as seg if CONFIG_JULIETTE
+ *
  *  Revision 1.23  2001/04/04 14:35:40  bjornw
  *  * Removed get_pte_slow and friends (2.4.3 change)
  *  * Removed bad_pmd handling (2.4.3 change)
@@ -85,6 +91,7 @@
 #include <asm/dma.h>
 #include <asm/svinto.h>
 #include <asm/io.h>
+#include <asm/mmu_context.h>
 
 static unsigned long totalram_pages;
 
@@ -177,6 +184,13 @@
 
 	for(i = 0; i < PTRS_PER_PGD; i++)
 		swapper_pg_dir[i] = __pgd(0);
+	
+	/* make sure the current pgd table points to something sane
+	 * (even if it is most probably not used until the next 
+	 *  switch_mm)
+	 */
+
+	current_pgd = init_mm.pgd;
 
 	/* initialise the TLB (tlb.c) */
 
@@ -241,7 +255,11 @@
 			IO_STATE(R_MMU_KSEG, seg_d, page ) | 
 			IO_STATE(R_MMU_KSEG, seg_c, page ) |   
 			IO_STATE(R_MMU_KSEG, seg_b, seg  ) |  /* kernel reg area */
+#ifdef CONFIG_JULIETTE
 			IO_STATE(R_MMU_KSEG, seg_a, seg  ) |  /* ARTPEC etc. */
+#else
+			IO_STATE(R_MMU_KSEG, seg_a, page ) |
+#endif
 			IO_STATE(R_MMU_KSEG, seg_9, seg  ) |  /* LED's on some boards */
 			IO_STATE(R_MMU_KSEG, seg_8, seg  ) |  /* CSE0/1, flash and I/O */
 			IO_STATE(R_MMU_KSEG, seg_7, page ) |  /* kernel vmalloc area */
@@ -258,7 +276,11 @@
 			    IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_c, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_b, 0xb ) |
+#ifdef CONFIG_JULIETTE
 			    IO_FIELD(R_MMU_KBASE_HI, base_a, 0xa ) |
+#else
+			    IO_FIELD(R_MMU_KBASE_HI, base_a, 0x0 ) |
+#endif
 			    IO_FIELD(R_MMU_KBASE_HI, base_9, 0x9 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_8, 0x8 ) );
 	
@@ -442,7 +464,7 @@
 
 	i = max_mapnr;
 	val->totalram = 0;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	while (i-- > 0)  {
diff -u --recursive --new-file v2.4.6/linux/arch/cris/mm/tlb.c linux/arch/cris/mm/tlb.c
--- v2.4.6/linux/arch/cris/mm/tlb.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/mm/tlb.c	Wed Jul  4 11:50:39 2001
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/cris/mm/tlb.c
  *
- *  Copyright (C) 2000  Axis Communications AB
+ *  Copyright (C) 2000, 2001  Axis Communications AB
  *  
  *  Authors:   Bjorn Wesen (bjornw@axis.com)
  *
@@ -21,6 +21,7 @@
 #include <asm/segment.h>
 #include <asm/pgtable.h>
 #include <asm/svinto.h>
+#include <asm/mmu_context.h>
 
 #define D(x)
 
@@ -252,6 +253,15 @@
 
 	get_mmu_context(next);
 
+	/* remember the pgd for the fault handlers
+	 * this is similar to the pgd register in some other CPU's.
+	 * we need our own copy of it because current and active_mm
+	 * might be invalid at points where we still need to derefer
+	 * the pgd.
+	 */
+
+	current_pgd = next->pgd;
+
 	/* switch context in the MMU */
 	
 	D(printk("switching mmu_context to %d (%p)\n", next->context, next));
@@ -288,7 +298,7 @@
 
 	/* clear the page_id map */
 
-	for(i = 0; i < NUM_PAGEID; i++)
+	for (i = 1; i < sizeof (page_id_map) / sizeof (page_id_map[0]); i++)
 		page_id_map[i] = NULL;
 	
 	/* invalidate the entire TLB */
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/andes.c linux/arch/mips/mm/andes.c
--- v2.4.6/linux/arch/mips/mm/andes.c	Thu Jul 27 18:36:54 2000
+++ linux/arch/mips/mm/andes.c	Wed Jul  4 11:50:39 2001
@@ -119,6 +119,17 @@
 	/* XXX */
 }
 
+static void __andes_flush_icache_range(unsigned long start, unsigned long end)
+{
+	/* XXX */
+}
+
+static void andes_flush_icache_page(struct vm_area_struct *vma,
+                                    struct page *page)
+{
+	/* XXX */
+}
+
 static void andes_flush_cache_sigtramp(unsigned long page)
 {
 	/* XXX */
@@ -146,10 +157,6 @@
 	/* XXX */
 }
 
-void load_pgd(unsigned long pg_dir)
-{
-}
-
 void pgd_init(unsigned long page)
 {
 }
@@ -166,11 +173,14 @@
 	_copy_page = andes_copy_page;
 
 	_flush_cache_all = andes_flush_cache_all;
+	___flush_cache_all = andes_flush_cache_all;
 	_flush_cache_mm = andes_flush_cache_mm;
 	_flush_cache_range = andes_flush_cache_range;
 	_flush_cache_page = andes_flush_cache_page;
 	_flush_cache_sigtramp = andes_flush_cache_sigtramp;
 	_flush_page_to_ram = andes_flush_page_to_ram;
+	_flush_icache_page = andes_flush_icache_page;
+	_flush_icache_range = andes_flush_icache_range;
 
 	flush_cache_all();
 	flush_tlb_all();
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/extable.c linux/arch/mips/mm/extable.c
--- v2.4.6/linux/arch/mips/mm/extable.c	Thu Feb 24 22:52:30 2000
+++ linux/arch/mips/mm/extable.c	Wed Jul  4 11:50:39 2001
@@ -3,6 +3,7 @@
  */
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/spinlock.h>
 #include <asm/uaccess.h>
 
 extern const struct exception_table_entry __start___ex_table[];
@@ -29,26 +30,33 @@
 	return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 unsigned long
 search_exception_table(unsigned long addr)
 {
-	unsigned long ret;
-
+	unsigned long ret = 0;
+	
 #ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
-	if (ret) return ret;
+	return ret;
 #else
+	unsigned long flags;
+
 	/* The kernel is the last "module" -- no need to treat it special.  */
 	struct module *mp;
+
+	spin_lock_irqsave(&modlist_lock, flags);
 	for (mp = module_list; mp != NULL; mp = mp->next) {
-		if (mp->ex_table_start == NULL)
+		if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
 			continue;
 		ret = search_one_table(mp->ex_table_start,
 				       mp->ex_table_end - 1, addr);
-		if (ret) return ret;
+		if (ret)
+			break;
 	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
 #endif
-
-	return 0;
 }
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/fault.c linux/arch/mips/mm/fault.c
--- v2.4.6/linux/arch/mips/mm/fault.c	Mon Mar 19 12:35:09 2001
+++ linux/arch/mips/mm/fault.c	Wed Jul  4 11:50:39 2001
@@ -49,6 +49,18 @@
 	unsigned long fixup;
 	siginfo_t info;
 
+	/*
+	 * We fault-in kernel-space virtual memory on-demand. The
+	 * 'reference' page table is init_mm.pgd.
+	 *
+	 * NOTE! We MUST NOT take any locks for this case. We may
+	 * be in an interrupt or a critical region, and should
+	 * only copy the information from the master page table,
+	 * nothing more.
+	 */
+	if (address >= TASK_SIZE)
+		goto vmalloc_fault;
+
 	info.si_code = SEGV_MAPERR;
 	/*
 	 * If we're in an interrupt or have no user
@@ -113,6 +125,8 @@
 bad_area:
 	up_read(&mm->mmap_sem);
 
+bad_area_nosemaphore:
+	/* User mode accesses just cause a SIGSEGV */
 	if (user_mode(regs)) {
 		tsk->thread.cp0_badvaddr = address;
 		tsk->thread.error_code = write;
@@ -186,4 +200,34 @@
 	/* Kernel mode? Handle exceptions or die */
 	if (!user_mode(regs))
 		goto no_context;
+
+	return;
+
+vmalloc_fault:
+	{
+		/*
+		 * Synchronize this task's top level page-table
+		 * with the 'reference' page table.
+		 */
+		int offset = pgd_index(address);
+		pgd_t *pgd, *pgd_k;
+		pmd_t *pmd, *pmd_k;
+
+		pgd = tsk->active_mm->pgd + offset;
+		pgd_k = init_mm.pgd + offset;
+
+		if (!pgd_present(*pgd)) {
+			if (!pgd_present(*pgd_k))
+				goto bad_area_nosemaphore;
+			set_pgd(pgd, *pgd_k);
+			return;
+		}
+
+		pmd = pmd_offset(pgd, address);
+		pmd_k = pmd_offset(pgd_k, address);
+
+		if (pmd_present(*pmd) || !pmd_present(*pmd_k))
+			goto bad_area_nosemaphore;
+		set_pmd(pmd, *pmd_k);
+	}
 }
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/init.c linux/arch/mips/mm/init.c
--- v2.4.6/linux/arch/mips/mm/init.c	Mon Oct 16 12:58:51 2000
+++ linux/arch/mips/mm/init.c	Wed Jul  4 11:50:39 2001
@@ -1,11 +1,13 @@
-/* $Id: init.c,v 1.26 2000/02/23 00:41:00 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1994 - 2000 by Ralf Baechle
  * Copyright (C) 2000 Silicon Graphics, Inc.
+ *
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -29,6 +31,7 @@
 
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
+#include <asm/cpu.h>
 #include <asm/dma.h>
 #include <asm/jazzdma.h>
 #include <asm/system.h>
@@ -38,74 +41,20 @@
 #include <asm/sgialib.h>
 #endif
 #include <asm/mmu_context.h>
+#include <asm/tlb.h>
+
+mmu_gather_t mmu_gathers[NR_CPUS];
 
 static unsigned long totalram_pages;
 
-extern void prom_fixup_mem_map(unsigned long start, unsigned long end);
 extern void prom_free_prom_memory(void);
 
 
-void __bad_pte_kernel(pmd_t *pmd)
-{
-	printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd));
-	pmd_set(pmd, BAD_PAGETABLE);
-}
-
-void __bad_pte(pmd_t *pmd)
-{
-	printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
-	pmd_set(pmd, BAD_PAGETABLE);
-}
-
-pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
-{
-	pte_t *page;
-
-	page = (pte_t *) __get_free_page(GFP_USER);
-	if (pmd_none(*pmd)) {
-		if (page) {
-			clear_page(page);
-			pmd_val(*pmd) = (unsigned long)page;
-			return page + offset;
-		}
-		pmd_set(pmd, BAD_PAGETABLE);
-		return NULL;
-	}
-	free_page((unsigned long)page);
-	if (pmd_bad(*pmd)) {
-		__bad_pte_kernel(pmd);
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + offset;
-}
-
-pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
-{
-	pte_t *page;
-
-	page = (pte_t *) __get_free_page(GFP_KERNEL);
-	if (pmd_none(*pmd)) {
-		if (page) {
-			clear_page(page);
-			pmd_val(*pmd) = (unsigned long)page;
-			return page + offset;
-		}
-		pmd_set(pmd, BAD_PAGETABLE);
-		return NULL;
-	}
-	free_page((unsigned long)page);
-	if (pmd_bad(*pmd)) {
-		__bad_pte(pmd);
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + offset;
-}
-
-
 asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
 {
-	/* XXX Just get it working for now... */
-	flush_cache_all();
+	/* This should flush more selectivly ...  */
+	__flush_cache_all();
+
 	return 0;
 }
 
@@ -122,17 +71,10 @@
 {
 	unsigned long order, size;
 	struct page *page;
-
-	switch (mips_cputype) {
-	case CPU_R4000SC:
-	case CPU_R4000MC:
-	case CPU_R4400SC:
-	case CPU_R4400MC:
+	if(mips_cpu.options & MIPS_CPU_VCE) 
 		order = 3;
-		break;
-	default:
+	else 
 		order = 0;
-	}
 
 	empty_zero_page = __get_free_pages(GFP_KERNEL, order);
 	if (!empty_zero_page)
@@ -169,48 +111,6 @@
 	return freed;
 }
 
-/*
- * BAD_PAGE is the page that is used for page faults when linux
- * is out-of-memory. Older versions of linux just did a
- * do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving a inode
- * unused etc..
- *
- * BAD_PAGETABLE is the accompanying page-table: it is initialized
- * to point to BAD_PAGE entries.
- *
- * ZERO_PAGE is a special page that is used for zero-initialized
- * data and COW.
- */
-pte_t * __bad_pagetable(void)
-{
-	extern char empty_bad_page_table[PAGE_SIZE];
-	unsigned long page, dummy1, dummy2;
-
-	page = (unsigned long) empty_bad_page_table;
-	__asm__ __volatile__(
-		".set\tnoreorder\n"
-		"1:\tsw\t%2,(%0)\n\t"
-		"subu\t%1,1\n\t"
-		"bnez\t%1,1b\n\t"
-		"addiu\t%0,4\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2)
-		:"r" (pte_val(BAD_PAGE)), "0" (page), "1" (PAGE_SIZE/4)
-		:"$1");
-
-	return (pte_t *)page;
-}
-
-pte_t __bad_page(void)
-{
-	extern char empty_bad_page[PAGE_SIZE];
-	unsigned long page = (unsigned long) empty_bad_page;
-
-	clear_page((void *)page);
-	return pte_mkdirty(mk_pte_phys(__pa(page), PAGE_SHARED));
-}
-
 void show_mem(void)
 {
 	int i, free = 0, total = 0, reserved = 0;
@@ -271,7 +171,30 @@
 	free_area_init(zones_size);
 }
 
-extern int page_is_ram(unsigned long pagenr);
+#define PFN_UP(x)	(((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
+#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
+
+static inline int page_is_ram(unsigned long pagenr)
+{
+	int i;
+
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		unsigned long addr, end;
+
+		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+			/* not usable memory */
+			continue;
+
+		addr = PFN_UP(boot_mem_map.map[i].addr);
+		end = PFN_DOWN(boot_mem_map.map[i].addr
+			       + boot_mem_map.map[i].size);
+
+		if (pagenr >= addr && pagenr < end)
+			return 1;
+	}
+
+	return 0;
+}
 
 void __init mem_init(void)
 {
@@ -309,13 +232,16 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
+	if (start < end)
+		printk("Freeing initrd memory: %ldk freed\n",
+		       (end - start) >> 10);
+
 	for (; start < end; start += PAGE_SIZE) {
 		ClearPageReserved(virt_to_page(start));
 		set_page_count(virt_to_page(start), 1);
 		free_page(start);
 		totalram_pages++;
 	}
-	printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
 }
 #endif
 
@@ -343,7 +269,7 @@
 void si_meminfo(struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = 0;
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/ioremap.c linux/arch/mips/mm/ioremap.c
--- v2.4.6/linux/arch/mips/mm/ioremap.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/mm/ioremap.c	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,176 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * (C) Copyright 1995 1996 Linus Torvalds
+ * (C) Copyright 2001 Ralf Baechle
+ */
+#include <linux/module.h>
+#include <asm/addrspace.h>
+#include <asm/byteorder.h>
+
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+#include <asm/pgalloc.h>
+
+static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
+	unsigned long phys_addr, unsigned long flags)
+{
+	unsigned long end;
+	pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
+	                           | __WRITEABLE | flags);
+
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	if (address >= end)
+		BUG();
+	do {
+		if (!pte_none(*pte)) {
+			printk("remap_area_pte: page already exists\n");
+			BUG();
+		}
+		set_pte(pte, mk_pte_phys(phys_addr, pgprot));
+		address += PAGE_SIZE;
+		phys_addr += PAGE_SIZE;
+		pte++;
+	} while (address && (address < end));
+}
+
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
+	unsigned long phys_addr, unsigned long flags)
+{
+	unsigned long end;
+
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	phys_addr -= address;
+	if (address >= end)
+		BUG();
+	do {
+		pte_t * pte = pte_alloc(&init_mm, pmd, address);
+		if (!pte)
+			return -ENOMEM;
+		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+	return 0;
+}
+
+static int remap_area_pages(unsigned long address, unsigned long phys_addr,
+				 unsigned long size, unsigned long flags)
+{
+	int error;
+	pgd_t * dir;
+	unsigned long end = address + size;
+
+	phys_addr -= address;
+	dir = pgd_offset(&init_mm, address);
+	flush_cache_all();
+	if (address >= end)
+		BUG();
+	spin_lock(&init_mm.page_table_lock);
+	do {
+		pmd_t *pmd;
+		pmd = pmd_alloc(&init_mm, dir, address);
+		error = -ENOMEM;
+		if (!pmd)
+			break;
+		if (remap_area_pmd(pmd, address, end - address,
+					 phys_addr + address, flags))
+			break;
+		error = 0;
+		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	} while (address && (address < end));
+	spin_unlock(&init_mm.page_table_lock);
+	flush_tlb_all();
+	return error;
+}
+
+/*
+ * Generic mapping function (not visible outside):
+ */
+
+/*
+ * Remap an arbitrary physical address space into the kernel virtual
+ * address space. Needed when the kernel wants to access high addresses
+ * directly.
+ *
+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+ * have to convert them into an offset in a page-aligned mapping, but the
+ * caller shouldn't need to know that small detail.
+ */
+
+#define IS_LOW512(addr) (!((unsigned long)(addr) & ~0x1fffffffUL))
+
+void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
+{
+	void * addr;
+	struct vm_struct * area;
+	unsigned long offset, last_addr;
+
+	/* Don't allow wraparound or zero size */
+	last_addr = phys_addr + size - 1;
+	if (!size || last_addr < phys_addr)
+		return NULL;
+
+	/*
+	 * Map objects in the low 512mb of address space using KSEG1, otherwise
+	 * map using page tables.
+	 */
+	if (IS_LOW512(phys_addr) && IS_LOW512(phys_addr + size - 1))
+		return (void *) KSEG1ADDR(phys_addr);
+
+	/*
+	 * Don't allow anybody to remap normal RAM that we're using..
+	 */
+	if (phys_addr < virt_to_phys(high_memory)) {
+		char *t_addr, *t_end;
+		struct page *page;
+
+		t_addr = __va(phys_addr);
+		t_end = t_addr + (size - 1);
+	   
+		for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
+			if(!PageReserved(page))
+				return NULL;
+	}
+
+	/*
+	 * Mappings have to be page-aligned
+	 */
+	offset = phys_addr & ~PAGE_MASK;
+	phys_addr &= PAGE_MASK;
+	size = PAGE_ALIGN(last_addr) - phys_addr;
+
+	/*
+	 * Ok, go for it..
+	 */
+	area = get_vm_area(size, VM_IOREMAP);
+	if (!area)
+		return NULL;
+	addr = area->addr;
+	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
+		vfree(addr);
+		return NULL;
+	}
+
+	return (void *) (offset + (char *)addr);
+}
+
+#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == KSEG1)
+
+void iounmap(void *addr)
+{
+	if (!IS_KSEG1(addr))
+		return vfree((void *) (PAGE_MASK & (unsigned long) addr));
+}
+
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/loadmmu.c linux/arch/mips/mm/loadmmu.c
--- v2.4.6/linux/arch/mips/mm/loadmmu.c	Sat May 13 08:29:14 2000
+++ linux/arch/mips/mm/loadmmu.c	Wed Jul  4 11:50:39 2001
@@ -2,8 +2,8 @@
  * loadmmu.c: Setup cpu/cache specific function ptrs at boot time.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: loadmmu.c,v 1.17 2000/03/13 10:33:05 raiko Exp $
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -11,10 +11,11 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
-#include <asm/bootinfo.h>
 
 /* memory functions */
 void (*_clear_page)(void * page);
@@ -22,84 +23,79 @@
 
 /* Cache operations. */
 void (*_flush_cache_all)(void);
+void (*___flush_cache_all)(void);
 void (*_flush_cache_mm)(struct mm_struct *mm);
 void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
 			  unsigned long end);
 void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
 void (*_flush_cache_sigtramp)(unsigned long addr);
 void (*_flush_page_to_ram)(struct page * page);
+void (*_flush_icache_range)(unsigned long start, unsigned long end);
+void (*_flush_icache_page)(struct vm_area_struct *vma, struct page *page);
 
 /* DMA cache operations. */
 void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
 void (*_dma_cache_wback)(unsigned long start, unsigned long size);
 void (*_dma_cache_inv)(unsigned long start, unsigned long size);
 
-#ifdef CONFIG_CPU_R3000
-extern void ld_mmu_r2300(void);
-#endif
-#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_R4300) || \
-    defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)
+extern void ld_mmu_r23000(void);
 extern void ld_mmu_r4xx0(void);
-#endif
-#ifdef CONFIG_CPU_R6000
+extern void ld_mmu_r5432(void);
 extern void ld_mmu_r6000(void);
-#endif
-#ifdef CONFIG_CPU_R8000
+extern void ld_mmu_rm7k(void);
 extern void ld_mmu_tfp(void);
-#endif
-#ifdef CONFIG_CPU_R10000
 extern void ld_mmu_andes(void);
-#endif
+extern void ld_mmu_sb1(void);
+extern void ld_mmu_mips32(void);
 
 void __init loadmmu(void)
 {
-	switch(mips_cputype) {
-#ifdef CONFIG_CPU_R3000
-	case CPU_R2000:
-	case CPU_R3000:
-	case CPU_R3000A:
-	case CPU_R3081E:
-		printk("Loading R[23]00 MMU routines.\n");
-		ld_mmu_r2300();
-		break;
-#endif
 
+	if (mips_cpu.options & MIPS_CPU_4KTLB) {
 #if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_R4300) || \
     defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)
-	case CPU_R4000PC:
-	case CPU_R4000SC:
-	case CPU_R4000MC:
-	case CPU_R4200:
-	case CPU_R4300:
-	case CPU_R4400PC:
-	case CPU_R4400SC:
-	case CPU_R4400MC:
-	case CPU_R4600:
-	case CPU_R4640:
-	case CPU_R4650:
-	case CPU_R4700:
-	case CPU_R5000:
-	case CPU_R5000A:
-	case CPU_NEVADA:
 		printk("Loading R4000 MMU routines.\n");
 		ld_mmu_r4xx0();
-		break;
+#endif
+#if defined(CONFIG_CPU_RM7000)
+               printk("Loading RM7000 MMU routines.\n");
+               ld_mmu_rm7k();
+#endif
+#if defined(CONFIG_CPU_R5432)
+		printk("Loading R5432 MMU routines.\n");
+		ld_mmu_r5432();
 #endif
 
+#if defined(CONFIG_CPU_MIPS32)
+		printk("Loading MIPS32 MMU routines.\n");
+		ld_mmu_mips32();
+#endif
+	} else switch(mips_cpu.cputype) {
+#ifdef CONFIG_CPU_R3000
+	case CPU_R2000:
+	case CPU_R3000:
+	case CPU_R3000A:
+	case CPU_TX3912:
+	case CPU_TX3922:
+	case CPU_TX3927:
+	case CPU_R3081E:
+		printk("Loading R[23]000 MMU routines.\n");
+		ld_mmu_r23000();
+		break;
+#endif
 #ifdef CONFIG_CPU_R10000
 	case CPU_R10000:
 		printk("Loading R10000 MMU routines.\n");
 		ld_mmu_andes();
 		break;
 #endif
-
+#ifdef CONFIG_CPU_SB1
+	case CPU_SB1:
+		printk("Loading SB1 MMU routines.\n");
+		ld_mmu_sb1();
+		break;
+#endif
 	default:
-		/* XXX We need an generic routine in the MIPS port
-		 * XXX to jabber stuff onto the screen on all machines
-		 * XXX before the console is setup.  The ARCS prom
-		 * XXX routines look good for this, but only the SGI
-		 * XXX code has a full library for that at this time.
-		 */
 		panic("Yeee, unsupported mmu/cache architecture.");
 	}
 }
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/mips32.c linux/arch/mips/mm/mips32.c
--- v2.4.6/linux/arch/mips/mm/mips32.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/mm/mips32.c	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,1078 @@
+/*
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS32 CPU variant specific MMU/Cache routines.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/bcache.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop; nop; nop;\n\t" \
+				     ".set reorder\n\t")
+
+/* Primary cache parameters. */
+static int icache_size, dcache_size; /* Size in bytes */
+static int ic_lsize, dc_lsize;       /* LineSize in bytes */
+
+/* Secondary cache (if present) parameters. */
+static unsigned int scache_size, sc_lsize;	/* Again, in bytes */
+
+#include <asm/cacheops.h>
+#include <asm/mips32_cache.h>
+
+#undef DEBUG_CACHE
+
+/*
+ * Dummy cache handling routines for machines without boardcaches
+ */
+static void no_sc_noop(void) {}
+
+static struct bcache_ops no_sc_ops = {
+	(void *)no_sc_noop, (void *)no_sc_noop,
+	(void *)no_sc_noop, (void *)no_sc_noop
+};
+
+struct bcache_ops *bcops = &no_sc_ops;
+
+
+/*
+ * Zero an entire page.
+ */
+
+static void mips32_clear_page_dc(unsigned long page)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
+	{
+	        for (i=page; i<page+PAGE_SIZE; i+=dc_lsize)
+		{
+		        __asm__ __volatile__(
+			        ".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				".set\tmips3\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tmips0\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_D));
+		}
+	}
+	for (i=page; i<page+PAGE_SIZE; i+=4)
+	        *(unsigned long *)(i) = 0;
+}
+
+static void mips32_clear_page_sc(unsigned long page)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
+	{
+	        for (i=page; i<page+PAGE_SIZE; i+=sc_lsize)
+		{
+		        __asm__ __volatile__(
+				".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				".set\tmips3\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tmips0\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_SD));
+		}
+	}
+	for (i=page; i<page+PAGE_SIZE; i+=4)
+	        *(unsigned long *)(i) = 0;
+}
+
+static void mips32_copy_page_dc(unsigned long to, unsigned long from)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
+	{
+	        for (i=to; i<to+PAGE_SIZE; i+=dc_lsize)
+		{
+		        __asm__ __volatile__(
+			        ".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				".set\tmips3\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tmips0\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_D));
+		}
+	}
+	for (i=0; i<PAGE_SIZE; i+=4)
+	        *(unsigned long *)(to+i) = *(unsigned long *)(from+i);
+}
+
+static void mips32_copy_page_sc(unsigned long to, unsigned long from)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
+	{
+	        for (i=to; i<to+PAGE_SIZE; i+=sc_lsize)
+		{
+		        __asm__ __volatile__(
+				".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				".set\tmips3\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tmips0\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_SD));
+		}
+	}
+	for (i=0; i<PAGE_SIZE; i+=4)
+	        *(unsigned long *)(to+i) = *(unsigned long *)(from+i);
+}
+
+static inline void mips32_flush_cache_all_sc(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache(); blast_icache(); blast_scache();
+	__restore_flags(flags);
+}
+
+static inline void mips32_flush_cache_all_pc(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache(); blast_icache();
+	__restore_flags(flags);
+}
+
+static void
+mips32_flush_cache_range_sc(struct mm_struct *mm,
+			 unsigned long start,
+			 unsigned long end)
+{
+	struct vm_area_struct *vma;
+	unsigned long flags;
+
+	if(mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if(vma) {
+		if(mm->context != current->mm->context) {
+			mips32_flush_cache_all_sc();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			__save_and_cli(flags);
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache_page(start);
+				start += PAGE_SIZE;
+			}
+			__restore_flags(flags);
+		}
+	}
+}
+
+static void mips32_flush_cache_range_pc(struct mm_struct *mm,
+				     unsigned long start,
+				     unsigned long end)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_CACHE
+		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+		__save_and_cli(flags);
+		blast_dcache(); blast_icache();
+		__restore_flags(flags);
+	}
+}
+
+/*
+ * On architectures like the Sparc, we could get rid of lines in
+ * the cache created only by a certain context, but on the MIPS
+ * (and actually certain Sparc's) we cannot.
+ */
+static void mips32_flush_cache_mm_sc(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		mips32_flush_cache_all_sc();
+	}
+}
+
+static void mips32_flush_cache_mm_pc(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		mips32_flush_cache_all_pc();
+	}
+}
+
+
+
+
+
+static void mips32_flush_cache_page_sc(struct vm_area_struct *vma,
+				    unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	__save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm->context != current->active_mm->context) {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache_page_indexed(page);
+		blast_scache_page_indexed(page);
+	} else
+		blast_scache_page(page);
+out:
+	__restore_flags(flags);
+}
+
+static void mips32_flush_cache_page_pc(struct vm_area_struct *vma,
+				    unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	__save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since Mips32 caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm == current->active_mm) {
+		blast_dcache_page(page);
+	} else {
+		/* Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (dcache_size - 1)));
+		blast_dcache_page_indexed(page);
+	}
+out:
+	__restore_flags(flags);
+}
+
+/* If the addresses passed to these routines are valid, they are
+ * either:
+ *
+ * 1) In KSEG0, so we can do a direct flush of the page.
+ * 2) In KSEG2, and since every process can translate those
+ *    addresses all the time in kernel mode we can do a direct
+ *    flush.
+ * 3) In KSEG1, no flush necessary.
+ */
+static void mips32_flush_page_to_ram_sc(struct page *page)
+{
+	blast_scache_page((unsigned long)page_address(page));
+}
+
+static void mips32_flush_page_to_ram_pc(struct page *page)
+{
+	blast_dcache_page((unsigned long)page_address(page));
+}
+
+static void
+mips32_flush_icache_page_s(struct vm_area_struct *vma, struct page *page)
+{
+	/*
+	 * We did an scache flush therefore PI is already clean.
+	 */
+}
+
+static void
+mips32_flush_icache_range(unsigned long start, unsigned long end)
+{
+	flush_cache_all();
+}
+
+static void
+mips32_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	int address;
+
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	address = KSEG0 + ((unsigned long)page_address(page) & PAGE_MASK & (dcache_size - 1));
+	blast_icache_page_indexed(address);
+}
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ */
+static void
+mips32_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+	        __save_and_cli(flags);
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+		__restore_flags(flags);
+	}
+	bc_wback_inv(addr, size);
+}
+
+static void
+mips32_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		flush_cache_all();
+		return;
+	}
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+}
+
+static void
+mips32_dma_cache_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+	        __save_and_cli(flags);
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+		__restore_flags(flags);
+	}
+
+	bc_inv(addr, size);
+}
+
+static void
+mips32_dma_cache_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		flush_cache_all();
+		return;
+	}
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		flush_scache_line(a); /* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+}
+
+static void
+mips32_dma_cache_wback(unsigned long addr, unsigned long size)
+{
+	panic("mips32_dma_cache called - should not happen.\n");
+}
+
+/*
+ * While we're protected against bad userland addresses we don't care
+ * very much about what happens in that case.  Usually a segmentation
+ * fault will dump the process later on anyway ...
+ */
+static void mips32_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long daddr, iaddr;
+
+	daddr = addr & ~(dc_lsize - 1);
+	protected_writeback_dcache_line(daddr);
+	protected_writeback_dcache_line(daddr + dc_lsize);
+	iaddr = addr & ~(ic_lsize - 1);
+	protected_flush_icache_line(iaddr);
+	protected_flush_icache_line(iaddr + ic_lsize);
+}
+
+#undef DEBUG_TLB
+#undef DEBUG_TLBUPDATE
+
+void flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	int entry;
+
+#ifdef DEBUG_TLB
+	printk("[tlball]");
+#endif
+
+	__save_and_cli(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = (get_entryhi() & 0xff);
+	set_entryhi(KSEG0);
+	set_entrylo0(0);
+	set_entrylo1(0);
+	BARRIER;
+
+	entry = get_wired();
+
+	/* Blast 'em all away. */
+	while(entry < mips_cpu.tlbsize) {
+	        /* Make sure all entries differ. */  
+	        set_entryhi(KSEG0+entry*0x2000);
+		set_index(entry);
+		BARRIER;
+		tlb_write_indexed();
+		BARRIER;
+		entry++;
+	}
+	BARRIER;
+	set_entryhi(old_ctx);
+	__restore_flags(flags);
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_TLB
+		printk("[tlbmm<%d>]", mm->context);
+#endif
+		__save_and_cli(flags);
+		get_new_mmu_context(mm, asid_cache);
+		if (mm == current->active_mm)
+			set_entryhi(mm->context & 0xff);
+		__restore_flags(flags);
+	}
+}
+
+void flush_tlb_range(struct mm_struct *mm, unsigned long start,
+				unsigned long end)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+		int size;
+
+#ifdef DEBUG_TLB
+		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
+		       start, end);
+#endif
+		__save_and_cli(flags);
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		size = (size + 1) >> 1;
+		if(size <= mips_cpu.tlbsize/2) {
+			int oldpid = (get_entryhi() & 0xff);
+			int newpid = (mm->context & 0xff);
+
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+			while(start < end) {
+				int idx;
+
+				set_entryhi(start | newpid);
+				start += (PAGE_SIZE << 1);
+				BARRIER;
+				tlb_probe();
+				BARRIER;
+				idx = get_index();
+				set_entrylo0(0);
+				set_entrylo1(0);
+				if(idx < 0)
+					continue;
+				/* Make sure all entries differ. */
+				set_entryhi(KSEG0+idx*0x2000);
+				BARRIER;
+				tlb_write_indexed();
+				BARRIER;
+			}
+			set_entryhi(oldpid);
+		} else {
+			get_new_mmu_context(mm, asid_cache);
+			if (mm == current->active_mm)
+				set_entryhi(mm->context & 0xff);
+		}
+		__restore_flags(flags);
+	}
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	if (vma->vm_mm->context != 0) {
+		unsigned long flags;
+		int oldpid, newpid, idx;
+
+#ifdef DEBUG_TLB
+		printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
+#endif
+		newpid = (vma->vm_mm->context & 0xff);
+		page &= (PAGE_MASK << 1);
+		__save_and_cli(flags);
+		oldpid = (get_entryhi() & 0xff);
+		set_entryhi(page | newpid);
+		BARRIER;
+		tlb_probe();
+		BARRIER;
+		idx = get_index();
+		set_entrylo0(0);
+		set_entrylo1(0);
+		if(idx < 0)
+			goto finish;
+		/* Make sure all entries differ. */  
+		set_entryhi(KSEG0+idx*0x2000);
+		BARRIER;
+		tlb_write_indexed();
+
+	finish:
+		BARRIER;
+		set_entryhi(oldpid);
+		__restore_flags(flags);
+	}
+}
+
+void pgd_init(unsigned long page)
+{
+	unsigned long *p = (unsigned long *) page;
+	int i;
+
+	for(i = 0; i < USER_PTRS_PER_PGD; i+=8) {
+		p[i + 0] = (unsigned long) invalid_pte_table;
+		p[i + 1] = (unsigned long) invalid_pte_table;
+		p[i + 2] = (unsigned long) invalid_pte_table;
+		p[i + 3] = (unsigned long) invalid_pte_table;
+		p[i + 4] = (unsigned long) invalid_pte_table;
+		p[i + 5] = (unsigned long) invalid_pte_table;
+		p[i + 6] = (unsigned long) invalid_pte_table;
+		p[i + 7] = (unsigned long) invalid_pte_table;
+	}
+}
+
+/* 
+ * Updates the TLB with the new pte(s).
+ */
+void update_mmu_cache(struct vm_area_struct * vma,
+		      unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx, pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	pid = get_entryhi() & 0xff;
+
+#ifdef DEBUG_TLB
+	if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) {
+		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
+		       (int) (vma->vm_mm->context & 0xff), pid);
+	}
+#endif
+
+	__save_and_cli(flags);
+	address &= (PAGE_MASK << 1);
+	set_entryhi(address | (pid));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	BARRIER;
+	tlb_probe();
+	BARRIER;
+	pmdp = pmd_offset(pgdp, address);
+	idx = get_index();
+	ptep = pte_offset(pmdp, address);
+	BARRIER;
+	set_entrylo0(pte_val(*ptep++) >> 6);
+	set_entrylo1(pte_val(*ptep) >> 6);
+	set_entryhi(address | (pid));
+	BARRIER;
+	if(idx < 0) {
+		tlb_write_random();
+	} else {
+		tlb_write_indexed();
+	}
+	BARRIER;
+	set_entryhi(pid);
+	BARRIER;
+	__restore_flags(flags);
+}
+
+void show_regs(struct pt_regs * regs)
+{
+	/* Saved main processor registers. */
+	printk("$0 : %08lx %08lx %08lx %08lx\n",
+	       0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
+	printk("$4 : %08lx %08lx %08lx %08lx\n",
+               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+	printk("$8 : %08lx %08lx %08lx %08lx\n",
+	       regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
+	printk("$12: %08lx %08lx %08lx %08lx\n",
+               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
+	printk("$16: %08lx %08lx %08lx %08lx\n",
+	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
+	printk("$20: %08lx %08lx %08lx %08lx\n",
+               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
+	printk("$24: %08lx %08lx\n",
+	       regs->regs[24], regs->regs[25]);
+	printk("$28: %08lx %08lx %08lx %08lx\n",
+	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
+
+	/* Saved cp0 registers. */
+	printk("epc   : %08lx\nStatus: %08lx\nCause : %08lx\n",
+	       regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
+}
+			
+void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+				      unsigned long entryhi, unsigned long pagemask)
+{
+        unsigned long flags;
+        unsigned long wired;
+        unsigned long old_pagemask;
+        unsigned long old_ctx;
+
+        __save_and_cli(flags);
+        /* Save old context and create impossible VPN2 value */
+        old_ctx = (get_entryhi() & 0xff);
+        old_pagemask = get_pagemask();
+        wired = get_wired();
+        set_wired (wired + 1);
+        set_index (wired);
+        BARRIER;    
+        set_pagemask (pagemask);
+        set_entryhi(entryhi);
+        set_entrylo0(entrylo0);
+        set_entrylo1(entrylo1);
+        BARRIER;    
+        tlb_write_indexed();
+        BARRIER;    
+    
+        set_entryhi(old_ctx);
+        BARRIER;    
+        set_pagemask (old_pagemask);
+        flush_tlb_all();    
+        __restore_flags(flags);
+}
+
+/* Detect and size the various caches. */
+static void __init probe_icache(unsigned long config)
+{
+        unsigned long config1;
+	unsigned int lsize;
+
+        if (!(config & (1 << 31))) {
+	        /* 
+		 * Not a MIPS32 complainant CPU. 
+		 * Config 1 register not supported, we assume R4k style.
+		 */
+	        icache_size = 1 << (12 + ((config >> 9) & 7));
+		ic_lsize = 16 << ((config >> 5) & 1);
+		mips_cpu.icache.linesz = ic_lsize;
+		
+		/* 
+		 * We cannot infer associativity - assume direct map
+		 * unless probe template indicates otherwise
+		 */
+		if(!mips_cpu.icache.ways) mips_cpu.icache.ways = 1;
+		mips_cpu.icache.sets = 
+			(icache_size / ic_lsize) / mips_cpu.icache.ways;
+	} else {
+	       config1 = read_mips32_cp0_config1(); 
+
+	       if ((lsize = ((config1 >> 19) & 7)))
+		       mips_cpu.icache.linesz = 2 << lsize;
+	       else 
+		       mips_cpu.icache.linesz = lsize;
+	       mips_cpu.icache.sets = 64 << ((config1 >> 22) & 7);
+	       mips_cpu.icache.ways = 1 + ((config1 >> 16) & 7);
+
+	       ic_lsize = mips_cpu.icache.linesz;
+	       icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways * 
+		             ic_lsize;
+	}
+	printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n",
+	       icache_size >> 10, ic_lsize, mips_cpu.icache.ways);
+}
+
+static void __init probe_dcache(unsigned long config)
+{
+        unsigned long config1;
+	unsigned int lsize;
+
+        if (!(config & (1 << 31))) {
+	        /* 
+		 * Not a MIPS32 complainant CPU. 
+		 * Config 1 register not supported, we assume R4k style.
+		 */  
+		dcache_size = 1 << (12 + ((config >> 6) & 7));
+		dc_lsize = 16 << ((config >> 4) & 1);
+		mips_cpu.dcache.linesz = dc_lsize;
+		/* 
+		 * We cannot infer associativity - assume direct map
+		 * unless probe template indicates otherwise
+		 */
+		if(!mips_cpu.dcache.ways) mips_cpu.dcache.ways = 1;
+		mips_cpu.dcache.sets = 
+			(dcache_size / dc_lsize) / mips_cpu.dcache.ways;
+	} else {
+	        config1 = read_mips32_cp0_config1();
+
+		if ((lsize = ((config1 >> 10) & 7)))
+		        mips_cpu.dcache.linesz = 2 << lsize;
+		else 
+		        mips_cpu.dcache.linesz= lsize;
+		mips_cpu.dcache.sets = 64 << ((config1 >> 13) & 7);
+		mips_cpu.dcache.ways = 1 + ((config1 >> 7) & 7);
+
+		dc_lsize = mips_cpu.dcache.linesz;
+		dcache_size = 
+			mips_cpu.dcache.sets * mips_cpu.dcache.ways
+			* dc_lsize;
+	}
+	printk("Primary data cache %dkb, linesize %d bytes (%d ways)\n",
+	       dcache_size >> 10, dc_lsize, mips_cpu.dcache.ways);
+}
+
+
+/* If you even _breathe_ on this function, look at the gcc output
+ * and make sure it does not pop things on and off the stack for
+ * the cache sizing loop that executes in KSEG1 space or else
+ * you will crash and burn badly.  You have been warned.
+ */
+static int __init probe_scache(unsigned long config)
+{
+	extern unsigned long stext;
+	unsigned long flags, addr, begin, end, pow2;
+	int tmp;
+
+	if (mips_cpu.scache.flags == MIPS_CACHE_NOT_PRESENT)
+		return 0;
+
+	tmp = ((config >> 17) & 1);
+	if(tmp)
+		return 0;
+	tmp = ((config >> 22) & 3);
+	switch(tmp) {
+	case 0:
+		sc_lsize = 16;
+		break;
+	case 1:
+		sc_lsize = 32;
+		break;
+	case 2:
+		sc_lsize = 64;
+		break;
+	case 3:
+		sc_lsize = 128;
+		break;
+	}
+
+	begin = (unsigned long) &stext;
+	begin &= ~((4 * 1024 * 1024) - 1);
+	end = begin + (4 * 1024 * 1024);
+
+	/* This is such a bitch, you'd think they would make it
+	 * easy to do this.  Away you daemons of stupidity!
+	 */
+	__save_and_cli(flags);
+
+	/* Fill each size-multiple cache line with a valid tag. */
+	pow2 = (64 * 1024);
+	for(addr = begin; addr < end; addr = (begin + pow2)) {
+		unsigned long *p = (unsigned long *) addr;
+		__asm__ __volatile__("nop" : : "r" (*p)); /* whee... */
+		pow2 <<= 1;
+	}
+
+	/* Load first line with zero (therefore invalid) tag. */
+	set_taglo(0);
+	set_taghi(0);
+	__asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     ".set mips3\n\t"
+			     "cache 8, (%0)\n\t"
+			     ".set mips0\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     ".set mips3\n\t"
+			     "cache 9, (%0)\n\t"
+			     ".set mips0\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     ".set mips3\n\t"
+			     "cache 11, (%0)\n\t"
+			     ".set mips0\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+
+	/* Now search for the wrap around point. */
+	pow2 = (128 * 1024);
+	tmp = 0;
+	for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) {
+		__asm__ __volatile__("\n\t.set noreorder\n\t"
+				     ".set mips3\n\t"
+				     "cache 7, (%0)\n\t"
+				     ".set mips0\n\t"
+				     ".set reorder\n\t" : : "r" (addr));
+		__asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */
+		if(!get_taglo())
+			break;
+		pow2 <<= 1;
+	}
+	__restore_flags(flags);
+	addr -= begin;
+	printk("Secondary cache sized at %dK linesize %d bytes.\n",
+	       (int) (addr >> 10), sc_lsize);
+	scache_size = addr;
+	return 1;
+}
+
+static void __init setup_noscache_funcs(void)
+{
+	_clear_page = (void *)mips32_clear_page_dc;
+	_copy_page = (void *)mips32_copy_page_dc;
+	_flush_cache_all = mips32_flush_cache_all_pc;
+	___flush_cache_all = mips32_flush_cache_all_pc;
+	_flush_cache_mm = mips32_flush_cache_mm_pc;
+	_flush_cache_range = mips32_flush_cache_range_pc;
+	_flush_cache_page = mips32_flush_cache_page_pc;
+	_flush_page_to_ram = mips32_flush_page_to_ram_pc;
+
+	_flush_icache_page = mips32_flush_icache_page;
+
+	_dma_cache_wback_inv = mips32_dma_cache_wback_inv_pc;
+	_dma_cache_wback = mips32_dma_cache_wback;
+	_dma_cache_inv = mips32_dma_cache_inv_pc;
+}
+
+static void __init setup_scache_funcs(void)
+{
+        _flush_cache_all = mips32_flush_cache_all_sc;
+        ___flush_cache_all = mips32_flush_cache_all_sc;
+	_flush_cache_mm = mips32_flush_cache_mm_sc;
+	_flush_cache_range = mips32_flush_cache_range_sc;
+	_flush_cache_page = mips32_flush_cache_page_sc;
+	_flush_page_to_ram = mips32_flush_page_to_ram_sc;
+	_clear_page = (void *)mips32_clear_page_sc;
+	_copy_page = (void *)mips32_copy_page_sc;
+
+	_flush_icache_page = mips32_flush_icache_page_s;
+
+	_dma_cache_wback_inv = mips32_dma_cache_wback_inv_sc;
+	_dma_cache_wback = mips32_dma_cache_wback;
+	_dma_cache_inv = mips32_dma_cache_inv_sc;
+}
+
+typedef int (*probe_func_t)(unsigned long);
+
+static inline void __init setup_scache(unsigned int config)
+{
+	probe_func_t probe_scache_kseg1;
+	int sc_present = 0;
+
+	/* Maybe the cpu knows about a l2 cache? */
+	probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
+	sc_present = probe_scache_kseg1(config);
+
+	if (sc_present) {
+	  	mips_cpu.scache.linesz = sc_lsize;
+		/* 
+		 * We cannot infer associativity - assume direct map
+		 * unless probe template indicates otherwise
+		 */
+		if(!mips_cpu.scache.ways) mips_cpu.scache.ways = 1;
+		mips_cpu.scache.sets = 
+		  (scache_size / sc_lsize) / mips_cpu.scache.ways;
+
+		setup_scache_funcs();
+		return;
+	}
+
+	setup_noscache_funcs();
+}
+
+static void __init probe_tlb(unsigned long config)
+{
+        unsigned long config1;
+
+        if (!(config & (1 << 31))) {
+	        /* 
+		 * Not a MIPS32 complainant CPU. 
+		 * Config 1 register not supported, we assume R4k style.
+		 */  
+	        mips_cpu.tlbsize = 48;
+	} else {
+	        config1 = read_mips32_cp0_config1();
+		if (!((config >> 7) & 3))
+		        panic("No MMU present");
+		else
+		        mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1;
+	}	
+
+	printk("Number of TLB entries %d.\n", mips_cpu.tlbsize);
+}
+
+void __init ld_mmu_mips32(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
+
+#ifdef CONFIG_MIPS_UNCACHED
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+#else
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+#endif
+
+	probe_icache(config);
+	probe_dcache(config);
+	setup_scache(config);
+	probe_tlb(config);
+
+	_flush_cache_sigtramp = mips32_flush_cache_sigtramp;
+	_flush_icache_range = mips32_flush_icache_range;	/* Ouch */
+
+	__flush_cache_all();
+	write_32bit_cp0_register(CP0_WIRED, 0);
+
+	/*
+	 * You should never change this register:
+	 *   - The entire mm handling assumes the c0_pagemask register to
+	 *     be set for 4kb pages.
+	 */
+	write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
+	flush_tlb_all();
+}
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/r2300.c linux/arch/mips/mm/r2300.c
--- v2.4.6/linux/arch/mips/mm/r2300.c	Thu Jul 27 18:36:54 2000
+++ linux/arch/mips/mm/r2300.c	Wed Jul  4 11:50:39 2001
@@ -4,7 +4,8 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
  * with a lot of changes to make this thing work for R3000s
- * Copyright (C) 1998, 2000 Harald Koerfgen
+ * Tx39XX R4k style caches added. HK
+ * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
  */
 #include <linux/init.h>
@@ -19,6 +20,8 @@
 #include <asm/isadep.h>
 #include <asm/io.h>
 #include <asm/wbflush.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
 
 /*
  * According to the paper written by D. Miller about Linux cache & TLB
@@ -27,15 +30,17 @@
  * Define this if driver does not handle cache consistency during DMA ops.
  */
 
-/* Primary cache parameters. */
-static int icache_size, dcache_size; /* Size in bytes */
-/* the linesizes are usually fixed on R3000s */
+/* For R3000 cores with R4000 style caches */
+static unsigned long icache_size, dcache_size;		/* Size in bytes */
+static unsigned long icache_lsize, dcache_lsize;	/* Size in bytes */
+static unsigned long scache_size = 0;
+
+#include <asm/cacheops.h>
+#include <asm/r4kcache.h>
 
 #undef DEBUG_TLB
 #undef DEBUG_CACHE
 
-#define NTLB_ENTRIES       64  /* Fixed on all R23000 variants... */
-
 /* page functions */
 void r3k_clear_page(void * page)
 {
@@ -120,7 +125,7 @@
 
 	p = (volatile unsigned long *) KSEG0;
 
-	save_and_cli(flags);
+	flags = read_32bit_cp0_register(CP0_STATUS);
 
 	/* isolate cache space */
 	write_32bit_cp0_register(CP0_STATUS, (ca_flags|flags)&~ST0_IEC);
@@ -142,34 +147,30 @@
 		if (size > 0x40000)
 			size = 0;
 	}
-	restore_flags(flags);
+	write_32bit_cp0_register(CP0_STATUS, flags);
 
 	return size * sizeof(*p);
 }
 
-static void __init probe_dcache(void)
+static void __init r3k_probe_cache(void)
 {
 	dcache_size = r3k_cache_size(ST0_ISC);
-	printk("Primary data cache %dkb, linesize 4 bytes\n",
-		dcache_size >> 10);
-}
+	dcache_lsize = 4;
 
-static void __init probe_icache(void)
-{
 	icache_size = r3k_cache_size(ST0_ISC|ST0_SWC);
-	printk("Primary instruction cache %dkb, linesize 4 bytes\n",
-		icache_size >> 10);
+	icache_lsize = 4;
 }
 
-static void r3k_flush_icache_range(unsigned long start, unsigned long size)
+static void r3k_flush_icache_range(unsigned long start, unsigned long end)
 {
-	unsigned long i, flags;
+	unsigned long size, i, flags;
 	volatile unsigned char *p = (char *)start;
 
+	size = end - start;
 	if (size > icache_size)
 		size = icache_size;
 
-	save_and_cli(flags);
+	flags = read_32bit_cp0_register(CP0_STATUS);
 
 	/* isolate cache space */
 	write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
@@ -211,18 +212,19 @@
 		p += 0x080;
 	}
 
-	restore_flags(flags);
+	write_32bit_cp0_register(CP0_STATUS,flags);
 }
 
-static void r3k_flush_dcache_range(unsigned long start, unsigned long size)
+static void r3k_flush_dcache_range(unsigned long start, unsigned long end)
 {
-	unsigned long i, flags;
+	unsigned long size, i, flags;
 	volatile unsigned char *p = (char *)start;
 
+	size = end - start;
 	if (size > dcache_size)
 		size = dcache_size;
 
-	save_and_cli(flags);
+	flags = read_32bit_cp0_register(CP0_STATUS);
 
 	/* isolate cache space */
 	write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|flags)&~ST0_IEC);
@@ -264,7 +266,7 @@
 		p += 0x080;
 	}
 
-	restore_flags(flags);
+	write_32bit_cp0_register(CP0_STATUS,flags);
 }
 
 static inline unsigned long get_phys_page (unsigned long addr,
@@ -279,15 +281,15 @@
 	pmd = pmd_offset(pgd, addr);
 	pte = pte_offset(pmd, addr);
 
-	if((physpage = pte_val(*pte)) & _PAGE_VALID)
-		return KSEG1ADDR(physpage & PAGE_MASK);
-	else
-		return 0;
+	if ((physpage = pte_val(*pte)) & _PAGE_VALID)
+		return KSEG0ADDR(physpage & PAGE_MASK);
+
+	return 0;
 }
 
 static inline void r3k_flush_cache_all(void)
 {
-	r3k_flush_icache_range(KSEG0, icache_size);
+	r3k_flush_icache_range(KSEG0, KSEG0 + icache_size);
 }
  
 static void r3k_flush_cache_mm(struct mm_struct *mm)
@@ -301,9 +303,8 @@
 	}
 }
 
-static void r3k_flush_cache_range(struct mm_struct *mm,
-				    unsigned long start,
-				    unsigned long end)
+static void r3k_flush_cache_range(struct mm_struct *mm, unsigned long start,
+				  unsigned long end)
 {
 	struct vm_area_struct *vma;
 
@@ -315,21 +316,22 @@
 	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
 	vma = find_vma(mm, start);
-	if (vma) {
-		if (mm->context != current->active_mm->context) {
-			flush_cache_all();
-		} else {
-			unsigned long flags, physpage;
+	if (!vma)
+		return;
 
-			save_and_cli(flags);
-			while (start < end) {
-				if ((physpage = get_phys_page(start, mm)))
-					r3k_flush_icache_range(physpage, PAGE_SIZE);
-		
-				start += PAGE_SIZE;
-			}
-			restore_flags(flags);
+	if (mm->context != current->active_mm->context) {
+		flush_cache_all();
+	} else {
+		unsigned long flags, physpage;
+
+		save_and_cli(flags);
+		while (start < end) {
+			if ((physpage = get_phys_page(start, mm)))
+				r3k_flush_icache_range(physpage,
+				                       physpage + PAGE_SIZE);
+			start += PAGE_SIZE;
 		}
+		restore_flags(flags);
 	}
 }
 
@@ -348,8 +350,7 @@
 		unsigned long physpage;
 
 		if ((physpage = get_phys_page(page, vma->vm_mm)))
-			r3k_flush_icache_range(physpage, PAGE_SIZE);
-
+			r3k_flush_icache_range(physpage, physpage + PAGE_SIZE);
 	}
 }
 
@@ -360,6 +361,26 @@
 	 */
 }
 
+static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long physpage;
+
+	if (mm->context == 0)
+		return;
+
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+
+	physpage = (unsigned long) page_address(page);
+	if (physpage)
+		r3k_flush_icache_range(physpage, physpage + PAGE_SIZE);
+}
+
 static void r3k_flush_cache_sigtramp(unsigned long addr)
 {
 	unsigned long flags;
@@ -367,26 +388,23 @@
 #ifdef DEBUG_CACHE
 	printk("csigtramp[%08lx]", addr);
 #endif
-	/*
-	 * I am assuming an 8 Byte cacheline here. HK
-	 */
-	addr &= ~7;
 
-	save_and_cli(flags);
+	flags = read_32bit_cp0_register(CP0_STATUS);
 
 	write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
 
 	asm ( 	"sb\t$0,0x000(%0)\n\t"
+		"sb\t$0,0x004(%0)\n\t"
 		"sb\t$0,0x008(%0)\n\t"
 		: : "r" (addr) );
 
-	restore_flags(flags);
+	write_32bit_cp0_register(CP0_STATUS, flags);
 }
 
 static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
 {
 	wbflush();
-	r3k_flush_dcache_range(start, size);
+	r3k_flush_dcache_range(start, start + size);
 }
 
 /* TLB operations. */
@@ -403,7 +421,7 @@
 	save_and_cli(flags);
 	old_ctx = (get_entryhi() & 0xfc0);
 	write_32bit_cp0_register(CP0_ENTRYLO0, 0);
-	for(entry = 0; entry < NTLB_ENTRIES; entry++) {
+	for (entry = 8; entry < mips_cpu.tlbsize; entry++) {
 		write_32bit_cp0_register(CP0_INDEX, entry << 8);
 		write_32bit_cp0_register(CP0_ENTRYHI, ((entry | 0x80000) << 12));
 		__asm__ __volatile__("tlbwi");
@@ -418,7 +436,7 @@
 		unsigned long flags;
 
 #ifdef DEBUG_TLB
-		printk("[tlbmm<%d>]", mm->context);
+		printk("[tlbmm<%lu>]", (unsigned long) mm->context);
 #endif
 		save_and_cli(flags);
 		get_new_mmu_context(mm, asid_cache);
@@ -429,19 +447,19 @@
 }
 
 void flush_tlb_range(struct mm_struct *mm, unsigned long start,
-				  unsigned long end)
+                     unsigned long end)
 {
 	if (mm->context != 0) {
 		unsigned long flags;
 		int size;
 
 #ifdef DEBUG_TLB
-		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xfc0),
-		       start, end);
+		printk("[tlbrange<%lu,0x%08lx,0x%08lx>]",
+			(mm->context & 0xfc0), start, end);
 #endif
 		save_and_cli(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
-		if(size <= NTLB_ENTRIES) {
+		if(size <= mips_cpu.tlbsize) {
 			int oldpid = (get_entryhi() & 0xfc0);
 			int newpid = (mm->context & 0xfc0);
 
@@ -478,7 +496,7 @@
 		int oldpid, newpid, idx;
 
 #ifdef DEBUG_TLB
-		printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
+		printk("[tlbpage<%lu,0x%08lx>]", vma->vm_mm->context, page);
 #endif
 		newpid = (vma->vm_mm->context & 0xfc0);
 		page &= PAGE_MASK;
@@ -531,8 +549,8 @@
 		 "1" (PAGE_SIZE/(sizeof(pmd_t)*8)));
 }
 
-void update_mmu_cache(struct vm_area_struct * vma,
-				   unsigned long address, pte_t pte)
+void update_mmu_cache(struct vm_area_struct * vma, unsigned long address,
+                      pte_t pte)
 {
 	unsigned long flags;
 	pgd_t *pgdp;
@@ -550,8 +568,8 @@
 
 #ifdef DEBUG_TLB
 	if((pid != (vma->vm_mm->context & 0xfc0)) || (vma->vm_mm->context == 0)) {
-		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
-		       (int) (vma->vm_mm->context & 0xfc0), pid);
+		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n",
+		       (vma->vm_mm->context & 0xfc0), pid);
 	}
 #endif
 
@@ -576,19 +594,6 @@
 		printk("[HIT]");
 #endif
 	}
-#if 0
-	if(!strcmp(current->comm, "args")) {
-		printk("<");
-		for(idx = 0; idx < NTLB_ENTRIES; idx++) {
-			set_index(idx);
-			tlb_read();
-			address = get_entryhi();
-			if((address & 0xfc0) != 0)
-				printk("[%08lx]", address);
-		}
-		printk(">\n");
-	}
-#endif
 	set_entryhi(pid);
 	restore_flags(flags);
 }
@@ -626,33 +631,135 @@
 	       (unsigned int) regs->cp0_cause);
 }
 
+/* Todo: handle r4k-style TX39 TLB */
 void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
-				  unsigned long entryhi, unsigned long pagemask)
+                     unsigned long entryhi, unsigned long pagemask)
 {
-printk("r3k_add_wired_entry");
-        /*
-	 * FIXME, to be done
-	 */
+	unsigned long flags;
+	unsigned long old_ctx;
+	static unsigned long wired = 0;
+	
+	if (wired < 8) {
+		save_and_cli(flags);
+		old_ctx = get_entryhi() & 0xfc0;
+		set_entrylo0(entrylo0);
+		set_entryhi(entryhi);
+		set_index(wired);
+		wired++;
+		tlb_write_indexed();
+		set_entryhi(old_ctx);
+	        flush_tlb_all();    
+		restore_flags(flags);
+	}
 }
 
-void __init ld_mmu_r2300(void)
+static void tx39_flush_icache_all(void )
 {
+
+	unsigned long start = KSEG0;
+	unsigned long end = (start + icache_size);
+	unsigned long dummy = 0;
+
+	/* disable icache and stop streaming */
+	__asm__ __volatile__(
+	".set\tnoreorder\n\t"
+	"mfc0\t%0,$3\n\t"
+	"xori\t%0,32\n\t"
+	"mtc0\t%0,$3\n\t"
+	"j\t1f\n\t"
+	"nop\n\t"
+	"1:\t.set\treorder\n\t"
+	: : "r"(dummy));
+
+	/* invalidate icache */
+	while (start < end) {
+		cache16_unroll32(start,Index_Invalidate_I);
+		start += 0x200;
+	}
+
+	/* enable icache */
+	__asm__ __volatile__(
+	".set\tnoreorder\n\t"
+	"mfc0\t%0,$3\n\t"
+	"xori\t%0,32\n\t"
+	"mtc0\t%0,$3\n\t"
+	".set\treorder\n\t"
+	: : "r"(dummy));
+}
+
+static __init void tx39_probe_cache(void)
+{
+	unsigned long	config;
+
+	config = read_32bit_cp0_register(CP0_CONF);
+
+	icache_size = 1 << (10 + ((config >> 19) & 3));
+	icache_lsize = 16;
+
+	dcache_size = 1 << (10 + ((config >> 16) & 3));
+	dcache_lsize = 4;
+}
+
+void __init ld_mmu_r23000(void)
+{
+	unsigned long config;
+
 	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
 
 	_clear_page = r3k_clear_page;
 	_copy_page = r3k_copy_page;
 
-	probe_icache();
-	probe_dcache();
-
-	_flush_cache_all = r3k_flush_cache_all;
-	_flush_cache_mm = r3k_flush_cache_mm;
-	_flush_cache_range = r3k_flush_cache_range;
-	_flush_cache_page = r3k_flush_cache_page;
-	_flush_cache_sigtramp = r3k_flush_cache_sigtramp;
-	_flush_page_to_ram = r3k_flush_page_to_ram;
-
-        _dma_cache_wback_inv = r3k_dma_cache_wback_inv;
+	switch (mips_cpu.cputype) {
+	case CPU_R2000:
+	case CPU_R3000:
+	case CPU_R3000A:
+	case CPU_R3081:
+	case CPU_R3081E:
+
+		r3k_probe_cache();
+
+		_flush_cache_all = r3k_flush_cache_all;
+		___flush_cache_all = r3k_flush_cache_all;
+		_flush_cache_mm = r3k_flush_cache_mm;
+		_flush_cache_range = r3k_flush_cache_range;
+		_flush_cache_page = r3k_flush_cache_page;
+		_flush_cache_sigtramp = r3k_flush_cache_sigtramp;
+		_flush_page_to_ram = r3k_flush_page_to_ram;
+		_flush_icache_page = r3k_flush_icache_page;
+		_flush_icache_range = r3k_flush_icache_range;
+
+		_dma_cache_wback_inv = r3k_dma_cache_wback_inv;
+		break;
+
+	case CPU_TX3912:
+	case CPU_TX3922:
+	case CPU_TX3927:
+
+		config=read_32bit_cp0_register(CP0_CONF);
+		config &= ~TX39_CONF_WBON;
+		write_32bit_cp0_register(CP0_CONF, config);
+
+		tx39_probe_cache();
+
+		_flush_cache_all = tx39_flush_icache_all;
+		___flush_cache_all = tx39_flush_icache_all;
+		_flush_cache_mm = tx39_flush_icache_all;
+		_flush_cache_range = tx39_flush_icache_all;
+		_flush_cache_page = tx39_flush_icache_all;
+		_flush_cache_sigtramp = tx39_flush_icache_all;
+		_flush_page_to_ram = r3k_flush_page_to_ram;
+		_flush_icache_page = tx39_flush_icache_all;
+		_flush_icache_range = tx39_flush_icache_all;
+
+		_dma_cache_wback_inv = r3k_dma_cache_wback_inv;
+
+		break;
+	}
+
+	printk("Primary instruction cache %dkb, linesize %d bytes\n",
+		(int) (icache_size >> 10), (int) icache_lsize);
+	printk("Primary data cache %dkb, linesize %d bytes\n",
+		(int) (dcache_size >> 10), (int) dcache_lsize);
 
 	flush_tlb_all();
 }
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/r4xx0.c linux/arch/mips/mm/r4xx0.c
--- v2.4.6/linux/arch/mips/mm/r4xx0.c	Sun Aug  6 11:43:17 2000
+++ linux/arch/mips/mm/r4xx0.c	Wed Jul  4 11:50:39 2001
@@ -19,12 +19,13 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
 #include <asm/bcache.h>
 #include <asm/io.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
-#include <asm/bootinfo.h>
 #include <asm/mmu_context.h>
 
 /* CP0 hazard avoidance. */
@@ -208,7 +209,7 @@
 {
 	unsigned int flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	*(volatile unsigned int *)KSEG1;
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
@@ -235,7 +236,7 @@
 		 "I" (PAGE_SIZE),
 		 "i" (Create_Dirty_Excl_D)
 		:"$1","memory");
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 /*
@@ -626,7 +627,7 @@
 		:"0" (to), "1" (from),
 		 "I" (PAGE_SIZE),
 		 "i" (Create_Dirty_Excl_D));
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 /*
@@ -910,81 +911,81 @@
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16(); blast_scache16();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s32d16i16(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16(); blast_scache32();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s64d16i16(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16(); blast_scache64();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s128d16i16(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16(); blast_scache128();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s32d32i32(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache32(); blast_icache32(); blast_scache32();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s64d32i32(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache32(); blast_icache32(); blast_scache64();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s128d32i32(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache32(); blast_icache32(); blast_scache128();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_d16i16(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_d32i32(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache32(); blast_icache32();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static void
@@ -1010,10 +1011,8 @@
 			pgd_t *pgd;
 			pmd_t *pmd;
 			pte_t *pte;
-			int text;
 
-			save_and_cli(flags);
-			text = vma->vm_flags & VM_EXEC;
+			__save_and_cli(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1023,7 +1022,7 @@
 					blast_scache16_page(start);
 				start += PAGE_SIZE;
 			}
-			restore_flags(flags);
+			__restore_flags(flags);
 		}
 	}
 }
@@ -1051,10 +1050,8 @@
 			pgd_t *pgd;
 			pmd_t *pmd;
 			pte_t *pte;
-			int text;
 
-			save_and_cli(flags);
-			text = vma->vm_flags & VM_EXEC;
+			__save_and_cli(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1064,7 +1061,7 @@
 					blast_scache32_page(start);
 				start += PAGE_SIZE;
 			}
-			restore_flags(flags);
+			__restore_flags(flags);
 		}
 	}
 }
@@ -1091,10 +1088,8 @@
 			pgd_t *pgd;
 			pmd_t *pmd;
 			pte_t *pte;
-			int text;
 
-			save_and_cli(flags);
-			text = vma->vm_flags & VM_EXEC;
+			__save_and_cli(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1104,7 +1099,7 @@
 					blast_scache64_page(start);
 				start += PAGE_SIZE;
 			}
-			restore_flags(flags);
+			__restore_flags(flags);
 		}
 	}
 }
@@ -1131,10 +1126,8 @@
 			pgd_t *pgd;
 			pmd_t *pmd;
 			pte_t *pte;
-			int text;
 
-			save_and_cli(flags);
-			text = vma->vm_flags & VM_EXEC;
+			__save_and_cli(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1144,7 +1137,7 @@
 					blast_scache128_page(start);
 				start += PAGE_SIZE;
 			}
-			restore_flags(flags);
+			__restore_flags(flags);
 		}
 	}
 }
@@ -1171,10 +1164,8 @@
 			pgd_t *pgd;
 			pmd_t *pmd;
 			pte_t *pte;
-			int text;
 
-			save_and_cli(flags);
-			text = vma->vm_flags & VM_EXEC;
+			__save_and_cli(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1184,7 +1175,7 @@
 					blast_scache32_page(start);
 				start += PAGE_SIZE;
 			}
-			restore_flags(flags);
+			__restore_flags(flags);
 		}
 	}
 }
@@ -1211,10 +1202,8 @@
 			pgd_t *pgd;
 			pmd_t *pmd;
 			pte_t *pte;
-			int text;
 
-			save_and_cli(flags);
-			text = vma->vm_flags & VM_EXEC;
+			__save_and_cli(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1224,7 +1213,7 @@
 					blast_scache64_page(start);
 				start += PAGE_SIZE;
 			}
-			restore_flags(flags);
+			__restore_flags(flags);
 		}
 	}
 }
@@ -1251,10 +1240,8 @@
 			pgd_t *pgd;
 			pmd_t *pmd;
 			pte_t *pte;
-			int text;
 
-			save_and_cli(flags);
-			text = vma->vm_flags & VM_EXEC;
+			__save_and_cli(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1264,7 +1251,7 @@
 					blast_scache128_page(start);
 				start += PAGE_SIZE;
 			}
-			restore_flags(flags);
+			__restore_flags(flags);
 		}
 	}
 }
@@ -1279,9 +1266,9 @@
 #ifdef DEBUG_CACHE
 		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
-		save_and_cli(flags);
+		__save_and_cli(flags);
 		blast_dcache16(); blast_icache16();
-		restore_flags(flags);
+		__restore_flags(flags);
 	}
 }
 
@@ -1295,9 +1282,9 @@
 #ifdef DEBUG_CACHE
 		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
-		save_and_cli(flags);
+		__save_and_cli(flags);
 		blast_dcache32(); blast_icache32();
-		restore_flags(flags);
+		__restore_flags(flags);
 	}
 }
 
@@ -1404,7 +1391,6 @@
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
-	int text;
 
 	/*
 	 * If ownes no valid ASID yet, cannot possibly have gotten
@@ -1416,7 +1402,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1429,25 +1415,24 @@
 	if (!(pte_val(*ptep) & _PAGE_VALID))
 		goto out;
 
-	text = (vma->vm_flags & VM_EXEC);
-	/* Doing flushes for another ASID than the current one is
+	/*
+	 * Doing flushes for another ASID than the current one is
 	 * too difficult since stupid R4k caches do a TLB translation
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
 	if (mm->context != current->active_mm->context) {
-		/* Do indexed flush, too much work to get the (possible)
+		/*
+		 * Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
 		 */
 		page = (KSEG0 + (page & (scache_size - 1)));
 		blast_dcache16_page_indexed(page);
-		if(text)
-			blast_icache16_page_indexed(page);
 		blast_scache16_page_indexed(page);
 	} else
 		blast_scache16_page(page);
 out:
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma,
@@ -1458,7 +1443,6 @@
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
-	int text;
 
 	/*
 	 * If ownes no valid ASID yet, cannot possibly have gotten
@@ -1470,7 +1454,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1482,25 +1466,24 @@
 	if (!(pte_val(*ptep) & _PAGE_VALID))
 		goto out;
 
-	text = (vma->vm_flags & VM_EXEC);
-	/* Doing flushes for another ASID than the current one is
+	/*
+	 * Doing flushes for another ASID than the current one is
 	 * too difficult since stupid R4k caches do a TLB translation
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
 	if (mm->context != current->active_mm->context) {
-		/* Do indexed flush, too much work to get the (possible)
+		/*
+		 * Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
 		 */
 		page = (KSEG0 + (page & (scache_size - 1)));
 		blast_dcache16_page_indexed(page);
-		if(text)
-			blast_icache16_page_indexed(page);
 		blast_scache32_page_indexed(page);
 	} else
 		blast_scache32_page(page);
 out:
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma,
@@ -1511,7 +1494,6 @@
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
-	int text;
 
 	/*
 	 * If ownes no valid ASID yet, cannot possibly have gotten
@@ -1523,7 +1505,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1535,7 +1517,6 @@
 	if (!(pte_val(*ptep) & _PAGE_VALID))
 		goto out;
 
-	text = (vma->vm_flags & VM_EXEC);
 	/*
 	 * Doing flushes for another ASID than the current one is
 	 * too difficult since stupid R4k caches do a TLB translation
@@ -1543,18 +1524,17 @@
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
 	if (mm->context != current->active_mm->context) {
-		/* Do indexed flush, too much work to get the (possible)
+		/*
+		 * Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
 		 */
 		page = (KSEG0 + (page & (scache_size - 1)));
 		blast_dcache16_page_indexed(page);
-		if(text)
-			blast_icache16_page_indexed(page);
 		blast_scache64_page_indexed(page);
 	} else
 		blast_scache64_page(page);
 out:
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma,
@@ -1565,7 +1545,6 @@
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
-	int text;
 
 	/*
 	 * If ownes no valid ASID yet, cannot possibly have gotten
@@ -1577,7 +1556,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1590,8 +1569,8 @@
 	if (!(pte_val(*ptep) & _PAGE_VALID))
 		goto out;
 
-	text = (vma->vm_flags & VM_EXEC);
-	/* Doing flushes for another ASID than the current one is
+	/*
+	 * Doing flushes for another ASID than the current one is
 	 * too difficult since stupid R4k caches do a TLB translation
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
@@ -1603,13 +1582,11 @@
 		 */
 		page = (KSEG0 + (page & (scache_size - 1)));
 		blast_dcache16_page_indexed(page);
-		if(text)
-			blast_icache16_page_indexed(page);
 		blast_scache128_page_indexed(page);
 	} else
 		blast_scache128_page(page);
 out:
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma,
@@ -1620,7 +1597,6 @@
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
-	int text;
 
 	/*
 	 * If ownes no valid ASID yet, cannot possibly have gotten
@@ -1632,7 +1608,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1645,7 +1621,6 @@
 	if (!(pte_val(*ptep) & _PAGE_VALID))
 		goto out;
 
-	text = (vma->vm_flags & VM_EXEC);
 	/*
 	 * Doing flushes for another ASID than the current one is
 	 * too difficult since stupid R4k caches do a TLB translation
@@ -1659,13 +1634,11 @@
 		 */
 		page = (KSEG0 + (page & (scache_size - 1)));
 		blast_dcache32_page_indexed(page);
-		if(text)
-			blast_icache32_page_indexed(page);
 		blast_scache32_page_indexed(page);
 	} else
 		blast_scache32_page(page);
 out:
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma,
@@ -1676,7 +1649,6 @@
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
-	int text;
 
 	/*
 	 * If ownes no valid ASID yet, cannot possibly have gotten
@@ -1688,7 +1660,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1701,7 +1673,6 @@
 	if (!(pte_val(*ptep) & _PAGE_VALID))
 		goto out;
 
-	text = (vma->vm_flags & VM_EXEC);
 	/*
 	 * Doing flushes for another ASID than the current one is
 	 * too difficult since stupid R4k caches do a TLB translation
@@ -1715,13 +1686,11 @@
 		 */
 		page = (KSEG0 + (page & (scache_size - 1)));
 		blast_dcache32_page_indexed(page);
-		if(text)
-			blast_icache32_page_indexed(page);
 		blast_scache64_page_indexed(page);
 	} else
 		blast_scache64_page(page);
 out:
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma,
@@ -1732,7 +1701,6 @@
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
-	int text;
 
 	/*
 	 * If ownes no valid ASID yet, cannot possibly have gotten
@@ -1744,19 +1712,19 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
 	ptep = pte_offset(pmdp, page);
 
-	/* If the page isn't marked valid, the page cannot possibly be
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
 	 * in the cache.
 	 */
 	if (!(pte_val(*ptep) & _PAGE_VALID))
 		goto out;
 
-	text = (vma->vm_flags & VM_EXEC);
 	/*
 	 * Doing flushes for another ASID than the current one is
 	 * too difficult since stupid R4k caches do a TLB translation
@@ -1769,13 +1737,11 @@
 		 */
 		page = (KSEG0 + (page & (scache_size - 1)));
 		blast_dcache32_page_indexed(page);
-		if(text)
-			blast_icache32_page_indexed(page);
 		blast_scache128_page_indexed(page);
 	} else
 		blast_scache128_page(page);
 out:
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma,
@@ -1786,7 +1752,6 @@
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
-	int text;
 
 	/*
 	 * If ownes no valid ASID yet, cannot possibly have gotten
@@ -1798,19 +1763,19 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
 	ptep = pte_offset(pmdp, page);
 
-	/* If the page isn't marked valid, the page cannot possibly be
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
 	 * in the cache.
 	 */
 	if (!(pte_val(*ptep) & _PAGE_VALID))
 		goto out;
 
-	text = (vma->vm_flags & VM_EXEC);
 	/*
 	 * Doing flushes for another ASID than the current one is
 	 * too difficult since stupid R4k caches do a TLB translation
@@ -1819,19 +1784,15 @@
 	 */
 	if (mm == current->active_mm) {
 		blast_dcache16_page(page);
-		if(text)
-			blast_icache16_page(page);
 	} else {
 		/* Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
 		 */
 		page = (KSEG0 + (page & (dcache_size - 1)));
 		blast_dcache16_page_indexed(page);
-		if(text)
-			blast_icache16_page_indexed(page);
 	}
 out:
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma,
@@ -1842,7 +1803,6 @@
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
-	int text;
 
 	/*
 	 * If ownes no valid ASID yet, cannot possibly have gotten
@@ -1854,7 +1814,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1867,7 +1827,6 @@
 	if (!(pte_val(*ptep) & _PAGE_PRESENT))
 		goto out;
 
-	text = (vma->vm_flags & VM_EXEC);
 	/*
 	 * Doing flushes for another ASID than the current one is
 	 * too difficult since stupid R4k caches do a TLB translation
@@ -1876,8 +1835,6 @@
 	 */
 	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
 		blast_dcache32_page(page);
-		if(text)
-			blast_icache32_page(page);
 	} else {
 		/*
 		 * Do indexed flush, too much work to get the (possible)
@@ -1885,11 +1842,9 @@
 		 */
 		page = (KSEG0 + (page & (dcache_size - 1)));
 		blast_dcache32_page_indexed(page);
-		if(text)
-			blast_icache32_page_indexed(page);
 	}
 out:
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma,
@@ -1900,7 +1855,6 @@
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
-	int text;
 
 	/*
 	 * If ownes no valid ASID yet, cannot possibly have gotten
@@ -1912,7 +1866,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1925,7 +1879,6 @@
 	if (!(pte_val(*ptep) & _PAGE_PRESENT))
 		goto out;
 
-	text = (vma->vm_flags & VM_EXEC);
 	/*
 	 * Doing flushes for another ASID than the current one is
 	 * too difficult since stupid R4k caches do a TLB translation
@@ -1934,8 +1887,6 @@
 	 */
 	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
 		blast_dcache32_page(page);
-		if(text)
-			blast_icache32_page(page);
 	} else {
 		/* Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
@@ -1943,13 +1894,9 @@
 		page = (KSEG0 + (page & (dcache_size - 1)));
 		blast_dcache32_page_indexed(page);
 		blast_dcache32_page_indexed(page ^ dcache_waybit);
-		if(text) {
-			blast_icache32_page_indexed(page);
-			blast_icache32_page_indexed(page ^ icache_waybit);
-		}
 	}
 out:
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 /* If the addresses passed to these routines are valid, they are
@@ -1961,120 +1908,71 @@
  *    flush.
  * 3) In KSEG1, no flush necessary.
  */
-static void r4k_flush_page_to_ram_s16d16i16(struct page * page)
+static void r4k_flush_page_to_ram_s16(struct page *page)
 {
-	unsigned long addr = (unsigned long) page_address(page) & PAGE_MASK;
-
-	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
-#ifdef DEBUG_CACHE
-		printk("cram[%08lx]", addr);
-#endif
-		blast_scache16_page(addr);
-	}
+	blast_scache16_page((unsigned long)page_address(page));
 }
 
-static void r4k_flush_page_to_ram_s32d16i16(struct page * page)
+static void r4k_flush_page_to_ram_s32(struct page *page)
 {
-	unsigned long addr = (unsigned long) page_address(page) & PAGE_MASK;
-
-	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
-#ifdef DEBUG_CACHE
-		printk("cram[%08lx]", addr);
-#endif
-		blast_scache32_page(addr);
-	}
+	blast_scache32_page((unsigned long)page_address(page));
 }
 
-static void r4k_flush_page_to_ram_s64d16i16(struct page * page)
+static void r4k_flush_page_to_ram_s64(struct page *page)
 {
-	unsigned long addr = (unsigned long) page_address(page) & PAGE_MASK;
-
-	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
-#ifdef DEBUG_CACHE
-		printk("cram[%08lx]", addr);
-#endif
-		blast_scache64_page(addr);
-	}
+	blast_scache64_page((unsigned long)page_address(page));
 }
 
-static void r4k_flush_page_to_ram_s128d16i16(struct page * page)
+static void r4k_flush_page_to_ram_s128(struct page *page)
 {
-	unsigned long addr = (unsigned long) page_address(page) & PAGE_MASK;
-
-	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
-#ifdef DEBUG_CACHE
-		printk("cram[%08lx]", addr);
-#endif
-		blast_scache128_page(addr);
-	}
+	blast_scache128_page((unsigned long)page_address(page));
 }
 
-static void r4k_flush_page_to_ram_s32d32i32(struct page * page)
+static void r4k_flush_page_to_ram_d16(struct page *page)
 {
-	unsigned long addr = (unsigned long) page_address(page) & PAGE_MASK;
-
-	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
-#ifdef DEBUG_CACHE
-		printk("cram[%08lx]", addr);
-#endif
-		blast_scache32_page(addr);
-	}
+	blast_dcache16_page((unsigned long)page_address(page));
 }
 
-static void r4k_flush_page_to_ram_s64d32i32(struct page * page)
+static void r4k_flush_page_to_ram_d32(struct page *page)
 {
-	unsigned long addr = (unsigned long) page_address(page) & PAGE_MASK;
-
-	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
-#ifdef DEBUG_CACHE
-		printk("cram[%08lx]", addr);
-#endif
-		blast_scache64_page(addr);
-	}
+	blast_dcache32_page((unsigned long)page_address(page));
 }
 
-static void r4k_flush_page_to_ram_s128d32i32(struct page * page)
+static void r4k_flush_page_to_ram_d32_r4600(struct page *page)
 {
-	unsigned long addr = (unsigned long) page_address(page) & PAGE_MASK;
+	unsigned long flags;
 
-	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
-#ifdef DEBUG_CACHE
-		printk("cram[%08lx]", addr);
-#endif
-		blast_scache128_page(addr);
-	}
+	__save_and_cli(flags);			/* For R4600 v1.7 bug.  */
+	blast_dcache32_page((unsigned long)page_address(page));
+	__restore_flags(flags);
 }
 
-static void r4k_flush_page_to_ram_d16i16(struct page * page)
+static void
+r4k_flush_icache_page_s(struct vm_area_struct *vma, struct page *page)
 {
-	unsigned long addr = (unsigned long) page_address(page) & PAGE_MASK;
-
-	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
-		unsigned long flags;
-
-#ifdef DEBUG_CACHE
-		printk("cram[%08lx]", addr);
-#endif
-		__save_and_cli(flags);
-		blast_dcache16_page(addr);
-		__restore_flags(flags);
-	}
+	/*
+	 * We did an scache flush therefore PI is already clean.
+	 */
 }
 
-static void r4k_flush_page_to_ram_d32i32(struct page * page)
+static void
+r4k_flush_icache_range(unsigned long start, unsigned long end)
 {
-	unsigned long addr = (unsigned long) page_address(page) & PAGE_MASK;
+	flush_cache_all();
+}
 
-	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
-		unsigned long flags;
+/*
+ * Ok, this seriously sucks.  We use them to flush a user page but don't
+ * know the virtual address, so we have to blast away the whole icache
+ * which is significantly more expensive than the real thing.
+ */
+static void
+r4k_flush_icache_page_p(struct vm_area_struct *vma, struct page *page)
+{
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
 
-#ifdef DEBUG_CACHE
-		printk("cram[%08lx]", addr);
-#endif
-		__save_and_cli(flags);
-		blast_dcache32_page(addr);
-		__restore_flags(flags);
-	}
+	flush_cache_all();
 }
 
 /*
@@ -2098,7 +1996,7 @@
 		flush_cache_all();
 	} else {
 		/* Workaround for R4600 bug.  See comment above. */
-		save_and_cli(flags);
+		__save_and_cli(flags);
 		*(volatile unsigned long *)KSEG1;
 
 		a = addr & ~(dc_lsize - 1);
@@ -2108,9 +2006,9 @@
 			if (a == end) break;
 			a += dc_lsize;
 		}
-		restore_flags(flags);
+		__restore_flags(flags);
 	}
-	bcops->bc_wback_inv(addr, size);
+	bc_wback_inv(addr, size);
 }
 
 static void
@@ -2142,7 +2040,7 @@
 		flush_cache_all();
 	} else {
 		/* Workaround for R4600 bug.  See comment above. */
-		save_and_cli(flags);
+		__save_and_cli(flags);
 		*(volatile unsigned long *)KSEG1;
 
 		a = addr & ~(dc_lsize - 1);
@@ -2152,10 +2050,10 @@
 			if (a == end) break;
 			a += dc_lsize;
 		}
-		restore_flags(flags);
+		__restore_flags(flags);
 	}
 
-	bcops->bc_inv(addr, size);
+	bc_inv(addr, size);
 }
 
 static void
@@ -2237,7 +2135,7 @@
 	printk("[tlball]");
 #endif
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	/* Save old context and create impossible VPN2 value */
 	old_ctx = (get_entryhi() & 0xff);
 	set_entryhi(KSEG0);
@@ -2257,7 +2155,7 @@
 	}
 	BARRIER;
 	set_entryhi(old_ctx);
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 void flush_tlb_mm(struct mm_struct *mm)
@@ -2268,11 +2166,11 @@
 #ifdef DEBUG_TLB
 		printk("[tlbmm<%d>]", mm->context);
 #endif
-		save_and_cli(flags);
+		__save_and_cli(flags);
 		get_new_mmu_context(mm, asid_cache);
 		if (mm == current->active_mm)
 			set_entryhi(mm->context & 0xff);
-		restore_flags(flags);
+		__restore_flags(flags);
 	}
 }
 
@@ -2287,7 +2185,7 @@
 		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
 		       start, end);
 #endif
-		save_and_cli(flags);
+		__save_and_cli(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 		size = (size + 1) >> 1;
 		if(size <= NTLB_ENTRIES_HALF) {
@@ -2321,7 +2219,7 @@
 			if (mm == current->active_mm)
 				set_entryhi(mm->context & 0xff);
 		}
-		restore_flags(flags);
+		__restore_flags(flags);
 	}
 }
 
@@ -2336,7 +2234,7 @@
 #endif
 		newpid = (vma->vm_mm->context & 0xff);
 		page &= (PAGE_MASK << 1);
-		save_and_cli(flags);
+		__save_and_cli(flags);
 		oldpid = (get_entryhi() & 0xff);
 		set_entryhi(page | newpid);
 		BARRIER;
@@ -2354,15 +2252,10 @@
 	finish:
 		BARRIER;
 		set_entryhi(oldpid);
-		restore_flags(flags);
+		__restore_flags(flags);
 	}
 }
 
-/* Load a new root pointer into the TLB. */
-void load_pgd(unsigned long pg_dir)
-{
-}
-
 void pgd_init(unsigned long page)
 {
 	unsigned long *p = (unsigned long *) page;
@@ -2380,12 +2273,6 @@
 	}
 }
 
-#ifdef DEBUG_TLBUPDATE
-static unsigned long ehi_debug[NTLB_ENTRIES];
-static unsigned long el0_debug[NTLB_ENTRIES];
-static unsigned long el1_debug[NTLB_ENTRIES];
-#endif
-
 /* We will need multiple versions of update_mmu_cache(), one that just
  * updates the TLB with the new pte(s), and another which also checks
  * for the R4k "end of page" hardware bug and does the needy.
@@ -2414,7 +2301,7 @@
 	}
 #endif
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	address &= (PAGE_MASK << 1);
 	set_entryhi(address | (pid));
 	pgdp = pgd_offset(vma->vm_mm, address);
@@ -2437,7 +2324,7 @@
 	BARRIER;
 	set_entryhi(pid);
 	BARRIER;
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 #if 0
@@ -2450,7 +2337,7 @@
 	pte_t *ptep;
 	int idx;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	address &= (PAGE_MASK << 1);
 	set_entryhi(address | (get_entryhi() & 0xff));
 	pgdp = pgd_offset(vma->vm_mm, address);
@@ -2466,7 +2353,7 @@
 	else
 		tlb_write_indexed();
 	BARRIER;
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 #endif
 
@@ -2503,7 +2390,7 @@
         unsigned long old_pagemask;
         unsigned long old_ctx;
 
-        save_and_cli(flags);
+        __save_and_cli(flags);
         /* Save old context and create impossible VPN2 value */
         old_ctx = (get_entryhi() & 0xff);
         old_pagemask = get_pagemask();
@@ -2523,7 +2410,7 @@
         BARRIER;    
         set_pagemask (old_pagemask);
         flush_tlb_all();    
-        restore_flags(flags);
+        __restore_flags(flags);
 }
 
 /* Detect and size the various r4k caches. */
@@ -2532,7 +2419,7 @@
 	icache_size = 1 << (12 + ((config >> 9) & 7));
 	ic_lsize = 16 << ((config >> 5) & 1);
 
-	printk("Primary instruction cache %dkb, linesize %d bytes)\n",
+	printk("Primary instruction cache %dkb, linesize %d bytes.\n",
 	       icache_size >> 10, ic_lsize);
 }
 
@@ -2541,7 +2428,7 @@
 	dcache_size = 1 << (12 + ((config >> 6) & 7));
 	dc_lsize = 16 << ((config >> 4) & 1);
 
-	printk("Primary data cache %dkb, linesize %d bytes)\n",
+	printk("Primary data cache %dkb, linesize %d bytes.\n",
 	       dcache_size >> 10, dc_lsize);
 }
 
@@ -2583,7 +2470,7 @@
 	/* This is such a bitch, you'd think they would make it
 	 * easy to do this.  Away you daemons of stupidity!
 	 */
-	save_and_cli(flags);
+	__save_and_cli(flags);
 
 	/* Fill each size-multiple cache line with a valid tag. */
 	pow2 = (64 * 1024);
@@ -2627,9 +2514,9 @@
 			break;
 		pow2 <<= 1;
 	}
-	restore_flags(flags);
+	__restore_flags(flags);
 	addr -= begin;
-	printk("Secondary cache sized at %dK linesize %d\n",
+	printk("Secondary cache sized at %dK linesize %d bytes.\n",
 	       (int) (addr >> 10), sc_lsize);
 	scache_size = addr;
 	return 1;
@@ -2647,27 +2534,33 @@
 		_flush_cache_mm = r4k_flush_cache_mm_d16i16;
 		_flush_cache_range = r4k_flush_cache_range_d16i16;
 		_flush_cache_page = r4k_flush_cache_page_d16i16;
-		_flush_page_to_ram = r4k_flush_page_to_ram_d16i16;
+		_flush_page_to_ram = r4k_flush_page_to_ram_d16;
 		break;
 	case 32:
 		prid = read_32bit_cp0_register(CP0_PRID) & 0xfff0;
 		if (prid == 0x2010) {			/* R4600 V1.7 */
 			_clear_page = r4k_clear_page_r4600_v1;
 			_copy_page = r4k_copy_page_r4600_v1;
+			_flush_page_to_ram = r4k_flush_page_to_ram_d32_r4600;
 		} else if (prid == 0x2020) {		/* R4600 V2.0 */
 			_clear_page = r4k_clear_page_r4600_v2;
 			_copy_page = r4k_copy_page_r4600_v2;
+			_flush_page_to_ram = r4k_flush_page_to_ram_d32;
 		} else {
 			_clear_page = r4k_clear_page_d32;
 			_copy_page = r4k_copy_page_d32;
+			_flush_page_to_ram = r4k_flush_page_to_ram_d32;
 		}
 		_flush_cache_all = r4k_flush_cache_all_d32i32;
 		_flush_cache_mm = r4k_flush_cache_mm_d32i32;
 		_flush_cache_range = r4k_flush_cache_range_d32i32;
 		_flush_cache_page = r4k_flush_cache_page_d32i32;
-		_flush_page_to_ram = r4k_flush_page_to_ram_d32i32;
 		break;
 	}
+	___flush_cache_all = _flush_cache_all;
+
+	_flush_icache_page = r4k_flush_icache_page_p;
+
 	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc;
 	_dma_cache_wback = r4k_dma_cache_wback;
 	_dma_cache_inv = r4k_dma_cache_inv_pc;
@@ -2683,11 +2576,11 @@
 			_flush_cache_mm = r4k_flush_cache_mm_s16d16i16;
 			_flush_cache_range = r4k_flush_cache_range_s16d16i16;
 			_flush_cache_page = r4k_flush_cache_page_s16d16i16;
-			_flush_page_to_ram = r4k_flush_page_to_ram_s16d16i16;
 			break;
 		case 32:
 			panic("Invalid cache configuration detected");
 		};
+		_flush_page_to_ram = r4k_flush_page_to_ram_s16;
 		_clear_page = r4k_clear_page_s16;
 		_copy_page = r4k_copy_page_s16;
 		break;
@@ -2698,16 +2591,15 @@
 			_flush_cache_mm = r4k_flush_cache_mm_s32d16i16;
 			_flush_cache_range = r4k_flush_cache_range_s32d16i16;
 			_flush_cache_page = r4k_flush_cache_page_s32d16i16;
-			_flush_page_to_ram = r4k_flush_page_to_ram_s32d16i16;
 			break;
 		case 32:
 			_flush_cache_all = r4k_flush_cache_all_s32d32i32;
 			_flush_cache_mm = r4k_flush_cache_mm_s32d32i32;
 			_flush_cache_range = r4k_flush_cache_range_s32d32i32;
 			_flush_cache_page = r4k_flush_cache_page_s32d32i32;
-			_flush_page_to_ram = r4k_flush_page_to_ram_s32d32i32;
 			break;
 		};
+		_flush_page_to_ram = r4k_flush_page_to_ram_s32;
 		_clear_page = r4k_clear_page_s32;
 		_copy_page = r4k_copy_page_s32;
 		break;
@@ -2718,16 +2610,15 @@
 			_flush_cache_mm = r4k_flush_cache_mm_s64d16i16;
 			_flush_cache_range = r4k_flush_cache_range_s64d16i16;
 			_flush_cache_page = r4k_flush_cache_page_s64d16i16;
-			_flush_page_to_ram = r4k_flush_page_to_ram_s64d16i16;
 			break;
 		case 32:
 			_flush_cache_all = r4k_flush_cache_all_s64d32i32;
 			_flush_cache_mm = r4k_flush_cache_mm_s64d32i32;
 			_flush_cache_range = r4k_flush_cache_range_s64d32i32;
 			_flush_cache_page = r4k_flush_cache_page_s64d32i32;
-			_flush_page_to_ram = r4k_flush_page_to_ram_s64d32i32;
 			break;
 		};
+		_flush_page_to_ram = r4k_flush_page_to_ram_s64;
 		_clear_page = r4k_clear_page_s64;
 		_copy_page = r4k_copy_page_s64;
 		break;
@@ -2738,20 +2629,21 @@
 			_flush_cache_mm = r4k_flush_cache_mm_s128d16i16;
 			_flush_cache_range = r4k_flush_cache_range_s128d16i16;
 			_flush_cache_page = r4k_flush_cache_page_s128d16i16;
-			_flush_page_to_ram = r4k_flush_page_to_ram_s128d16i16;
 			break;
 		case 32:
 			_flush_cache_all = r4k_flush_cache_all_s128d32i32;
 			_flush_cache_mm = r4k_flush_cache_mm_s128d32i32;
 			_flush_cache_range = r4k_flush_cache_range_s128d32i32;
 			_flush_cache_page = r4k_flush_cache_page_s128d32i32;
-			_flush_page_to_ram = r4k_flush_page_to_ram_s128d32i32;
 			break;
 		};
+		_flush_page_to_ram = r4k_flush_page_to_ram_s128;
 		_clear_page = r4k_clear_page_s128;
 		_copy_page = r4k_copy_page_s128;
 		break;
 	}
+	___flush_cache_all = _flush_cache_all;
+	_flush_icache_page = r4k_flush_icache_page_s;
 	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc;
 	_dma_cache_wback = r4k_dma_cache_wback;
 	_dma_cache_inv = r4k_dma_cache_inv_sc;
@@ -2782,13 +2674,17 @@
 
 	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
 
-	set_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+#ifdef CONFIG_MIPS_UNCACHED
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+#else
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+#endif
 
 	probe_icache(config);
 	probe_dcache(config);
 	setup_scache(config);
 
-	switch(mips_cputype) {
+	switch(mips_cpu.cputype) {
 	case CPU_R4600:			/* QED style two way caches? */
 	case CPU_R4700:
 	case CPU_R5000:
@@ -2797,11 +2693,12 @@
 	}
 
 	_flush_cache_sigtramp = r4k_flush_cache_sigtramp;
+	_flush_icache_range = r4k_flush_icache_range;	/* Ouch */
 	if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) {
 		_flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp;
 	}
 
-	flush_cache_all();
+	__flush_cache_all();
 	write_32bit_cp0_register(CP0_WIRED, 0);
 
 	/*
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/r5432.c linux/arch/mips/mm/r5432.c
--- v2.4.6/linux/arch/mips/mm/r5432.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/mm/r5432.c	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,868 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * r5432.c: NEC Vr5432 processor.  We cannot use r4xx0.c because of
+ *      its unique way-selection method for indexed operations.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000 Jun Sun (jsun@mvista.com)
+ *
+ */
+
+/*
+ * [jsun]
+ * In a sense, this is really silly.  We cannot re-use r4xx0.c because
+ * the lowest-level indexed cache operation does not take way-selection
+ * into account.  So all what I am doing here is to copy all the funcs
+ * and macros (in r4kcache.h) relavent to R5432 to this file, and then
+ * modify a few indexed cache operations.  *sigh*
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/bcache.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/mmu_context.h>
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop; nop; nop;\n\t" \
+				     ".set reorder\n\t")
+
+#include <asm/asm.h>
+#include <asm/cacheops.h>
+
+#undef DEBUG_CACHE
+
+/* Primary cache parameters. */
+static int icache_size, dcache_size; /* Size in bytes */
+static int ic_lsize, dc_lsize;       /* LineSize in bytes */
+
+
+/* -------------------------------------------------------------------- */
+/* #include <asm/r4kcache.h> */
+
+extern inline void flush_icache_line_indexed(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n\t"
+		"cache %1, (%0)\n\t"
+		"cache %1, 1(%0)\n\t"
+		".set mips0\n\t"
+		".set reorder"
+		:
+		: "r" (addr),
+		  "i" (Index_Invalidate_I));
+}
+
+extern inline void flush_dcache_line_indexed(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n\t"
+		"cache %1, (%0)\n\t"
+		"cache %1, 1(%0)\n\t"
+		".set mips0\n\t"
+		".set reorder"
+		:
+		: "r" (addr),
+		  "i" (Index_Writeback_Inv_D));
+}
+
+extern inline void flush_icache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n\t"
+		"cache %1, (%0)\n\t"
+		".set mips0\n\t"
+		".set reorder"
+		:
+		: "r" (addr),
+		  "i" (Hit_Invalidate_I));
+}
+
+extern inline void flush_dcache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n\t"
+		"cache %1, (%0)\n\t"
+		".set mips0\n\t"
+		".set reorder"
+		:
+		: "r" (addr),
+		  "i" (Hit_Writeback_Inv_D));
+}
+
+extern inline void invalidate_dcache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n\t"
+		"cache %1, (%0)\n\t"
+		".set mips0\n\t"
+		".set reorder"
+		:
+		: "r" (addr),
+		  "i" (Hit_Invalidate_D));
+}
+
+
+/*
+ * The next two are for badland addresses like signal trampolines.
+ */
+extern inline void protected_flush_icache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n"
+		"1:\tcache %1,(%0)\n"
+		"2:\t.set mips0\n\t"
+		".set reorder\n\t"
+		".section\t__ex_table,\"a\"\n\t"
+		STR(PTR)"\t1b,2b\n\t"
+		".previous"
+		:
+		: "r" (addr),
+		  "i" (Hit_Invalidate_I));
+}
+
+extern inline void protected_writeback_dcache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n"
+		"1:\tcache %1,(%0)\n"
+		"2:\t.set mips0\n\t"
+		".set reorder\n\t"
+		".section\t__ex_table,\"a\"\n\t"
+		STR(PTR)"\t1b,2b\n\t"
+		".previous"
+		:
+		: "r" (addr),
+		  "i" (Hit_Writeback_D));
+}
+
+
+#define cache32_unroll32(base,op)				\
+	__asm__ __volatile__("					\
+		.set noreorder;					\
+		.set mips3;					\
+		cache %1, 0x000(%0); cache %1, 0x020(%0);	\
+		cache %1, 0x040(%0); cache %1, 0x060(%0);	\
+		cache %1, 0x080(%0); cache %1, 0x0a0(%0);	\
+		cache %1, 0x0c0(%0); cache %1, 0x0e0(%0);	\
+		cache %1, 0x100(%0); cache %1, 0x120(%0);	\
+		cache %1, 0x140(%0); cache %1, 0x160(%0);	\
+		cache %1, 0x180(%0); cache %1, 0x1a0(%0);	\
+		cache %1, 0x1c0(%0); cache %1, 0x1e0(%0);	\
+		cache %1, 0x200(%0); cache %1, 0x220(%0);	\
+		cache %1, 0x240(%0); cache %1, 0x260(%0);	\
+		cache %1, 0x280(%0); cache %1, 0x2a0(%0);	\
+		cache %1, 0x2c0(%0); cache %1, 0x2e0(%0);	\
+		cache %1, 0x300(%0); cache %1, 0x320(%0);	\
+		cache %1, 0x340(%0); cache %1, 0x360(%0);	\
+		cache %1, 0x380(%0); cache %1, 0x3a0(%0);	\
+		cache %1, 0x3c0(%0); cache %1, 0x3e0(%0);	\
+		.set mips0;					\
+		.set reorder"					\
+		:						\
+		: "r" (base),					\
+		  "i" (op));
+
+extern inline void blast_dcache32(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + dcache_size/2);
+
+	while(start < end) {
+		cache32_unroll32(start,Index_Writeback_Inv_D);
+		cache32_unroll32(start+1,Index_Writeback_Inv_D);
+		start += 0x400;
+	}
+}
+
+extern inline void blast_dcache32_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache32_unroll32(start,Hit_Writeback_Inv_D);
+		start += 0x400;
+	}
+}
+
+extern inline void blast_dcache32_page_indexed(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache32_unroll32(start,Index_Writeback_Inv_D);
+		cache32_unroll32(start+1,Index_Writeback_Inv_D);
+		start += 0x400;
+	}
+}
+
+extern inline void blast_icache32(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + icache_size/2);
+
+	while(start < end) {
+		cache32_unroll32(start,Index_Invalidate_I);
+		cache32_unroll32(start+1,Index_Invalidate_I);
+		start += 0x400;
+	}
+}
+
+extern inline void blast_icache32_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache32_unroll32(start,Hit_Invalidate_I);
+		start += 0x400;
+	}
+}
+
+extern inline void blast_icache32_page_indexed(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache32_unroll32(start,Index_Invalidate_I);
+		cache32_unroll32(start+1,Index_Invalidate_I);
+		start += 0x400;
+	}
+}
+
+/* -------------------------------------------------------------------- */
+
+static void r5432_clear_page_d32(void * page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		".set\tmips3\n\t"
+		"daddiu\t$1,%0,%2\n"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"cache\t%3,-32(%0)\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tmips0\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_D)
+		:"$1","memory");
+}
+
+
+
+/*
+ * This is still inefficient.  We only can do better if we know the
+ * virtual address where the copy will be accessed.
+ */
+
+static void r5432_copy_page_d32(void * to, void * from)
+{
+	unsigned long dummy1, dummy2;
+	unsigned long reg1, reg2, reg3, reg4;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		".set\tmips3\n\t"
+		"daddiu\t$1,%0,%8\n"
+		"1:\tcache\t%9,(%0)\n\t"
+		"lw\t%2,(%1)\n\t"
+		"lw\t%3,4(%1)\n\t"
+		"lw\t%4,8(%1)\n\t"
+		"lw\t%5,12(%1)\n\t"
+		"sw\t%2,(%0)\n\t"
+		"sw\t%3,4(%0)\n\t"
+		"sw\t%4,8(%0)\n\t"
+		"sw\t%5,12(%0)\n\t"
+		"lw\t%2,16(%1)\n\t"
+		"lw\t%3,20(%1)\n\t"
+		"lw\t%4,24(%1)\n\t"
+		"lw\t%5,28(%1)\n\t"
+		"sw\t%2,16(%0)\n\t"
+		"sw\t%3,20(%0)\n\t"
+		"sw\t%4,24(%0)\n\t"
+		"sw\t%5,28(%0)\n\t"
+		"cache\t%9,32(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"daddiu\t%1,64\n\t"
+		"lw\t%2,-32(%1)\n\t"
+		"lw\t%3,-28(%1)\n\t"
+		"lw\t%4,-24(%1)\n\t"
+		"lw\t%5,-20(%1)\n\t"
+		"sw\t%2,-32(%0)\n\t"
+		"sw\t%3,-28(%0)\n\t"
+		"sw\t%4,-24(%0)\n\t"
+		"sw\t%5,-20(%0)\n\t"
+		"lw\t%2,-16(%1)\n\t"
+		"lw\t%3,-12(%1)\n\t"
+		"lw\t%4,-8(%1)\n\t"
+		"lw\t%5,-4(%1)\n\t"
+		"sw\t%2,-16(%0)\n\t"
+		"sw\t%3,-12(%0)\n\t"
+		"sw\t%4,-8(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sw\t%5,-4(%0)\n\t"
+		".set\tmips0\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2),
+		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
+		:"0" (to), "1" (from),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_D));
+}
+
+
+/*
+ * If you think for one second that this stuff coming up is a lot
+ * of bulky code eating too many kernel cache lines.  Think _again_.
+ *
+ * Consider:
+ * 1) Taken branches have a 3 cycle penalty on R4k
+ * 2) The branch itself is a real dead cycle on even R4600/R5000.
+ * 3) Only one of the following variants of each type is even used by
+ *    the kernel based upon the cache parameters we detect at boot time.
+ *
+ * QED.
+ */
+
+static inline void r5432_flush_cache_all_d32i32(void)
+{
+	blast_dcache32(); blast_icache32();
+}
+
+static void r5432_flush_cache_range_d32i32(struct mm_struct *mm,
+					 unsigned long start,
+					 unsigned long end)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+		blast_dcache32(); blast_icache32();
+	}
+}
+
+/*
+ * On architectures like the Sparc, we could get rid of lines in
+ * the cache created only by a certain context, but on the MIPS
+ * (and actually certain Sparc's) we cannot.
+ */
+static void r5432_flush_cache_mm_d32i32(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r5432_flush_cache_all_d32i32();
+	}
+}
+
+static void r5432_flush_cache_page_d32i32(struct vm_area_struct *vma,
+					unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_PRESENT))
+		return;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+		blast_dcache32_page(page);
+	} else {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (dcache_size - 1)));
+		blast_dcache32_page_indexed(page);
+	}
+}
+
+
+/* If the addresses passed to these routines are valid, they are
+ * either:
+ *
+ * 1) In KSEG0, so we can do a direct flush of the page.
+ * 2) In KSEG2, and since every process can translate those
+ *    addresses all the time in kernel mode we can do a direct
+ *    flush.
+ * 3) In KSEG1, no flush necessary.
+ */
+static void r5432_flush_page_to_ram_d32(struct page *page)
+{
+	blast_dcache32_page((unsigned long)page_address(page));
+}
+
+static void 
+r5432_flush_icache_range(unsigned long start, unsigned long end)
+{
+	r5432_flush_cache_all_d32i32();
+}
+
+/*
+ * Ok, this seriously sucks.  We use them to flush a user page but don't
+ * know the virtual address, so we have to blast away the whole icache
+ * which is significantly more expensive than the real thing.
+ */
+static void
+r5432_flush_icache_page_i32(struct vm_area_struct *vma, struct page *page)
+{
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	r5432_flush_cache_all_d32i32();
+}
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ */
+static void
+r5432_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+	}
+	bc_wback_inv(addr, size);
+}
+
+static void
+r5432_dma_cache_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+	}
+
+	bc_inv(addr, size);
+}
+
+static void
+r5432_dma_cache_wback(unsigned long addr, unsigned long size)
+{
+	panic("r5432_dma_cache called - should not happen.\n");
+}
+
+/*
+ * While we're protected against bad userland addresses we don't care
+ * very much about what happens in that case.  Usually a segmentation
+ * fault will dump the process later on anyway ...
+ */
+static void r5432_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long daddr, iaddr;
+
+	daddr = addr & ~(dc_lsize - 1);
+	protected_writeback_dcache_line(daddr);
+	protected_writeback_dcache_line(daddr + dc_lsize);
+	iaddr = addr & ~(ic_lsize - 1);
+	protected_flush_icache_line(iaddr);
+	protected_flush_icache_line(iaddr + ic_lsize);
+}
+
+#undef DEBUG_TLB
+#undef DEBUG_TLBUPDATE
+
+#define NTLB_ENTRIES       48  /* Fixed on all R4XX0 variants... */
+
+#define NTLB_ENTRIES_HALF  24  /* Fixed on all R4XX0 variants... */
+
+void flush_tlb_all(void)
+{
+	unsigned long old_ctx;
+	int entry;
+	unsigned long flags;
+
+#ifdef DEBUG_TLB
+	printk("[tlball]");
+#endif
+
+	__save_and_cli(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = (get_entryhi() & 0xff);
+	set_entryhi(KSEG0);
+	set_entrylo0(0);
+	set_entrylo1(0);
+	BARRIER;
+
+	entry = get_wired();
+
+	/* Blast 'em all away. */
+	while(entry < NTLB_ENTRIES) {
+		set_index(entry);
+		BARRIER;
+		tlb_write_indexed();
+		BARRIER;
+		entry++;
+	}
+	BARRIER;
+	set_entryhi(old_ctx);
+	__restore_flags(flags);
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_TLB
+		printk("[tlbmm<%d>]", mm->context);
+#endif
+		__save_and_cli(flags);
+		get_new_mmu_context(mm, asid_cache);
+		if (mm == current->active_mm)
+			set_entryhi(mm->context & 0xff);
+		__restore_flags(flags);
+	}
+}
+
+void flush_tlb_range(struct mm_struct *mm, unsigned long start,
+				unsigned long end)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+		int size;
+
+#ifdef DEBUG_TLB
+		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
+		       start, end);
+#endif
+		__save_and_cli(flags);
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		size = (size + 1) >> 1;
+		if(size <= NTLB_ENTRIES_HALF) {
+			int oldpid = (get_entryhi() & 0xff);
+			int newpid = (mm->context & 0xff);
+
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+			while(start < end) {
+				int idx;
+
+				set_entryhi(start | newpid);
+				start += (PAGE_SIZE << 1);
+				BARRIER;
+				tlb_probe();
+				BARRIER;
+				idx = get_index();
+				set_entrylo0(0);
+				set_entrylo1(0);
+				set_entryhi(KSEG0);
+				BARRIER;
+				if(idx < 0)
+					continue;
+				tlb_write_indexed();
+				BARRIER;
+			}
+			set_entryhi(oldpid);
+		} else {
+			get_new_mmu_context(mm, asid_cache);
+			if (mm == current->active_mm)
+				set_entryhi(mm->context & 0xff);
+		}
+		__restore_flags(flags);
+	}
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	if (vma->vm_mm->context != 0) {
+		unsigned long flags;
+		int oldpid, newpid, idx;
+
+#ifdef DEBUG_TLB
+		printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
+#endif
+		newpid = (vma->vm_mm->context & 0xff);
+		page &= (PAGE_MASK << 1);
+		__save_and_cli(flags);
+		oldpid = (get_entryhi() & 0xff);
+		set_entryhi(page | newpid);
+		BARRIER;
+		tlb_probe();
+		BARRIER;
+		idx = get_index();
+		set_entrylo0(0);
+		set_entrylo1(0);
+		set_entryhi(KSEG0);
+		if(idx < 0)
+			goto finish;
+		BARRIER;
+		tlb_write_indexed();
+
+	finish:
+		BARRIER;
+		set_entryhi(oldpid);
+		__restore_flags(flags);
+	}
+}
+
+void pgd_init(unsigned long page)
+{
+	unsigned long *p = (unsigned long *) page;
+	int i;
+
+	for(i = 0; i < USER_PTRS_PER_PGD; i+=8) {
+		p[i + 0] = (unsigned long) invalid_pte_table;
+		p[i + 1] = (unsigned long) invalid_pte_table;
+		p[i + 2] = (unsigned long) invalid_pte_table;
+		p[i + 3] = (unsigned long) invalid_pte_table;
+		p[i + 4] = (unsigned long) invalid_pte_table;
+		p[i + 5] = (unsigned long) invalid_pte_table;
+		p[i + 6] = (unsigned long) invalid_pte_table;
+		p[i + 7] = (unsigned long) invalid_pte_table;
+	}
+}
+
+/* We will need multiple versions of update_mmu_cache(), one that just
+ * updates the TLB with the new pte(s), and another which also checks
+ * for the R4k "end of page" hardware bug and does the needy.
+ */
+void update_mmu_cache(struct vm_area_struct * vma,
+				 unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx, pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	pid = get_entryhi() & 0xff;
+
+#ifdef DEBUG_TLB
+	if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) {
+		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
+		       (int) (vma->vm_mm->context & 0xff), pid);
+	}
+#endif
+
+	__save_and_cli(flags);
+	address &= (PAGE_MASK << 1);
+	set_entryhi(address | (pid));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	BARRIER;
+	tlb_probe();
+	BARRIER;
+	pmdp = pmd_offset(pgdp, address);
+	idx = get_index();
+	ptep = pte_offset(pmdp, address);
+	BARRIER;
+	set_entrylo0(pte_val(*ptep++) >> 6);
+	set_entrylo1(pte_val(*ptep) >> 6);
+	set_entryhi(address | (pid));
+	BARRIER;
+	if(idx < 0) {
+		tlb_write_random();
+	} else {
+		tlb_write_indexed();
+	}
+	BARRIER;
+	set_entryhi(pid);
+	BARRIER;
+	__restore_flags(flags);
+}
+
+void show_regs(struct pt_regs * regs)
+{
+	/* Saved main processor registers. */
+	printk("$0 : %08lx %08lx %08lx %08lx\n",
+	       0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
+	printk("$4 : %08lx %08lx %08lx %08lx\n",
+               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+	printk("$8 : %08lx %08lx %08lx %08lx\n",
+	       regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
+	printk("$12: %08lx %08lx %08lx %08lx\n",
+               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
+	printk("$16: %08lx %08lx %08lx %08lx\n",
+	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
+	printk("$20: %08lx %08lx %08lx %08lx\n",
+               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
+	printk("$24: %08lx %08lx\n",
+	       regs->regs[24], regs->regs[25]);
+	printk("$28: %08lx %08lx %08lx %08lx\n",
+	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
+
+	/* Saved cp0 registers. */
+	printk("epc   : %08lx\nStatus: %08lx\nCause : %08lx\n",
+	       regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
+}
+			
+void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+		     unsigned long entryhi, unsigned long pagemask)
+{
+        unsigned long flags;
+        unsigned long wired;
+        unsigned long old_pagemask;
+        unsigned long old_ctx;
+
+        __save_and_cli(flags);
+        /* Save old context and create impossible VPN2 value */
+        old_ctx = (get_entryhi() & 0xff);
+        old_pagemask = get_pagemask();
+        wired = get_wired();
+        set_wired (wired + 1);
+        set_index (wired);
+        BARRIER;    
+        set_pagemask (pagemask);
+        set_entryhi(entryhi);
+        set_entrylo0(entrylo0);
+        set_entrylo1(entrylo1);
+        BARRIER;    
+        tlb_write_indexed();
+        BARRIER;    
+    
+        set_entryhi(old_ctx);
+        BARRIER;    
+        set_pagemask (old_pagemask);
+        flush_tlb_all();    
+        __restore_flags(flags);
+}
+
+/* Detect and size the various r4k caches. */
+static void __init probe_icache(unsigned long config)
+{
+	icache_size = 1 << (12 + ((config >> 9) & 7));
+	ic_lsize = 16 << ((config >> 5) & 1);
+
+	printk("Primary instruction cache %dkb, linesize %d bytes.\n",
+	       icache_size >> 10, ic_lsize);
+}
+
+static void __init probe_dcache(unsigned long config)
+{
+	dcache_size = 1 << (12 + ((config >> 6) & 7));
+	dc_lsize = 16 << ((config >> 4) & 1);
+
+	printk("Primary data cache %dkb, linesize %d bytes.\n",
+	       dcache_size >> 10, dc_lsize);
+}
+
+
+void __init ld_mmu_r5432(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
+
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+
+	probe_icache(config);
+	probe_dcache(config);
+
+	_clear_page = r5432_clear_page_d32;
+	_copy_page = r5432_copy_page_d32;
+	_flush_cache_all = r5432_flush_cache_all_d32i32;
+	___flush_cache_all = r5432_flush_cache_all_d32i32;
+	_flush_page_to_ram = r5432_flush_page_to_ram_d32;
+	_flush_cache_mm = r5432_flush_cache_mm_d32i32;
+	_flush_cache_range = r5432_flush_cache_range_d32i32;
+	_flush_cache_page = r5432_flush_cache_page_d32i32;
+	_flush_icache_page = r5432_flush_icache_page_i32;
+	_dma_cache_wback_inv = r5432_dma_cache_wback_inv_pc;
+	_dma_cache_wback = r5432_dma_cache_wback;
+	_dma_cache_inv = r5432_dma_cache_inv_pc;
+
+	_flush_cache_sigtramp = r5432_flush_cache_sigtramp;
+	_flush_icache_range = r5432_flush_icache_range;	/* Ouch */
+
+	__flush_cache_all();
+	write_32bit_cp0_register(CP0_WIRED, 0);
+
+	/*
+	 * You should never change this register:
+	 *   - On R4600 1.7 the tlbp never hits for pages smaller than
+	 *     the value in the c0_pagemask register.
+	 *   - The entire mm handling assumes the c0_pagemask register to
+	 *     be set for 4kb pages.
+	 */
+	write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
+	flush_tlb_all();
+}
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/rm7k.c linux/arch/mips/mm/rm7k.c
--- v2.4.6/linux/arch/mips/mm/rm7k.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/mm/rm7k.c	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,751 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998 Ralf Baechle ralf@gnu.org
+ *
+ * To do:
+ *
+ *  - this code is a overbloated pig
+ *  - many of the bug workarounds are not efficient at all, but at
+ *    least they are functional ...
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/mmu_context.h>
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop; nop; nop;\n\t" \
+				     ".set reorder\n\t")
+
+/* Primary cache parameters. */
+static int icache_size, dcache_size; /* Size in bytes */
+
+#define ic_lsize	32		/* Fixed to 32 byte on RM7000  */
+#define dc_lsize	32		/* Fixed to 32 byte on RM7000  */
+#define sc_lsize	32		/* Fixed to 32 byte on RM7000  */
+#define tc_pagesize	(32*128)
+
+/* Secondary cache parameters. */
+#define scache_size	(256*1024)	/* Fixed to 256KiB on RM7000 */
+
+#include <asm/cacheops.h>
+#include <asm/r4kcache.h>
+
+int rm7k_tcache_enabled = 0;
+
+/*
+ * Not added to asm/r4kcache.h because it seems to be RM7000-specific.
+ */
+#define Page_Invalidate_T 0x16
+
+static inline void invalidate_tcache_page(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\t\t\t# invalidate_tcache_page\n\t"
+		".set\tmips3\n\t"
+		"cache\t%1, (%0)\n\t"
+		".set\tmips0\n\t"
+		".set\treorder"
+		:
+		: "r" (addr),
+		  "i" (Page_Invalidate_T));
+}
+
+/*
+ * Zero an entire page.  Note that while the RM7000 has a second level cache
+ * it doesn't have a Create_Dirty_Excl_SD operation.
+ */
+static void rm7k_clear_page(void * page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		".set\tmips3\n\t"
+		"daddiu\t$1,%0,%2\n"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"cache\t%3,-32(%0)\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tmips0\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_D)
+		:"$1","memory");
+}
+
+
+/*
+ * Copy an entire page.  Note that while the RM7000 has a second level cache
+ * it doesn't have a Create_Dirty_Excl_SD operation.
+ */
+static void rm7k_copy_page(void * to, void * from)
+{
+	unsigned long dummy1, dummy2;
+	unsigned long reg1, reg2, reg3, reg4;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		".set\tmips3\n\t"
+		"daddiu\t$1,%0,%8\n"
+		"1:\tcache\t%9,(%0)\n\t"
+		"lw\t%2,(%1)\n\t"
+		"lw\t%3,4(%1)\n\t"
+		"lw\t%4,8(%1)\n\t"
+		"lw\t%5,12(%1)\n\t"
+		"sw\t%2,(%0)\n\t"
+		"sw\t%3,4(%0)\n\t"
+		"sw\t%4,8(%0)\n\t"
+		"sw\t%5,12(%0)\n\t"
+		"lw\t%2,16(%1)\n\t"
+		"lw\t%3,20(%1)\n\t"
+		"lw\t%4,24(%1)\n\t"
+		"lw\t%5,28(%1)\n\t"
+		"sw\t%2,16(%0)\n\t"
+		"sw\t%3,20(%0)\n\t"
+		"sw\t%4,24(%0)\n\t"
+		"sw\t%5,28(%0)\n\t"
+		"cache\t%9,32(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"daddiu\t%1,64\n\t"
+		"lw\t%2,-32(%1)\n\t"
+		"lw\t%3,-28(%1)\n\t"
+		"lw\t%4,-24(%1)\n\t"
+		"lw\t%5,-20(%1)\n\t"
+		"sw\t%2,-32(%0)\n\t"
+		"sw\t%3,-28(%0)\n\t"
+		"sw\t%4,-24(%0)\n\t"
+		"sw\t%5,-20(%0)\n\t"
+		"lw\t%2,-16(%1)\n\t"
+		"lw\t%3,-12(%1)\n\t"
+		"lw\t%4,-8(%1)\n\t"
+		"lw\t%5,-4(%1)\n\t"
+		"sw\t%2,-16(%0)\n\t"
+		"sw\t%3,-12(%0)\n\t"
+		"sw\t%4,-8(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sw\t%5,-4(%0)\n\t"
+		".set\tmips0\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2),
+		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
+		:"0" (to), "1" (from),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_D));
+}
+
+static void __flush_cache_all_d32i32(void)
+{
+	blast_dcache32();
+	blast_icache32();
+}
+
+static inline void rm7k_flush_cache_all_d32i32(void)
+{
+	/* Yes! Caches that don't suck ...  */
+}
+
+static void rm7k_flush_cache_range_d32i32(struct mm_struct *mm,
+					 unsigned long start,
+					 unsigned long end)
+{
+	/* RM7000 caches are sane ...  */
+}
+
+static void rm7k_flush_cache_mm_d32i32(struct mm_struct *mm)
+{
+	/* RM7000 caches are sane ...  */
+}
+
+static void rm7k_flush_cache_page_d32i32(struct vm_area_struct *vma,
+					unsigned long page)
+{
+	/* RM7000 caches are sane ...  */
+}
+
+static void rm7k_flush_page_to_ram_d32i32(struct page * page)
+{
+	/* Yes!  Caches that don't suck!  */
+}
+
+static void rm7k_flush_icache_range(unsigned long start, unsigned long end)
+{
+	/*
+	 * FIXME: This is overdoing things and harms performance.
+	 */
+	__flush_cache_all_d32i32();
+}
+
+static void rm7k_flush_icache_page(struct vm_area_struct *vma,
+                                   struct page *page)
+{
+	/*
+	 * FIXME: We should not flush the entire cache but establish some
+	 * temporary mapping and use hit_invalidate operation to flush out
+	 * the line from the cache.
+	 */
+	__flush_cache_all_d32i32();
+}
+
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ * (XXX These need to be fixed ...)
+ */
+static void
+rm7k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		flush_dcache_line(a);	/* Hit_Writeback_Inv_D */
+		flush_icache_line(a);	/* Hit_Invalidate_I */
+		flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+
+	if (!rm7k_tcache_enabled) 
+		return;
+
+	a = addr & ~(tc_pagesize - 1);
+	end = (addr + size) & ~(tc_pagesize - 1);
+	while(1) {
+		invalidate_tcache_page(a);	/* Page_Invalidate_T */
+		if (a == end) break;
+		a += tc_pagesize;
+	}
+}
+	       
+static void
+rm7k_dma_cache_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		invalidate_dcache_line(a);	/* Hit_Invalidate_D */
+		flush_icache_line(a);		/* Hit_Invalidate_I */
+		invalidate_scache_line(a);	/* Hit_Invalidate_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+
+	if (!rm7k_tcache_enabled) 
+		return;
+
+	a = addr & ~(tc_pagesize - 1);
+	end = (addr + size) & ~(tc_pagesize - 1);
+	while(1) {
+		invalidate_tcache_page(a);	/* Page_Invalidate_T */
+		if (a == end) break;
+		a += tc_pagesize;
+	}
+}
+
+static void
+rm7k_dma_cache_wback(unsigned long addr, unsigned long size)
+{
+	panic("rm7k_dma_cache_wback called - should not happen.\n");
+}
+
+/*
+ * While we're protected against bad userland addresses we don't care
+ * very much about what happens in that case.  Usually a segmentation
+ * fault will dump the process later on anyway ...
+ */
+static void rm7k_flush_cache_sigtramp(unsigned long addr)
+{
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+}
+
+/*
+ * Undocumented RM7000:  Bit 29 in the info register of the RM7000 v2.0
+ * indicates if the TLB has 48 or 64 entries.
+ *
+ * 29      1 =>    64 entry JTLB
+ *         0 =>    48 entry JTLB
+ */
+static inline int __attribute__((const)) ntlb_entries(void)
+{
+	if (get_info() & (1 << 29))
+		return 64;
+
+	return 48;
+}
+
+void flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	int entry;
+
+	__save_and_cli(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = get_entryhi() & 0xff;
+	set_entryhi(KSEG0);
+	set_entrylo0(0);
+	set_entrylo1(0);
+	BARRIER;
+
+	entry = get_wired();
+
+	/* Blast 'em all away. */
+	while (entry < ntlb_entries()) {
+		set_index(entry);
+		BARRIER;
+		tlb_write_indexed();
+		BARRIER;
+		entry++;
+	}
+	BARRIER;
+	set_entryhi(old_ctx);
+	__restore_flags(flags);
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+
+		__save_and_cli(flags);
+		get_new_mmu_context(mm, asid_cache);
+		if (mm == current->mm)
+			set_entryhi(mm->context & 0xff);
+		__restore_flags(flags);
+	}
+}
+
+void flush_tlb_range(struct mm_struct *mm, unsigned long start,
+				unsigned long end)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+		int size;
+
+		__save_and_cli(flags);
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		size = (size + 1) >> 1;
+		if (size <= (ntlb_entries() / 2)) {
+			int oldpid = (get_entryhi() & 0xff);
+			int newpid = (mm->context & 0xff);
+
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+			while(start < end) {
+				int idx;
+
+				set_entryhi(start | newpid);
+				start += (PAGE_SIZE << 1);
+				BARRIER;
+				tlb_probe();
+				BARRIER;
+				idx = get_index();
+				set_entrylo0(0);
+				set_entrylo1(0);
+				set_entryhi(KSEG0);
+				BARRIER;
+				if(idx < 0)
+					continue;
+				tlb_write_indexed();
+				BARRIER;
+			}
+			set_entryhi(oldpid);
+		} else {
+			get_new_mmu_context(mm, asid_cache);
+			if(mm == current->mm)
+				set_entryhi(mm->context & 0xff);
+		}
+		__restore_flags(flags);
+	}
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	if(vma->vm_mm->context != 0) {
+		unsigned long flags;
+		int oldpid, newpid, idx;
+
+		newpid = (vma->vm_mm->context & 0xff);
+		page &= (PAGE_MASK << 1);
+		__save_and_cli(flags);
+		oldpid = (get_entryhi() & 0xff);
+		set_entryhi(page | newpid);
+		BARRIER;
+		tlb_probe();
+		BARRIER;
+		idx = get_index();
+		set_entrylo0(0);
+		set_entrylo1(0);
+		set_entryhi(KSEG0);
+		if(idx < 0)
+			goto finish;
+		BARRIER;
+		tlb_write_indexed();
+
+	finish:
+		BARRIER;
+		set_entryhi(oldpid);
+		__restore_flags(flags);
+	}
+}
+
+void pgd_init(unsigned long page)
+{
+	unsigned long *p = (unsigned long *) page;
+	int i;
+
+	for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
+		p[i + 0] = (unsigned long) invalid_pte_table;
+		p[i + 1] = (unsigned long) invalid_pte_table;
+		p[i + 2] = (unsigned long) invalid_pte_table;
+		p[i + 3] = (unsigned long) invalid_pte_table;
+		p[i + 4] = (unsigned long) invalid_pte_table;
+		p[i + 5] = (unsigned long) invalid_pte_table;
+		p[i + 6] = (unsigned long) invalid_pte_table;
+		p[i + 7] = (unsigned long) invalid_pte_table;
+	}
+}
+
+/*
+ * We will need multiple versions of update_mmu_cache(), one that just
+ * updates the TLB with the new pte(s), and another which also checks
+ * for the R4k "end of page" hardware bug and does the needy.
+ */
+void update_mmu_cache(struct vm_area_struct * vma,
+				 unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx, pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	pid = get_entryhi() & 0xff;
+
+	__save_and_cli(flags);
+	address &= (PAGE_MASK << 1);
+	set_entryhi(address | (pid));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	BARRIER;
+	tlb_probe();
+	BARRIER;
+	pmdp = pmd_offset(pgdp, address);
+	idx = get_index();
+	ptep = pte_offset(pmdp, address);
+	BARRIER;
+	set_entrylo0(pte_val(*ptep++) >> 6);
+	set_entrylo1(pte_val(*ptep) >> 6);
+	set_entryhi(address | (pid));
+	BARRIER;
+	if (idx < 0) {
+		tlb_write_random();
+	} else {
+		tlb_write_indexed();
+	}
+	BARRIER;
+	set_entryhi(pid);
+	BARRIER;
+	__restore_flags(flags);
+}
+
+void show_regs(struct pt_regs * regs)
+{
+	/* Saved main processor registers. */
+	printk(KERN_INFO "$0 : %08lx %08lx %08lx %08lx\n",
+	       0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
+	printk(KERN_INFO "$4 : %08lx %08lx %08lx %08lx\n",
+               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+	printk(KERN_INFO "$8 : %08lx %08lx %08lx %08lx\n",
+	       regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
+	printk(KERN_INFO "$12: %08lx %08lx %08lx %08lx\n",
+               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
+	printk(KERN_INFO "$16: %08lx %08lx %08lx %08lx\n",
+	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
+	printk(KERN_INFO "$20: %08lx %08lx %08lx %08lx\n",
+               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
+	printk(KERN_INFO "$24: %08lx %08lx\n",
+	       regs->regs[24], regs->regs[25]);
+	printk(KERN_INFO "$28: %08lx %08lx %08lx %08lx\n",
+	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
+
+	/* Saved cp0 registers. */
+	printk(KERN_INFO "epc   : %08lx\nStatus: %08lx\nCause : %08lx\n",
+	       regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
+}
+
+void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+                     unsigned long entryhi, unsigned long pagemask)
+{
+        unsigned long flags;
+        unsigned long wired;
+        unsigned long old_pagemask;
+        unsigned long old_ctx;
+
+        __save_and_cli(flags);
+        /* Save old context and create impossible VPN2 value */
+        old_ctx = (get_entryhi() & 0xff);
+        old_pagemask = get_pagemask();
+        wired = get_wired();
+        set_wired (wired + 1);
+        set_index (wired);
+        BARRIER;    
+        set_pagemask (pagemask);
+        set_entryhi(entryhi);
+        set_entrylo0(entrylo0);
+        set_entrylo1(entrylo1);
+        BARRIER;    
+        tlb_write_indexed();
+        BARRIER;    
+    
+        set_entryhi(old_ctx);
+        BARRIER;    
+        set_pagemask (old_pagemask);
+        flush_tlb_all();    
+        __restore_flags(flags);
+}
+
+/* Used for loading TLB entries before trap_init() has started, when we
+   don't actually want to add a wired entry which remains throughout the
+   lifetime of the system */
+
+static int temp_tlb_entry __initdata;
+
+__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
+                               unsigned long entryhi, unsigned long pagemask)
+{
+	int ret = 0;
+        unsigned long flags;
+        unsigned long wired;
+        unsigned long old_pagemask;
+        unsigned long old_ctx;
+
+        __save_and_cli(flags);
+        /* Save old context and create impossible VPN2 value */
+        old_ctx = (get_entryhi() & 0xff);
+        old_pagemask = get_pagemask();
+        wired = get_wired();
+        if (--temp_tlb_entry < wired) {
+		printk(KERN_WARNING "No TLB space left for add_temporary_entry\n");
+		ret = -ENOSPC;
+		goto out;
+	}
+
+        set_index (temp_tlb_entry);
+        BARRIER;    
+        set_pagemask (pagemask);
+        set_entryhi(entryhi);
+        set_entrylo0(entrylo0);
+        set_entrylo1(entrylo1);
+        BARRIER;    
+        tlb_write_indexed();
+        BARRIER;    
+    
+        set_entryhi(old_ctx);
+        BARRIER;    
+        set_pagemask (old_pagemask);
+ out:
+        __restore_flags(flags);
+	return ret;
+}
+
+
+
+/* Detect and size the caches. */
+static inline void probe_icache(unsigned long config)
+{
+	icache_size = 1 << (12 + ((config >> 9) & 7));
+
+	printk(KERN_INFO "Primary instruction cache %dKiB.\n", icache_size >> 10);
+}
+
+static inline void probe_dcache(unsigned long config)
+{
+	dcache_size = 1 << (12 + ((config >> 6) & 7));
+
+	printk(KERN_INFO "Primary data cache %dKiB.\n", dcache_size >> 10);
+}
+
+
+/* 
+ * This function is executed in the uncached segment KSEG1.
+ * It must not touch the stack, because the stack pointer still points
+ * into KSEG0. 
+ *
+ * Three options:
+ *	- Write it in assembly and guarantee that we don't use the stack.
+ *	- Disable caching for KSEG0 before calling it.
+ *	- Pray that GCC doesn't randomly start using the stack.
+ *
+ * This being Linux, we obviously take the least sane of those options -
+ * following DaveM's lead in r4xx0.c
+ *
+ * It seems we get our kicks from relying on unguaranteed behaviour in GCC
+ */
+static __init void setup_scache(void)
+{
+	int register i;
+	
+	set_cp0_config(1<<3 /* CONF_SE */);
+
+	set_taglo(0);
+	set_taghi(0);
+	
+	for (i=0; i<scache_size; i+=sc_lsize) {
+		__asm__ __volatile__ (
+		      ".set noreorder\n\t"
+		      ".set mips3\n\t"
+		      "cache %1, (%0)\n\t"
+		      ".set mips0\n\t"
+		      ".set reorder"
+		      :
+		      : "r" (KSEG0ADDR(i)),
+		        "i" (Index_Store_Tag_SD));
+	}
+
+}
+
+static inline void probe_scache(unsigned long config)
+{
+	void (*func)(void) = KSEG1ADDR(&setup_scache);
+
+	if ((config >> 31) & 1)
+		return;
+
+	printk(KERN_INFO "Secondary cache %dKiB, linesize %d bytes.\n",
+	       (scache_size >> 10), sc_lsize);
+
+	if ((config >> 3) & 1)
+		return;
+
+	printk(KERN_INFO "Enabling secondary cache...");
+	func();
+	printk("Done\n");
+}
+ 
+static inline void probe_tcache(unsigned long config)
+{
+	if ((config >> 17) & 1)
+		return;
+
+	/* We can't enable the L3 cache yet. There may be board-specific
+	 * magic necessary to turn it on, and blindly asking the CPU to
+	 * start using it would may give cache errors.
+	 *
+	 * Also, board-specific knowledge may allow us to use the 
+	 * CACHE Flash_Invalidate_T instruction if the tag RAM supports
+	 * it, and may specify the size of the L3 cache so we don't have
+	 * to probe it. 
+	 */
+	printk(KERN_INFO "Tertiary cache present, %s enabled\n",
+	       config&(1<<12) ? "already" : "not (yet)");
+
+	if ((config >> 12) & 1)
+		rm7k_tcache_enabled = 1;
+}
+
+void __init ld_mmu_rm7k(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+	unsigned long addr;
+
+	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
+
+        change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+
+	/* RM7000 erratum #31. The icache is screwed at startup. */
+	set_taglo(0);
+	set_taghi(0);
+	for (addr = KSEG0; addr <= KSEG0 + 4096; addr += ic_lsize) {
+		__asm__ __volatile__ (
+			".set noreorder\n\t"
+			".set mips3\n\t"
+			"cache\t%1, 0(%0)\n\t"
+			"cache\t%1, 0x1000(%0)\n\t"
+			"cache\t%1, 0x2000(%0)\n\t"
+			"cache\t%1, 0x3000(%0)\n\t"
+			"cache\t%2, 0(%0)\n\t"
+			"cache\t%2, 0x1000(%0)\n\t"
+			"cache\t%2, 0x2000(%0)\n\t"
+			"cache\t%2, 0x3000(%0)\n\t"
+			"cache\t%1, 0(%0)\n\t"
+			"cache\t%1, 0x1000(%0)\n\t"
+			"cache\t%1, 0x2000(%0)\n\t"
+			"cache\t%1, 0x3000(%0)\n\t"
+			".set\tmips0\n\t"
+			".set\treorder\n\t"
+			:
+			: "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill));
+	}
+
+#ifndef CONFIG_MIPS_UNCACHED
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+#endif
+
+	probe_icache(config);
+	probe_dcache(config);
+	probe_scache(config);
+	probe_tcache(config);
+
+	printk("TLB has %d entries.\n", ntlb_entries());
+
+	_clear_page = rm7k_clear_page;
+	_copy_page = rm7k_copy_page;
+
+	_flush_cache_all = rm7k_flush_cache_all_d32i32;
+	___flush_cache_all = __flush_cache_all_d32i32;
+	_flush_cache_mm = rm7k_flush_cache_mm_d32i32;
+	_flush_cache_range = rm7k_flush_cache_range_d32i32;
+	_flush_cache_page = rm7k_flush_cache_page_d32i32;
+	_flush_page_to_ram = rm7k_flush_page_to_ram_d32i32;
+	_flush_cache_sigtramp = rm7k_flush_cache_sigtramp;
+	_flush_icache_range = rm7k_flush_icache_range;
+	_flush_icache_page = rm7k_flush_icache_page;
+
+	_dma_cache_wback_inv = rm7k_dma_cache_wback_inv;
+	_dma_cache_wback = rm7k_dma_cache_wback;
+	_dma_cache_inv = rm7k_dma_cache_inv;
+
+	__flush_cache_all_d32i32();
+	write_32bit_cp0_register(CP0_WIRED, 0);
+	temp_tlb_entry = ntlb_entries() - 1;
+	write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
+	flush_tlb_all();
+}
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/sb1.c linux/arch/mips/mm/sb1.c
--- v2.4.6/linux/arch/mips/mm/sb1.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/mm/sb1.c	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000 Sibyte
+ * 
+ * Written by Justin Carlson (carlson@sibyte.com)
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */ 
+
+
+/*
+ * In this entire file, I'm not sure what the role of the L2 on the sb1250 
+ * is.  Since it is coherent to the system, we should never need to flush
+ * it...right?...right???  -JDC
+ */
+
+#include <asm/mmu_context.h>
+
+/* These are probed at ld_mmu time */
+static unsigned int icache_size;
+static unsigned int dcache_size;
+
+static unsigned int icache_line_size;
+static unsigned int dcache_line_size;
+
+static unsigned int icache_assoc;
+static unsigned int dcache_assoc;
+
+static unsigned int icache_sets;
+static unsigned int dcache_sets;
+static unsigned int tlb_entries;
+
+void pgd_init(unsigned long page)
+{
+	unsigned long *p = (unsigned long *) page;
+	int i;
+
+	for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
+		p[i + 0] = (unsigned long) invalid_pte_table;
+		p[i + 1] = (unsigned long) invalid_pte_table;
+		p[i + 2] = (unsigned long) invalid_pte_table;
+		p[i + 3] = (unsigned long) invalid_pte_table;
+		p[i + 4] = (unsigned long) invalid_pte_table;
+		p[i + 5] = (unsigned long) invalid_pte_table;
+		p[i + 6] = (unsigned long) invalid_pte_table;
+		p[i + 7] = (unsigned long) invalid_pte_table;
+	}
+}
+
+void flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	int entry;
+
+	__save_and_cli(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = (get_entryhi() & 0xff);
+	set_entrylo0(0);
+	set_entrylo1(0);
+	for (entry = 0; entry < tlb_entries; entry++) {
+		set_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry);
+		set_index(entry);
+		tlb_write_indexed();
+	}
+	set_entryhi(old_ctx);
+	__restore_flags(flags);	
+}
+
+
+
+/* These are the functions hooked by the memory management function pointers */
+static void sb1_clear_page(void *page)
+{
+	/* JDCXXX - This should be bottlenecked by the write buffer, but these
+	   things tend to be mildly unpredictable...should check this on the
+	   performance model */
+
+	/* We prefetch 4 lines ahead.  We're also "cheating" slightly here...
+	   since we know we're on an SB1, we force the assembler to take 
+	   64-bit operands to speed things up */
+	__asm__ __volatile__(
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     addiu     $1, %0, %2  \n"  /* Calculate the end of the page to clear */
+		"     pref       5,  0(%0)  \n"  /* Prefetch the first 4 lines */
+		"     pref       5, 32(%0)  \n"  
+		"     pref       5, 64(%0)  \n"  
+		"     pref       5, 96(%0)  \n"  
+		"1:   sd        $0,  0(%0)  \n"  /* Throw out a cacheline of 0's */
+		"     sd        $0,  8(%0)  \n"
+		"     sd        $0, 16(%0)  \n"
+		"     sd        $0, 24(%0)  \n"
+		"     pref       5,128(%0)  \n"  /* Prefetch 4 lines ahead     */
+		"     bne       $1, %0, 1b  \n"
+		"     addiu     %0, %0, 32  \n"  /* Next cacheline (This instruction better be short piped!) */
+		".set pop                   \n"
+		:"=r" (page)
+		:"0" (page),
+		 "I" (PAGE_SIZE-32)
+		:"$1","memory");
+
+}
+
+static void sb1_copy_page(void *to, void *from)
+{
+
+	/* This should be optimized in assembly...can't use ld/sd, though,
+	 * because the top 32 bits could be nuked if we took an interrupt
+	 * during the routine.  And this is not a good place to be cli()'ing
+	 */
+
+	/* The pref's used here are using "streaming" hints, which cause the
+	 * copied data to be kicked out of the cache sooner.  A page copy often
+	 * ends up copying a lot more data than is commonly used, so this seems
+	 * to make sense in terms of reducing cache pollution, but I've no real
+	 * performance data to back this up
+	 */ 
+
+	__asm__ __volatile__(
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     addiu     $1, %0, %4  \n"  /* Calculate the end of the page to copy */
+		"     pref       4,  0(%0)  \n"  /* Prefetch the first 3 lines to be read and copied */
+		"     pref       5,  0(%1)  \n"  
+		"     pref       4, 32(%0)  \n"  
+		"     pref       5, 32(%1)  \n"  
+		"     pref       4, 64(%0)  \n"  
+		"     pref       5, 64(%1)  \n"  
+		"1:   lw        $2,  0(%0)  \n"  /* Block copy a cacheline */
+		"     lw        $3,  4(%0)  \n"
+		"     lw        $4,  8(%0)  \n"
+		"     lw        $5, 12(%0)  \n"
+		"     lw        $6, 16(%0)  \n"
+		"     lw        $7, 20(%0)  \n"
+		"     lw        $8, 24(%0)  \n"
+		"     lw        $9, 28(%0)  \n"
+		"     pref       4, 96(%0)  \n"  /* Prefetch ahead         */
+		"     pref       5, 96(%1)  \n"
+		"     sw        $2,  0(%1)  \n"  
+		"     sw        $3,  4(%1)  \n"
+		"     sw        $4,  8(%1)  \n"
+		"     sw        $5, 12(%1)  \n"
+		"     sw        $6, 16(%1)  \n"
+		"     sw        $7, 20(%1)  \n"
+		"     sw        $8, 24(%1)  \n"
+		"     sw        $9, 28(%1)  \n"		
+		"     addiu     %1, %1, 32  \n"  /* Next cacheline */
+		"     nop                   \n"  /* Force next add to short pipe */
+		"     nop                   \n"  /* Force next add to short pipe */
+		"     bne       $1, %0, 1b  \n"
+		"     addiu     %0, %0, 32  \n"  /* Next cacheline */
+		".set pop                   \n" 
+		:"=r" (to),
+		"=r" (from)
+		:
+		"0" (from),
+		"1" (to),
+		"I" (PAGE_SIZE-32)
+		:"$1","$2","$3","$4","$5","$6","$7","$8","$9","memory");
+/*
+	unsigned long *src = from;
+	unsigned long *dest = to;
+	unsigned long *target = (unsigned long *) (((unsigned long)src) + PAGE_SIZE);
+	while (src != target) {
+		*dest++ = *src++;
+	}
+*/
+}
+
+/*
+ * The dcache is fully coherent to the system, with one
+ * big caveat:  the instruction stream.  In other words,
+ * if we miss in the icache, and have dirty data in the
+ * L1 dcache, then we'll go out to memory (or the L2) and
+ * get the not-as-recent data.
+ * 
+ * So the only time we have to flush the dcache is when
+ * we're flushing the icache.  Since the L2 is fully
+ * coherent to everything, including I/O, we never have
+ * to flush it
+ */
+
+static void sb1_flush_cache_all(void)
+{
+
+	/*
+	 * Haven't worried too much about speed here; given that we're flushing
+	 * the icache, the time to invalidate is dwarfed by the time it's going
+	 * to take to refill it.  Register usage:
+	 * 
+	 * $1 - moving cache index
+	 * $2 - set count
+	 */
+	if (icache_sets) { 
+		__asm__ __volatile__ (
+			".set push                  \n"
+			".set noreorder             \n"
+			".set noat                  \n"
+			".set mips4                 \n"
+			"     move   $1, %2         \n" /* Start at index 0 */
+                        "1:   cache  0, 0($1)       \n" /* Invalidate this index */
+			"     addiu  %1, %1, -1     \n" /* Decrement loop count */
+			"     bnez   %1, 1b         \n" /* loop test */
+			"     addu   $1, $1, %0     \n" /* Next address JDCXXX - Should be short piped */
+			".set pop                   \n"
+			::"r" (icache_line_size),
+			"r" (icache_sets * icache_assoc),
+			"r" (KSEG0)
+			:"$1");
+	}
+	if (dcache_sets) {
+		__asm__ __volatile__ (
+			".set push                  \n"
+			".set noreorder             \n"
+			".set noat                  \n"
+			".set mips4                 \n"
+			"     move   $1, %2         \n" /* Start at index 0 */
+                        "1:   cache  0x1, 0($1)     \n" /* WB/Invalidate this index */
+			"     addiu  %1, %1, -1     \n" /* Decrement loop count */
+			"     bnez   %1, 1b         \n" /* loop test */
+			"     addu   $1, $1, %0     \n" /* Next address JDCXXX - Should be short piped */
+			".set pop                   \n"
+			::"r" (dcache_line_size),
+			"r" (dcache_sets * dcache_assoc),
+			"r" (KSEG0)
+			:"$1");
+	}
+}
+
+/*
+ * When flushing a range in the icache, we have to first writeback
+ * the dcache for the same range, so new ifetches will see any
+ * data that was dirty in the dcache
+ */
+
+static void sb1_flush_icache_range(unsigned long start, unsigned long end)
+{
+	
+	/* JDCXXX - Implement me! */
+	sb1_flush_cache_all();
+}
+
+static void sb1_flush_cache_mm(struct mm_struct *mm)
+{
+	/* Don't need to do this, as the dcache is physically tagged */
+}
+
+static void sb1_flush_cache_range(struct mm_struct *mm, 
+				  unsigned long start,
+				  unsigned long end)
+{
+	/* Don't need to do this, as the dcache is physically tagged */
+}
+
+
+static void sb1_flush_cache_sigtramp(unsigned long page)
+{
+	/* JDCXXX - Implement me! */
+	sb1_flush_cache_all();
+}
+
+
+/*
+ * This only needs to make sure stores done up to this
+ * point are visible to other agents outside the CPU.  Given 
+ * the coherent nature of the ZBus, all that's required here is 
+ * a sync to make sure the data gets out to the caches and is
+ * visible to an arbitrary A Phase from an external agent 
+ *   
+ * Actually, I'm not even sure that's necessary; the semantics
+ * of this function aren't clear.  If it's supposed to serve as
+ * a memory barrier, this is needed.  If it's only meant to 
+ * prevent data from being invisible to non-cpu memory accessors
+ * for some indefinite period of time (e.g. in a non-coherent 
+ * dcache) then this function would be a complete nop.
+ */
+static void sb1_flush_page_to_ram(struct page *page)
+{
+	__asm__ __volatile__(
+		"     sync  \n"  /* Short pipe */
+		:::"memory");	
+}
+
+
+/* Cribbed from the r2300 code */
+static void sb1_flush_cache_page(struct vm_area_struct *vma,
+				  unsigned long page)
+{
+	sb1_flush_cache_all();
+#if 0
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long physpage;
+
+	/* No icache flush needed without context; */
+	if (mm->context == 0) 
+		return;  
+
+	/* No icache flush needed if the page isn't executable */
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	physpage = (unsigned long) page_address(page);
+	if (physpage)
+		sb1_flush_icache_range(physpage, physpage + PAGE_SIZE);
+#endif
+}
+
+
+/*
+ *  Cache set values (from the mips64 spec)
+ * 0 - 64
+ * 1 - 128
+ * 2 - 256
+ * 3 - 512
+ * 4 - 1024
+ * 5 - 2048
+ * 6 - 4096
+ * 7 - Reserved
+ */
+static unsigned int decode_cache_sets(unsigned int config_field)
+{
+	if (config_field == 7) {
+		/* JDCXXX - Find a graceful way to abort. */
+		return 0;
+	} 
+
+	return (1<<(config_field + 6));
+}
+
+/*
+ *  Cache line size values (from the mips64 spec)
+ * 0 - No cache present.
+ * 1 - 4 bytes
+ * 2 - 8 bytes
+ * 3 - 16 bytes
+ * 4 - 32 bytes
+ * 5 - 64 bytes
+ * 6 - 128 bytes
+ * 7 - Reserved
+ */
+static unsigned int decode_cache_line_size(unsigned int config_field)
+{
+	if (config_field == 0) {
+		return 0;
+	} else if (config_field == 7) {
+		/* JDCXXX - Find a graceful way to abort. */
+		return 0;
+	} 
+	return (1<<(config_field + 1));
+}
+
+/*
+ * Relevant bits of the config1 register format (from the MIPS32/MIPS64 specs)
+ *
+ * 24:22 Icache sets per way
+ * 21:19 Icache line size
+ * 18:16 Icache Associativity
+ * 15:13 Dcache sets per way
+ * 12:10 Dcache line size
+ * 9:7   Dcache Associativity
+ */
+
+
+static void probe_cache_sizes(void)
+{
+	u32 config1;
+
+	__asm__ __volatile__(
+		".set push                  \n"
+		".set mips64                \n"
+		"     mfc0    %0, $16, 1    \n"  /* Get config1 register */
+		".set pop                   \n"
+		:"=r" (config1));
+	icache_line_size = decode_cache_line_size((config1 >> 19) & 0x7);
+	dcache_line_size = decode_cache_line_size((config1 >> 10) & 0x7);
+	icache_sets = decode_cache_sets((config1 >> 22) & 0x7);
+	dcache_sets = decode_cache_sets((config1 >> 13) & 0x7);
+        icache_assoc = ((config1 >> 16) & 0x7) + 1;
+	dcache_assoc = ((config1 >> 7) & 0x7) + 1;
+	icache_size = icache_line_size * icache_sets * icache_assoc;
+	dcache_size = dcache_line_size * dcache_sets * dcache_assoc;
+	tlb_entries = ((config1 >> 25) & 0x3f) + 1;
+}
+
+
+/* This is called from loadmmu.c.  We have to set up all the
+   memory management function pointers, as well as initialize
+   the caches and tlbs */
+void ld_mmu_sb1(void)
+{
+	probe_cache_sizes();
+
+	_clear_page = sb1_clear_page;
+	_copy_page = sb1_copy_page;
+	
+	_flush_cache_all = sb1_flush_cache_all;
+	_flush_cache_mm = sb1_flush_cache_mm;
+	_flush_cache_range = sb1_flush_cache_range;
+	_flush_cache_page = sb1_flush_cache_page;
+	_flush_cache_sigtramp = sb1_flush_cache_sigtramp;
+
+	_flush_page_to_ram = sb1_flush_page_to_ram;
+	_flush_icache_page = sb1_flush_cache_page;
+	_flush_icache_range = sb1_flush_icache_range;
+
+	
+	/*
+	 * JDCXXX I'm not sure whether these are necessary: is this the right 
+	 * place to initialize the tlb?  If it is, why is it done 
+	 * at this level instead of as common code in loadmmu()?
+	 */
+	flush_cache_all();
+	flush_tlb_all();
+	
+	/* Turn on caching in kseg0 */
+	set_cp0_config(CONF_CM_CMASK, 0);
+}
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/umap.c linux/arch/mips/mm/umap.c
--- v2.4.6/linux/arch/mips/mm/umap.c	Mon Mar 19 12:35:09 2001
+++ linux/arch/mips/mm/umap.c	Wed Jul  4 11:50:39 2001
@@ -1,6 +1,4 @@
 /*
- * arch/mips/mm/umap.c
- *
  * (C) Copyright 1994 Linus Torvalds
  *
  * Changes:
@@ -21,6 +19,7 @@
 #include <linux/shm.h>
 #include <linux/errno.h>
 #include <linux/mman.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
 #include <linux/swap.h>
@@ -106,6 +105,8 @@
 	up_write (&task->mm->mmap_sem);
 }
 
+EXPORT_SYMBOL(remove_mapping);
+
 void *vmalloc_uncached (unsigned long size)
 {
 	return __vmalloc (size, GFP_KERNEL | __GFP_HIGHMEM,
@@ -180,7 +181,7 @@
 		end = PGDIR_SIZE;
 	vaddr -= address;
 	do {
-		pte_t * pte = pte_alloc(pmd, address);
+		pte_t * pte = pte_alloc(current->mm, pmd, address);
 		if (!pte)
 			return -ENOMEM;
 		vmap_pte_range(pte, address, end - address, address + vaddr);
@@ -202,7 +203,7 @@
 	dir = pgd_offset(current->mm, from);
 	flush_cache_range(current->mm, beg, end);
 	while (from < end) {
-		pmd_t *pmd = pmd_alloc(dir, from);
+		pmd_t *pmd = pmd_alloc(current->mm, dir, from);
 		error = -ENOMEM;
 		if (!pmd)
 			break;
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/Makefile linux/arch/mips64/Makefile
--- v2.4.6/linux/arch/mips64/Makefile	Sun Feb  4 21:48:46 2001
+++ linux/arch/mips64/Makefile	Wed Jul  4 11:50:38 2001
@@ -64,6 +64,11 @@
 CFLAGS		:= $(CFLAGS) -mcpu=r8000 -mips4
 endif
 
+ifdef CONFIG_MIPS_FPU_EMULATOR
+CORE_FILES	+= arch/mips64/math-emu/fpu_emulator.o
+SUBDIRS		+= arch/mips64/math-emu
+endif
+
 #
 # Board-dependent options and extra files
 #
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/arc/Makefile linux/arch/mips64/arc/Makefile
--- v2.4.6/linux/arch/mips64/arc/Makefile	Sun Feb  4 21:48:46 2001
+++ linux/arch/mips64/arc/Makefile	Wed Jul  4 11:50:39 2001
@@ -3,13 +3,10 @@
 #
 
 L_TARGET = arclib.a
-obj-y	:= init.o printf.o tree.o env.o cmdline.o misc.o time.o file.o \
-	   identify.o
-
-ifndef CONFIG_SGI_IP27
-  obj-y += console.o
-endif
+obj-y	:= console.o init.o identify.o tree.o env.o cmdline.o misc.o time.o \
+	   file.o
 
 obj-$(CONFIG_ARC_MEMORY) += memory.o
+obj-$(CONFIG_ARC_CONSOLE) += arc_con.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/arc/arc_con.c linux/arch/mips64/arc/arc_con.c
--- v2.4.6/linux/arch/mips64/arc/arc_con.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/arc/arc_con.c	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,78 @@
+/*
+ * Wrap-around code for a console using the
+ * ARC io-routines.
+ *
+ * Copyright (c) 1998 Harald Koerfgen 
+ * Copyright (c) 2001 Ralf Baechle
+ */
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/ptrace.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/fs.h>
+
+#include <asm/sgialib.h>
+
+extern void prom_printf (char *, ...);
+
+void prom_putchar(char c)
+{
+	ULONG cnt;
+	CHAR it = c;
+
+	ArcWrite(1, &it, 1, &cnt);
+}
+
+static void prom_console_write(struct console *co, const char *s,
+			       unsigned count)
+{
+	unsigned i;
+
+	/*
+	 *    Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		if (*s == 10)
+			prom_printf("%c", 13);
+		prom_printf("%c", *s++);
+	}
+}
+
+static int prom_console_wait_key(struct console *co)
+{
+	return 0;
+}
+
+static int __init prom_console_setup(struct console *co, char *options)
+{
+	return 0;
+}
+
+static kdev_t prom_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static struct console arc_cons = {
+	"ttyS",
+	prom_console_write,
+	NULL,
+	prom_console_device,
+	prom_console_wait_key,
+	NULL,
+	prom_console_setup,
+	CON_PRINTBUFFER,
+	-1,
+	0,
+	NULL
+};
+
+/*
+ *    Register console.
+ */
+
+void __init arc_console_init(void)
+{
+	register_console(&arc_cons);
+}
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/arc/cmdline.c linux/arch/mips64/arc/cmdline.c
--- v2.4.6/linux/arch/mips64/arc/cmdline.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/arc/cmdline.c	Wed Jul  4 11:50:39 2001
@@ -1,5 +1,4 @@
-/* $Id: cmdline.c,v 1.2 1999/10/19 20:51:44 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -30,10 +29,49 @@
 	"SystemPartition=",
 	"OSLoader=",
 	"OSLoadPartition=",
-	"OSLoadFilename="
+	"OSLoadFilename=",
+	"OSLoadOptions="
 };
 #define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0])))))
 
+static char *used_arc[][2] = {
+	{ "OSLoadPartition=", "root=" },
+	{ "OSLoadOptions=", "" }
+};
+
+static char * __init move_firmware_args(char* cp)
+{
+	char *s;
+	int actr, i;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	while (actr < prom_argc) {
+		for(i = 0; i < NENTS(used_arc); i++) {
+			int len = strlen(used_arc[i][0]);
+
+			if (!strncmp(prom_argv(actr), used_arc[i][0], len)) {
+			/* Ok, we want it. First append the replacement... */
+				strcat(cp, used_arc[i][1]);
+				cp += strlen(used_arc[i][1]);
+				/* ... and now the argument */
+				s = strstr(prom_argv(actr), "=");
+				if (s) {
+					s++;
+					strcpy(cp, s);
+					cp += strlen(s);
+				}
+				*cp++ = ' ';
+				break;
+			}
+		}
+		actr++;
+	}
+
+	return cp;
+}
+
+
 void __init prom_init_cmdline(void)
 {
 	char *cp;
@@ -42,11 +80,17 @@
 	actr = 1; /* Always ignore argv[0] */
 
 	cp = &(arcs_cmdline[0]);
-	while(actr < prom_argc) {
-		for(i = 0; i < NENTS(ignored); i++) {
+	/* 
+	 * Move ARC variables to the beginning to make sure they can be
+	 * overridden by later arguments.
+	 */
+	cp = move_firmware_args(cp);
+
+	while (actr < prom_argc) {
+		for (i = 0; i < NENTS(ignored); i++) {
 			int len = strlen(ignored[i]);
 
-			if(!strncmp(prom_argv(actr), ignored[i], len))
+			if (!strncmp(prom_argv(actr), ignored[i], len))
 				goto pic_cont;
 		}
 		/* Ok, we want it. */
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/arc/console.c linux/arch/mips64/arc/console.c
--- v2.4.6/linux/arch/mips64/arc/console.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/arc/console.c	Wed Jul  4 11:50:39 2001
@@ -6,22 +6,28 @@
  * Copyright (C) 1996 David S. Miller (dm@sgi.com)
  */
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <asm/sgialib.h>
 
-void prom_putchar(char c)
+static char ppbuf[1024];
+
+void prom_printf(char *fmt, ...)
 {
-	ULONG cnt;
-	CHAR it = c;
+	va_list args;
+	char ch, *bptr;
+	int i;
 
-	ArcWrite(1, &it, 1, &cnt);
-}
+	va_start(args, fmt);
+	i = vsprintf(ppbuf, fmt, args);
 
-char __init prom_getchar(void)
-{
-	ULONG cnt;
-	CHAR c;
+	bptr = ppbuf;
 
-	ArcRead(0, &c, 1, &cnt);
+	while((ch = *(bptr++)) != 0) {
+		if(ch == '\n')
+			prom_putchar('\r');
 
-	return c;
+		prom_putchar(ch);
+	}
+	va_end(args);
+	return;
 }
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/arc/identify.c linux/arch/mips64/arc/identify.c
--- v2.4.6/linux/arch/mips64/arc/identify.c	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips64/arc/identify.c	Wed Jul  4 11:50:39 2001
@@ -42,14 +42,11 @@
 {
 	int i;
     
-	for (i = 0; i < sizeof (mach_table); i++) {
+	for (i = 0; i < (sizeof (mach_table) / sizeof (mach_table[0])); i++) {
 		if(!strcmp(s, mach_table[i].name))
 			return &mach_table[i];
 	}
-	prom_printf("\nYeee, could not determine architecture type <%s>\n", s);
-	prom_printf("press a key to reboot\n");
-	prom_getchar();
-	ArcEnterInteractiveMode();
+	panic("\nYeee, could not determine architecture type <%s>", s);
 
 	return NULL;
 }
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/arc/memory.c linux/arch/mips64/arc/memory.c
--- v2.4.6/linux/arch/mips64/arc/memory.c	Mon Aug  7 21:02:27 2000
+++ linux/arch/mips64/arc/memory.c	Wed Jul  4 11:50:39 2001
@@ -1,11 +1,9 @@
-/* $Id: memory.c,v 1.5 2000/01/27 23:21:57 ralf Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
+/*
+ * memory.c: PROM library functions for acquiring/using memory descriptors
+ *           given to us from the ARCS firmware.
  *
  * Copyright (C) 1996 by David S. Miller
- * Copyright (C) 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001 by Ralf Baechle
  * Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
  *
  * PROM library functions for acquiring/using memory descriptors given to us
@@ -41,7 +39,7 @@
 	"Free/Contig RAM",
 	"Generic Free RAM",
 	"Bad Memory",
-	"Standlong Program Pages",
+	"Standalone Program Pages",
 	"ARCS Temp Storage Area",
 	"ARCS Permanent Storage Area"
 };
@@ -54,31 +52,25 @@
 	"LoadedProgram",
 	"FirmwareTemporary",
 	"FirmwarePermanent",
-	"FreeContigiuous"
+	"FreeContiguous"
 };
 #define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] : arc_mtypes[a.arc]
 #endif
 
-static struct prom_pmemblock pblocks[PROM_MAX_PMEMBLOCKS];
-
-#define MEMTYPE_DONTUSE   0
-#define MEMTYPE_PROM      1
-#define MEMTYPE_FREE      2
-
 static inline int memtype_classify_arcs (union linux_memtypes type)
 {
 	switch (type.arcs) {
 	case arcs_fcontig:
 	case arcs_free:
-		return MEMTYPE_FREE;
+		return BOOT_MEM_RAM;
 	case arcs_atmp:
-		return MEMTYPE_PROM;
+		return BOOT_MEM_ROM_DATA;
 	case arcs_eblock:
 	case arcs_rvpage:
 	case arcs_bmem:
 	case arcs_prog:
 	case arcs_aperm:
-		return MEMTYPE_DONTUSE;
+		return BOOT_MEM_RESERVED;
 	default:
 		BUG();
 	}
@@ -90,15 +82,15 @@
 	switch (type.arc) {
 	case arc_free:
 	case arc_fcontig:
-		return MEMTYPE_FREE;
+		return BOOT_MEM_RAM;
 	case arc_atmp:
-		return MEMTYPE_PROM;
+		return BOOT_MEM_ROM_DATA;
 	case arc_eblock:
 	case arc_rvpage:
 	case arc_bmem:
 	case arc_prog:
 	case arc_aperm:
-		return MEMTYPE_DONTUSE;
+		return BOOT_MEM_RESERVED;
 	default:
 		BUG();
 	}
@@ -113,52 +105,18 @@
 	return memtype_classify_arc(type);
 }
 
-static inline unsigned long find_max_low_pfn(void)
-{
-	struct prom_pmemblock *p, *highest;
-	unsigned long pfn;
-
-	p = pblocks;
-	highest = 0;
-	while (p->size != 0) {
-		if (!highest || p->base > highest->base)
-			highest = p;
-		p++;
-	}
-
-	pfn = (highest->base + highest->size) >> PAGE_SHIFT;
-#ifdef DEBUG
-	prom_printf("find_max_low_pfn: 0x%lx pfns.\n", pfn);
-#endif
-	return pfn;
-}
-
-static inline struct prom_pmemblock *find_largest_memblock(void)
-{
-	struct prom_pmemblock *p, *largest;
-
-	p = pblocks;
-	largest = 0;
-	while (p->size != 0) {
-		if (!largest || p->size > largest->size)
-			largest = p;
-		p++;
-	}
-
-	return largest;
-}
-
 void __init prom_meminit(void)
 {
-	struct prom_pmemblock *largest;
-	unsigned long bootmap_size;
 	struct linux_mdesc *p;
-	int totram;
-	int i = 0;
 
 #ifdef DEBUG
+	int i = 0;
+
 	prom_printf("ARCS MEMORY DESCRIPTOR dump:\n");
+	i=0;
+	prom_printf ("i=%d\n", i);
 	p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
+	prom_printf ("i=%d\n", i);
 	while(p) {
 		prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
 			    i, p, p->base, p->pages, mtypes(p->type));
@@ -167,56 +125,17 @@
 	}
 #endif
 
-	totram = 0;
-	i = 0;
 	p = PROM_NULL_MDESC;
 	while ((p = ArcGetMemoryDescriptor(p))) {
-		pblocks[i].type = prom_memtype_classify(p->type);
-		pblocks[i].base = p->base << PAGE_SHIFT;
-		pblocks[i].size = p->pages << PAGE_SHIFT;
-
-		switch (pblocks[i].type) {
-		case MEMTYPE_FREE:
-			totram += pblocks[i].size;
-#ifdef DEBUG
-			prom_printf("free_chunk[%d]: base=%08lx size=%x\n",
-				    i, pblocks[i].base,
-				    pblocks[i].size);
-#endif
-			i++;
-			break;
-		case MEMTYPE_PROM:
-#ifdef DEBUG
-			prom_printf("prom_chunk[%d]: base=%08lx size=%x\n",
-				    i, pblocks[i].base,
-				    pblocks[i].size);
-#endif
-			i++;
-			break;
-		default:
-			break;
-		}
-	}
-	pblocks[i].size = 0;
+		unsigned long base, size;
+		long type;
 
-	max_low_pfn = find_max_low_pfn();
-	largest = find_largest_memblock();
-	bootmap_size = init_bootmem(largest->base >> PAGE_SHIFT, max_low_pfn);
-
-	for (i = 0; pblocks[i].size; i++)
-		if (pblocks[i].type == MEMTYPE_FREE)
-			free_bootmem(pblocks[i].base, pblocks[i].size);
-
-	/* This test is simpleminded.  It will fail if the bootmem bitmap
-	   falls into multiple adjacent ARC memory areas.  */
-	if (bootmap_size > largest->size) {
-		prom_printf("CRITIAL: overwriting PROM data.\n");
-		BUG();
-	}
-	reserve_bootmem(largest->base, bootmap_size);
+		base = p->base << PAGE_SHIFT;
+		size = p->pages << PAGE_SHIFT;
+		type = prom_memtype_classify(p->type);
 
-	printk("PROMLIB: Total free ram %dK / %dMB.\n",
-	       totram >> 10, totram >> 20);
+		add_memory_region(base, size, type);
+	}
 }
 
 void __init
@@ -224,18 +143,19 @@
 {
 	struct prom_pmemblock *p;
 	unsigned long freed = 0;
-	unsigned long addr, end;
+	unsigned long addr;
+	int i;
 
-	for (p = pblocks; p->size != 0; p++) {
-		if (p->type != MEMTYPE_PROM)
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
 			continue;
 
-		addr = PAGE_OFFSET + (unsigned long) (long) p->base;
-		end = addr + (unsigned long) (long) p->size;
-		while (addr < end) {
-			ClearPageReserved(virt_to_page(addr));
-			set_page_count(virt_to_page(addr), 1);
-			free_page(addr);
+		addr = boot_mem_map.map[i].addr;
+		while (addr < boot_mem_map.map[i].addr
+			      + boot_mem_map.map[i].size) {
+			ClearPageReserved(virt_to_page(__va(addr)));
+			set_page_count(virt_to_page(__va(addr)), 1);
+			free_page((unsigned long)__va(addr));
 			addr += PAGE_SIZE;
 			freed += PAGE_SIZE;
 		}
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/arc/printf.c linux/arch/mips64/arc/printf.c
--- v2.4.6/linux/arch/mips64/arc/printf.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/arc/printf.c	Wed Dec 31 16:00:00 1969
@@ -1,37 +0,0 @@
-/* $Id: printf.c,v 1.1 1999/08/20 21:13:33 ralf Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Putting things on the screen using SGI arcs PROM facilities.
- *
- * Copyright (C) 1996 David S. Miller (dm@sgi.com)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-#include <asm/sgialib.h>
-
-static char ppbuf[1024];
-
-void prom_printf(char *fmt, ...)
-{
-	va_list args;
-	char ch, *bptr;
-	int i;
-
-	va_start(args, fmt);
-	i = vsprintf(ppbuf, fmt, args);
-
-	bptr = ppbuf;
-
-	while((ch = *(bptr++)) != 0) {
-		if(ch == '\n')
-			prom_putchar('\r');
-
-		prom_putchar(ch);
-	}
-	va_end(args);
-	return;
-}
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/arc/tree.c linux/arch/mips64/arc/tree.c
--- v2.4.6/linux/arch/mips64/arc/tree.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/arc/tree.c	Wed Jul  4 11:50:39 2001
@@ -123,8 +123,6 @@
 		dump_component(p);
 		p = ArcGetPeer(p);
 	}
-	prom_printf("press a key\n");
-	prom_getchar();
 }
 
 #endif /* DEBUG_PROM_TREE  */
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/config.in linux/arch/mips64/config.in
--- v2.4.6/linux/arch/mips64/config.in	Tue Apr 17 17:19:25 2001
+++ linux/arch/mips64/config.in	Wed Jul  4 11:50:39 2001
@@ -11,8 +11,10 @@
 
 mainmenu_option next_comment
 comment 'Machine selection'
-bool 'Support for SGI IP22' CONFIG_SGI_IP22
-bool 'Support for SGI IP27' CONFIG_SGI_IP27
+choice 'Machine type'						\
+	"SGI-IP22,Indy/Indigo2 CONFIG_SGI_IP22			\
+	 SGI-IP27,Origin200/2000 CONFIG_SGI_IP27 SGI-IP27,Origin200/2000"
+
 if [ "$CONFIG_SGI_IP27" = "y" ]; then
    bool '  IP27 N-Mode' CONFIG_SGI_SN0_N_MODE
    bool '  Discontiguous Memory Support' CONFIG_DISCONTIGMEM
@@ -47,6 +49,7 @@
    define_bool CONFIG_BOARD_SCACHE y
    define_bool CONFIG_ARC_MEMORY y
    define_bool CONFIG_SGI y
+   define_int CONFIG_L1_CACHE_SHIFT 5
 fi
 
 if [ "$CONFIG_SGI_IP27" = "y" ]; then
@@ -55,6 +58,7 @@
    define_bool CONFIG_COHERENT_IO y
    define_bool CONFIG_PCI y
    define_bool CONFIG_QL_ISP_A64 y
+   define_int CONFIG_L1_CACHE_SHIFT 7
 fi
 
 if [ "$CONFIG_ISA" != "y" ]; then
@@ -91,6 +95,10 @@
 fi
 bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
 
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   bool 'Kernel floating-point emulation' CONFIG_MIPS_FPU_EMULATOR
+fi
+
 bool 'Networking support' CONFIG_NET
 
 source drivers/pci/Config.in
@@ -106,6 +114,11 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+
+if [ "$CONFIG_ARC32" = "y" ]; then
+   bool 'ARC console support' CONFIG_ARC_CONSOLE
+fi
+
 tristate 'Kernel support for 64-bit ELF binaries' CONFIG_BINFMT_ELF
 bool 'Kernel support for Linux/MIPS 32-bit binary compatibility' CONFIG_MIPS32_COMPAT
 if [ "$CONFIG_MIPS32_COMPAT" = "y" ]; then
@@ -125,14 +138,12 @@
 
 source drivers/pci/Config.in
 
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   bool 'Support for frame buffer devices (EXPERIMENTAL)' CONFIG_FB
-fi
-
 endmenu
 
 source drivers/mtd/Config.in
 
+source drivers/parport/Config.in
+
 source drivers/block/Config.in
 
 source drivers/md/Config.in
@@ -166,7 +177,7 @@
 fi
 endmenu
 
-source drivers/i2o/Config.in
+source drivers/message/i2o/Config.in
 
 if [ "$CONFIG_NET" = "y" ]; then
    mainmenu_option next_comment
@@ -175,16 +186,6 @@
    bool 'Network device support' CONFIG_NETDEVICES
    if [ "$CONFIG_NETDEVICES" = "y" ]; then
       source drivers/net/Config.in
-      if [ "$CONFIG_SGI_IP22" = "y" ]; then
-	 bool 'SGI Seeq ethernet controller support' CONFIG_SGISEEQ
-      fi
-      if [ "$CONFIG_DECSTATION" = "y" ]; then
-	 bool 'DEC LANCE ethernet controller support' CONFIG_DECLANCE
-      fi
-      if [ "$CONFIG_BAGET_MIPS" = "y" ]; then
-	 tristate 'Baget AMD LANCE support' CONFIG_BAGETLANCE
-	 tristate 'Baget Backplane Shared Memory support' CONFIG_BAGETBSM
-      fi
       if [ "$CONFIG_ATM" = "y" ]; then
 	 source drivers/atm/Config.in
       fi
@@ -227,6 +228,7 @@
 if [ "$CONFIG_VT" = "y" ]; then
    mainmenu_option next_comment
    comment 'Console drivers'
+   source drivers/video/Config.in
    if [ "$CONFIG_SGI_IP22" = "y" ]; then
       tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE
       if [ "$CONFIG_SGI_NEWPORT_CONSOLE" != "y" ]; then
@@ -268,4 +270,7 @@
 fi
 bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+if [ "$CONFIG_SMP" != "n" ]; then
+   bool 'Run uncached' CONFIG_MIPS_UNCACHED
+fi
 endmenu
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/defconfig linux/arch/mips64/defconfig
--- v2.4.6/linux/arch/mips64/defconfig	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips64/defconfig	Wed Jul  4 11:50:39 2001
@@ -14,16 +14,19 @@
 CONFIG_SGI_IP27=y
 # CONFIG_SGI_SN0_N_MODE is not set
 CONFIG_DISCONTIGMEM=y
-# CONFIG_NUMA is not set
+CONFIG_NUMA=y
 # CONFIG_MAPPED_KERNEL is not set
 # CONFIG_REPLICATE_KTEXT is not set
 # CONFIG_REPLICATE_EXHANDLERS is not set
 CONFIG_SMP=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF64=y
 CONFIG_ARC64=y
 CONFIG_COHERENT_IO=y
 CONFIG_PCI=y
 CONFIG_QL_ISP_A64=y
+CONFIG_L1_CACHE_SHIFT=7
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
@@ -68,6 +71,11 @@
 # CONFIG_MTD is not set
 
 #
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
@@ -95,19 +103,24 @@
 #
 # Networking options
 #
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 
@@ -187,8 +200,6 @@
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_PPA is not set
-# CONFIG_SCSI_IMM is not set
 # CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_NCR53C8XX is not set
@@ -254,7 +265,6 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
-# CONFIG_PLIP is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 
@@ -302,9 +312,8 @@
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
-# CONFIG_PRINTER is not set
-# CONFIG_PPDEV is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 
 #
 # I2C support
@@ -370,10 +379,12 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -381,7 +392,7 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
@@ -458,3 +469,4 @@
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/defconfig-ip22 linux/arch/mips64/defconfig-ip22
--- v2.4.6/linux/arch/mips64/defconfig-ip22	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips64/defconfig-ip22	Wed Jul  4 11:50:39 2001
@@ -5,18 +5,21 @@
 #
 # Code maturity level options
 #
-# CONFIG_EXPERIMENTAL is not set
+CONFIG_EXPERIMENTAL=y
 
 #
 # Machine selection
 #
 CONFIG_SGI_IP22=y
 # CONFIG_SGI_IP27 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
 CONFIG_ARC32=y
 CONFIG_BOARD_SCACHE=y
 CONFIG_ARC_MEMORY=y
 CONFIG_SGI=y
+CONFIG_L1_CACHE_SHIFT=5
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_PCI is not set
@@ -37,20 +40,25 @@
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_MIPS_FPU_EMULATOR is not set
 CONFIG_NET=y
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+# CONFIG_ARC_CONSOLE is not set
 CONFIG_BINFMT_ELF=y
-# CONFIG_MIPS32_COMPAT is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
 
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
 
 #
 # Memory Technology Devices (MTD)
@@ -58,6 +66,11 @@
 # CONFIG_MTD is not set
 
 #
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
@@ -85,21 +98,30 @@
 #
 # Networking options
 #
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
 
 #
 #  
@@ -108,6 +130,14 @@
 # CONFIG_ATALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
 # QoS and/or fair queueing
@@ -130,7 +160,66 @@
 #
 # SCSI support
 #
-# CONFIG_SCSI is not set
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_SR_EXTRA_DEVS=2
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+CONFIG_SGIWD93_SCSI=y
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
 
 #
 # I2O device support
@@ -154,21 +243,33 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 # CONFIG_NET_SB1000 is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
-# CONFIG_NET_ETHERNET is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+CONFIG_SGISEEQ=y
 
 #
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
 # CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
-# CONFIG_PLIP is not set
+# CONFIG_HIPPI is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 
@@ -182,12 +283,13 @@
 #
 # CONFIG_TR is not set
 # CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
 
 #
 # Wan interfaces
 #
 # CONFIG_WAN is not set
-CONFIG_SGISEEQ=y
 
 #
 # Amateur Radio support
@@ -217,9 +319,8 @@
 # CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
-# CONFIG_PRINTER is not set
-# CONFIG_PPDEV is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 
 #
 # I2C support
@@ -269,8 +370,8 @@
 # File systems
 #
 # CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
@@ -285,10 +386,12 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
 # CONFIG_RAMFS is not set
-# CONFIG_ISO9660_FS is not set
+CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -296,7 +399,7 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
@@ -315,7 +418,7 @@
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
-# CONFIG_NFSD is not set
+CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
@@ -333,14 +436,31 @@
 #
 # Partition Types
 #
-# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
 CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
 # Console drivers
 #
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
 CONFIG_SGI_NEWPORT_CONSOLE=y
 CONFIG_FONT_8x16=y
 CONFIG_KCORE_ELF=y
@@ -353,8 +473,10 @@
 #
 # SGI devices
 #
-# CONFIG_SGI_SERIAL is not set
+CONFIG_SGI_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
 CONFIG_SGI_DS1286=y
+# CONFIG_SGI_NEWPORT_GFX is not set
 
 #
 # USB support
@@ -370,5 +492,7 @@
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
+# CONFIG_MIPS_FPE_MODULE is not set
 # CONFIG_REMOTE_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/defconfig-ip27 linux/arch/mips64/defconfig-ip27
--- v2.4.6/linux/arch/mips64/defconfig-ip27	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips64/defconfig-ip27	Wed Jul  4 11:50:39 2001
@@ -14,16 +14,19 @@
 CONFIG_SGI_IP27=y
 # CONFIG_SGI_SN0_N_MODE is not set
 CONFIG_DISCONTIGMEM=y
-# CONFIG_NUMA is not set
+CONFIG_NUMA=y
 # CONFIG_MAPPED_KERNEL is not set
 # CONFIG_REPLICATE_KTEXT is not set
 # CONFIG_REPLICATE_EXHANDLERS is not set
 CONFIG_SMP=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF64=y
 CONFIG_ARC64=y
 CONFIG_COHERENT_IO=y
 CONFIG_PCI=y
 CONFIG_QL_ISP_A64=y
+CONFIG_L1_CACHE_SHIFT=7
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
@@ -68,6 +71,11 @@
 # CONFIG_MTD is not set
 
 #
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
@@ -95,19 +103,24 @@
 #
 # Networking options
 #
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 
@@ -187,8 +200,6 @@
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_PPA is not set
-# CONFIG_SCSI_IMM is not set
 # CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_NCR53C8XX is not set
@@ -254,7 +265,6 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
-# CONFIG_PLIP is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 
@@ -302,9 +312,8 @@
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
-# CONFIG_PRINTER is not set
-# CONFIG_PPDEV is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 
 #
 # I2C support
@@ -370,10 +379,12 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -381,7 +392,7 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
@@ -458,3 +469,4 @@
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/binfmt_elf32.c linux/arch/mips64/kernel/binfmt_elf32.c
--- v2.4.6/linux/arch/mips64/kernel/binfmt_elf32.c	Thu Jul 27 18:36:54 2000
+++ linux/arch/mips64/kernel/binfmt_elf32.c	Wed Jul  4 11:50:39 2001
@@ -1,8 +1,8 @@
 /*
  * Support for 32-bit Linux/MIPS ELF binaries.
  *
- * Copyright (C) 1999 Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999, 2001 Ralf Baechle
+ * Copyright (C) 1999, 2001 Silicon Graphics, Inc.
  *
  * Heavily inspired by the 32-bit Sparc compat code which is
  * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com)
@@ -28,7 +28,7 @@
 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 
 #define elf_check_arch(x)	\
-	((x)->e_machine == EM_MIPS || (x)->e_machine == EM_MIPS_RS4_BE)
+	((x)->e_machine == EM_MIPS)
 
 #define TASK32_SIZE		0x80000000UL
 #undef ELF_ET_DYN_BASE
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/branch.c linux/arch/mips64/kernel/branch.c
--- v2.4.6/linux/arch/mips64/kernel/branch.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/kernel/branch.c	Wed Jul  4 11:50:39 2001
@@ -1,5 +1,4 @@
-/* $Id: branch.c,v 1.1 1999/10/09 20:55:05 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -66,7 +65,7 @@
 		switch (insn.i_format.rt) {
 	 	case bltz_op:
 		case bltzl_op:
-			if (regs->regs[insn.i_format.rs] < 0)
+			if ((long)regs->regs[insn.i_format.rs] < 0)
 				epc = epc + 4 + (insn.i_format.simmediate << 2);
 			else
 				epc += 8;
@@ -75,7 +74,7 @@
 
 		case bgez_op:
 		case bgezl_op:
-			if (regs->regs[insn.i_format.rs] >= 0)
+			if ((long)regs->regs[insn.i_format.rs] >= 0)
 				epc = epc + 4 + (insn.i_format.simmediate << 2);
 			else
 				epc += 8;
@@ -85,7 +84,7 @@
 		case bltzal_op:
 		case bltzall_op:
 			regs->regs[31] = epc + 8;
-			if (regs->regs[insn.i_format.rs] < 0)
+			if ((long)regs->regs[insn.i_format.rs] < 0)
 				epc = epc + 4 + (insn.i_format.simmediate << 2);
 			else
 				epc += 8;
@@ -95,7 +94,7 @@
 		case bgezal_op:
 		case bgezall_op:
 			regs->regs[31] = epc + 8;
-			if (regs->regs[insn.i_format.rs] >= 0)
+			if ((long)regs->regs[insn.i_format.rs] >= 0)
 				epc = epc + 4 + (insn.i_format.simmediate << 2);
 			else
 				epc += 8;
@@ -143,7 +142,7 @@
 	case blez_op: /* not really i_format */
 	case blezl_op:
 		/* rt field assumed to be zero */
-		if (regs->regs[insn.i_format.rs] <= 0)
+		if ((long)regs->regs[insn.i_format.rs] <= 0)
 			epc = epc + 4 + (insn.i_format.simmediate << 2);
 		else
 			epc += 8;
@@ -153,7 +152,7 @@
 	case bgtz_op:
 	case bgtzl_op:
 		/* rt field assumed to be zero */
-		if (regs->regs[insn.i_format.rs] > 0)
+		if ((long)regs->regs[insn.i_format.rs] > 0)
 			epc = epc + 4 + (insn.i_format.simmediate << 2);
 		else
 			epc += 8;
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/entry.S linux/arch/mips64/kernel/entry.S
--- v2.4.6/linux/arch/mips64/kernel/entry.S	Fri Aug  4 16:15:37 2000
+++ linux/arch/mips64/kernel/entry.S	Wed Jul  4 11:50:39 2001
@@ -1,5 +1,4 @@
-/* $Id: entry.S,v 1.5 2000/02/23 00:41:00 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/head.S linux/arch/mips64/kernel/head.S
--- v2.4.6/linux/arch/mips64/kernel/head.S	Wed Jul 12 15:14:41 2000
+++ linux/arch/mips64/kernel/head.S	Wed Jul  4 11:50:39 2001
@@ -33,6 +33,7 @@
 #endif
 	.endm
 
+#ifdef CONFIG_SGI_IP27
 	/*
 	 * outputs the local nasid into t1.
 	 */
@@ -42,6 +43,7 @@
 	and	t1, NSRI_NODEID_MASK
 	dsrl	t1, NSRI_NODEID_SHFT
 	.endm
+#endif /* CONFIG_SGI_IP27 */
 
 	/*
 	 * inputs are the text nasid in t1, data nasid in t2.
@@ -94,9 +96,11 @@
 	ori	sp, 0xf				# align stack on 16 byte.
 	xori	sp, 0xf
 
+#ifdef CONFIG_SGI_IP27
 	GET_NASID_ASM
 	move	t2, t1				# text and data are here
 	MAPPED_KERNEL_SETUP_TLB
+#endif /* IP27 */
 
 	ARC64_TWIDDLE_PC
 
@@ -131,6 +135,7 @@
 1:	b	1b				# just in case ...
 	END(kernel_entry)
 
+#ifdef CONFIG_SGI_IP27
 NESTED(bootstrap, 16, sp)
 	GET_NASID_ASM
 	li	t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + KLDIR_OFF_POINTER + K0BASE
@@ -149,6 +154,7 @@
 	mtc0	t0, CP0_STATUS			   # thread in copy_thread.
 	jal	cboot
 	END(bootstrap)
+#endif /* CONFIG_SGI_IP27 */
 
 	__FINIT
 
@@ -170,8 +176,6 @@
 	page	swapper_pg_dir, 1
 	page	invalid_pte_table, 0
 	page	invalid_pmd_table, 1
-	page	empty_bad_page_table, 0
-	page	empty_bad_pmd_table, 1
 	page	kptbl, KPTBL_PAGE_ORDER
 	.globl	ekptbl
 	page	kpmdtbl, 0
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/ioctl32.c linux/arch/mips64/kernel/ioctl32.c
--- v2.4.6/linux/arch/mips64/kernel/ioctl32.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/kernel/ioctl32.c	Wed Jul  4 11:50:39 2001
@@ -7,6 +7,7 @@
  *
  * Mostly stolen from the sparc64 ioctl32 implementation.
  */
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
@@ -25,6 +26,7 @@
 #include <linux/elevator.h>
 #include <linux/auto_fs.h>
 #include <linux/ext2_fs.h>
+#include <linux/raid/md_u.h>
 #include <asm/types.h>
 #include <asm/uaccess.h>
 
@@ -67,6 +69,24 @@
 	int tv_usec;
 };
 
+static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct timeval32 *up = (struct timeval32 *)arg;
+	struct timeval ktv;
+	mm_segment_t old_fs = get_fs();
+	int err;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&ktv);
+	set_fs(old_fs);
+	if (!err) {
+		err = put_user(ktv.tv_sec, &up->tv_sec);
+		err |= __put_user(ktv.tv_usec, &up->tv_usec);
+	}
+
+	return err;
+}
+
 #define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)
 #define EXT2_IOC32_SETFLAGS               _IOW('f', 2, int)
 #define EXT2_IOC32_GETVERSION             _IOR('v', 1, int)
@@ -108,6 +128,8 @@
         __kernel_caddr_t32  ifcbuf;
 };
 
+#ifdef CONFIG_NET
+
 static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
 	struct ireq32 *uir32 = (struct ireq32 *)arg;
@@ -308,6 +330,8 @@
 	return ret;
 }
 
+#endif /* CONFIG_NET */
+
 static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
 	/* These are just misnamed, they actually get/put from/to user an int */
@@ -364,6 +388,11 @@
 	return error;
 }
 
+static int ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return -EINVAL;
+}
+
 struct blkpg_ioctl_arg32 {
 	int op;
 	int flags;
@@ -634,6 +663,27 @@
 	IOCTL32_DEFAULT(VT_LOCKSWITCH),
 	IOCTL32_DEFAULT(VT_UNLOCKSWITCH),
 
+#ifdef CONFIG_NET
+	/* Socket level stuff */
+	IOCTL32_DEFAULT(FIOSETOWN),
+	IOCTL32_DEFAULT(SIOCSPGRP),
+	IOCTL32_DEFAULT(FIOGETOWN),
+	IOCTL32_DEFAULT(SIOCGPGRP),
+	IOCTL32_DEFAULT(SIOCATMARK),
+	IOCTL32_DEFAULT(SIOCSIFLINK),
+	IOCTL32_DEFAULT(SIOCSIFENCAP),
+	IOCTL32_DEFAULT(SIOCGIFENCAP),
+	IOCTL32_DEFAULT(SIOCSIFBR),
+	IOCTL32_DEFAULT(SIOCGIFBR),
+	IOCTL32_DEFAULT(SIOCSARP),
+	IOCTL32_DEFAULT(SIOCGARP),
+	IOCTL32_DEFAULT(SIOCDARP),
+	IOCTL32_DEFAULT(SIOCSRARP),
+	IOCTL32_DEFAULT(SIOCGRARP),
+	IOCTL32_DEFAULT(SIOCDRARP),
+	IOCTL32_DEFAULT(SIOCADDDLCI),
+	IOCTL32_DEFAULT(SIOCDELDLCI),
+
 	IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
 	IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
 	IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc),
@@ -665,6 +715,14 @@
 	IOCTL32_HANDLER(SIOCSIFTXQLEN, dev_ifsioc),
 	IOCTL32_HANDLER(SIOCADDRT, routing_ioctl),
 	IOCTL32_HANDLER(SIOCDELRT, routing_ioctl),
+	/*
+	 * Note SIOCRTMSG is no longer, so this is safe and * the user would
+	 * have seen just an -EINVAL anyways.
+	 */
+	IOCTL32_HANDLER(SIOCRTMSG, ret_einval),
+	IOCTL32_HANDLER(SIOCGSTAMP, do_siocgstamp),
+
+#endif /* CONFIG_NET */
 
 	IOCTL32_HANDLER(EXT2_IOC32_GETFLAGS, do_ext2_ioctl),
 	IOCTL32_HANDLER(EXT2_IOC32_SETFLAGS, do_ext2_ioctl),
@@ -712,6 +770,34 @@
 	IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans),
 	IOCTL32_DEFAULT(BLKELVGET),
 	IOCTL32_DEFAULT(BLKELVSET),
+
+#ifdef CONFIG_MD
+	/* status */
+	IOCTL32_DEFAULT(RAID_VERSION),
+	IOCTL32_DEFAULT(GET_ARRAY_INFO),
+	IOCTL32_DEFAULT(GET_DISK_INFO),
+	IOCTL32_DEFAULT(PRINT_RAID_DEBUG),
+	IOCTL32_DEFAULT(RAID_AUTORUN),
+
+	/* configuration */
+	IOCTL32_DEFAULT(CLEAR_ARRAY),
+	IOCTL32_DEFAULT(ADD_NEW_DISK),
+	IOCTL32_DEFAULT(HOT_REMOVE_DISK),
+	IOCTL32_DEFAULT(SET_ARRAY_INFO),
+	IOCTL32_DEFAULT(SET_DISK_INFO),
+	IOCTL32_DEFAULT(WRITE_RAID_INFO),
+	IOCTL32_DEFAULT(UNPROTECT_ARRAY),
+	IOCTL32_DEFAULT(PROTECT_ARRAY),
+	IOCTL32_DEFAULT(HOT_ADD_DISK),
+	IOCTL32_DEFAULT(SET_DISK_FAULTY),
+
+	/* usage */
+	IOCTL32_DEFAULT(RUN_ARRAY),
+	IOCTL32_DEFAULT(START_ARRAY),
+	IOCTL32_DEFAULT(STOP_ARRAY),
+	IOCTL32_DEFAULT(STOP_ARRAY_RO),
+	IOCTL32_DEFAULT(RESTART_ARRAY_RW),
+#endif /* CONFIG_MD */
 
 	IOCTL32_DEFAULT(MTIOCTOP),			/* mtio.h ioctls  */
 	IOCTL32_HANDLER(MTIOCGET32, mt_ioctl_trans),
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/linux32.c linux/arch/mips64/kernel/linux32.c
--- v2.4.6/linux/arch/mips64/kernel/linux32.c	Mon Mar 19 12:35:10 2001
+++ linux/arch/mips64/kernel/linux32.c	Wed Jul  4 11:50:39 2001
@@ -742,7 +742,9 @@
 	set_fs (KERNEL_DS);
 	ret = sys_getrusage(who, &r);
 	set_fs (old_fs);
-	if (put_rusage (ru, &r)) return -EFAULT;
+	if (put_rusage (ru, &r))
+		return -EFAULT;
+
 	return ret;
 }
 
@@ -752,7 +754,6 @@
 	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
 		(__get_user(o->tv_sec, &i->tv_sec) |
 		 __get_user(o->tv_usec, &i->tv_usec)));
-	return ENOSYS;
 }
 
 static inline long
@@ -763,7 +764,6 @@
 		 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
 		 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
 		 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
-	return ENOSYS;
 }
 
 static inline long
@@ -777,12 +777,11 @@
 static inline long
 put_it32(struct itimerval32 *o, struct itimerval *i)
 {
-	return (!access_ok(VERIFY_WRITE, i, sizeof(*i)) ||
+	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
 		(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
 		 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
 		 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
 		 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
-	return ENOSYS;
 }
 
 extern int do_getitimer(int which, struct itimerval *value);
@@ -839,6 +838,7 @@
 	/* And we'd better return too much than too little anyway */
 	if (it_old.it_value.tv_usec)
 		oldalarm++;
+
 	return oldalarm;
 }
 
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/mips64_ksyms.c linux/arch/mips64/kernel/mips64_ksyms.c
--- v2.4.6/linux/arch/mips64/kernel/mips64_ksyms.c	Fri Mar  2 11:15:47 2001
+++ linux/arch/mips64/kernel/mips64_ksyms.c	Wed Jul  4 11:50:39 2001
@@ -5,8 +5,8 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997, 1998, 1999, 2000 by Ralf Baechle
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
  */
 #include <linux/config.h>
 #include <linux/module.h>
@@ -90,16 +90,11 @@
 EXPORT_SYMBOL(invalid_pte_table);
 
 /*
- * Semaphore stuff
- */
-EXPORT_SYMBOL(__down_read);
-EXPORT_SYMBOL(__down_write);
-EXPORT_SYMBOL(__rwsem_wake);
-
-/*
  * Base address of ports for Intel style I/O.
  */
+#if defined (CONFIG_PCI) || defined (CONFIG_ISA)
 EXPORT_SYMBOL(mips_io_port_base);
+#endif
 
 /*
  * Kernel hacking ...
@@ -121,4 +116,4 @@
 #endif
 
 EXPORT_SYMBOL(get_wchan);
-EXPORT_SYMBOL(flush_tlb_page);
+EXPORT_SYMBOL(_flush_tlb_page);
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/proc.c linux/arch/mips64/kernel/proc.c
--- v2.4.6/linux/arch/mips64/kernel/proc.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/kernel/proc.c	Wed Jul  4 11:50:39 2001
@@ -26,67 +26,50 @@
  * Currently /proc/cpuinfo is being abused to print data about the
  * number of date/instruction cacheflushes.
  */
-int get_cpuinfo(char *buffer, char **start, off_t offset, int count)
+int get_cpuinfo(char *buffer)
 {
 	char fmt [64];
-	struct cpuinfo_mips *c = cpu_data;
-	size_t len = 0;
-  int n;
+	size_t len;
 
-  for (n = 0; n < smp_num_cpus; n++, c++) {
-		len += sprintf(buffer + len, "processor\t\t: %d\n", n);
-		len += sprintf(buffer + len, "vendor_id\t\t: MIPS\n");
-		len += sprintf(buffer + len, "model name\t\t: R10000\n");
-/*		len += sprintf(buffer + len, "cpu model\t\t: %s V%d.%d\n",
+	len = sprintf(buffer, "cpu\t\t\t: MIPS\n");
+#if 0
+	len += sprintf(buffer + len, "cpu model\t\t: %s V%d.%d\n",
 	               cpu_name[mips_cputype <= CPU_LAST ?
 	                        mips_cputype :
 	                        CPU_UNKNOWN],
 	               (version >> 4) & 0x0f,
 	               version & 0x0f);
-		len += sprintf(buffer + len, "system type\t\t: %s %s\n",
+	len += sprintf(buffer + len, "system type\t\t: %s %s\n",
 		       mach_group_names[mips_machgroup],
 		       mach_group_to_name[mips_machgroup][mips_machtype]);
-*/
-		len += sprintf(buffer + len, "BogoMIPS\t\t: %lu.%02lu\n",
-		       (loops_per_sec + 2500) / 500000,
-	               ((loops_per_sec + 2500) / 5000) % 100);
-/*		len += sprintf(buffer + len, "Number of cpus\t\t: %d\n", smp_num_cpus);*/
+#endif
+	len += sprintf(buffer + len, "BogoMIPS\t\t: %lu.%02lu\n",
+		       (loops_per_jiffy + 2500) / (500000/HZ),
+	               ((loops_per_jiffy + 2500) / (5000/HZ)) % 100);
+	len += sprintf(buffer + len, "Number of cpus\t\t: %d\n", smp_num_cpus);
 #if defined (__MIPSEB__)
-		len += sprintf(buffer + len, "byteorder\t\t: big endian\n");
+	len += sprintf(buffer + len, "byteorder\t\t: big endian\n");
 #endif
 #if defined (__MIPSEL__)
-		len += sprintf(buffer + len, "byteorder\t\t: little endian\n");
+	len += sprintf(buffer + len, "byteorder\t\t: little endian\n");
 #endif
-		len += sprintf(buffer + len, "unaligned accesses\t: %lu\n",
+	len += sprintf(buffer + len, "unaligned accesses\t: %lu\n",
 		       unaligned_instructions);
-		len += sprintf(buffer + len, "wait instruction\t: %s\n",
+	len += sprintf(buffer + len, "wait instruction\t: %s\n",
 	               wait_available ? "yes" : "no");
-		len += sprintf(buffer + len, "microsecond timers\t: %s\n",
+	len += sprintf(buffer + len, "microsecond timers\t: %s\n",
 	               cyclecounter_available ? "yes" : "no");
-		len += sprintf(buffer + len, "extra interrupt vector\t: %s\n",
+	len += sprintf(buffer + len, "extra interrupt vector\t: %s\n",
 	               dedicated_iv_available ? "yes" : "no");
-		len += sprintf(buffer + len, "hardware watchpoint\t: %s\n",
+	len += sprintf(buffer + len, "hardware watchpoint\t: %s\n",
 	               watch_available ? "yes" : "no");
 
-		sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
+	sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
 	        vce_available ? "%d" : "not available");
-		len += sprintf(buffer + len, fmt, 'D', vced_count);
-		len += sprintf(buffer + len, fmt, 'I', vcei_count);
-		len += sprintf(buffer + len, "\n");
-
-		if (len < offset)
-			offset -= len, len = 0;
-		else if (len >= offset + count)
-			goto leave_loop;
-	}
-
-leave_loop:
-	*start = buffer + offset;
-	len -= offset;
-	if (len < 0)
-		len = 0;
-	return len > count ? count : len;
+	len += sprintf(buffer + len, fmt, 'D', vced_count);
+	len += sprintf(buffer + len, fmt, 'I', vcei_count);
 
+	return len;
 }
 
 void init_irq_proc(void)
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/r4k_fpu.S linux/arch/mips64/kernel/r4k_fpu.S
--- v2.4.6/linux/arch/mips64/kernel/r4k_fpu.S	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/kernel/r4k_fpu.S	Wed Jul  4 11:50:39 2001
@@ -1,17 +1,16 @@
-/* $Id: r4k_fpu.S,v 1.1 1999/09/27 16:01:38 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Save/restore floating point context for signal handlers.
  *
- * Copyright (C) 1996, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1996, 1998, 1999, 2001 by Ralf Baechle
  *
  * Multi-arch abstraction and asm macros for easier reading:
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999, 2001 Silicon Graphics, Inc.
  */
 #include <asm/asm.h>
 #include <asm/errno.h>
@@ -33,11 +32,11 @@
 	.set	noreorder
 	/* Save floating point context */
 LEAF(save_fp_context)
-	mfc0	t1,CP0_STATUS
-	 sll	t2,t1,5
+	mfc0	t1, CP0_STATUS
+	sll	t2, t1,5
 
-	bgez	t2,1f
-	 cfc1	t1,fcr31
+	bgez	t2, 1f
+	 cfc1	t1, fcr31
 	/* Store the 16 odd double precision registers */
 	EX	sdc1 $f1, SC_FPREGS+8(a0)
 	EX	sdc1 $f3, SC_FPREGS+24(a0)
@@ -75,8 +74,8 @@
 	EX	sdc1 $f28, SC_FPREGS+224(a0)
 	EX	sdc1 $f30, SC_FPREGS+240(a0)
 	EX	sw t1, SC_FPC_CSR(a0)
-	cfc1	t0,$0				# implementation/version
-	EX	sw t0,SC_FPC_EIR(a0)
+	cfc1	t0, $0				# implementation/version
+	EX	sw t0, SC_FPC_EIR(a0)
 
 	jr	ra
 	 li	v0, 0					# success
@@ -93,8 +92,8 @@
  */
 LEAF(restore_fp_context)
 	mfc0	t1, CP0_STATUS
-	sll	t0,t1,5
-	bgez	t0,1f
+	sll	t0, t1,5
+	bgez	t0, 1f
 	 EX	lw t0, SC_FPC_CSR(a0)
 
 	/* Restore the 16 odd double precision registers only
@@ -137,13 +136,13 @@
 	EX	ldc1 $f26, SC_FPREGS+208(a0)
 	EX	ldc1 $f28, SC_FPREGS+224(a0)
 	EX	ldc1 $f30, SC_FPREGS+240(a0)
-	ctc1	t0,fcr31
+	ctc1	t0, fcr31
 	jr	ra
 	 li	v0, 0					# success
 	END(restore_fp_context)
 
 	.type	fault@function
 	.ent	fault
-fault:	li	v0, -EFAULT
-	jr	ra
+fault:	jr	ra
+	 li	v0, -EFAULT				# failure
 	.end	fault
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/r4k_tlb.S linux/arch/mips64/kernel/r4k_tlb.S
--- v2.4.6/linux/arch/mips64/kernel/r4k_tlb.S	Wed Jul 12 15:14:41 2000
+++ linux/arch/mips64/kernel/r4k_tlb.S	Wed Jul  4 11:50:39 2001
@@ -24,7 +24,7 @@
 
 	.macro	LOAD_PTE2, ptr, tmp
 #ifdef CONFIG_SMP
-	mfc0	\tmp, CP0_CONTEXT
+	dmfc0	\tmp, CP0_CONTEXT
 	dla	\ptr, pgd_current
 	dsrl	\tmp, 23
 	daddu	\ptr, \tmp
@@ -96,9 +96,6 @@
 	 */
 	dmfc0	k0, CP0_BADVADDR
 	dli	k1, VMALLOC_START
-	sltu	k1, k0, k1
-	bne	k1, zero, not_vmalloc
-	 dli	k1, VMALLOC_START
 
 	/*
 	 * Now find offset into kptbl.
@@ -114,20 +111,16 @@
 	 */
 	dla	k0, ekptbl
 	sltu	k0, k1, k0
-	beq	k0, zero, not_vmalloc
+	beqz	k0, not_vmalloc
 
 	/*
 	 * Load cp0 registers.
 	 */
 	ld	k0, 0(k1)			# get even pte
 	ld	k1, 8(k1)			# get odd pte
-1:
+
+not_vmalloc:
 	PTE_RELOAD k0 k1
 	nop
 	tlbwr
 	eret
-not_vmalloc:
-	daddu	k0, zero, zero
-	daddu	k1, zero, zero
-	j	1b
-	nop
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/scall_64.S linux/arch/mips64/kernel/scall_64.S
--- v2.4.6/linux/arch/mips64/kernel/scall_64.S	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/kernel/scall_64.S	Wed Jul  4 11:50:39 2001
@@ -63,8 +63,14 @@
 1:	sd	v0, PT_R2(sp)		# result
 
 FEXPORT(ret_from_sys_call_64)
-	lw	t0, irq_stat		# softirq_active
-	lw	t1, irq_stat+4		# softirq_mask.  unused delay slot
+	la	t1, irq_stat		# softirq_active
+#ifdef CONFIG_SMP
+	lwu	t0, TASK_PROCESSOR($28)
+	dsll	t0, t0, 5
+	daddu	t1, t0
+#endif
+	lw	t0, 0(t1)		# softirq_active
+	lw	t1, 4(t1)		# softirq_mask.  unused delay slot
 	and	t0, t1
 	bnez	t0, handle_softirq_64
 
@@ -131,217 +137,217 @@
 	END(handle_sys64)
 
 sys_call_table:
-	PTR	sys_syscall				/* 4000 */
+	PTR	sys_syscall				/* 5000 */
 	PTR	sys_exit
 	PTR	sys_fork
 	PTR	sys_read
 	PTR	sys_write
-	PTR	sys_open				/* 4005 */
+	PTR	sys_open				/* 5005 */
 	PTR	sys_close
 	PTR	sys_waitpid
 	PTR	sys_creat
 	PTR	sys_link
-	PTR	sys_unlink				/* 4010 */
+	PTR	sys_unlink				/* 5010 */
 	PTR	sys_execve
 	PTR	sys_chdir
 	PTR	sys_time
 	PTR	sys_mknod
-	PTR	sys_chmod				/* 4015 */
+	PTR	sys_chmod				/* 5015 */
 	PTR	sys_lchown
 	PTR	sys_ni_syscall
 	PTR	sys_stat
 	PTR	sys_lseek
-	PTR	sys_getpid				/* 4020 */
+	PTR	sys_getpid				/* 5020 */
 	PTR	sys_mount
 	PTR	sys_oldumount
 	PTR	sys_setuid
 	PTR	sys_getuid
-	PTR	sys_stime				/* 4025 */
+	PTR	sys_stime				/* 5025 */
 	PTR	sys_ni_syscall		/* ptrace */
 	PTR	sys_alarm
 	PTR	sys_fstat
 	PTR	sys_pause
-	PTR	sys_utime				/* 4030 */
+	PTR	sys_utime				/* 5030 */
 	PTR	sys_ni_syscall
 	PTR	sys_ni_syscall
 	PTR	sys_access
 	PTR	sys_nice
-	PTR	sys_ni_syscall				/* 4035 */
+	PTR	sys_ni_syscall				/* 5035 */
 	PTR	sys_sync
 	PTR	sys_kill
 	PTR	sys_rename
 	PTR	sys_mkdir
-	PTR	sys_rmdir				/* 4040 */
+	PTR	sys_rmdir				/* 5040 */
 	PTR	sys_dup
 	PTR	sys_pipe
 	PTR	sys_times
 	PTR	sys_ni_syscall
-	PTR	sys_brk					/* 4045 */
+	PTR	sys_brk					/* 5045 */
 	PTR	sys_setgid
 	PTR	sys_getgid
 	PTR	sys_ni_syscall		/* was signal	2 */
 	PTR	sys_geteuid
-	PTR	sys_getegid				/* 4050 */
+	PTR	sys_getegid				/* 5050 */
 	PTR	sys_acct
 	PTR	sys_umount
 	PTR	sys_ni_syscall
 	PTR	sys_ioctl
-	PTR	sys_fcntl				/* 4055 */
+	PTR	sys_fcntl				/* 5055 */
 	PTR	sys_ni_syscall
 	PTR	sys_setpgid
 	PTR	sys_ni_syscall
 	PTR	sys_ni_syscall
-	PTR	sys_umask				/* 4060 */
+	PTR	sys_umask				/* 5060 */
 	PTR	sys_chroot
 	PTR	sys_ustat
 	PTR	sys_dup2
 	PTR	sys_getppid
-	PTR	sys_getpgrp				/* 4065 */
+	PTR	sys_getpgrp				/* 5065 */
 	PTR	sys_setsid
 	PTR	sys_sigaction
 	PTR	sys_sgetmask
 	PTR	sys_ssetmask
-	PTR	sys_setreuid				/* 4070 */
+	PTR	sys_setreuid				/* 5070 */
 	PTR	sys_setregid
 	PTR	sys_sigsuspend
 	PTR	sys_sigpending
 	PTR	sys_sethostname
-	PTR	sys_setrlimit				/* 4075 */
+	PTR	sys_setrlimit				/* 5075 */
 	PTR	sys_getrlimit
 	PTR	sys_getrusage
 	PTR	sys_gettimeofday
 	PTR	sys_settimeofday
-	PTR	sys_getgroups				/* 4080 */
+	PTR	sys_getgroups				/* 5080 */
 	PTR	sys_setgroups
 	PTR	sys_ni_syscall			/* old_select */
 	PTR	sys_symlink
 	PTR	sys_lstat
-	PTR	sys_readlink				/* 4085 */
+	PTR	sys_readlink				/* 5085 */
 	PTR	sys_uselib
 	PTR	sys_swapon
 	PTR	sys_reboot
 	PTR	sys_ni_syscall			/* old_readdir */
-	PTR	sys_mmap				/* 4090 */
+	PTR	sys_mmap				/* 5090 */
 	PTR	sys_munmap
 	PTR	sys_truncate
 	PTR	sys_ftruncate
 	PTR	sys_fchmod
-	PTR	sys_fchown				/* 4095 */
+	PTR	sys_fchown				/* 5095 */
 	PTR	sys_getpriority
 	PTR	sys_setpriority
 	PTR	sys_ni_syscall
 	PTR	sys_statfs
-	PTR	sys_fstatfs				/* 4100 */
+	PTR	sys_fstatfs				/* 5100 */
 	PTR	sys_ni_syscall		/* sys_ioperm */
 	PTR	sys_socketcall
 	PTR	sys_syslog
 	PTR	sys_setitimer
-	PTR	sys_getitimer				/* 4105 */
+	PTR	sys_getitimer				/* 5105 */
 	PTR	sys_newstat
 	PTR	sys_newlstat
 	PTR	sys_newfstat
 	PTR	sys_ni_syscall
-	PTR	sys_ni_syscall		/* sys_ioperm  *//* 4110 */
+	PTR	sys_ni_syscall		/* sys_ioperm  *//* 5110 */
 	PTR	sys_vhangup
 	PTR	sys_ni_syscall		/* was sys_idle	 */
 	PTR	sys_ni_syscall		/* sys_vm86 */
 	PTR	sys_wait4
-	PTR	sys_swapoff				/* 4115 */
+	PTR	sys_swapoff				/* 5115 */
 	PTR	sys_sysinfo
 	PTR	sys_ipc
 	PTR	sys_fsync
 	PTR	sys_sigreturn
-	PTR	sys_clone				/* 4120 */
+	PTR	sys_clone				/* 5120 */
 	PTR	sys_setdomainname
 	PTR	sys_newuname
 	PTR	sys_ni_syscall		/* sys_modify_ldt */
 	PTR	sys_adjtimex
-	PTR	sys_mprotect				/* 4125 */
+	PTR	sys_mprotect				/* 5125 */
 	PTR	sys_sigprocmask
 	PTR	sys_create_module
 	PTR	sys_init_module
 	PTR	sys_delete_module
-	PTR	sys_get_kernel_syms 			/* 4130 */
+	PTR	sys_get_kernel_syms 			/* 5130 */
 	PTR	sys_quotactl
 	PTR	sys_getpgid
 	PTR	sys_fchdir
 	PTR	sys_bdflush
-	PTR	sys_sysfs				/* 4135 */
+	PTR	sys_sysfs				/* 5135 */
 	PTR	sys_personality
 	PTR	sys_ni_syscall		/* for afs_syscall */
 	PTR	sys_setfsuid
 	PTR	sys_setfsgid
-	PTR	sys_llseek				/* 4140 */
+	PTR	sys_llseek				/* 5140 */
 	PTR	sys_getdents
 	PTR	sys_select
 	PTR	sys_flock
 	PTR	sys_msync
-	PTR	sys_readv				/* 4145 */
+	PTR	sys_readv				/* 5145 */
 	PTR	sys_writev
 	PTR	sys_cacheflush
 	PTR	sys_cachectl
 	PTR	sys_sysmips
-	PTR	sys_ni_syscall				/* 4150 */
+	PTR	sys_ni_syscall				/* 5150 */
 	PTR	sys_getsid
 	PTR	sys_fdatasync
 	PTR	sys_sysctl
 	PTR	sys_mlock
-	PTR	sys_munlock				/* 4155 */
+	PTR	sys_munlock				/* 5155 */
 	PTR	sys_mlockall
 	PTR	sys_munlockall
 	PTR	sys_sched_setparam
 	PTR	sys_sched_getparam
-	PTR	sys_sched_setscheduler			/* 4160 */
+	PTR	sys_sched_setscheduler			/* 5160 */
 	PTR	sys_sched_getscheduler
 	PTR	sys_sched_yield
 	PTR	sys_sched_get_priority_max
 	PTR	sys_sched_get_priority_min
-	PTR	sys_sched_rr_get_interval		/* 4165 */
+	PTR	sys_sched_rr_get_interval		/* 5165 */
 	PTR	sys_nanosleep
 	PTR	sys_mremap
 	PTR	sys_accept
 	PTR	sys_bind
-	PTR	sys_connect				/* 4170 */
+	PTR	sys_connect				/* 5170 */
 	PTR	sys_getpeername
 	PTR	sys_getsockname
 	PTR	sys_getsockopt
 	PTR	sys_listen
-	PTR	sys_recv				/* 4175 */
+	PTR	sys_recv				/* 5175 */
 	PTR	sys_recvfrom
 	PTR	sys_recvmsg
 	PTR	sys_send
 	PTR	sys_sendmsg
-	PTR	sys_sendto				/* 4180 */
+	PTR	sys_sendto				/* 5180 */
 	PTR	sys_setsockopt
 	PTR	sys_shutdown
 	PTR	sys_socket
 	PTR	sys_socketpair
-	PTR	sys_setresuid				/* 4185 */
+	PTR	sys_setresuid				/* 5185 */
 	PTR	sys_getresuid
 	PTR	sys_query_module
 	PTR	sys_poll
 	PTR	sys_nfsservctl
-	PTR	sys_setresgid				/* 4190 */
+	PTR	sys_setresgid				/* 5190 */
 	PTR	sys_getresgid
 	PTR	sys_prctl
 	PTR	sys_rt_sigreturn
 	PTR	sys_rt_sigaction
-	PTR	sys_rt_sigprocmask 			/* 4195 */
+	PTR	sys_rt_sigprocmask 			/* 5195 */
 	PTR	sys_rt_sigpending
 	PTR	sys_rt_sigtimedwait
 	PTR	sys_rt_sigqueueinfo
 	PTR	sys_rt_sigsuspend
-	PTR	sys_pread				/* 4200 */
+	PTR	sys_pread				/* 5200 */
 	PTR	sys_pwrite
 	PTR	sys_chown
 	PTR	sys_getcwd
 	PTR	sys_capget
-	PTR	sys_capset				/* 4205 */
+	PTR	sys_capset				/* 5205 */
 	PTR	sys_sigaltstack
 	PTR	sys_sendfile
 	PTR	sys_ni_syscall
 	PTR	sys_ni_syscall
-	PTR	sys_pivot_root				/* 4210 */
+	PTR	sys_pivot_root				/* 5210 */
 	PTR	sys_mincore
 	PTR	sys_madvise
 	PTR	sys_getdents64
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/scall_o32.S linux/arch/mips64/kernel/scall_o32.S
--- v2.4.6/linux/arch/mips64/kernel/scall_o32.S	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/kernel/scall_o32.S	Wed Jul  4 11:50:39 2001
@@ -76,8 +76,14 @@
 1:	sd	v0, PT_R2(sp)		# result
 	
 FEXPORT(o32_ret_from_sys_call)
-	lw	t0, irq_stat		# softirq_active
-	lw	t1, irq_stat+4		# softirq_mask.  unused delay slot
+	la	t1, irq_stat		# softirq_active
+#ifdef CONFIG_SMP
+	lwu	t0, TASK_PROCESSOR($28)
+	dsll	t0, t0, 5
+	daddu	t1, t0
+#endif
+	lw	t0, 0(t1)		# softirq_active
+	lw	t1, 4(t1)		# softirq_mask.  unused delay slot
 	and	t0, t1
 	bnez	t0, o32_handle_softirq
 
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/setup.c linux/arch/mips64/kernel/setup.c
--- v2.4.6/linux/arch/mips64/kernel/setup.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/mips64/kernel/setup.c	Wed Jul  4 11:50:39 2001
@@ -31,7 +31,6 @@
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
 #include <asm/cpu.h>
-#include <asm/io.h>
 #include <asm/stackframe.h>
 #include <asm/system.h>
 #include <asm/pgalloc.h>
@@ -56,8 +55,6 @@
  */
 char cyclecounter_available;
 
-unsigned long loops_per_sec;
-
 /*
  * Set if box has EISA slots.
  */
@@ -89,8 +86,9 @@
 unsigned long mips_machtype = MACH_UNKNOWN;
 unsigned long mips_machgroup = MACH_GROUP_UNKNOWN;
 
+struct boot_mem_map boot_mem_map;
+
 unsigned char aux_device_present;
-extern int _end;
 
 extern void load_mmu(void);
 
@@ -98,15 +96,6 @@
        char saved_command_line[CL_SIZE];
 extern char arcs_cmdline[CL_SIZE];
 
-/*
- * mips_io_port_base is the begin of the address space to which x86 style
- * I/O ports are mapped.
- */
-#ifdef CONFIG_SGI_IP27
-/* XXX Origin garbage has no business in this file  */
-unsigned long mips_io_port_base = IO_BASE;
-#endif
-
 extern void ip22_setup(void);
 extern void ip27_setup(void);
 
@@ -137,6 +126,7 @@
 		mips_cputype = CPU_R8000;
 		break;
 	case PRID_IMP_R10000:
+	case PRID_IMP_R12000:
 		mips_cputype = CPU_R10000;
 		break;
 	default:
@@ -146,14 +136,6 @@
 
 void __init setup_arch(char **cmdline_p)
 {
-#ifdef CONFIG_BLK_DEV_INITRD
-	unsigned long tmp;
-	unsigned long *initrd_header;
-#endif
-	int i;
-	pmd_t *pmd = kpmdtbl;
-	pte_t *pte = kptbl;
-
 	cpu_probe();
 	load_mmu();
 
@@ -164,37 +146,15 @@
 	ip27_setup();
 #endif
 
-	strncpy (command_line, arcs_cmdline, CL_SIZE);
+#ifdef CONFIG_ARC_MEMORY
+	bootmem_init ();
+#endif
+
+	strncpy(command_line, arcs_cmdline, CL_SIZE);
 	memcpy(saved_command_line, command_line, CL_SIZE);
 	saved_command_line[CL_SIZE-1] = '\0';
 
 	*cmdline_p = command_line;
 
-#ifdef CONFIG_BLK_DEV_INITRD
-#error "Initrd is broken, please fit it."
-	tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8;
-	if (tmp < (unsigned long)&_end)
-		tmp += PAGE_SIZE;
-	initrd_header = (unsigned long *)tmp;
-	if (initrd_header[0] == 0x494E5244) {
-		initrd_start = (unsigned long)&initrd_header[2];
-		initrd_end = initrd_start + initrd_header[1];
-		initrd_below_start_ok = 1;
-		if (initrd_end > memory_end) {
-			printk("initrd extends beyond end of memory "
-			       "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
-			       initrd_end,memory_end);
-			initrd_start = 0;
-		} else
-			*memory_start_p = initrd_end;
-	}
-#endif
-
 	paging_init();
-
-	memset((void *)kptbl, 0, PAGE_SIZE << KPTBL_PAGE_ORDER);
-	memset((void *)kpmdtbl, 0, PAGE_SIZE);
-	pgd_set(swapper_pg_dir, kpmdtbl);
-	for (i = 0; i < (1 << KPTBL_PAGE_ORDER); pmd++,i++,pte+=PTRS_PER_PTE)
-		pmd_val(*pmd) = (unsigned long)pte;
 }
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/smp.c linux/arch/mips64/kernel/smp.c
--- v2.4.6/linux/arch/mips64/kernel/smp.c	Sun Feb  4 21:48:46 2001
+++ linux/arch/mips64/kernel/smp.c	Wed Jul  4 11:50:39 2001
@@ -12,6 +12,7 @@
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
 #include <asm/mmu_context.h>
+#include <asm/irq.h>
 
 #ifdef CONFIG_SGI_IP27
 
@@ -24,8 +25,6 @@
 #define DORESCHED	0xab
 #define DOCALL		0xbc
 
-#define IRQ_TO_SWLEVEL(i)	i + 7	/* Delete this from here */
-
 static void sendintr(int destid, unsigned char status)
 {
 	int irq;
@@ -44,7 +43,7 @@
 	 * with the CPU we want to send the interrupt to.
 	 */
 	REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cputocnode(destid)),
-			IRQ_TO_SWLEVEL(irq));
+			FAST_IRQ_TO_LEVEL(irq));
 #else
 	<< Bomb!  Must redefine this for more than 2 CPUS. >>
 #endif
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/traps.c linux/arch/mips64/kernel/traps.c
--- v2.4.6/linux/arch/mips64/kernel/traps.c	Sun Dec  3 17:48:19 2000
+++ linux/arch/mips64/kernel/traps.c	Wed Jul  4 11:50:39 2001
@@ -264,7 +264,7 @@
 
 	epc = (unsigned int *) (unsigned long) regs->cp0_epc;
 	if (regs->cp0_cause & CAUSEF_BD)
-		epc += 4;
+		epc++;
 
 	if (verify_area(VERIFY_READ, epc, 4)) {
 		force_sig(SIGSEGV, current);
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/kernel/unaligned.c linux/arch/mips64/kernel/unaligned.c
--- v2.4.6/linux/arch/mips64/kernel/unaligned.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/kernel/unaligned.c	Wed Jul  4 11:50:39 2001
@@ -82,6 +82,7 @@
 #include <asm/byteorder.h>
 #include <asm/inst.h>
 #include <asm/uaccess.h>
+#include <asm/system.h>
 
 #define STR(x)  __STR(x)
 #define __STR(x)  #x
@@ -364,12 +365,15 @@
 		return;
 	}
 
+	die_if_kernel ("Unhandled kernel unaligned access", regs);
 	send_sig(SIGSEGV, current, 1);
 	return;
 sigbus:
+	die_if_kernel ("Unhandled kernel unaligned access", regs);
 	send_sig(SIGBUS, current, 1);
 	return;
 sigill:
+	die_if_kernel ("Unhandled kernel unaligned access or invalid instruction", regs);
 	send_sig(SIGILL, current, 1);
 	return;
 }
@@ -400,5 +404,6 @@
 	return;
 
 sigbus:
+	die_if_kernel ("Kernel unaligned instruction access", regs);
 	force_sig(SIGBUS, current);
 }
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/lib/memcpy.S linux/arch/mips64/lib/memcpy.S
--- v2.4.6/linux/arch/mips64/lib/memcpy.S	Tue Dec  5 23:15:12 2000
+++ linux/arch/mips64/lib/memcpy.S	Wed Jul  4 11:50:39 2001
@@ -238,8 +238,10 @@
 	 andi	ta2, a2, 0x40
 
 move_128bytes:
+#if (_MIPS_ISA == _MIPS_ISA_MIPS4)
 	pref	0, 2*128(a0)
 	pref	1, 2*128(a1)
+#endif
 	MOVE_BIGGERCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0)
 	MOVE_BIGGERCHUNK(a1, a0, 0x40, ta0, ta1, ta3, t0)
 	dsubu	t8, t8, 0x01
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/lib/memset.S linux/arch/mips64/lib/memset.S
--- v2.4.6/linux/arch/mips64/lib/memset.S	Tue Dec  5 23:15:12 2000
+++ linux/arch/mips64/lib/memset.S	Wed Jul  4 11:50:39 2001
@@ -52,6 +52,7 @@
 1:
 
 FEXPORT(__bzero)
+	.type	__bzero, @function
 	sltiu	t0, a2, 8			/* very small region? */
 	bnez	t0, small_memset
 	 andi	t0, a0, 7			/* aligned? */
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/lib/rtc-no.c linux/arch/mips64/lib/rtc-no.c
--- v2.4.6/linux/arch/mips64/lib/rtc-no.c	Sun Feb  4 21:48:46 2001
+++ linux/arch/mips64/lib/rtc-no.c	Wed Jul  4 11:50:39 2001
@@ -9,7 +9,6 @@
  * Copyright (C) 1998, 2001 by Ralf Baechle
  */
 #include <linux/kernel.h>
-#include <linux/spinlock.h>
 #include <linux/mc146818rtc.h>
 
 static unsigned char no_rtc_read_data(unsigned long addr)
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/lib/rtc-std.c linux/arch/mips64/lib/rtc-std.c
--- v2.4.6/linux/arch/mips64/lib/rtc-std.c	Sun Feb  4 21:48:46 2001
+++ linux/arch/mips64/lib/rtc-std.c	Wed Jul  4 11:50:39 2001
@@ -7,7 +7,6 @@
  *
  * Copyright (C) 1998 by Ralf Baechle
  */
-#include <linux/spinlock.h>
 #include <linux/mc146818rtc.h>
 #include <asm/io.h>
 
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/lib/watch.S linux/arch/mips64/lib/watch.S
--- v2.4.6/linux/arch/mips64/lib/watch.S	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/lib/watch.S	Wed Jul  4 11:50:39 2001
@@ -1,5 +1,4 @@
-/* $Id: watch.S,v 1.1 1999/08/21 21:43:01 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -7,7 +6,7 @@
  * Kernel debug stuff to use the Watch registers.
  * Useful to find stack overflows, dangling pointers etc.
  *
- * Copyright (C) 1995, 1996, 1999 by Ralf Baechle
+ * Copyright (C) 1995, 1996, 1999, 2001 by Ralf Baechle
  */
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
@@ -15,23 +14,21 @@
 
 		.set	noreorder
 /*
- * Parameter: a0 - logic address to watch
- *                 Currently only KSEG0 addresses are allowed!
+ * Parameter: a0 - physical address to watch
  *            a1 - set bit #1 to trap on load references
  *                     bit #0 to trap on store references
  * Results  : none
  */
 		LEAF(__watch_set)
-		li	t0,0x80000000
-		subu	a0,t0
-		ori	a0,7
-		xori	a0,7
-		or	a0,a1
-		mtc0	a0,CP0_WATCHLO
-		sw	a0,watch_savelo
+		ori	a0, 7
+		xori	a0, 7
+		or	a0, a1
+		mtc0	a0, CP0_WATCHLO
+		sd	a0, watch_savelo
+		dsrl32	a0, a0, 0
 
 		jr	ra
-		 mtc0	zero,CP0_WATCHHI
+		 mtc0	zero, CP0_WATCHHI
 		END(__watch_set)
 
 /*
@@ -40,7 +37,7 @@
  */
 		LEAF(__watch_clear)
 		jr	ra
-		 mtc0	zero,CP0_WATCHLO
+		 mtc0	zero, CP0_WATCHLO
 		END(__watch_clear)
 
 /*
@@ -48,14 +45,13 @@
  * Results  : none
  */
 		LEAF(__watch_reenable)
-		lw	t0,watch_savelo
+		ld	t0, watch_savelo
 		jr	ra
-		 mtc0	t0,CP0_WATCHLO
+		 mtc0	t0, CP0_WATCHLO
 		END(__watch_reenable)
 
 /*
  * Saved value of the c0_watchlo register for watch_reenable()
  */
-		.data
-watch_savelo:	.word	0
-		.text
+		.local	watch_savelo
+		.comm	watch_savelo, 8, 8
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/mm/andes.c linux/arch/mips64/mm/andes.c
--- v2.4.6/linux/arch/mips64/mm/andes.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/mm/andes.c	Wed Jul  4 11:50:39 2001
@@ -284,8 +284,8 @@
 
 	if((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff)) ||
 	   (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) == 0)) {
-		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d 
-			tlbpid=%d\n", (int) (CPU_CONTEXT(smp_processor_id(), 
+		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d "
+			"tlbpid=%d\n", (int) (CPU_CONTEXT(smp_processor_id(),
 			vma->vm_mm) & 0xff), pid);
 	}
 
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/mm/extable.c linux/arch/mips64/mm/extable.c
--- v2.4.6/linux/arch/mips64/mm/extable.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/mm/extable.c	Wed Jul  4 11:50:39 2001
@@ -9,6 +9,7 @@
  */
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/spinlock.h>
 #include <asm/uaccess.h>
 
 extern const struct exception_table_entry __start___ex_table[];
@@ -35,26 +36,32 @@
 	return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 unsigned long
 search_exception_table(unsigned long addr)
 {
-	unsigned long ret;
-
+	unsigned long ret = 0;
+	unsigned long flags;
+	
 #ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
-	if (ret) return ret;
+	return ret;
 #else
 	/* The kernel is the last "module" -- no need to treat it special.  */
 	struct module *mp;
+
+	spin_lock_irqsave(&modlist_lock, flags);
 	for (mp = module_list; mp != NULL; mp = mp->next) {
 		if (mp->ex_table_start == NULL)
 			continue;
 		ret = search_one_table(mp->ex_table_start,
 				       mp->ex_table_end - 1, addr);
-		if (ret) return ret;
+		if (ret)
+			break;
 	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
 #endif
-
-	return 0;
 }
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/mm/fault.c linux/arch/mips64/mm/fault.c
--- v2.4.6/linux/arch/mips64/mm/fault.c	Mon Mar 19 12:35:10 2001
+++ linux/arch/mips64/mm/fault.c	Wed Jul  4 11:50:39 2001
@@ -6,6 +6,7 @@
  * Copyright (C) 1995 - 2000 by Ralf Baechle
  * Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
  */
+#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
@@ -31,6 +32,7 @@
 #define development_version (LINUX_VERSION_CODE & 0x100)
 
 extern void die(char *, struct pt_regs *, unsigned long write);
+extern int console_loglevel;
 
 /*
  * Macro for exception fixup code to access integer registers.
@@ -57,17 +59,34 @@
 	printk("Got exception 0x%lx at 0x%lx\n", retaddr, regs.cp0_epc);
 }
 
-extern spinlock_t console_lock, timerlist_lock;
+extern spinlock_t timerlist_lock;
 
 /*
  * Unlock any spinlocks which will prevent us from getting the
- * message out (timerlist_lock is acquired through the
+ * message out (timerlist_lock is aquired through the
  * console unblank code)
  */
-void bust_spinlocks(void)
+void bust_spinlocks(int yes)
 {
-	spin_lock_init(&console_lock);
 	spin_lock_init(&timerlist_lock);
+	if (yes) {
+		oops_in_progress = 1;
+#ifdef CONFIG_SMP
+		global_irq_lock = 0;	/* Many serial drivers do __global_cli() */
+#endif
+	} else {
+		int loglevel_save = console_loglevel;
+		unblank_screen();
+		oops_in_progress = 0;
+		/*
+		 * OK, the message is on the console.  Now we call printk()
+		 * without oops_in_progress set so that printk will give klogd
+		 * a poke.  Hold onto your hats...
+		 */
+		console_loglevel = 15;		/* NMI oopser may have shut the console up */
+		printk(" ");
+		console_loglevel = loglevel_save;
+	}
 }
 
 /*
@@ -84,6 +103,18 @@
 	unsigned long fixup;
 	siginfo_t info;
 
+	/*
+	 * We fault-in kernel-space virtual memory on-demand. The
+	 * 'reference' page table is init_mm.pgd.
+	 *
+	 * NOTE! We MUST NOT take any locks for this case. We may
+	 * be in an interrupt or a critical region, and should
+	 * only copy the information from the master page table,
+	 * nothing more.
+	 */
+	if (address >= TASK_SIZE)
+		goto vmalloc_fault;
+
 	info.si_code = SEGV_MAPERR;
 	/*
 	 * If we're in an interrupt or have no user
@@ -148,13 +179,7 @@
 bad_area:
 	up_read(&mm->mmap_sem);
 
-	/*
-	 * Quickly check for vmalloc range faults.
-	 */
-	if ((!vma) && (address >= VMALLOC_START) && (address < VMALLOC_END)) {
-		printk("Fix vmalloc invalidate fault\n");
-		while(1);
-	}
+bad_area_nosemaphore:
 	if (user_mode(regs)) {
 		tsk->thread.cp0_badvaddr = address;
 		tsk->thread.error_code = write;
@@ -195,7 +220,7 @@
 	 * terminate things with extreme prejudice.
 	 */
 
-	bust_spinlocks();
+	bust_spinlocks(1);
 
 	printk(KERN_ALERT "Cpu %d Unable to handle kernel paging request at "
 	       "address %08lx, epc == %08x, ra == %08x\n",
@@ -203,6 +228,7 @@
                (unsigned int) regs->regs[31]);
 	die("Oops", regs, write);
 	do_exit(SIGKILL);
+	bust_spinlocks(0);
 
 /*
  * We ran out of memory, or some other thing happened to us that made
@@ -232,4 +258,9 @@
 	/* Kernel mode? Handle exceptions or die */
 	if (!user_mode(regs))
 		goto no_context;
+
+	return;
+
+vmalloc_fault:
+	panic("Pagefault for kernel virtual memory");
 }
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/mm/init.c linux/arch/mips64/mm/init.c
--- v2.4.6/linux/arch/mips64/mm/init.c	Mon Oct 16 12:58:51 2000
+++ linux/arch/mips64/mm/init.c	Wed Jul  4 11:50:39 2001
@@ -1,5 +1,4 @@
-/* $Id: init.c,v 1.13 2000/02/23 00:41:00 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -37,27 +36,11 @@
 #include <asm/sgialib.h>
 #endif
 #include <asm/mmu_context.h>
+#include <asm/tlb.h>
 
-unsigned long totalram_pages;
-
-void __bad_pte_kernel(pmd_t *pmd)
-{
-	printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd));
-	pmd_set(pmd, BAD_PAGETABLE);
-}
-
-void __bad_pte(pmd_t *pmd)
-{
-	printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
-	pmd_set(pmd, BAD_PAGETABLE);
-}
+mmu_gather_t mmu_gathers[NR_CPUS];
 
-/* Fixme, we need something like BAD_PMDTABLE ...  */
-void __bad_pmd(pgd_t *pgd)
-{
-	printk("Bad pgd in pmd_alloc: %08lx\n", pgd_val(*pgd));
-	pgd_set(pgd, empty_bad_pmd_table);
-}
+unsigned long totalram_pages;
 
 void pgd_init(unsigned long page)
 {
@@ -113,72 +96,6 @@
 	}
 }
 
-pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset)
-{
-	pmd_t *pmd;
-
-	pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, 1);
-	if (pgd_none(*pgd)) {
-		if (pmd) {
-			pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table);
-			pgd_set(pgd, pmd);
-			return pmd + offset;
-		}
-		pgd_set(pgd, BAD_PMDTABLE);
-		return NULL;
-	}
-	free_page((unsigned long)pmd);
-	if (pgd_bad(*pgd)) {
-		__bad_pmd(pgd);
-		return NULL;
-	}
-	return (pmd_t *) pgd_page(*pgd) + offset;
-}
-
-pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
-{
-	pte_t *page;
-
-	page = (pte_t *) __get_free_pages(GFP_USER, 1);
-	if (pmd_none(*pmd)) {
-		if (page) {
-			clear_page(page);
-			pmd_set(pmd, page);
-			return page + offset;
-		}
-		pmd_set(pmd, BAD_PAGETABLE);
-		return NULL;
-	}
-	free_page((unsigned long)page);
-	if (pmd_bad(*pmd)) {
-		__bad_pte_kernel(pmd);
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + offset;
-}
-
-pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
-{
-	pte_t *page;
-
-	page = (pte_t *) __get_free_pages(GFP_KERNEL, 0);
-	if (pmd_none(*pmd)) {
-		if (page) {
-			clear_page(page);
-			pmd_val(*pmd) = (unsigned long)page;
-			return page + offset;
-		}
-		pmd_set(pmd, BAD_PAGETABLE);
-		return NULL;
-	}
-	free_pages((unsigned long)page, 0);
-	if (pmd_bad(*pmd)) {
-		__bad_pte(pmd);
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + offset;
-}
-
 int do_check_pgt_cache(int low, int high)
 {
 	int freed = 0;
@@ -205,7 +122,7 @@
 }
 
 /*
- * We have upto 8 empty zeroed pages so we can map one of the right colour
+ * We have up to 8 empty zeroed pages so we can map one of the right colour
  * when needed.  This is necessary only on R4000 / R4400 SC and MC versions
  * where we have to avoid VCED / VECI exceptions for good performance at
  * any price.  Since page is never written to after the initialization we
@@ -247,32 +164,155 @@
 	return 1UL << order;
 }
 
-/*
- * BAD_PAGE is the page that is used for page faults when linux
- * is out-of-memory. Older versions of linux just did a
- * do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving a inode
- * unused etc..
- *
- * BAD_PAGETABLE is the accompanying page-table: it is initialized
- * to point to BAD_PAGE entries.
- *
- * ZERO_PAGE is a special page that is used for zero-initialized
- * data and COW.
- */
-pmd_t * __bad_pmd_table(void)
+void __init add_memory_region(unsigned long start, unsigned long size,
+                              long type)
 {
-	return empty_bad_pmd_table;
-}
+        int x = boot_mem_map.nr_map;
 
-pte_t * __bad_pagetable(void)
-{
-	return empty_bad_page_table;
+        if (x == BOOT_MEM_MAP_MAX) {
+                printk("Ooops! Too many entries in the memory map!\n");
+                return;
+        }
+
+        boot_mem_map.map[x].addr = start;
+        boot_mem_map.map[x].size = size;
+        boot_mem_map.map[x].type = type;
+        boot_mem_map.nr_map++;
+}
+
+static void __init print_memory_map(void)
+{
+        int i;
+
+        for (i = 0; i < boot_mem_map.nr_map; i++) {
+                printk(" memory: %08lx @ %08lx ",
+                        boot_mem_map.map[i].size, boot_mem_map.map[i].addr);
+                switch (boot_mem_map.map[i].type) {
+                case BOOT_MEM_RAM:
+                        printk("(usable)\n");
+                        break;
+                case BOOT_MEM_ROM_DATA:
+                        printk("(ROM data)\n");
+                        break;
+                case BOOT_MEM_RESERVED:
+                        printk("(reserved)\n");
+                        break;
+                default:
+                        printk("type %lu\n", boot_mem_map.map[i].type);
+                        break;
+                }
+        }
 }
 
-pte_t __bad_page(void)
-{
-	return __pte(0);
+void bootmem_init(void) {
+#ifdef CONFIG_BLK_DEV_INITRD
+	unsigned long tmp;
+	unsigned long *initrd_header;
+#endif
+	unsigned long bootmap_size;
+	unsigned long start_pfn, max_pfn;
+	int i;
+	extern int _end;
+
+#define PFN_UP(x)	(((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
+#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
+#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
+
+	/*
+	 * Partially used pages are not usable - thus
+	 * we are rounding upwards.
+	 */
+	start_pfn = PFN_UP(__pa(&_end));
+
+	/* Find the highest page frame number we have available.  */
+	max_pfn = 0;
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		unsigned long start, end;
+
+		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+			continue;
+
+		start = PFN_UP(boot_mem_map.map[i].addr);
+		end = PFN_DOWN(boot_mem_map.map[i].addr
+		      + boot_mem_map.map[i].size);
+
+		if (start >= end)
+			continue;
+		if (end > max_pfn)
+			max_pfn = end;
+	}
+
+	/* Initialize the boot-time allocator.  */
+	bootmap_size = init_bootmem(start_pfn, max_pfn);
+
+	/*
+	 * Register fully available low RAM pages with the bootmem allocator.
+	 */
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		unsigned long curr_pfn, last_pfn, size;
+
+		/*
+		 * Reserve usable memory.
+		 */
+		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+			continue;
+
+		/*
+		 * We are rounding up the start address of usable memory:
+		 */
+		curr_pfn = PFN_UP(boot_mem_map.map[i].addr);
+		if (curr_pfn >= max_pfn)
+			continue;
+		if (curr_pfn < start_pfn)
+			curr_pfn = start_pfn;
+
+		/*
+		 * ... and at the end of the usable range downwards:
+		 */
+		last_pfn = PFN_DOWN(boot_mem_map.map[i].addr
+				    + boot_mem_map.map[i].size);
+
+		if (last_pfn > max_pfn)
+			last_pfn = max_pfn;
+
+		/*
+		 * ... finally, did all the rounding and playing
+		 * around just make the area go away?
+		 */
+		if (last_pfn <= curr_pfn)
+			continue;
+
+		size = last_pfn - curr_pfn;
+		free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
+	}
+
+	/* Reserve the bootmap memory.  */
+	reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size);
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#error "Initrd is broken, please fit it."
+	tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8;
+	if (tmp < (unsigned long)&_end)
+		tmp += PAGE_SIZE;
+	initrd_header = (unsigned long *)tmp;
+	if (initrd_header[0] == 0x494E5244) {
+		initrd_start = (unsigned long)&initrd_header[2];
+		initrd_end = initrd_start + initrd_header[1];
+		initrd_below_start_ok = 1;
+		if (initrd_end > memory_end) {
+			printk("initrd extends beyond end of memory "
+			       "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+			       initrd_end,memory_end);
+			initrd_start = 0;
+		} else
+			*memory_start_p = initrd_end;
+	}
+#endif
+
+#undef PFN_UP
+#undef PFN_DOWN
+#undef PFN_PHYS
+
 }
 
 void show_mem(void)
@@ -312,27 +352,39 @@
 
 void __init paging_init(void)
 {
+	pmd_t *pmd = kpmdtbl;
+	pte_t *pte = kptbl;
+
 	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
 	unsigned long max_dma, low;
+	int i;
 
 	/* Initialize the entire pgd.  */
 	pgd_init((unsigned long)swapper_pg_dir);
 	pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
 	memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
-	pmd_init((unsigned long)empty_bad_pmd_table, (unsigned long)empty_bad_page_table);
-	memset((void *)empty_bad_page_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
 
 	max_dma =  virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
 	low = max_low_pfn;
 
+#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
 	if (low < max_dma)
 		zones_size[ZONE_DMA] = low;
 	else {
 		zones_size[ZONE_DMA] = max_dma;
 		zones_size[ZONE_NORMAL] = low - max_dma;
 	}
+#else
+	zones_size[ZONE_DMA] = low;
+#endif
 
 	free_area_init(zones_size);
+	
+	memset((void *)kptbl, 0, PAGE_SIZE << KPTBL_PAGE_ORDER);
+	memset((void *)kpmdtbl, 0, PAGE_SIZE);
+	pgd_set(swapper_pg_dir, kpmdtbl);
+	for (i = 0; i < (1 << KPTBL_PAGE_ORDER); pmd++,i++,pte+=PTRS_PER_PTE)
+		pmd_val(*pmd) = (unsigned long)pte;
 }
 
 extern int page_is_ram(unsigned long pagenr);
@@ -411,7 +463,7 @@
 si_meminfo(struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = 0;
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/mm/r4xx0.c linux/arch/mips64/mm/r4xx0.c
--- v2.4.6/linux/arch/mips64/mm/r4xx0.c	Sun Feb  4 21:48:46 2001
+++ linux/arch/mips64/mm/r4xx0.c	Wed Jul  4 11:50:39 2001
@@ -6,7 +6,7 @@
  * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/init.h>
@@ -377,7 +377,7 @@
 		"ld\t%3,-8(%1)\n\t"
 		"sd\t%2,-16(%0)\n\t"
 		"bne\t$1,%0,1b\n\t"
-		" sd\t%4,-8(%0)\n\t"
+		" sd\t%3,-8(%0)\n\t"
 		".set\tat\n\t"
 		".set\treorder"
 		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
@@ -1017,7 +1017,7 @@
 	struct vm_area_struct *vma;
 	unsigned long flags;
 
-	if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
+	if (CPU_CONTEXT(smp_processor_id(), mm) != 0)
 		return;
 
 	start &= PAGE_MASK;
@@ -1747,15 +1747,15 @@
 	unsigned long end, a;
 	unsigned int flags;
 
-	if (size >= dcache_size) {
+	if (size >= (unsigned long)dcache_size) {
 		flush_cache_l1();
 	} else {
 		/* Workaround for R4600 bug.  See comment above. */
 		__save_and_cli(flags);
 		*(volatile unsigned long *)KSEG1;
 
-		a = addr & ~(dc_lsize - 1);
-		end = (addr + size) & ~(dc_lsize - 1);
+		a = addr & ~((unsigned long)dc_lsize - 1);
+		end = (addr + size) & ~((unsigned long)dc_lsize - 1);
 		while (1) {
 			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
 			if (a == end) break;
@@ -1771,13 +1771,13 @@
 {
 	unsigned long end, a;
 
-	if (size >= scache_size) {
+	if (size >= (unsigned long)scache_size) {
 		flush_cache_l1();
 		return;
 	}
 
-	a = addr & ~(sc_lsize - 1);
-	end = (addr + size) & ~(sc_lsize - 1);
+	a = addr & ~((unsigned long)sc_lsize - 1);
+	end = (addr + size) & ~((unsigned long)sc_lsize - 1);
 	while (1) {
 		flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
 		if (a == end) break;
@@ -1791,15 +1791,15 @@
 	unsigned long end, a;
 	unsigned int flags;
 
-	if (size >= dcache_size) {
+	if (size >= (unsigned long)dcache_size) {
 		flush_cache_l1();
 	} else {
 		/* Workaround for R4600 bug.  See comment above. */
 		__save_and_cli(flags);
 		*(volatile unsigned long *)KSEG1;
 
-		a = addr & ~(dc_lsize - 1);
-		end = (addr + size) & ~(dc_lsize - 1);
+		a = addr & ~((unsigned long)dc_lsize - 1);
+		end = (addr + size) & ~((unsigned long)dc_lsize - 1);
 		while (1) {
 			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
 			if (a == end) break;
@@ -1816,13 +1816,13 @@
 {
 	unsigned long end, a;
 
-	if (size >= scache_size) {
+	if (size >= (unsigned long)scache_size) {
 		flush_cache_l1();
 		return;
 	}
 
-	a = addr & ~(sc_lsize - 1);
-	end = (addr + size) & ~(sc_lsize - 1);
+	a = addr & ~((unsigned long)sc_lsize - 1);
+	end = (addr + size) & ~((unsigned long)sc_lsize - 1);
 	while (1) {
 		flush_scache_line(a); /* Hit_Writeback_Inv_SD */
 		if (a == end) break;
@@ -1845,11 +1845,11 @@
 {
 	unsigned long daddr, iaddr;
 
-	daddr = addr & ~(dc_lsize - 1);
+	daddr = addr & ~((unsigned long)dc_lsize - 1);
 	__asm__ __volatile__("nop;nop;nop;nop");	/* R4600 V1.7 */
 	protected_writeback_dcache_line(daddr);
 	protected_writeback_dcache_line(daddr + dc_lsize);
-	iaddr = addr & ~(ic_lsize - 1);
+	iaddr = addr & ~((unsigned long)ic_lsize - 1);
 	protected_flush_icache_line(iaddr);
 	protected_flush_icache_line(iaddr + ic_lsize);
 }
@@ -1859,7 +1859,7 @@
 	unsigned long daddr, iaddr;
 	unsigned int flags;
 
-	daddr = addr & ~(dc_lsize - 1);
+	daddr = addr & ~((unsigned long)dc_lsize - 1);
 	__save_and_cli(flags);
 
 	/* Clear internal cache refill buffer */
@@ -1867,7 +1867,7 @@
 
 	protected_writeback_dcache_line(daddr);
 	protected_writeback_dcache_line(daddr + dc_lsize);
-	iaddr = addr & ~(ic_lsize - 1);
+	iaddr = addr & ~((unsigned long)ic_lsize - 1);
 	protected_flush_icache_line(iaddr);
 	protected_flush_icache_line(iaddr + ic_lsize);
 	__restore_flags(flags);
@@ -2384,7 +2384,11 @@
 
 	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
 
+#ifdef CONFIG_MIPS_UNCACHED
+	set_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+#else
 	set_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+#endif /* UNCACHED */
 
 	probe_icache(config);
 	probe_dcache(config);
diff -u --recursive --new-file v2.4.6/linux/arch/mips64/mm/umap.c linux/arch/mips64/mm/umap.c
--- v2.4.6/linux/arch/mips64/mm/umap.c	Mon Mar 19 12:35:10 2001
+++ linux/arch/mips64/mm/umap.c	Wed Jul  4 11:50:39 2001
@@ -1,11 +1,11 @@
-/* $Id: umap.c,v 1.4 2000/01/29 01:41:59 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1994 Linus Torvalds
  * Copyright (C) 1997 Miguel de Icaza
+ * Copyright (C) 2001 Ralf Baechle
  */
 #include <linux/stat.h>
 #include <linux/sched.h>
@@ -16,6 +16,7 @@
 #include <linux/shm.h>
 #include <linux/errno.h>
 #include <linux/mman.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
 #include <linux/swap.h>
@@ -101,9 +102,12 @@
 	up_write (&task->mm->mmap_sem);
 }
 
+EXPORT_SYMBOL(remove_mapping);
+
 void *vmalloc_uncached (unsigned long size)
 {
-	return vmalloc_prot (size, PAGE_KERNEL_UNCACHED);
+	return __vmalloc (size, GFP_KERNEL | __GFP_HIGHMEM,
+				PAGE_KERNEL_UNCACHED);
 }
 
 static inline void free_pte(pte_t page)
diff -u --recursive --new-file v2.4.6/linux/arch/ppc/kernel/pmac_pci.c linux/arch/ppc/kernel/pmac_pci.c
--- v2.4.6/linux/arch/ppc/kernel/pmac_pci.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/kernel/pmac_pci.c	Wed Jul  4 11:50:39 2001
@@ -249,7 +249,7 @@
 	out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID);
 	udelay(2);
 	vendev = in_le32((volatile unsigned int *)bp->cfg_data);
-	if (vendev == (PCI_VENDOR_ID_APPLE_BANDIT << 16) + 
+	if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) + 
 			PCI_VENDOR_ID_APPLE) {
 		/* read the revision id */
 		out_le32(bp->cfg_addr,
diff -u --recursive --new-file v2.4.6/linux/arch/s390/kernel/entry.S linux/arch/s390/kernel/entry.S
--- v2.4.6/linux/arch/s390/kernel/entry.S	Wed Apr 11 19:02:27 2001
+++ linux/arch/s390/kernel/entry.S	Wed Jul  4 11:50:39 2001
@@ -668,7 +668,7 @@
         la      %r2,SP_PTREGS(%r15) # address of register-save area
         srl     %r3,2
         cl      %r3,BASED(.Lc4)   # protection-exception ?
-        bne     BASED(pgm_go)     # if not,
+        bne     BASED(pgm_per)    # if not,
         l       %r5,SP_PSW+4(15)  # load psw addr
         sr      %r5,%r7           # substract ilc from psw
         st      %r5,SP_PSW+4(15)  # store corrected psw addr
diff -u --recursive --new-file v2.4.6/linux/arch/s390/kernel/head.S linux/arch/s390/kernel/head.S
--- v2.4.6/linux/arch/s390/kernel/head.S	Wed Apr 11 19:02:27 2001
+++ linux/arch/s390/kernel/head.S	Wed Jul  4 11:50:39 2001
@@ -262,8 +262,7 @@
         la    %r2,IPL_BS                       # load start address
         bas   %r14,.Lloader                    # load rest of ipl image
         l     %r12,.Lparm                      # pointer to parameter area
-        st    %r1,__LC_IPLDEV                  # store ipl device number
-        st    %r1,IPL_DEVICE-PARMAREA(%r12)
+        st    %r1,IPL_DEVICE-PARMAREA(%r12)    # store ipl device number
 
 #
 # load parameter file from ipl device
@@ -463,7 +462,9 @@
 startup:basr  %r13,0                     # get base
 .LPG1:  lctl  %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
 	l     %r12,.Lparm1-.LPG1(%r13)   # pointer to parameter area
-
+					 # move IPL device to lowcore
+        mvc   __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
+	
 #
 # find out memory size.
 #
diff -u --recursive --new-file v2.4.6/linux/arch/s390/kernel/irq.c linux/arch/s390/kernel/irq.c
--- v2.4.6/linux/arch/s390/kernel/irq.c	Wed Apr 11 19:02:27 2001
+++ linux/arch/s390/kernel/irq.c	Wed Jul  4 11:50:39 2001
@@ -386,8 +386,11 @@
         /* For now, nothing... */
 }
 
+#ifdef CONFIG_SMP
 EXPORT_SYMBOL(__global_cli);
 EXPORT_SYMBOL(__global_sti);
 EXPORT_SYMBOL(__global_save_flags);
 EXPORT_SYMBOL(__global_restore_flags);
+#endif
+
 EXPORT_SYMBOL(global_bh_lock);
diff -u --recursive --new-file v2.4.6/linux/arch/s390/kernel/reipl.S linux/arch/s390/kernel/reipl.S
--- v2.4.6/linux/arch/s390/kernel/reipl.S	Tue Feb 13 14:13:43 2001
+++ linux/arch/s390/kernel/reipl.S	Wed Jul  4 11:50:39 2001
@@ -55,7 +55,7 @@
 .Ldispsw:	.long   0x000a0000,0x00000000
 .Liplccws:	.long   0x02000000,0x60000018
 		.long   0x08000008,0x20000001
-.Liplorb:	.long	0x0049504c,0x0000ff80
+.Liplorb:	.long	0x0049504c,0x0040ff80
 		.long	0x00000000+.Liplccws
 .Lschib:        .long   0x00000000,0x00000000
 		.long   0x00000000,0x00000000
diff -u --recursive --new-file v2.4.6/linux/arch/s390/kernel/smp.c linux/arch/s390/kernel/smp.c
--- v2.4.6/linux/arch/s390/kernel/smp.c	Wed Apr 11 19:02:28 2001
+++ linux/arch/s390/kernel/smp.c	Wed Jul  4 11:50:39 2001
@@ -420,6 +420,7 @@
 void smp_ptlb_all(void)
 {
         smp_ext_call_others(smp_ptlb_callback, NULL, 1);
+	local_flush_tlb();
 }
 
 /*
@@ -522,8 +523,7 @@
  */
 {
         if (atomic_read(&smp_commenced) != 0)
-                smp_ext_call_others(func, info, 1);
-        (func)(info);
+                smp_ext_call_others(func, info, wait);
         return 0;
 }
 
@@ -776,3 +776,4 @@
 EXPORT_SYMBOL(kernel_flag);
 EXPORT_SYMBOL(smp_ctl_set_bit);
 EXPORT_SYMBOL(smp_ctl_clear_bit);
+EXPORT_SYMBOL(smp_num_cpus);
diff -u --recursive --new-file v2.4.6/linux/arch/s390x/kernel/entry.S linux/arch/s390x/kernel/entry.S
--- v2.4.6/linux/arch/s390x/kernel/entry.S	Wed Apr 11 19:02:29 2001
+++ linux/arch/s390x/kernel/entry.S	Wed Jul  4 11:50:39 2001
@@ -632,8 +632,6 @@
  * we just ignore the PER event (FIXME: is there anything we have to do
  * for LPSW?).
  */
-	stmg    %r14,%r15,__LC_SAVE_AREA
-        stam    %a2,%a4,__LC_SAVE_AREA+16
         tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
         jz      pgm_sv                   # skip if not
         tm      __LC_PGM_OLD_PSW,0x40    # test if per event recording is on
@@ -642,29 +640,10 @@
         clc     __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW
         je      pgm_svcper
 # no interesting special case, ignore PER event
-        lm      %r13,%r15,__LC_SAVE_AREA
 	lpswe   __LC_PGM_OLD_PSW
 # it was a single stepped SVC that is causing all the trouble
 pgm_svcper:
-        tm      __LC_SVC_OLD_PSW+1,0x01  # test problem state bit
-	jz	0f                       # skip stack & access regs setup
-	lg      %r15,__LC_KERNEL_STACK   # problem state -> load ksp
-        slr     %r14,%r14
-        sar     %a2,%r14                 # set ac.reg. 2 to primary space
-        lhi     %r14,1   
-        sar     %a4,%r14                 # and access reg. 4 to home space
-0:	aghi    %r15,-SP_SIZE            # make room for registers & psw
-        nill    %r15,0xfff8              # align stack pointer to 8
-        stmg    %r0,%r14,SP_R0(%r15)     # store gprs 0-14 to kernel stack 
-        stg     %r2,SP_ORIG_R2(%r15)     # store original content of gpr 2
-        mvc     SP_R14(16,%r15),__LC_SAVE_AREA         # move R14-R15 to stack
-        stam    %a0,%a15,SP_AREGS(%r15)  # store access registers to kst.
-        mvc     SP_AREGS+8(12,%r15),__LC_SAVE_AREA+16 # store ac. regs
-        mvc     SP_PSW(16,%r15),__LC_PGM_OLD_PSW      # move user PSW to stack
-        lhi     %r0,__LC_SVC_OLD_PSW     # store trap indication
-        st      %r0,SP_TRAP(%r15)
-        xc      0(8,%r15),0(%r15)        # clear back chain
-
+	SAVE_ALL __LC_SVC_OLD_PSW
         mvc     SP_PGM_OLD_ILC(4,%r15),__LC_PGM_ILC # save program check information
         j       pgm_system_call          # now do the svc
 pgm_svcret:
@@ -674,24 +653,7 @@
         mvi     SP_PGM_OLD_ILC(%r15),1   # mark PGM_OLD_ILC as invalid
 	j       pgm_no_sv
 pgm_sv:
-        tm      __LC_PGM_OLD_PSW+1,0x01  # test problem state bit
-	jz	1f		         # skip stack setup save
-	lg      %r15,__LC_KERNEL_STACK   # problem state -> load ksp
-        slr     %r14,%r14
-        sar     %a2,%r14                 # set ac.reg. 2 to primary space
-        lhi     %r14,1
-        sar     %a4,%r14                 # set access reg. 4 to home space
-1:	aghi    %r15,-SP_SIZE            # make room for registers & psw
-        nill    %r15,0xfff8              # align stack pointer to 8
-        stmg    %r0,%r14,SP_R0(%r15)     # store gprs 0-14 to kernel stack
-        stg     %r2,SP_ORIG_R2(%r15)     # store original content of gpr 2
-        mvc     SP_R14(16,%r15),__LC_SAVE_AREA         # move R14-R15 to stack
-        stam    %a0,%a15,SP_AREGS(%r15)  # store access registers to kst.
-        mvc     SP_AREGS+8(12,%r15),__LC_SAVE_AREA+16 # store ac. regs
-        mvc     SP_PSW(16,%r15),__LC_PGM_OLD_PSW      # move user PSW to stack
-        lhi     %r0,__LC_PGM_OLD_PSW     # store trap indication
-        st      %r0,SP_TRAP(%r15)
-        xc      0(8,%r15),0(%r15)        # clear back chain
+	SAVE_ALL __LC_PGM_OLD_PSW
         mvi     SP_PGM_OLD_ILC(%r15),1   # mark PGM_OLD_ILC as invalid
         llgh    %r7,__LC_PGM_ILC         # load instruction length
 	GET_CURRENT
@@ -823,8 +785,10 @@
         .globl restart_int_handler
 restart_int_handler:
         lg      %r15,__LC_KERNEL_STACK # load ksp
-        lctlg   %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
-        lam     %a0,%a15,__LC_AREGS_SAVE_AREA
+        lhi     %r10,__LC_CREGS_SAVE_AREA
+        lctlg   %c0,%c15,0(%r10) # get new ctl regs
+        lhi     %r10,__LC_AREGS_SAVE_AREA
+        lam     %a0,%a15,0(%r10)
         stosm   0(%r15),0x04           # now we can turn dat on
         lmg     %r6,%r15,48(%r15)      # load registers from clone
 	jg      start_secondary
diff -u --recursive --new-file v2.4.6/linux/arch/s390x/kernel/head.S linux/arch/s390x/kernel/head.S
--- v2.4.6/linux/arch/s390x/kernel/head.S	Wed Apr 11 19:02:29 2001
+++ linux/arch/s390x/kernel/head.S	Wed Jul  4 11:50:39 2001
@@ -262,8 +262,7 @@
         la    %r2,IPL_BS                       # load start address
         bas   %r14,.Lloader                    # load rest of ipl image
         l     %r12,.Lparm                      # pointer to parameter area
-        st    %r1,__LC_IPLDEV                  # store ipl device number
-        st    %r1,IPL_DEVICE+4-PARMAREA(%r12)
+        st    %r1,IPL_DEVICE+4-PARMAREA(%r12)  # store ipl device number
 
 #
 # load parameter file from ipl device
@@ -467,6 +466,8 @@
 	sam64				 # switch to 64 bit mode
 	lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
 	lg    %r12,.Lparm1-.LPG1(%r13)   # pointer to parameter area
+					 # move IPL device to lowcore
+        mvc   __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
 
 #
 # find out memory size.
diff -u --recursive --new-file v2.4.6/linux/arch/s390x/kernel/irq.c linux/arch/s390x/kernel/irq.c
--- v2.4.6/linux/arch/s390x/kernel/irq.c	Wed Apr 11 19:02:29 2001
+++ linux/arch/s390x/kernel/irq.c	Wed Jul  4 11:50:39 2001
@@ -380,8 +380,11 @@
         /* For now, nothing... */
 }
 
+#ifdef CONFIG_SMP
 EXPORT_SYMBOL(__global_cli);
 EXPORT_SYMBOL(__global_sti);
 EXPORT_SYMBOL(__global_save_flags);
 EXPORT_SYMBOL(__global_restore_flags);
+#endif
+
 EXPORT_SYMBOL(global_bh_lock);
diff -u --recursive --new-file v2.4.6/linux/arch/s390x/kernel/linux32.c linux/arch/s390x/kernel/linux32.c
--- v2.4.6/linux/arch/s390x/kernel/linux32.c	Thu Apr 26 14:10:16 2001
+++ linux/arch/s390x/kernel/linux32.c	Wed Jul  4 11:50:39 2001
@@ -897,24 +897,24 @@
 	return sys32_fcntl(fd, cmd, arg);
 }
 
-struct dqblk32 {
-    __u32 dqb_bhardlimit;
-    __u32 dqb_bsoftlimit;
-    __u32 dqb_curblocks;
+struct mem_dqblk32 {
     __u32 dqb_ihardlimit;
     __u32 dqb_isoftlimit;
     __u32 dqb_curinodes;
+    __u32 dqb_bhardlimit;
+    __u32 dqb_bsoftlimit;
+    __u64 dqb_curspace;
     __kernel_time_t32 dqb_btime;
     __kernel_time_t32 dqb_itime;
 };
                                 
-extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
+extern asmlinkage long sys_quotactl(int cmd, const char *special, int id, __kernel_caddr_t addr);
 
 asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr)
 {
 	int cmds = cmd >> SUBCMDSHIFT;
 	int err;
-	struct dqblk d;
+	struct mem_dqblk d;
 	mm_segment_t old_fs;
 	char *spec;
 	
@@ -924,33 +924,35 @@
 	case Q_SETQUOTA:
 	case Q_SETUSE:
 	case Q_SETQLIM:
-		if (copy_from_user (&d, (struct dqblk32 *)addr,
-				    sizeof (struct dqblk32)))
+		if (copy_from_user (&d, (struct mem_dqblk32 *)addr,
+				    sizeof (struct mem_dqblk32)))
 			return -EFAULT;
-		d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
-		d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
+		d.dqb_itime = ((struct mem_dqblk32 *)&d)->dqb_itime;
+		d.dqb_btime = ((struct mem_dqblk32 *)&d)->dqb_btime;
 		break;
 	default:
 		return sys_quotactl(cmd, special,
-				    id, (caddr_t)addr);
+				    id, (__kernel_caddr_t)addr);
 	}
 	spec = getname (special);
 	err = PTR_ERR(spec);
 	if (IS_ERR(spec)) return err;
 	old_fs = get_fs ();
 	set_fs (KERNEL_DS);
-	err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
+	err = sys_quotactl(cmd, (const char *)spec, id, (__kernel_caddr_t)&d);
 	set_fs (old_fs);
 	putname (spec);
+	if (err)
+		return err;
 	if (cmds == Q_GETQUOTA) {
 		__kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
-		((struct dqblk32 *)&d)->dqb_itime = i;
-		((struct dqblk32 *)&d)->dqb_btime = b;
-		if (copy_to_user ((struct dqblk32 *)addr, &d,
-				  sizeof (struct dqblk32)))
+		((struct mem_dqblk32 *)&d)->dqb_itime = i;
+		((struct mem_dqblk32 *)&d)->dqb_btime = b;
+		if (copy_to_user ((struct mem_dqblk32 *)addr, &d,
+				  sizeof (struct mem_dqblk32)))
 			return -EFAULT;
 	}
-	return err;
+	return 0;
 }
 
 static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
diff -u --recursive --new-file v2.4.6/linux/arch/s390x/kernel/reipl.S linux/arch/s390x/kernel/reipl.S
--- v2.4.6/linux/arch/s390x/kernel/reipl.S	Tue Feb 13 14:13:44 2001
+++ linux/arch/s390x/kernel/reipl.S	Wed Jul  4 11:50:39 2001
@@ -73,7 +73,7 @@
 		.quad   0x0000000000000000
 .Liplccws:	.long   0x02000000,0x60000018
 		.long   0x08000008,0x20000001
-.Liplorb:	.long	0x0049504c,0x0000ff80
+.Liplorb:	.long	0x0049504c,0x0040ff80
 		.long	0x00000000+.Liplccws
 .Lschib:        .long   0x00000000,0x00000000
 		.long   0x00000000,0x00000000
diff -u --recursive --new-file v2.4.6/linux/arch/s390x/kernel/smp.c linux/arch/s390x/kernel/smp.c
--- v2.4.6/linux/arch/s390x/kernel/smp.c	Wed Apr 11 19:02:29 2001
+++ linux/arch/s390x/kernel/smp.c	Wed Jul  4 11:50:39 2001
@@ -510,8 +510,7 @@
  */
 {
         if (atomic_read(&smp_commenced) != 0)
-                smp_ext_call_others(func, info, 1);
-        (func)(info);
+                smp_ext_call_others(func, info, wait);
         return 0;
 }
 
diff -u --recursive --new-file v2.4.6/linux/arch/s390x/mm/fault.c linux/arch/s390x/mm/fault.c
--- v2.4.6/linux/arch/s390x/mm/fault.c	Thu Apr 26 14:10:16 2001
+++ linux/arch/s390x/mm/fault.c	Wed Jul  4 11:50:39 2001
@@ -33,6 +33,34 @@
 
 extern void die(const char *,struct pt_regs *,long);
 
+extern spinlock_t timerlist_lock;
+
+/*
+ * Unlock any spinlocks which will prevent us from getting the
+ * message out
+ */
+void bust_spinlocks(int yes)
+{
+        spin_lock_init(&timerlist_lock);
+        if (yes) {
+                oops_in_progress = 1;
+#ifdef CONFIG_SMP
+                atomic_set(&global_irq_lock,0);
+#endif
+        } else {
+                int loglevel_save = console_loglevel;
+                oops_in_progress = 0;
+                /*
+                 * OK, the message is on the console.  Now we call printk()
+                 * without oops_in_progress set so that printk will give klogd
+                 * a poke.  Hold onto your hats...
+                 */
+                console_loglevel = 15;          /* NMI oopser may have shut the console up */
+                printk(" ");
+                console_loglevel = loglevel_save;
+        }
+}
+
 /*
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
diff -u --recursive --new-file v2.4.6/linux/drivers/cdrom/mcd.c linux/drivers/cdrom/mcd.c
--- v2.4.6/linux/drivers/cdrom/mcd.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/cdrom/mcd.c	Wed Jul  4 11:50:39 2001
@@ -105,17 +105,17 @@
 #define mcd_port mcd    /* for compatible parameter passing with "insmod" */
 #include "mcd.h"
 
-static int mcd_blocksizes[1] = { 0, };
+static int mcd_blocksizes[1];
 
 
 /* I added A flag to drop to 1x speed if too many errors 0 = 1X ; 1 = 2X */
-static int mcdDouble = 0; 
+static int mcdDouble; 
 
 /* How many sectors to hold at 1x speed counter */
-static int mcd1xhold = 0;
+static int mcd1xhold;
 
 /* Is the drive connected properly and responding?? */
-static int mcdPresent = 0;
+static int mcdPresent;
 
 #if 0
 #define TEST1 /* <int-..> */
@@ -162,7 +162,7 @@
 #define WORK_AROUND_MITSUMI_BUG_92
 #define WORK_AROUND_MITSUMI_BUG_93
 #ifdef WORK_AROUND_MITSUMI_BUG_93
-int mitsumi_bug_93_wait = 0;
+int mitsumi_bug_93_wait;
 #endif /* WORK_AROUND_MITSUMI_BUG_93 */
 
 static short mcd_port = CONFIG_MCD_BASE; /* used as "mcd" by "insmod" */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/irda/Config.in linux/drivers/net/irda/Config.in
--- v2.4.6/linux/drivers/net/irda/Config.in	Tue May  1 16:05:00 2001
+++ linux/drivers/net/irda/Config.in	Wed Jul  4 11:50:38 2001
@@ -23,6 +23,7 @@
 dep_tristate 'Toshiba Type-O IR Port' CONFIG_TOSHIBA_FIR $CONFIG_IRDA
 if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
 dep_tristate 'SMC IrCC (Experimental)' CONFIG_SMC_IRCC_FIR $CONFIG_IRDA
+dep_tristate 'ALi M5123 FIR (Experimental)' CONFIG_ALI_FIR $CONFIG_IRDA
 fi
 
 endmenu
diff -u --recursive --new-file v2.4.6/linux/drivers/net/irda/Makefile linux/drivers/net/irda/Makefile
--- v2.4.6/linux/drivers/net/irda/Makefile	Tue May  1 16:05:00 2001
+++ linux/drivers/net/irda/Makefile	Wed Jul  4 11:50:38 2001
@@ -17,6 +17,7 @@
 obj-$(CONFIG_WINBOND_FIR)	+= w83977af_ir.o
 obj-$(CONFIG_TOSHIBA_FIR)	+= toshoboe.o
 obj-$(CONFIG_SMC_IRCC_FIR)	+= smc-ircc.o	irport.o
+obj-$(CONFIG_ALI_FIR)		+= ali-ircc.o
 obj-$(CONFIG_ESI_DONGLE)	+= esi.o
 obj-$(CONFIG_TEKRAM_DONGLE)	+= tekram.o
 obj-$(CONFIG_ACTISYS_DONGLE)	+= actisys.o
diff -u --recursive --new-file v2.4.6/linux/drivers/net/irda/ali-ircc.c linux/drivers/net/irda/ali-ircc.c
--- v2.4.6/linux/drivers/net/irda/ali-ircc.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/irda/ali-ircc.c	Wed Jul  4 11:50:38 2001
@@ -0,0 +1,2306 @@
+/*********************************************************************
+ *                
+ * Filename:      ali-ircc.h
+ * Version:       0.5
+ * Description:   Driver for the ALI M1535D and M1543C FIR Controller
+ * Status:        Experimental.
+ * Author:        Benjamin Kong <benjamin_kong@ali.com.tw>
+ * Created at:    2000/10/16 03:46PM
+ * Modified at:   2001/1/3 02:55PM
+ * Modified by:   Benjamin Kong <benjamin_kong@ali.com.tw>
+ * 
+ *     Copyright (c) 2000 Benjamin Kong <benjamin_kong@ali.com.tw>
+ *     All Rights Reserved
+ *      
+ *     This program is free software; you can redistribute it and/or 
+ *     modify it under the terms of the GNU General Public License as 
+ *     published by the Free Software Foundation; either version 2 of 
+ *     the License, or (at your option) any later version.
+ *  
+ ********************************************************************/
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/malloc.h>
+#include <linux/init.h>
+#include <linux/rtnetlink.h>
+#include <linux/serial_reg.h>
+
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/byteorder.h>
+
+#include <linux/pm.h>
+
+#include <net/irda/wrapper.h>
+#include <net/irda/irda.h>
+#include <net/irda/irmod.h>
+#include <net/irda/irlap_frame.h>
+#include <net/irda/irda_device.h>
+
+#include <net/irda/ali-ircc.h>
+
+#define CHIP_IO_EXTENT 8
+#define BROKEN_DONGLE_ID
+
+static char *driver_name = "ali-ircc";
+
+/* Module parameters */
+static int qos_mtt_bits = 0x07;  /* 1 ms or more */
+
+/* Use BIOS settions by default, but user may supply module parameters */
+static unsigned int io[]  = { ~0, ~0, ~0, ~0 };
+static unsigned int irq[] = { 0, 0, 0, 0 };
+static unsigned int dma[] = { 0, 0, 0, 0 };
+
+static int  ali_ircc_probe_43(ali_chip_t *chip, chipio_t *info);
+static int  ali_ircc_probe_53(ali_chip_t *chip, chipio_t *info);
+static int  ali_ircc_init_43(ali_chip_t *chip, chipio_t *info);
+static int  ali_ircc_init_53(ali_chip_t *chip, chipio_t *info);
+
+/* These are the currently known ALi sourth-bridge chipsets, the only one difference
+ * is that M1543C doesn't support HP HDSL-3600
+ */
+static ali_chip_t chips[] =
+{
+	{ "M1543", { 0x3f0, 0x370 }, 0x51, 0x23, 0x20, 0x43, ali_ircc_probe_53, ali_ircc_init_43 },
+	{ "M1535", { 0x3f0, 0x370 }, 0x51, 0x23, 0x20, 0x53, ali_ircc_probe_53, ali_ircc_init_53 },
+	{ NULL }
+};
+
+/* Max 4 instances for now */
+static struct ali_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL };
+
+/* Dongle Types */
+static char *dongle_types[] = {
+	"TFDS6000",
+	"HP HSDL-3600",
+	"HP HSDL-1100",	
+	"No dongle connected",
+};
+
+/* Some prototypes */
+static int  ali_ircc_open(int i, chipio_t *info);
+
+#ifdef MODULE
+static int  ali_ircc_close(struct ali_ircc_cb *self);
+#endif /* MODULE */
+
+static int  ali_ircc_setup(chipio_t *info);
+static int  ali_ircc_is_receiving(struct ali_ircc_cb *self);
+static int  ali_ircc_net_init(struct net_device *dev);
+static int  ali_ircc_net_open(struct net_device *dev);
+static int  ali_ircc_net_close(struct net_device *dev);
+static int  ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int  ali_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data);
+static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud);
+static void ali_ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void ali_ircc_suspend(struct ali_ircc_cb *self);
+static void ali_ircc_wakeup(struct ali_ircc_cb *self);
+static struct net_device_stats *ali_ircc_net_get_stats(struct net_device *dev);
+
+/* SIR function */
+static int  ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev);
+static void ali_ircc_sir_interrupt(int irq, struct ali_ircc_cb *self, struct pt_regs *regs);
+static void ali_ircc_sir_receive(struct ali_ircc_cb *self);
+static void ali_ircc_sir_write_wakeup(struct ali_ircc_cb *self);
+static int  ali_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len);
+static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed);
+
+/* FIR function */
+static int  ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev);
+static void ali_ircc_fir_change_speed(struct ali_ircc_cb *priv, __u32 speed);
+static void ali_ircc_fir_interrupt(int irq, struct ali_ircc_cb *self, struct pt_regs *regs);
+static int  ali_ircc_dma_receive(struct ali_ircc_cb *self); 
+static int  ali_ircc_dma_receive_complete(struct ali_ircc_cb *self);
+static int  ali_ircc_dma_xmit_complete(struct ali_ircc_cb *self);
+static void ali_ircc_dma_xmit(struct ali_ircc_cb *self);
+
+/* My Function */
+static int  ali_ircc_read_dongle_id (int i, chipio_t *info);
+static void ali_ircc_change_dongle_speed(struct ali_ircc_cb *priv, int speed);
+
+/* ALi chip function */
+static void SIR2FIR(int iobase);
+static void FIR2SIR(int iobase);
+static void SetCOMInterrupts(struct ali_ircc_cb *self , unsigned char enable);
+
+/*
+ * Function ali_ircc_init ()
+ *
+ *    Initialize chip. Find out whay kinds of chips we are dealing with
+ *    and their configuation registers address
+ */
+int __init ali_ircc_init(void)
+{
+	ali_chip_t *chip;
+	chipio_t info;
+	int ret = -ENODEV;
+	int cfg, cfg_base;
+	int reg, revision;
+	int i = 0;
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	/* Probe for all the ALi chipsets we know about */
+	for (chip= chips; chip->name; chip++, i++) 
+	{
+		IRDA_DEBUG(2, __FUNCTION__"(), Probing for %s ...\n", chip->name);
+				
+		/* Try all config registers for this chip */
+		for (cfg=0; cfg<2; cfg++)
+		{
+			cfg_base = chip->cfg[cfg];
+			if (!cfg_base)
+				continue;
+				
+			memset(&info, 0, sizeof(chipio_t));
+			info.cfg_base = cfg_base;
+			info.fir_base = io[i];
+			info.dma = dma[i];
+			info.irq = irq[i];
+			
+			
+			/* Enter Configuration */
+			outb(chip->entr1, cfg_base);
+			outb(chip->entr2, cfg_base);
+			
+			/* Select Logical Device 5 Registers (UART2) */
+			outb(0x07, cfg_base);
+			outb(0x05, cfg_base+1);
+			
+			/* Read Chip Identification Register */
+			outb(chip->cid_index, cfg_base);	
+			reg = inb(cfg_base+1);	
+				
+			if (reg == chip->cid_value)
+			{
+				IRDA_DEBUG(2, __FUNCTION__
+					"(), Chip found at 0x%03x\n", cfg_base);
+					   
+				outb(0x1F, cfg_base);
+				revision = inb(cfg_base+1);
+				IRDA_DEBUG(2, __FUNCTION__ 
+					   "(), Found %s chip, revision=%d\n",
+					   chip->name, revision);					
+				
+				/* 
+				 * If the user supplies the base address, then
+				 * we init the chip, if not we probe the values
+				 * set by the BIOS
+				 */				
+				if (io[i] < 2000)
+				{
+					chip->init(chip, &info);
+				}
+				else
+				{
+					chip->probe(chip, &info);	
+				}
+				
+				if (ali_ircc_open(i, &info) == 0)
+					ret = 0;
+				i++;				
+			}
+			else
+			{
+				IRDA_DEBUG(2, __FUNCTION__ 
+					   "(), No %s chip at 0x%03x\n", chip->name, cfg_base);
+			}
+			/* Exit configuration */
+			outb(0xbb, cfg_base);
+		}
+	}		
+		
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End -----------------\n");					   		
+	return ret;
+}
+
+/*
+ * Function ali_ircc_cleanup ()
+ *
+ *    Close all configured chips
+ *
+ */
+#ifdef MODULE
+static void ali_ircc_cleanup(void)
+{
+	int i;
+
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");	
+	
+	pm_unregister_all(ali_ircc_pmproc);
+
+	for (i=0; i < 4; i++) {
+		if (dev_self[i])
+			ali_ircc_close(dev_self[i]);
+	}
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End -----------------\n");
+}
+#endif /* MODULE */
+
+/*
+ * Function ali_ircc_open (int i, chipio_t *inf)
+ *
+ *    Open driver instance
+ *
+ */
+static int ali_ircc_open(int i, chipio_t *info)
+{
+	struct net_device *dev;
+	struct ali_ircc_cb *self;
+	struct pm_dev *pmdev;
+	int dongle_id;
+	int ret;
+	int err;
+			
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");	
+	
+	/* Set FIR FIFO and DMA Threshold */
+	if ((ali_ircc_setup(info)) == -1)
+		return -1;
+		
+	/* Allocate new instance of the driver */
+	self = kmalloc(sizeof(struct ali_ircc_cb), GFP_KERNEL);
+	if (self == NULL) 
+	{
+		ERROR(__FUNCTION__ "(), can't allocate memory for control block!\n");
+		return -ENOMEM;
+	}
+	memset(self, 0, sizeof(struct ali_ircc_cb));
+	spin_lock_init(&self->lock);
+   
+	/* Need to store self somewhere */
+	dev_self[i] = self;
+	self->index = i;
+
+	/* Initialize IO */
+	self->io.cfg_base  = info->cfg_base;	/* In ali_ircc_probe_53 assign 		*/
+	self->io.fir_base  = info->fir_base;	/* info->sir_base = info->fir_base 	*/
+	self->io.sir_base  = info->sir_base; 	/* ALi SIR and FIR use the same address */
+        self->io.irq       = info->irq;
+        self->io.fir_ext   = CHIP_IO_EXTENT;
+        self->io.dma       = info->dma;
+        self->io.fifo_size = 16;		/* SIR: 16, FIR: 32 Benjamin 2000/11/1 */
+	
+	/* Reserve the ioports that we need */
+	ret = check_region(self->io.fir_base, self->io.fir_ext);
+	if (ret < 0) { 
+		WARNING(__FUNCTION__ "(), can't get iobase of 0x%03x\n",
+			self->io.fir_base);
+		dev_self[i] = NULL;
+		kfree(self);
+		return -ENODEV;
+	}
+	request_region(self->io.fir_base, self->io.fir_ext, driver_name);
+
+	/* Initialize QoS for this device */
+	irda_init_max_qos_capabilies(&self->qos);
+	
+	/* The only value we must override it the baudrate */
+	self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
+		IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8); // benjamin 2000/11/8 05:27PM
+			
+	self->qos.min_turn_time.bits = qos_mtt_bits;
+			
+	irda_qos_bits_to_value(&self->qos);
+	
+	self->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO; 	// benjamin 2000/11/8 05:27PM	
+
+	/* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */
+	self->rx_buff.truesize = 14384; 
+	self->tx_buff.truesize = 14384;
+
+	/* Allocate memory if needed */
+	self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
+					      GFP_KERNEL |GFP_DMA); 
+	if (self->rx_buff.head == NULL) 
+	{
+		kfree(self);
+		return -ENOMEM;
+	}
+	memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+	
+	self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
+					      GFP_KERNEL|GFP_DMA); 
+	if (self->tx_buff.head == NULL) {
+		kfree(self);
+		kfree(self->rx_buff.head);
+		return -ENOMEM;
+	}
+	memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+
+	self->rx_buff.in_frame = FALSE;
+	self->rx_buff.state = OUTSIDE_FRAME;
+	self->tx_buff.data = self->tx_buff.head;
+	self->rx_buff.data = self->rx_buff.head;
+	
+	/* Reset Tx queue info */
+	self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
+	self->tx_fifo.tail = self->tx_buff.head;
+
+	if (!(dev = dev_alloc("irda%d", &err))) {
+		ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
+		return -ENOMEM;
+	}
+
+	dev->priv = (void *) self;
+	self->netdev = dev;
+	
+	/* Override the network functions we need to use */
+	dev->init            = ali_ircc_net_init;
+	dev->hard_start_xmit = ali_ircc_sir_hard_xmit;
+	dev->open            = ali_ircc_net_open;
+	dev->stop            = ali_ircc_net_close;
+	dev->do_ioctl        = ali_ircc_net_ioctl;
+	dev->get_stats	     = ali_ircc_net_get_stats;
+
+	rtnl_lock();
+	err = register_netdevice(dev);
+	rtnl_unlock();
+	if (err) {
+		ERROR(__FUNCTION__ "(), register_netdev() failed!\n");
+		return -1;
+	}
+	MESSAGE("IrDA: Registered device %s\n", dev->name);
+
+	/* Check dongle id */
+	dongle_id = ali_ircc_read_dongle_id(i, info);
+	MESSAGE(__FUNCTION__ "(), %s, Found dongle: %s\n", driver_name, dongle_types[dongle_id]);
+		
+	self->io.dongle_id = dongle_id;
+	
+        pmdev = pm_register(PM_SYS_DEV, PM_SYS_IRDA, ali_ircc_pmproc);
+        if (pmdev)
+                pmdev->data = self;
+
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End -----------------\n");
+	
+	return 0;
+}
+
+
+#ifdef MODULE
+/*
+ * Function ali_ircc_close (self)
+ *
+ *    Close driver instance
+ *
+ */
+static int ali_ircc_close(struct ali_ircc_cb *self)
+{
+	int iobase;
+
+	IRDA_DEBUG(4, __FUNCTION__ "(), ---------------- Start ----------------\n");
+
+	ASSERT(self != NULL, return -1;);
+
+        iobase = self->io.fir_base;
+
+	/* Remove netdevice */
+	if (self->netdev) {
+		rtnl_lock();
+		unregister_netdevice(self->netdev);
+		rtnl_unlock();
+	}
+
+	/* Release the PORT that this driver is using */
+	IRDA_DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", self->io.fir_base);
+	release_region(self->io.fir_base, self->io.fir_ext);
+
+	if (self->tx_buff.head)
+		kfree(self->tx_buff.head);
+	
+	if (self->rx_buff.head)
+		kfree(self->rx_buff.head);
+
+	dev_self[self->index] = NULL;
+	kfree(self);
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End -----------------\n");
+	
+	return 0;
+}
+#endif /* MODULE */
+
+/*
+ * Function ali_ircc_init_43 (chip, info)
+ *
+ *    Initialize the ALi M1543 chip. 
+ */
+static int ali_ircc_init_43(ali_chip_t *chip, chipio_t *info) 
+{
+	/* All controller information like I/O address, DMA channel, IRQ
+	 * are set by BIOS
+	 */
+	
+	return 0;
+}
+
+/*
+ * Function ali_ircc_init_53 (chip, info)
+ *
+ *    Initialize the ALi M1535 chip. 
+ */
+static int ali_ircc_init_53(ali_chip_t *chip, chipio_t *info) 
+{
+	/* All controller information like I/O address, DMA channel, IRQ
+	 * are set by BIOS
+	 */
+	
+	return 0;
+}
+
+/*
+ * Function ali_ircc_probe_43 (chip, info)
+ *    	
+ *	Probes for the ALi M1543
+ */
+static int ali_ircc_probe_43(ali_chip_t *chip, chipio_t *info)
+{
+	return 0;	
+}
+
+/*
+ * Function ali_ircc_probe_53 (chip, info)
+ *    	
+ *	Probes for the ALi M1535D or M1535
+ */
+static int ali_ircc_probe_53(ali_chip_t *chip, chipio_t *info)
+{
+	int cfg_base = info->cfg_base;
+	int hi, low, reg;
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	/* Enter Configuration */
+	outb(chip->entr1, cfg_base);
+	outb(chip->entr2, cfg_base);
+	
+	/* Select Logical Device 5 Registers (UART2) */
+	outb(0x07, cfg_base);
+	outb(0x05, cfg_base+1);
+	
+	/* Read address control register */
+	outb(0x60, cfg_base);
+	hi = inb(cfg_base+1);	
+	outb(0x61, cfg_base);
+	low = inb(cfg_base+1);
+	info->fir_base = (hi<<8) + low;
+	
+	info->sir_base = info->fir_base;
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), probing fir_base=0x%03x\n", info->fir_base);
+		
+	/* Read IRQ control register */
+	outb(0x70, cfg_base);
+	reg = inb(cfg_base+1);
+	info->irq = reg & 0x0f;
+	IRDA_DEBUG(2, __FUNCTION__ "(), probing irq=%d\n", info->irq);
+	
+	/* Read DMA channel */
+	outb(0x74, cfg_base);
+	reg = inb(cfg_base+1);
+	info->dma = reg & 0x07;
+	
+	if(info->dma == 0x04)
+		WARNING(__FUNCTION__ "(), No DMA channel assigned !\n");
+	else
+		IRDA_DEBUG(2, __FUNCTION__ "(), probing dma=%d\n", info->dma);
+	
+	/* Read Enabled Status */
+	outb(0x30, cfg_base);
+	reg = inb(cfg_base+1);
+	info->enabled = (reg & 0x80) && (reg & 0x01);
+	IRDA_DEBUG(2, __FUNCTION__ "(), probing enabled=%d\n", info->enabled);
+	
+	/* Read Power Status */
+	outb(0x22, cfg_base);
+	reg = inb(cfg_base+1);
+	info->suspended = (reg & 0x20);
+	IRDA_DEBUG(2, __FUNCTION__ "(), probing suspended=%d\n", info->suspended);
+	
+	/* Exit configuration */
+	outb(0xbb, cfg_base);
+		
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End -----------------\n");	
+	
+	return 0;	
+}
+
+/*
+ * Function ali_ircc_setup (info)
+ *
+ *    	Set FIR FIFO and DMA Threshold
+ *	Returns non-negative on success.
+ *
+ */
+static int ali_ircc_setup(chipio_t *info)
+{
+	unsigned char tmp;
+	int version;
+	int iobase = info->fir_base;
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	/* Switch to FIR space */
+	SIR2FIR(iobase);
+	
+	/* Master Reset */
+	outb(0x40, iobase+FIR_MCR); // benjamin 2000/11/30 11:45AM
+	
+	/* Read FIR ID Version Register */
+	switch_bank(iobase, BANK3);
+	version = inb(iobase+FIR_ID_VR);
+	
+	/* Should be 0x00 in the M1535/M1535D */
+	if(version != 0x00)
+	{
+		ERROR("%s, Wrong chip version %02x\n", driver_name, version);
+		return -1;
+	}
+	
+	// MESSAGE("%s, Found chip at base=0x%03x\n", driver_name, info->cfg_base);
+	
+	/* Set FIR FIFO Threshold Register */
+	switch_bank(iobase, BANK1);
+	outb(RX_FIFO_Threshold, iobase+FIR_FIFO_TR);
+	
+	/* Set FIR DMA Threshold Register */
+	outb(RX_DMA_Threshold, iobase+FIR_DMA_TR);
+	
+	/* CRC enable */
+	switch_bank(iobase, BANK2);
+	outb(inb(iobase+FIR_IRDA_CR) | IRDA_CR_CRC, iobase+FIR_IRDA_CR);
+	
+	/* NDIS driver set TX Length here BANK2 Alias 3, Alias4*/
+	
+	/* Switch to Bank 0 */
+	switch_bank(iobase, BANK0);
+	
+	tmp = inb(iobase+FIR_LCR_B);
+	tmp &=~0x20; // disable SIP
+	tmp |= 0x80; // these two steps make RX mode
+	tmp &= 0xbf;	
+	outb(tmp, iobase+FIR_LCR_B);
+		
+	/* Disable Interrupt */
+	outb(0x00, iobase+FIR_IER);
+	
+	
+	/* Switch to SIR space */
+	FIR2SIR(iobase);
+	
+	MESSAGE("%s, driver loaded (Benjamin Kong)\n", driver_name);
+	
+	/* Enable receive interrupts */ 
+	// outb(UART_IER_RDI, iobase+UART_IER); //benjamin 2000/11/23 01:25PM
+	// Turn on the interrupts in ali_ircc_net_open
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	
+	return 0;
+}
+
+/*
+ * Function ali_ircc_read_dongle_id (int index, info)
+ *
+ * Try to read dongle indentification. This procedure needs to be executed
+ * once after power-on/reset. It also needs to be used whenever you suspect
+ * that the user may have plugged/unplugged the IrDA Dongle.
+ */
+static int ali_ircc_read_dongle_id (int i, chipio_t *info)
+{
+	int dongle_id, reg;
+	int cfg_base = info->cfg_base;
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+		
+	/* Enter Configuration */
+	outb(chips[i].entr1, cfg_base);
+	outb(chips[i].entr2, cfg_base);
+	
+	/* Select Logical Device 5 Registers (UART2) */
+	outb(0x07, cfg_base);
+	outb(0x05, cfg_base+1);
+	
+	/* Read Dongle ID */
+	outb(0xf0, cfg_base);
+	reg = inb(cfg_base+1);	
+	dongle_id = ((reg>>6)&0x02) | ((reg>>5)&0x01);
+	IRDA_DEBUG(2, __FUNCTION__ "(), probing dongle_id=%d, dongle_types=%s\n", 
+		dongle_id, dongle_types[dongle_id]);
+	
+	/* Exit configuration */
+	outb(0xbb, cfg_base);
+			
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	
+	return dongle_id;
+}
+
+/*
+ * Function ali_ircc_interrupt (irq, dev_id, regs)
+ *
+ *    An interrupt from the chip has arrived. Time to do some work
+ *
+ */
+static void ali_ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct ali_ircc_cb *self;
+		
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+		
+ 	if (!dev) {
+		WARNING("%s: irq %d for unknown device.\n", driver_name, irq);
+		return;
+	}	
+	
+	self = (struct ali_ircc_cb *) dev->priv;
+	
+	spin_lock(&self->lock);
+	
+	/* Dispatch interrupt handler for the current speed */
+	if (self->io.speed > 115200)
+		ali_ircc_fir_interrupt(irq, self, regs);
+	else
+		ali_ircc_sir_interrupt(irq, self, regs);	
+		
+	spin_unlock(&self->lock);
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");		
+}
+/*
+ * Function ali_ircc_fir_interrupt(irq, struct ali_ircc_cb *self, regs)
+ *
+ *    Handle MIR/FIR interrupt
+ *
+ */
+static void ali_ircc_fir_interrupt(int irq, struct ali_ircc_cb *self, struct pt_regs *regs)
+{
+	__u8 eir, OldMessageCount;
+	int iobase, tmp;
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	iobase = self->io.fir_base;
+	
+	switch_bank(iobase, BANK0);	
+	self->InterruptID = inb(iobase+FIR_IIR);		
+	self->BusStatus = inb(iobase+FIR_BSR);	
+	
+	OldMessageCount = (self->LineStatus + 1) & 0x07;
+	self->LineStatus = inb(iobase+FIR_LSR);	
+	//self->ier = inb(iobase+FIR_IER); 		2000/12/1 04:32PM
+	eir = self->InterruptID & self->ier; /* Mask out the interesting ones */ 
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), self->InterruptID = %x\n",self->InterruptID);
+	IRDA_DEBUG(1, __FUNCTION__ "(), self->LineStatus = %x\n",self->LineStatus);
+	IRDA_DEBUG(1, __FUNCTION__ "(), self->ier = %x\n",self->ier);
+	IRDA_DEBUG(1, __FUNCTION__ "(), eir = %x\n",eir);
+	
+	/* Disable interrupts */
+	 SetCOMInterrupts(self, FALSE);
+	
+	/* Tx or Rx Interrupt */
+	
+	if (eir & IIR_EOM) 
+	{		
+		if (self->io.direction == IO_XMIT) /* TX */
+		{
+			IRDA_DEBUG(1, __FUNCTION__ "(), ******* IIR_EOM (Tx) *******\n");
+			
+			if(ali_ircc_dma_xmit_complete(self))
+			{
+				if (irda_device_txqueue_empty(self->netdev)) 
+				{
+					/* Prepare for receive */
+					ali_ircc_dma_receive(self);					
+					self->ier = IER_EOM;									
+				}
+			}
+			else
+			{
+				self->ier = IER_EOM; 					
+			}
+									
+		}	
+		else /* RX */
+		{
+			IRDA_DEBUG(1, __FUNCTION__ "(), ******* IIR_EOM (Rx) *******\n");
+			
+			if(OldMessageCount > ((self->LineStatus+1) & 0x07))
+			{
+				self->rcvFramesOverflow = TRUE;	
+				IRDA_DEBUG(1, __FUNCTION__ "(), ******* self->rcvFramesOverflow = TRUE ******** \n");
+			}
+						
+			if (ali_ircc_dma_receive_complete(self))
+			{
+				IRDA_DEBUG(1, __FUNCTION__ "(), ******* receive complete ******** \n");
+				
+				self->ier = IER_EOM;				
+			}
+			else
+			{
+				IRDA_DEBUG(1, __FUNCTION__ "(), ******* Not receive complete ******** \n");
+				
+				self->ier = IER_EOM | IER_TIMER;								
+			}	
+		
+		}		
+	}
+	/* Timer Interrupt */
+	else if (eir & IIR_TIMER)
+	{	
+		if(OldMessageCount > ((self->LineStatus+1) & 0x07))
+		{
+			self->rcvFramesOverflow = TRUE;	
+			IRDA_DEBUG(1, __FUNCTION__ "(), ******* self->rcvFramesOverflow = TRUE ******* \n");
+		}
+		/* Disable Timer */
+		switch_bank(iobase, BANK1);
+		tmp = inb(iobase+FIR_CR);
+		outb( tmp& ~CR_TIMER_EN, iobase+FIR_CR);
+		
+		/* Check if this is a Tx timer interrupt */
+		if (self->io.direction == IO_XMIT)
+		{
+			ali_ircc_dma_xmit(self);
+			
+			/* Interrupt on EOM */
+			self->ier = IER_EOM;
+									
+		}
+		else /* Rx */
+		{
+			if(ali_ircc_dma_receive_complete(self)) 
+			{
+				self->ier = IER_EOM;
+			}
+			else
+			{
+				self->ier = IER_EOM | IER_TIMER;
+			}	
+		}		
+	}
+	
+	/* Restore Interrupt */	
+	SetCOMInterrupts(self, TRUE);	
+		
+	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ---------------\n");
+}
+
+/*
+ * Function ali_ircc_sir_interrupt (irq, self, eir)
+ *
+ *    Handle SIR interrupt
+ *
+ */
+static void ali_ircc_sir_interrupt(int irq, struct ali_ircc_cb *self, struct pt_regs *regs)
+{
+	int iobase;
+	int iir, lsr;
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	iobase = self->io.sir_base;
+
+	iir = inb(iobase+UART_IIR) & UART_IIR_ID;
+	if (iir) {	
+		/* Clear interrupt */
+		lsr = inb(iobase+UART_LSR);
+
+		IRDA_DEBUG(4, __FUNCTION__ 
+			   "(), iir=%02x, lsr=%02x, iobase=%#x\n", 
+			   iir, lsr, iobase);
+
+		switch (iir) 
+		{
+			case UART_IIR_RLSI:
+				IRDA_DEBUG(2, __FUNCTION__ "(), RLSI\n");
+				break;
+			case UART_IIR_RDI:
+				/* Receive interrupt */
+				ali_ircc_sir_receive(self);
+				break;
+			case UART_IIR_THRI:
+				if (lsr & UART_LSR_THRE)
+				{
+					/* Transmitter ready for data */
+					ali_ircc_sir_write_wakeup(self);				
+				}				
+				break;
+			default:
+				IRDA_DEBUG(0, __FUNCTION__ "(), unhandled IIR=%#x\n", iir);
+				break;
+		} 
+		
+	}
+	
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+}
+
+
+/*
+ * Function ali_ircc_sir_receive (self)
+ *
+ *    Receive one frame from the infrared port
+ *
+ */
+static void ali_ircc_sir_receive(struct ali_ircc_cb *self) 
+{
+	int boguscount = 0;
+	int iobase;
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	ASSERT(self != NULL, return;);
+
+	iobase = self->io.sir_base;
+
+	/*  
+	 * Receive all characters in Rx FIFO, unwrap and unstuff them. 
+         * async_unwrap_char will deliver all found frames  
+	 */
+	do {
+		async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, 
+				  inb(iobase+UART_RX));
+
+		/* Make sure we don't stay here to long */
+		if (boguscount++ > 32) {
+			IRDA_DEBUG(2,__FUNCTION__ "(), breaking!\n");
+			break;
+		}
+	} while (inb(iobase+UART_LSR) & UART_LSR_DR);	
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+}
+
+/*
+ * Function ali_ircc_sir_write_wakeup (tty)
+ *
+ *    Called by the driver when there's room for more data.  If we have
+ *    more packets to send, we send them here.
+ *
+ */
+static void ali_ircc_sir_write_wakeup(struct ali_ircc_cb *self)
+{
+	int actual = 0;
+	int iobase;	
+
+	ASSERT(self != NULL, return;);
+
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	iobase = self->io.sir_base;
+
+	/* Finished with frame?  */
+	if (self->tx_buff.len > 0)  
+	{
+		/* Write data left in transmit buffer */
+		actual = ali_ircc_sir_write(iobase, self->io.fifo_size, 
+				      self->tx_buff.data, self->tx_buff.len);
+		self->tx_buff.data += actual;
+		self->tx_buff.len  -= actual;
+	} 
+	else 
+	{
+		if (self->new_speed) 
+		{
+			/* We must wait until all data are gone */
+			while(!(inb(iobase+UART_LSR) & UART_LSR_TEMT))
+				IRDA_DEBUG(1, __FUNCTION__ "(), UART_LSR_THRE\n");
+			
+			IRDA_DEBUG(1, __FUNCTION__ "(), Changing speed! self->new_speed = %d\n", self->new_speed);
+			ali_ircc_change_speed(self, self->new_speed);
+			self->new_speed = 0;			
+			
+			// benjamin 2000/11/10 06:32PM
+			if (self->io.speed > 115200)
+			{
+				IRDA_DEBUG(2, __FUNCTION__ "(), ali_ircc_change_speed from UART_LSR_TEMT \n");				
+					
+				self->ier = IER_EOM;
+				// SetCOMInterrupts(self, TRUE);							
+				return;							
+			}
+		}
+		else
+		{
+			netif_wake_queue(self->netdev);	
+		}
+			
+		self->stats.tx_packets++;
+		
+		/* Turn on receive interrupts */
+		outb(UART_IER_RDI, iobase+UART_IER);
+	}
+		
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+}
+
+static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud)
+{
+	struct net_device *dev = self->netdev;
+	int iobase;
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), setting speed = %d \n", baud);
+	
+	iobase = self->io.fir_base;
+	
+	SetCOMInterrupts(self, FALSE); // 2000/11/24 11:43AM
+	
+	/* Go to MIR, FIR Speed */
+	if (baud > 115200)
+	{
+		
+					
+		ali_ircc_fir_change_speed(self, baud);			
+		
+		/* Install FIR xmit handler*/
+		dev->hard_start_xmit = ali_ircc_fir_hard_xmit;		
+				
+		/* Enable Interuupt */
+		self->ier = IER_EOM; // benjamin 2000/11/20 07:24PM					
+				
+		/* Be ready for incomming frames */
+		ali_ircc_dma_receive(self);	// benajmin 2000/11/8 07:46PM not complete
+	}	
+	/* Go to SIR Speed */
+	else
+	{
+		ali_ircc_sir_change_speed(self, baud);
+				
+		/* Install SIR xmit handler*/
+		dev->hard_start_xmit = ali_ircc_sir_hard_xmit;
+	}
+	
+		
+	SetCOMInterrupts(self, TRUE);	// 2000/11/24 11:43AM
+		
+	netif_wake_queue(self->netdev);	
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+}
+
+static void ali_ircc_fir_change_speed(struct ali_ircc_cb *priv, __u32 baud)
+{
+		
+	int iobase; 
+	struct ali_ircc_cb *self = (struct ali_ircc_cb *) priv;
+	struct net_device *dev;
+
+	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start ----------------\n");
+		
+	ASSERT(self != NULL, return;);
+
+	dev = self->netdev;
+	iobase = self->io.fir_base;
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), self->io.speed = %d, change to speed = %d\n",self->io.speed,baud);
+	
+	/* Come from SIR speed */
+	if(self->io.speed <=115200)
+	{
+		SIR2FIR(iobase);
+	}
+		
+	/* Update accounting for new speed */
+	self->io.speed = baud;
+		
+	// Set Dongle Speed mode
+	ali_ircc_change_dongle_speed(self, baud);
+		
+	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");	
+}
+
+/*
+ * Function ali_sir_change_speed (self, speed)
+ *
+ *    Set speed of IrDA port to specified baudrate
+ *
+ */
+static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed)
+{
+	struct ali_ircc_cb *self = (struct ali_ircc_cb *) priv;
+	unsigned long flags;
+	int iobase; 
+	int fcr;    /* FIFO control reg */
+	int lcr;    /* Line control reg */
+	int divisor;
+
+	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), Setting speed to: %d\n", speed);
+
+	ASSERT(self != NULL, return;);
+
+	iobase = self->io.sir_base;
+	
+	/* Come from MIR or FIR speed */
+	if(self->io.speed >115200)
+	{	
+		// Set Dongle Speed mode first
+		ali_ircc_change_dongle_speed(self, speed);
+			
+		FIR2SIR(iobase);
+	}
+		
+	// Clear Line and Auxiluary status registers 2000/11/24 11:47AM
+		
+	inb(iobase+UART_LSR);
+	inb(iobase+UART_SCR);
+		
+	/* Update accounting for new speed */
+	self->io.speed = speed;
+
+	spin_lock_irqsave(&self->lock, flags);
+
+	divisor = 115200/speed;
+	
+	fcr = UART_FCR_ENABLE_FIFO;
+
+	/* 
+	 * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
+	 * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
+	 * about this timeout since it will always be fast enough. 
+	 */
+	if (self->io.speed < 38400)
+		fcr |= UART_FCR_TRIGGER_1;
+	else 
+		fcr |= UART_FCR_TRIGGER_14;
+        
+	/* IrDA ports use 8N1 */
+	lcr = UART_LCR_WLEN8;
+	
+	outb(UART_LCR_DLAB | lcr, iobase+UART_LCR); /* Set DLAB */
+	outb(divisor & 0xff,      iobase+UART_DLL); /* Set speed */
+	outb(divisor >> 8,	  iobase+UART_DLM);
+	outb(lcr,		  iobase+UART_LCR); /* Set 8N1	*/
+	outb(fcr,		  iobase+UART_FCR); /* Enable FIFO's */
+
+	/* without this, the conection will be broken after come back from FIR speed,
+	   but with this, the SIR connection is harder to established */
+	outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase+UART_MCR);
+	
+	spin_unlock_irqrestore(&self->lock, flags);
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");	
+}
+
+static void ali_ircc_change_dongle_speed(struct ali_ircc_cb *priv, int speed)
+{
+	
+	struct ali_ircc_cb *self = (struct ali_ircc_cb *) priv;
+	int iobase,dongle_id;
+	unsigned long flags;
+	int tmp = 0;
+			
+	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start ----------------\n");	
+	
+	iobase = self->io.fir_base; 	/* or iobase = self->io.sir_base; */
+	dongle_id = self->io.dongle_id;
+	
+	save_flags(flags);
+	cli();
+		
+	IRDA_DEBUG(1, __FUNCTION__ "(), Set Speed for %s , Speed = %d\n", dongle_types[dongle_id], speed);		
+	
+	switch_bank(iobase, BANK2);
+	tmp = inb(iobase+FIR_IRDA_CR);
+		
+	/* IBM type dongle */
+	if(dongle_id == 0)
+	{				
+		if(speed == 4000000)
+		{
+			//	      __ __	
+			// SD/MODE __|     |__ __
+			//               __ __ 
+			// IRTX    __ __|     |__
+			//         T1 T2 T3 T4 T5
+			
+			tmp &=  ~IRDA_CR_HDLC;		// HDLC=0
+			tmp |= IRDA_CR_CRC;	   	// CRC=1
+			
+			switch_bank(iobase, BANK2);
+			outb(tmp, iobase+FIR_IRDA_CR);
+			
+      			// T1 -> SD/MODE:0 IRTX:0
+      			tmp &= ~0x09;
+      			tmp |= 0x02;
+      			outb(tmp, iobase+FIR_IRDA_CR);
+      			udelay(2);
+      			
+      			// T2 -> SD/MODE:1 IRTX:0
+      			tmp &= ~0x01;
+      			tmp |= 0x0a;
+      			outb(tmp, iobase+FIR_IRDA_CR);
+      			udelay(2);
+      			
+      			// T3 -> SD/MODE:1 IRTX:1
+      			tmp |= 0x0b;
+      			outb(tmp, iobase+FIR_IRDA_CR);
+      			udelay(2);
+      			
+      			// T4 -> SD/MODE:0 IRTX:1
+      			tmp &= ~0x08;
+      			tmp |= 0x03;
+      			outb(tmp, iobase+FIR_IRDA_CR);
+      			udelay(2);
+      			
+      			// T5 -> SD/MODE:0 IRTX:0
+      			tmp &= ~0x09;
+      			tmp |= 0x02;
+      			outb(tmp, iobase+FIR_IRDA_CR);
+      			udelay(2);
+      			
+      			// reset -> Normal TX output Signal
+      			outb(tmp & ~0x02, iobase+FIR_IRDA_CR);      			
+		}
+		else /* speed <=1152000 */
+		{	
+			//	      __	
+			// SD/MODE __|  |__
+			//
+			// IRTX    ________
+			//         T1 T2 T3  
+			
+			/* MIR 115200, 57600 */
+			if (speed==1152000)
+			{
+				tmp |= 0xA0;	   //HDLC=1, 1.152Mbps=1
+      			}
+      			else
+      			{
+				tmp &=~0x80;	   //HDLC 0.576Mbps
+				tmp |= 0x20;	   //HDLC=1,
+      			}			
+      			
+      			tmp |= IRDA_CR_CRC;	   	// CRC=1
+      			
+      			switch_bank(iobase, BANK2);
+      			outb(tmp, iobase+FIR_IRDA_CR);
+						
+			/* MIR 115200, 57600 */	
+						
+			//switch_bank(iobase, BANK2);			
+			// T1 -> SD/MODE:0 IRTX:0
+      			tmp &= ~0x09;
+      			tmp |= 0x02;
+      			outb(tmp, iobase+FIR_IRDA_CR);
+      			udelay(2);
+      			
+      			// T2 -> SD/MODE:1 IRTX:0
+      			tmp &= ~0x01;     
+      			tmp |= 0x0a;      
+      			outb(tmp, iobase+FIR_IRDA_CR);
+      			
+      			// T3 -> SD/MODE:0 IRTX:0
+      			tmp &= ~0x09;
+      			tmp |= 0x02;
+      			outb(tmp, iobase+FIR_IRDA_CR);
+      			udelay(2);
+      			
+      			// reset -> Normal TX output Signal
+      			outb(tmp & ~0x02, iobase+FIR_IRDA_CR);      						
+		}		
+	}
+	else if (dongle_id == 1) /* HP HDSL-3600 */
+	{
+		switch(speed)
+		{
+		case 4000000:
+			tmp &=  ~IRDA_CR_HDLC;	// HDLC=0
+			break;	
+			
+		case 1152000:
+			tmp |= 0xA0;	   	// HDLC=1, 1.152Mbps=1
+      			break;
+      			
+      		case 576000:
+      			tmp &=~0x80;	   	// HDLC 0.576Mbps
+			tmp |= 0x20;	   	// HDLC=1,
+			break;
+      		}			
+			
+		tmp |= IRDA_CR_CRC;	   	// CRC=1
+			
+		switch_bank(iobase, BANK2);
+      		outb(tmp, iobase+FIR_IRDA_CR);		
+	}
+	else /* HP HDSL-1100 */
+	{
+		if(speed <= 115200) /* SIR */
+		{
+			
+			tmp &= ~IRDA_CR_FIR_SIN;	// HP sin select = 0
+			
+			switch_bank(iobase, BANK2);
+      			outb(tmp, iobase+FIR_IRDA_CR);			
+		}
+		else /* MIR FIR */
+		{	
+			
+			switch(speed)
+			{
+			case 4000000:
+				tmp &=  ~IRDA_CR_HDLC;	// HDLC=0
+				break;	
+			
+			case 1152000:
+				tmp |= 0xA0;	   	// HDLC=1, 1.152Mbps=1
+      				break;
+      			
+      			case 576000:
+      				tmp &=~0x80;	   	// HDLC 0.576Mbps
+				tmp |= 0x20;	   	// HDLC=1,
+				break;
+      			}			
+			
+			tmp |= IRDA_CR_CRC;	   	// CRC=1
+			tmp |= IRDA_CR_FIR_SIN;		// HP sin select = 1
+			
+			switch_bank(iobase, BANK2);
+      			outb(tmp, iobase+FIR_IRDA_CR);			
+		}
+	}
+			
+	switch_bank(iobase, BANK0);
+	
+	restore_flags(flags);
+		
+	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");		
+}
+
+/*
+ * Function ali_ircc_sir_write (driver)
+ *
+ *    Fill Tx FIFO with transmit data
+ *
+ */
+static int ali_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len)
+{
+	int actual = 0;
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+		
+	/* Tx FIFO should be empty! */
+	if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
+		IRDA_DEBUG(0, __FUNCTION__ "(), failed, fifo not empty!\n");
+		return 0;
+	}
+        
+	/* Fill FIFO with current frame */
+	while ((fifo_size-- > 0) && (actual < len)) {
+		/* Transmit next byte */
+		outb(buf[actual], iobase+UART_TX);
+
+		actual++;
+	}
+	
+        IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	return actual;
+}
+
+/*
+ * Function ali_ircc_net_init (dev)
+ *
+ *    Initialize network device
+ *
+ */
+static int ali_ircc_net_init(struct net_device *dev)
+{
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	/* Setup to be a normal IrDA network device driver */
+	irda_device_setup(dev);
+
+	/* Insert overrides below this line! */
+
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	
+	return 0;
+}
+
+/*
+ * Function ali_ircc_net_open (dev)
+ *
+ *    Start the device
+ *
+ */
+static int ali_ircc_net_open(struct net_device *dev)
+{
+	struct ali_ircc_cb *self;
+	int iobase;
+		
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	ASSERT(dev != NULL, return -1;);
+	
+	self = (struct ali_ircc_cb *) dev->priv;
+	
+	ASSERT(self != NULL, return 0;);
+	
+	iobase = self->io.fir_base;
+	
+	/* Request IRQ and install Interrupt Handler */
+	if (request_irq(self->io.irq, ali_ircc_interrupt, 0, dev->name, dev)) 
+	{
+		WARNING("%s, unable to allocate irq=%d\n", driver_name, 
+			self->io.irq);
+		return -EAGAIN;
+	}
+	
+	/*
+	 * Always allocate the DMA channel after the IRQ, and clean up on 
+	 * failure.
+	 */
+	if (request_dma(self->io.dma, dev->name)) {
+		WARNING("%s, unable to allocate dma=%d\n", driver_name, 
+			self->io.dma);
+		free_irq(self->io.irq, self);
+		return -EAGAIN;
+	}
+	
+	/* Turn on interrups */
+	outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, iobase+UART_IER);
+
+	/* Ready to play! */
+	netif_start_queue(dev); //benjamin by irport
+	
+	/* 
+	 * Open new IrLAP layer instance, now that everything should be
+	 * initialized properly 
+	 */
+	self->irlap = irlap_open(dev, &self->qos);
+		
+	MOD_INC_USE_COUNT;
+
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	
+	return 0;
+}
+
+/*
+ * Function ali_ircc_net_close (dev)
+ *
+ *    Stop the device
+ *
+ */
+static int ali_ircc_net_close(struct net_device *dev)
+{	
+
+	struct ali_ircc_cb *self;
+	//int iobase;
+			
+	IRDA_DEBUG(4, __FUNCTION__ "(), ---------------- Start ----------------\n");
+		
+	ASSERT(dev != NULL, return -1;);
+
+	self = (struct ali_ircc_cb *) dev->priv;
+	ASSERT(self != NULL, return 0;);
+
+	/* Stop device */
+	netif_stop_queue(dev);
+	
+	/* Stop and remove instance of IrLAP */
+	if (self->irlap)
+		irlap_close(self->irlap);
+	self->irlap = NULL;
+		
+	disable_dma(self->io.dma);
+
+	/* Disable interrupts */
+	SetCOMInterrupts(self, FALSE);
+	       
+	free_irq(self->io.irq, dev);
+	free_dma(self->io.dma);
+
+	MOD_DEC_USE_COUNT;
+
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	
+	return 0;
+}
+
+/*
+ * Function ali_ircc_fir_hard_xmit (skb, dev)
+ *
+ *    Transmit the frame
+ *
+ */
+static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ali_ircc_cb *self;
+	unsigned long flags;
+	int iobase;
+	__u32 speed;
+	int mtt, diff;
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start -----------------\n");	
+	
+	self = (struct ali_ircc_cb *) dev->priv;
+	iobase = self->io.fir_base;
+
+	netif_stop_queue(dev);
+	
+	/* Check if we need to change the speed */
+	speed = irda_get_next_speed(skb);
+	if ((speed != self->io.speed) && (speed != -1)) {
+		/* Check for empty frame */
+		if (!skb->len) {
+			ali_ircc_change_speed(self, speed); 
+			dev_kfree_skb(skb);
+			return 0;
+		} else
+			self->new_speed = speed;
+	}
+
+	spin_lock_irqsave(&self->lock, flags);
+	
+	/* Register and copy this frame to DMA memory */
+	self->tx_fifo.queue[self->tx_fifo.free].start = self->tx_fifo.tail;
+	self->tx_fifo.queue[self->tx_fifo.free].len = skb->len;
+	self->tx_fifo.tail += skb->len;
+
+	self->stats.tx_bytes += skb->len;
+
+	memcpy(self->tx_fifo.queue[self->tx_fifo.free].start, skb->data, 
+	       skb->len);
+	
+	self->tx_fifo.len++;
+	self->tx_fifo.free++;
+
+	/* Start transmit only if there is currently no transmit going on */
+	if (self->tx_fifo.len == 1) 
+	{
+		/* Check if we must wait the min turn time or not */
+		mtt = irda_get_mtt(skb);
+				
+		if (mtt) 
+		{
+			/* Check how much time we have used already */
+			get_fast_time(&self->now);
+			
+			diff = self->now.tv_usec - self->stamp.tv_usec;
+			/* self->stamp is set from ali_ircc_dma_receive_complete() */
+							
+			IRDA_DEBUG(1, __FUNCTION__ "(), ******* diff = %d ******* \n", diff);	
+			
+			if (diff < 0) 
+				diff += 1000000;
+			
+			/* Check if the mtt is larger than the time we have
+			 * already used by all the protocol processing
+			 */
+			if (mtt > diff)
+			{				
+				mtt -= diff;
+								
+				/* 
+				 * Use timer if delay larger than 1000 us, and
+				 * use udelay for smaller values which should
+				 * be acceptable
+				 */
+				if (mtt > 500) 
+				{
+					/* Adjust for timer resolution */
+					mtt = (mtt+250) / 500; 	/* 4 discard, 5 get advanced, Let's round off */
+					
+					IRDA_DEBUG(1, __FUNCTION__ "(), ************** mtt = %d ***********\n", mtt);	
+					
+					/* Setup timer */
+					if (mtt == 1) /* 500 us */
+					{
+						switch_bank(iobase, BANK1);
+						outb(TIMER_IIR_500, iobase+FIR_TIMER_IIR);
+					}	
+					else if (mtt == 2) /* 1 ms */
+					{
+						switch_bank(iobase, BANK1);
+						outb(TIMER_IIR_1ms, iobase+FIR_TIMER_IIR);
+					}					
+					else /* > 2ms -> 4ms */
+					{
+						switch_bank(iobase, BANK1);
+						outb(TIMER_IIR_2ms, iobase+FIR_TIMER_IIR);
+					}
+					
+					
+					/* Start timer */
+					outb(inb(iobase+FIR_CR) | CR_TIMER_EN, iobase+FIR_CR);
+					self->io.direction = IO_XMIT;
+					
+					/* Enable timer interrupt */
+					self->ier = IER_TIMER;
+					SetCOMInterrupts(self, TRUE);					
+					
+					/* Timer will take care of the rest */
+					goto out; 
+				} 
+				else
+					udelay(mtt);
+			} // if (if (mtt > diff)
+		}// if (mtt) 
+				
+		/* Enable EOM interrupt */
+		self->ier = IER_EOM;
+		SetCOMInterrupts(self, TRUE);
+		
+		/* Transmit frame */
+		ali_ircc_dma_xmit(self);
+	} // if (self->tx_fifo.len == 1) 
+	
+ out:
+ 	
+	/* Not busy transmitting anymore if window is not full */
+	if (self->tx_fifo.free < MAX_TX_WINDOW)
+		netif_wake_queue(self->netdev);
+	
+	/* Restore bank register */
+	switch_bank(iobase, BANK0);
+
+	spin_unlock_irqrestore(&self->lock, flags);
+	dev_kfree_skb(skb);
+
+	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	return 0;	
+}
+
+
+static void ali_ircc_dma_xmit(struct ali_ircc_cb *self)
+{
+	int iobase, tmp;
+	unsigned char FIFO_OPTI, Hi, Lo;
+	
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start -----------------\n");	
+	
+	iobase = self->io.fir_base;
+	
+	/* FIFO threshold , this method comes from NDIS5 code */
+	
+	if(self->tx_fifo.queue[self->tx_fifo.ptr].len < TX_FIFO_Threshold)
+		FIFO_OPTI = self->tx_fifo.queue[self->tx_fifo.ptr].len-1;
+	else
+		FIFO_OPTI = TX_FIFO_Threshold;
+	
+	/* Disable DMA */
+	switch_bank(iobase, BANK1);
+	outb(inb(iobase+FIR_CR) & ~CR_DMA_EN, iobase+FIR_CR);
+	
+	self->io.direction = IO_XMIT;
+	
+	setup_dma(self->io.dma, 
+		  self->tx_fifo.queue[self->tx_fifo.ptr].start, 
+		  self->tx_fifo.queue[self->tx_fifo.ptr].len, 
+		  DMA_TX_MODE);
+		
+	/* Reset Tx FIFO */
+	switch_bank(iobase, BANK0);
+	outb(LCR_A_FIFO_RESET, iobase+FIR_LCR_A);
+	
+	/* Set Tx FIFO threshold */
+	if (self->fifo_opti_buf!=FIFO_OPTI) 
+	{
+		switch_bank(iobase, BANK1);
+	    	outb(FIFO_OPTI, iobase+FIR_FIFO_TR) ;
+	    	self->fifo_opti_buf=FIFO_OPTI;
+	}
+	
+	/* Set Tx DMA threshold */
+	switch_bank(iobase, BANK1);
+	outb(TX_DMA_Threshold, iobase+FIR_DMA_TR);
+	
+	/* Set max Tx frame size */
+	Hi = (self->tx_fifo.queue[self->tx_fifo.ptr].len >> 8) & 0x0f;
+	Lo = self->tx_fifo.queue[self->tx_fifo.ptr].len & 0xff;
+	switch_bank(iobase, BANK2);
+	outb(Hi, iobase+FIR_TX_DSR_HI);
+	outb(Lo, iobase+FIR_TX_DSR_LO);
+	
+	/* Disable SIP , Disable Brick Wall (we don't support in TX mode), Change to TX mode */
+	switch_bank(iobase, BANK0);	
+	tmp = inb(iobase+FIR_LCR_B);
+	tmp &= ~0x20; // Disable SIP
+	outb(((unsigned char)(tmp & 0x3f) | LCR_B_TX_MODE) & ~LCR_B_BW, iobase+FIR_LCR_B);
+	IRDA_DEBUG(1, __FUNCTION__ "(), ******* Change to TX mode: FIR_LCR_B = 0x%x ******* \n", inb(iobase+FIR_LCR_B));
+	
+	outb(0, iobase+FIR_LSR);
+			
+	/* Enable DMA and Burst Mode */
+	switch_bank(iobase, BANK1);
+	outb(inb(iobase+FIR_CR) | CR_DMA_EN | CR_DMA_BURST, iobase+FIR_CR);
+	
+	switch_bank(iobase, BANK0); 
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");
+}
+
+static int  ali_ircc_dma_xmit_complete(struct ali_ircc_cb *self)
+{
+	int iobase;
+	int ret = TRUE;
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start -----------------\n");	
+	
+	iobase = self->io.fir_base;
+	
+	/* Disable DMA */
+	switch_bank(iobase, BANK1);
+	outb(inb(iobase+FIR_CR) & ~CR_DMA_EN, iobase+FIR_CR);
+	
+	/* Check for underrun! */
+	switch_bank(iobase, BANK0);
+	if((inb(iobase+FIR_LSR) & LSR_FRAME_ABORT) == LSR_FRAME_ABORT)
+	
+	{
+		ERROR(__FUNCTION__ "(), ********* LSR_FRAME_ABORT *********\n");	
+		self->stats.tx_errors++;
+		self->stats.tx_fifo_errors++;		
+	}
+	else 
+	{
+		self->stats.tx_packets++;
+	}
+
+	/* Check if we need to change the speed */
+	if (self->new_speed) 
+	{
+		ali_ircc_change_speed(self, self->new_speed);
+		self->new_speed = 0;
+	}
+
+	/* Finished with this frame, so prepare for next */
+	self->tx_fifo.ptr++;
+	self->tx_fifo.len--;
+
+	/* Any frames to be sent back-to-back? */
+	if (self->tx_fifo.len) 
+	{
+		ali_ircc_dma_xmit(self);
+		
+		/* Not finished yet! */
+		ret = FALSE;
+	} 
+	else 
+	{	/* Reset Tx FIFO info */
+		self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
+		self->tx_fifo.tail = self->tx_buff.head;
+	}
+
+	/* Make sure we have room for more frames */
+	if (self->tx_fifo.free < MAX_TX_WINDOW) {
+		/* Not busy transmitting anymore */
+		/* Tell the network layer, that we can accept more frames */
+		netif_wake_queue(self->netdev);
+	}
+		
+	switch_bank(iobase, BANK0); 
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	return ret;
+}
+
+/*
+ * Function ali_ircc_dma_receive (self)
+ *
+ *    Get ready for receiving a frame. The device will initiate a DMA
+ *    if it starts to receive a frame.
+ *
+ */
+static int ali_ircc_dma_receive(struct ali_ircc_cb *self) 
+{
+	int iobase, tmp;
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start -----------------\n");	
+	
+	iobase = self->io.fir_base;
+	
+	/* Reset Tx FIFO info */
+	self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
+	self->tx_fifo.tail = self->tx_buff.head;
+		
+	/* Disable DMA */
+	switch_bank(iobase, BANK1);
+	outb(inb(iobase+FIR_CR) & ~CR_DMA_EN, iobase+FIR_CR);
+	
+	/* Reset Message Count */
+	switch_bank(iobase, BANK0);
+	outb(0x07, iobase+FIR_LSR);
+		
+	self->rcvFramesOverflow = FALSE;	
+	
+	self->LineStatus = inb(iobase+FIR_LSR) ;
+	
+	/* Reset Rx FIFO info */
+	self->io.direction = IO_RECV;
+	self->rx_buff.data = self->rx_buff.head;
+		
+	/* Reset Rx FIFO */
+	// switch_bank(iobase, BANK0);
+	outb(LCR_A_FIFO_RESET, iobase+FIR_LCR_A); 
+	
+	self->st_fifo.len = self->st_fifo.pending_bytes = 0;
+	self->st_fifo.tail = self->st_fifo.head = 0;
+		
+	setup_dma(self->io.dma, self->rx_buff.data, self->rx_buff.truesize, 
+		  DMA_RX_MODE);	
+	 
+	/* Set Receive Mode,Brick Wall */
+	//switch_bank(iobase, BANK0);
+	tmp = inb(iobase+FIR_LCR_B);
+	outb((unsigned char)(tmp &0x3f) | LCR_B_RX_MODE | LCR_B_BW , iobase + FIR_LCR_B); // 2000/12/1 05:16PM
+	IRDA_DEBUG(1, __FUNCTION__ "(), *** Change To RX mode: FIR_LCR_B = 0x%x *** \n", inb(iobase+FIR_LCR_B));
+			
+	/* Set Rx Threshold */
+	switch_bank(iobase, BANK1);
+	outb(RX_FIFO_Threshold, iobase+FIR_FIFO_TR);
+	outb(RX_DMA_Threshold, iobase+FIR_DMA_TR);
+		
+	/* Enable DMA and Burst Mode */
+	// switch_bank(iobase, BANK1);
+	outb(CR_DMA_EN | CR_DMA_BURST, iobase+FIR_CR);
+				
+	switch_bank(iobase, BANK0); 
+	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	return 0;
+}
+
+static int  ali_ircc_dma_receive_complete(struct ali_ircc_cb *self)
+{
+	struct st_fifo *st_fifo;
+	struct sk_buff *skb;
+	__u8 status, MessageCount;
+	int len, i, iobase, val;	
+
+	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start -----------------\n");	
+
+	st_fifo = &self->st_fifo;		
+	iobase = self->io.fir_base;	
+		
+	switch_bank(iobase, BANK0);
+	MessageCount = inb(iobase+ FIR_LSR)&0x07;
+	
+	if (MessageCount > 0)	
+		IRDA_DEBUG(0, __FUNCTION__ "(), Messsage count = %d,\n", MessageCount);	
+		
+	for (i=0; i<=MessageCount; i++)
+	{
+		/* Bank 0 */
+		switch_bank(iobase, BANK0);
+		status = inb(iobase+FIR_LSR);
+		
+		switch_bank(iobase, BANK2);
+		len = inb(iobase+FIR_RX_DSR_HI) & 0x0f;
+		len = len << 8; 
+		len |= inb(iobase+FIR_RX_DSR_LO);
+		
+		IRDA_DEBUG(1, __FUNCTION__ "(), RX Length = 0x%.2x,\n", len);	
+		IRDA_DEBUG(1, __FUNCTION__ "(), RX Status = 0x%.2x,\n", status);
+		
+		if (st_fifo->tail >= MAX_RX_WINDOW) {
+			IRDA_DEBUG(0, __FUNCTION__ "(), window is full!\n");
+			continue;
+		}
+			
+		st_fifo->entries[st_fifo->tail].status = status;
+		st_fifo->entries[st_fifo->tail].len = len;
+		st_fifo->pending_bytes += len;
+		st_fifo->tail++;
+		st_fifo->len++;
+	}
+			
+	for (i=0; i<=MessageCount; i++)
+	{	
+		/* Get first entry */
+		status = st_fifo->entries[st_fifo->head].status;
+		len    = st_fifo->entries[st_fifo->head].len;
+		st_fifo->pending_bytes -= len;
+		st_fifo->head++;
+		st_fifo->len--;			
+		
+		/* Check for errors */
+		if ((status & 0xd8) || self->rcvFramesOverflow || (len==0)) 		
+		{
+			IRDA_DEBUG(0,__FUNCTION__ "(), ************* RX Errors ************ \n");	
+			
+			/* Skip frame */
+			self->stats.rx_errors++;
+			
+			self->rx_buff.data += len;
+			
+			if (status & LSR_FIFO_UR) 
+			{
+				self->stats.rx_frame_errors++;
+				IRDA_DEBUG(0,__FUNCTION__ "(), ************* FIFO Errors ************ \n");
+			}	
+			if (status & LSR_FRAME_ERROR)
+			{
+				self->stats.rx_frame_errors++;
+				IRDA_DEBUG(0,__FUNCTION__ "(), ************* FRAME Errors ************ \n");
+			}
+							
+			if (status & LSR_CRC_ERROR) 
+			{
+				self->stats.rx_crc_errors++;
+				IRDA_DEBUG(0,__FUNCTION__ "(), ************* CRC Errors ************ \n");
+			}
+			
+			if(self->rcvFramesOverflow)
+			{
+				self->stats.rx_frame_errors++;
+				IRDA_DEBUG(0,__FUNCTION__ "(), ************* Overran DMA buffer ************ \n");								
+			}
+			if(len == 0)
+			{
+				self->stats.rx_frame_errors++;
+				IRDA_DEBUG(0,__FUNCTION__ "(), ********** Receive Frame Size = 0 ********* \n");
+			}
+		}	 
+		else 
+		{
+			
+			if (st_fifo->pending_bytes < 32) 
+			{
+				switch_bank(iobase, BANK0);
+				val = inb(iobase+FIR_BSR);	
+				if ((val& BSR_FIFO_NOT_EMPTY)== 0x80) 
+				{
+					IRDA_DEBUG(0, __FUNCTION__ "(), ************* BSR_FIFO_NOT_EMPTY ************ \n");
+					
+					/* Put this entry back in fifo */
+					st_fifo->head--;
+					st_fifo->len++;
+					st_fifo->pending_bytes += len;
+					st_fifo->entries[st_fifo->head].status = status;
+					st_fifo->entries[st_fifo->head].len = len;
+						
+					/*  
+		 			* DMA not finished yet, so try again 
+		 			* later, set timer value, resolution 
+		 			* 500 us 
+		 			*/
+					 
+					switch_bank(iobase, BANK1);
+					outb(TIMER_IIR_500, iobase+FIR_TIMER_IIR); // 2001/1/2 05:07PM
+					
+					/* Enable Timer */
+					outb(inb(iobase+FIR_CR) | CR_TIMER_EN, iobase+FIR_CR);
+						
+					return FALSE; /* I'll be back! */
+				}
+			}		
+			
+			/* 
+			 * Remember the time we received this frame, so we can
+			 * reduce the min turn time a bit since we will know
+			 * how much time we have used for protocol processing
+			 */
+			get_fast_time(&self->stamp);
+
+			skb = dev_alloc_skb(len+1);
+			if (skb == NULL)  
+			{
+				WARNING(__FUNCTION__ "(), memory squeeze, "
+					"dropping frame.\n");
+				self->stats.rx_dropped++;
+
+				return FALSE;
+			}
+			
+			/* Make sure IP header gets aligned */
+			skb_reserve(skb, 1); 
+			
+			/* Copy frame without CRC, CRC is removed by hardware*/
+			skb_put(skb, len);
+			memcpy(skb->data, self->rx_buff.data, len);
+
+			/* Move to next frame */
+			self->rx_buff.data += len;
+			self->stats.rx_bytes += len;
+			self->stats.rx_packets++;
+
+			skb->dev = self->netdev;
+			skb->mac.raw  = skb->data;
+			skb->protocol = htons(ETH_P_IRDA);
+			netif_rx(skb);
+		}
+	}
+	
+	switch_bank(iobase, BANK0);	
+		
+	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	return TRUE;
+}
+
+
+
+/*
+ * Function ali_ircc_sir_hard_xmit (skb, dev)
+ *
+ *    Transmit the frame!
+ *
+ */
+static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ali_ircc_cb *self;
+	unsigned long flags;
+	int iobase;
+	__u32 speed;
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	ASSERT(dev != NULL, return 0;);
+	
+	self = (struct ali_ircc_cb *) dev->priv;
+	ASSERT(self != NULL, return 0;);
+
+	iobase = self->io.sir_base;
+
+	netif_stop_queue(dev);
+	
+	/* Check if we need to change the speed */
+	speed = irda_get_next_speed(skb);
+	if ((speed != self->io.speed) && (speed != -1)) {
+		/* Check for empty frame */
+		if (!skb->len) {
+			ali_ircc_change_speed(self, speed); 
+			dev_kfree_skb(skb);
+			return 0;
+		} else
+			self->new_speed = speed;
+	}
+
+	spin_lock_irqsave(&self->lock, flags);
+
+	/* Init tx buffer */
+	self->tx_buff.data = self->tx_buff.head;
+
+        /* Copy skb to tx_buff while wrapping, stuffing and making CRC */
+	self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, 
+					   self->tx_buff.truesize);
+	
+	self->stats.tx_bytes += self->tx_buff.len;
+
+	/* Turn on transmit finished interrupt. Will fire immediately!  */
+	outb(UART_IER_THRI, iobase+UART_IER); 
+
+	spin_unlock_irqrestore(&self->lock, flags);
+
+	dev_kfree_skb(skb);
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	
+	return 0;	
+}
+
+
+/*
+ * Function ali_ircc_net_ioctl (dev, rq, cmd)
+ *
+ *    Process IOCTL commands for this device
+ *
+ */
+static int ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct if_irda_req *irq = (struct if_irda_req *) rq;
+	struct ali_ircc_cb *self;
+	unsigned long flags;
+	int ret = 0;
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	ASSERT(dev != NULL, return -1;);
+
+	self = dev->priv;
+
+	ASSERT(self != NULL, return -1;);
+
+	IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
+	
+	/* Disable interrupts & save flags */
+	save_flags(flags);
+	cli();	
+	
+	switch (cmd) {
+	case SIOCSBANDWIDTH: /* Set bandwidth */
+		IRDA_DEBUG(1, __FUNCTION__ "(), SIOCSBANDWIDTH\n");
+		/*
+		 * This function will also be used by IrLAP to change the
+		 * speed, so we still must allow for speed change within
+		 * interrupt context.
+		 */
+		if (!in_interrupt() && !capable(CAP_NET_ADMIN))
+			return -EPERM;
+		
+		ali_ircc_change_speed(self, irq->ifr_baudrate);		
+		break;
+	case SIOCSMEDIABUSY: /* Set media busy */
+		IRDA_DEBUG(1, __FUNCTION__ "(), SIOCSMEDIABUSY\n");
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		irda_device_set_media_busy(self->netdev, TRUE);
+		break;
+	case SIOCGRECEIVING: /* Check if we are receiving right now */
+		IRDA_DEBUG(2, __FUNCTION__ "(), SIOCGRECEIVING\n");
+		irq->ifr_receiving = ali_ircc_is_receiving(self);
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+	}
+	
+	restore_flags(flags);
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	
+	return ret;
+}
+
+/*
+ * Function ali_ircc_is_receiving (self)
+ *
+ *    Return TRUE is we are currently receiving a frame
+ *
+ */
+static int ali_ircc_is_receiving(struct ali_ircc_cb *self)
+{
+	unsigned long flags;
+	int status = FALSE;
+	int iobase;		
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start -----------------\n");
+	
+	ASSERT(self != NULL, return FALSE;);
+
+	spin_lock_irqsave(&self->lock, flags);
+
+	if (self->io.speed > 115200) 
+	{
+		iobase = self->io.fir_base;
+		
+		switch_bank(iobase, BANK1);
+		if((inb(iobase+FIR_FIFO_FR) & 0x3f) != 0) 		
+		{
+			/* We are receiving something */
+			IRDA_DEBUG(1, __FUNCTION__ "(), We are receiving something\n");
+			status = TRUE;
+		}
+		switch_bank(iobase, BANK0);		
+	} 
+	else
+	{ 
+		status = (self->rx_buff.state != OUTSIDE_FRAME);
+	}
+	
+	spin_unlock_irqrestore(&self->lock, flags);
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");
+	
+	return status;
+}
+
+static struct net_device_stats *ali_ircc_net_get_stats(struct net_device *dev)
+{
+	struct ali_ircc_cb *self = (struct ali_ircc_cb *) dev->priv;
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+		
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+	
+	return &self->stats;
+}
+
+static void ali_ircc_suspend(struct ali_ircc_cb *self)
+{
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	MESSAGE("%s, Suspending\n", driver_name);
+
+	if (self->io.suspended)
+		return;
+
+	ali_ircc_net_close(self->netdev);
+
+	self->io.suspended = 1;
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+}
+
+static void ali_ircc_wakeup(struct ali_ircc_cb *self)
+{
+	IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	if (!self->io.suspended)
+		return;
+	
+	ali_ircc_net_open(self->netdev);
+	
+	MESSAGE("%s, Waking up\n", driver_name);
+
+	self->io.suspended = 0;
+	
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+}
+
+static int ali_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data)
+{
+        struct ali_ircc_cb *self = (struct ali_ircc_cb*) dev->data;
+        
+        IRDA_DEBUG(2, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+        if (self) {
+                switch (rqst) {
+                case PM_SUSPEND:
+                        ali_ircc_suspend(self);
+                        break;
+                case PM_RESUME:
+                        ali_ircc_wakeup(self);
+                        break;
+                }
+        }
+        
+        IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+        
+	return 0;
+}
+
+
+/* ALi Chip Function */
+
+static void SetCOMInterrupts(struct ali_ircc_cb *self , unsigned char enable)
+{
+	
+	unsigned char newMask;
+	
+	int iobase = self->io.fir_base; /* or sir_base */
+
+	IRDA_DEBUG(2, __FUNCTION__ "(), -------- Start -------- ( Enable = %d )\n", enable);	
+	
+	/* Enable the interrupt which we wish to */
+	if (enable){
+		if (self->io.direction == IO_XMIT)
+		{
+			if (self->io.speed > 115200) /* FIR, MIR */
+			{
+				newMask = self->ier;
+			}
+			else /* SIR */
+			{
+				newMask = UART_IER_THRI | UART_IER_RDI;
+			}
+		}
+		else {
+			if (self->io.speed > 115200) /* FIR, MIR */
+			{
+				newMask = self->ier;
+			}
+			else /* SIR */
+			{
+				newMask = UART_IER_RDI;
+			}
+		}
+	}
+	else /* Disable all the interrupts */
+	{
+		newMask = 0x00;
+
+	}
+
+	//SIR and FIR has different registers
+	if (self->io.speed > 115200)
+	{	
+		switch_bank(iobase, BANK0);
+		outb(newMask, iobase+FIR_IER);
+	}
+	else
+		outb(newMask, iobase+UART_IER);
+		
+	IRDA_DEBUG(2, __FUNCTION__ "(), ----------------- End ------------------\n");	
+}
+
+static void SIR2FIR(int iobase)
+{
+	//unsigned char tmp;
+	unsigned long flags;
+		
+	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	save_flags(flags);
+	cli();
+	
+	outb(0x28, iobase+UART_MCR);
+	outb(0x68, iobase+UART_MCR);
+	outb(0x88, iobase+UART_MCR);		
+	
+	restore_flags(flags);
+		
+	outb(0x60, iobase+FIR_MCR); 	/*  Master Reset */
+	outb(0x20, iobase+FIR_MCR); 	/*  Master Interrupt Enable */
+	
+	//tmp = inb(iobase+FIR_LCR_B);	/* SIP enable */
+	//tmp |= 0x20;
+	//outb(tmp, iobase+FIR_LCR_B);	
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");	
+}
+
+static void FIR2SIR(int iobase)
+{
+	unsigned char val;
+	unsigned long flags;
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), ---------------- Start ----------------\n");
+	
+	save_flags(flags);
+	cli();
+	
+	outb(0x20, iobase+FIR_MCR); 	/* IRQ to low */
+	outb(0x00, iobase+UART_IER); 	
+		
+	outb(0xA0, iobase+FIR_MCR); 	/* Don't set master reset */
+	outb(0x00, iobase+UART_FCR);
+	outb(0x07, iobase+UART_FCR);		
+	
+	val = inb(iobase+UART_RX);
+	val = inb(iobase+UART_LSR);
+	val = inb(iobase+UART_MSR);
+	
+	restore_flags(flags);
+	
+	IRDA_DEBUG(1, __FUNCTION__ "(), ----------------- End ------------------\n");
+}
+
+#ifdef MODULE
+MODULE_AUTHOR("Benjamin Kong <benjamin_kong@ali.com.tw>");
+MODULE_DESCRIPTION("ALi FIR Controller Driver");
+
+MODULE_PARM(io,  "1-4i");
+MODULE_PARM_DESC(io, "Base I/O addresses");
+MODULE_PARM(irq, "1-4i");
+MODULE_PARM_DESC(irq, "IRQ lines");
+MODULE_PARM(dma, "1-4i");
+MODULE_PARM_DESC(dma, "DMA channels");
+
+int init_module(void)
+{
+	return ali_ircc_init();	
+}
+
+void cleanup_module(void)
+{
+	ali_ircc_cleanup();
+}
+#endif /* MODULE */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/irda/irport.c linux/drivers/net/irda/irport.c
--- v2.4.6/linux/drivers/net/irda/irport.c	Tue Mar 20 12:04:59 2001
+++ linux/drivers/net/irda/irport.c	Wed Jul  4 11:50:38 2001
@@ -951,13 +951,17 @@
 	switch (cmd) {
 	case SIOCSBANDWIDTH: /* Set bandwidth */
 		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		irda_task_execute(self, __irport_change_speed, NULL, NULL, 
-				  (void *) irq->ifr_baudrate);
+			ret = -EPERM;
+                else
+			irda_task_execute(self, __irport_change_speed, NULL, 
+					  NULL, (void *) irq->ifr_baudrate);
 		break;
 	case SIOCSDONGLE: /* Set dongle */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
+		if (!capable(CAP_NET_ADMIN)) {
+			ret = -EPERM;
+			break;
+		}
+
 		/* Initialize dongle */
 		dongle = irda_device_dongle_init(dev, irq->ifr_dongle);
 		if (!dongle)
@@ -978,16 +982,22 @@
 				  NULL);	
 		break;
 	case SIOCSMEDIABUSY: /* Set media busy */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
+		if (!capable(CAP_NET_ADMIN)) {
+			ret = -EPERM;
+			break;
+		}
+
 		irda_device_set_media_busy(self->netdev, TRUE);
 		break;
 	case SIOCGRECEIVING: /* Check if we are receiving right now */
 		irq->ifr_receiving = irport_is_receiving(self);
 		break;
 	case SIOCSDTRRTS:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
+		if (!capable(CAP_NET_ADMIN)) {
+			ret = -EPERM;
+			break;
+		}
+
 		irport_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts);
 		break;
 	default:
diff -u --recursive --new-file v2.4.6/linux/drivers/net/irda/irtty.c linux/drivers/net/irda/irtty.c
--- v2.4.6/linux/drivers/net/irda/irtty.c	Tue Mar 20 12:04:59 2001
+++ linux/drivers/net/irda/irtty.c	Wed Jul  4 11:50:38 2001
@@ -971,13 +971,17 @@
 	switch (cmd) {
 	case SIOCSBANDWIDTH: /* Set bandwidth */
 		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		irda_task_execute(self, irtty_change_speed, NULL, NULL, 
-				  (void *) irq->ifr_baudrate);
+			ret = -EPERM;
+		else
+			irda_task_execute(self, irtty_change_speed, NULL, NULL, 
+					  (void *) irq->ifr_baudrate);
 		break;
 	case SIOCSDONGLE: /* Set dongle */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
+		if (!capable(CAP_NET_ADMIN)) {
+			ret = -EPERM;
+			break;
+		}
+
 		/* Initialize dongle */
 		dongle = irda_device_dongle_init(dev, irq->ifr_dongle);
 		if (!dongle)
@@ -999,21 +1003,24 @@
 		break;
 	case SIOCSMEDIABUSY: /* Set media busy */
 		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		irda_device_set_media_busy(self->netdev, TRUE);
+			ret = -EPERM;
+		else
+			irda_device_set_media_busy(self->netdev, TRUE);
 		break;
 	case SIOCGRECEIVING: /* Check if we are receiving right now */
 		irq->ifr_receiving = irtty_is_receiving(self);
 		break;
 	case SIOCSDTRRTS:
 		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		irtty_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts);
+			ret = -EPERM;
+		else
+			irtty_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts);
 		break;
 	case SIOCSMODE:
 		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		irtty_set_mode(dev, irq->ifr_mode);
+			ret = -EPERM;
+		else
+			irtty_set_mode(dev, irq->ifr_mode);
 		break;
 	default:
 		ret = -EOPNOTSUPP;
diff -u --recursive --new-file v2.4.6/linux/drivers/net/irda/nsc-ircc.c linux/drivers/net/irda/nsc-ircc.c
--- v2.4.6/linux/drivers/net/irda/nsc-ircc.c	Tue May  1 16:05:00 2001
+++ linux/drivers/net/irda/nsc-ircc.c	Wed Jul  4 11:50:38 2001
@@ -90,7 +90,7 @@
 static nsc_chip_t chips[] = {
 	{ "PC87108", { 0x150, 0x398, 0xea }, 0x05, 0x10, 0xf0, 
 	  nsc_ircc_probe_108, nsc_ircc_init_108 },
-	{ "PC87338", { 0x398, 0x15c, 0x2e }, 0x08, 0xb0, 0xf0, 
+	{ "PC87338", { 0x398, 0x15c, 0x2e }, 0x08, 0xb0, 0xf8, 
 	  nsc_ircc_probe_338, nsc_ircc_init_338 },
 	{ NULL }
 };
@@ -160,7 +160,7 @@
 	int i = 0;
 
 	/* Probe for all the NSC chipsets we know about */
-	for (chip=chips; chip->name ; chip++,i++) {
+	for (chip=chips; chip->name ; chip++) {
 		IRDA_DEBUG(2, __FUNCTION__"(), Probing for %s ...\n", 
 			   chip->name);
 		
@@ -196,7 +196,7 @@
 				 * we init the chip, if not we probe the values
 				 * set by the BIOS
 				 */				
-				if (io[i] < 2000) {
+				if (io[i] < 0x2000) {
 					chip->init(chip, &info);
 				} else
 					chip->probe(chip, &info);
@@ -602,7 +602,7 @@
 	outb(CFG_PNP0, cfg_base);
 	reg = inb(cfg_base+1);
 	
-	pnp = (reg >> 4) & 0x01;
+	pnp = (reg >> 3) & 0x01;
 	if (pnp) {
 		IRDA_DEBUG(2, "(), Chip is in PnP mode\n");
 		outb(0x46, cfg_base);
diff -u --recursive --new-file v2.4.6/linux/drivers/net/irda/smc-ircc.c linux/drivers/net/irda/smc-ircc.c
--- v2.4.6/linux/drivers/net/irda/smc-ircc.c	Tue Mar 20 12:04:59 2001
+++ linux/drivers/net/irda/smc-ircc.c	Wed Jul  4 11:50:38 2001
@@ -98,6 +98,8 @@
 	{ "FDC37N769", 0x55, 0x55, 0x0d, 0x28, ircc_probe_69 },
 	{ "FDC37N869", 0x55, 0x00, 0x0d, 0x29, ircc_probe_69 },
 	{ "FDC37N958", 0x55, 0x55, 0x20, 0x09, ircc_probe_58 },
+	{ "FDC37N971", 0x55, 0x55, 0x20, 0x0a, ircc_probe_58 },
+	{ "FDC37N972", 0x55, 0x55, 0x20, 0x0b, ircc_probe_58 },
 	{ NULL }
 };
 
@@ -127,7 +129,7 @@
 	IRDA_DEBUG(0, __FUNCTION__ "\n");
 
 	/* Probe for all the NSC chipsets we know about */
-	for (chip=chips; chip->name ; chip++,i++) {
+	for (chip=chips; chip->name ; chip++) {
 		for (i=0; i<2; i++) {
 			info.cfg_base = smcreg[i];
 			
@@ -136,7 +138,7 @@
                          * parameters which we should use instead of probed
 			 * values
 			 */
-			if (io[i] < 2000) {
+			if (io[i] < 0x2000) {
 				info.fir_base = io[i];
 				info.sir_base = io2[i];
 			} else if (chip->probe(chip, &info) < 0)
diff -u --recursive --new-file v2.4.6/linux/drivers/net/irda/toshoboe.c linux/drivers/net/irda/toshoboe.c
--- v2.4.6/linux/drivers/net/irda/toshoboe.c	Tue May  1 16:05:00 2001
+++ linux/drivers/net/irda/toshoboe.c	Wed Jul  4 11:50:38 2001
@@ -43,9 +43,6 @@
 /* Define this to enable FIR and MIR support */
 #define ENABLE_FAST
 
-/* Number of ports this driver can support, you also need to edit dev_self below */
-#define NSELFS 4
-
 /* Size of IO window */
 #define CHIP_IO_EXTENT	0x1f
 
@@ -77,7 +74,6 @@
 #include <net/irda/irda_device.h>
 
 #include <linux/pm.h>
-static int toshoboe_pmproc (struct pm_dev *dev, pm_request_t rqst, void *data);
 
 #include <net/irda/toshoboe.h>
 
@@ -92,8 +88,6 @@
 
 static const char *driver_name = "toshoboe";
 
-static struct toshoboe_cb *dev_self[NSELFS + 1];
-
 static int max_baud = 4000000;
 
 /* Shutdown the chip and point the taskfile reg somewhere else */
@@ -644,21 +638,20 @@
 	return ret;
 }
 
-#ifdef MODULE
-
 MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver");
 MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>");
 MODULE_PARM (max_baud, "i");
 MODULE_PARM_DESC(max_baus, "Maximum baud rate");
 
-static int
-toshoboe_close (struct toshoboe_cb *self)
+static void
+toshoboe_remove (struct pci_dev *pci_dev)
 {
   int i;
+  struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
 
   IRDA_DEBUG (4, __FUNCTION__ "()\n");
 
-  ASSERT (self != NULL, return -1;
+  ASSERT (self != NULL, return;
     );
 
   if (!self->stopped)
@@ -693,16 +686,12 @@
   self->taskfilebuf = NULL;
   self->taskfile = NULL;
 
-  return (0);
+  return;
 
 }
 
-#endif
-
-
-
 static int
-toshoboe_open (struct pci_dev *pci_dev)
+toshoboe_probe (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
 {
   struct toshoboe_cb *self;
   struct net_device *dev;
@@ -713,15 +702,6 @@
 
   IRDA_DEBUG (4, __FUNCTION__ "()\n");
 
-  while (dev_self[i])
-    i++;
-
-  if (i == NSELFS)
-    {
-      printk (KERN_ERR "Oboe: No more instances available");
-      return -ENOMEM;
-    }
-
   if ((err=pci_enable_device(pci_dev)))
 	  return err;
 
@@ -736,12 +716,10 @@
 
   memset (self, 0, sizeof (struct toshoboe_cb));
 
-  dev_self[i] = self;           /*This needs moving if we ever get more than one chip */
-
   self->open = 0;
   self->stopped = 0;
   self->pdev = pci_dev;
-  self->base = pci_dev->resource[0].start;
+  self->base = pci_resource_start(pci_dev,0);
 
   self->io.sir_base = self->base;
   self->io.irq = pci_dev->irq;
@@ -749,19 +727,15 @@
   self->io.speed = 9600;
 
   /* Lock the port that we need */
-  i = check_region (self->io.sir_base, self->io.sir_ext);
-  if (i < 0)
+  if (NULL==request_region (self->io.sir_base, self->io.sir_ext, driver_name))
     {
       IRDA_DEBUG (0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
              self->io.sir_base);
 
-      dev_self[i] = NULL;
-      kfree (self);
-
-      return -ENODEV;
+      err = -EBUSY;
+      goto freeself;
     }
 
-
   irda_init_max_qos_capabilies (&self->qos);
   self->qos.baud_rate.bits = 0;
 
@@ -804,8 +778,8 @@
   if (!self->taskfilebuf)
     {
       printk (KERN_ERR "toshoboe: kmalloc for DMA failed()\n");
-      kfree (self);
-      return -ENOMEM;
+      err = -ENOMEM;
+      goto freeregion;
     }
 
 
@@ -839,25 +813,16 @@
   if (ok != RX_SLOTS + TX_SLOTS)
     {
       printk (KERN_ERR "toshoboe: kmalloc for buffers failed()\n");
+      err = -ENOMEM;
+      goto freebufs;
 
+  }
 
-      for (i = 0; i < TX_SLOTS; ++i)
-        if (self->xmit_bufs[i])
-          kfree (self->xmit_bufs[i]);
-      for (i = 0; i < RX_SLOTS; ++i)
-        if (self->recv_bufs[i])
-          kfree (self->recv_bufs[i]);
-
-      kfree (self);
-      return -ENOMEM;
-
-    }
-
-  request_region (self->io.sir_base, self->io.sir_ext, driver_name);
 
   if (!(dev = dev_alloc("irda%d", &err))) {
-	  ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
-	  return -ENOMEM;
+      ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
+      err = -ENOMEM;
+      goto freebufs;
   }
   dev->priv = (void *) self;
   self->netdev = dev;
@@ -875,12 +840,15 @@
   rtnl_unlock();
   if (err) {
 	  ERROR(__FUNCTION__ "(), register_netdev() failed!\n");
-	  return -1;
+	  /* XXX there is not freeing for dev? */
+          goto freebufs;
   }
+  pci_set_drvdata(pci_dev,self);
 
-  pmdev = pm_register (PM_PCI_DEV, PM_PCI_ID(pci_dev), toshoboe_pmproc);
+/*  pmdev = pm_register (PM_PCI_DEV, PM_PCI_ID(pci_dev), toshoboe_pmproc);
   if (pmdev)
 	  pmdev->data = self;
+	  */
 
   printk (KERN_WARNING "ToshOboe: Using ");
 #ifdef ONETASK
@@ -891,22 +859,36 @@
   printk (" tasks, version %s\n", rcsid);
 
   return (0);
+freebufs:
+      for (i = 0; i < TX_SLOTS; ++i)
+        if (self->xmit_bufs[i])
+          kfree (self->xmit_bufs[i]);
+      for (i = 0; i < RX_SLOTS; ++i)
+        if (self->recv_bufs[i])
+          kfree (self->recv_bufs[i]);
+      kfree(self->taskfilebuf);
+freeregion:
+      release_region (self->io.sir_base, self->io.sir_ext);
+freeself:
+      kfree (self);
+      return err;
 }
 
-static void 
-toshoboe_gotosleep (struct toshoboe_cb *self)
+static int
+toshoboe_suspend (struct pci_dev *pci_dev, u32 crap)
 {
   int i = 10;
+  struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
 
   printk (KERN_WARNING "ToshOboe: suspending\n");
 
-  if (self->stopped)
-    return;
+  if (!self || self->stopped)
+    return 0;
 
   self->stopped = 1;
 
   if (!self->open)
-    return;
+    return 0;
 
 /*FIXME: can't sleep here wait one second */
 
@@ -917,22 +899,26 @@
   toshoboe_disablebm (self);
 
   self->txpending = 0;
-
+  return 0;
 }
 
 
-static void 
-toshoboe_wakeup (struct toshoboe_cb *self)
+static int 
+toshoboe_resume (struct pci_dev *pci_dev)
 {
+  struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
   unsigned long flags;
 
+  if (!self)
+    return 0;
+
   if (!self->stopped)
-    return;
+    return 0;
 
   if (!self->open)
     {
       self->stopped = 0;
-      return;
+      return 0;
     }
 
   save_flags (flags);
@@ -949,108 +935,29 @@
   netif_wake_queue(self->netdev);
   restore_flags (flags);
   printk (KERN_WARNING "ToshOboe: waking up\n");
-
-}
-
-static int 
-toshoboe_pmproc (struct pm_dev *dev, pm_request_t rqst, void *data)
-{
-  struct toshoboe_cb *self = (struct toshoboe_cb *) dev->data;
-  if (self) {
-	  switch (rqst) {
-	  case PM_SUSPEND:
-		  toshoboe_gotosleep (self);
-		  break;
-	  case PM_RESUME:
-		  toshoboe_wakeup (self);
-		  break;
-	  }
-  }
   return 0;
 }
 
+static struct pci_driver toshoboe_pci_driver = {
+  name		: "toshoboe",
+  id_table	: toshoboe_pci_tbl,
+  probe		: toshoboe_probe,
+  remove	: toshoboe_remove,
+  suspend	: toshoboe_suspend,
+  resume	: toshoboe_resume 
+};
 
-int __init toshoboe_init (void)
-{
-  struct pci_dev *pci_dev = NULL;
-  int found = 0;
-
-  do
-    {
-      pci_dev = pci_find_device (PCI_VENDOR_ID_TOSHIBA,
-                                 PCI_DEVICE_ID_FIR701, pci_dev);
-      if (pci_dev)
-        {
-          printk (KERN_WARNING "ToshOboe: Found 701 chip at 0x%0lx irq %d\n",
-		  pci_dev->resource[0].start,
-                  pci_dev->irq);
-
-          if (!toshoboe_open (pci_dev))
-	      found++;
-        }
-
-    }
-  while (pci_dev);
-
-  if (!found) do
-    {
-      pci_dev = pci_find_device (PCI_VENDOR_ID_TOSHIBA,
-                                 PCI_DEVICE_ID_FIR701b, pci_dev);
-      if (pci_dev)
-        {
-          printk (KERN_WARNING "ToshOboe: Found 701b chip at 0x%0lx irq %d\n",
-		  pci_dev->resource[0].start,
-                  pci_dev->irq);
-
-          if (!toshoboe_open (pci_dev))
-	      found++;
-        }
-
-    }
-  while (pci_dev);
-
-
-
-  if (found)
-    {
-      return 0;
-    }
-
-  return -ENODEV;
-}
-
-#ifdef MODULE
-
-static void
-toshoboe_cleanup (void)
-{
-  int i;
-
-  IRDA_DEBUG (4, __FUNCTION__ "()\n");
-
-  for (i = 0; i < 4; i++)
-    {
-      if (dev_self[i])
-        toshoboe_close (dev_self[i]);
-    }
-
-  pm_unregister_all (toshoboe_pmproc);
-}
-
-
-
-int
-init_module (void)
-{
-  return toshoboe_init ();
+int __init
+toshoboe_init (void) {
+  pci_module_init(&toshoboe_pci_driver);
+  return 0;
 }
 
-
 void
-cleanup_module (void)
+toshoboe_cleanup (void)
 {
-  toshoboe_cleanup ();
+  pci_unregister_driver(&toshoboe_pci_driver);
 }
 
-
-#endif
+module_init(toshoboe_init);
+module_exit(toshoboe_cleanup);
diff -u --recursive --new-file v2.4.6/linux/drivers/net/pcmcia/ibmtr_cs.c linux/drivers/net/pcmcia/ibmtr_cs.c
--- v2.4.6/linux/drivers/net/pcmcia/ibmtr_cs.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/pcmcia/ibmtr_cs.c	Wed Jul  4 11:50:39 2001
@@ -25,20 +25,9 @@
     All we do here is set the card up enough so that the real ibmtr.c
     driver can find it and work with it properly.
 
-    i.e. We set up the io port, irq, mmio memory and shared ram memory.
-    This enables ibmtr_probe in ibmtr.c to find the card and configure it
-    as though it was a normal ISA and/or PnP card.
-
-    There is some confusion with the difference between available shared
-    ram and the amount actually reserved from memory.  ibmtr.c sets up
-    several offsets depending upon the actual on-board memory, not the
-    reserved memory.  We need to get around this to allow the cards to 
-    work with other cards in restricted memory space.  Therefore the 
-    pcmcia_reality_check function.
-
-    TODO
-	- Write the suspend / resume functions. 
-	- Fix Kernel Oops when removing card before ifconfig down
+    i.e. We set up the io port, irq, mmio memory and shared ram
+    memory.  This enables ibmtr_probe in ibmtr.c to find the card and
+    configure it as though it was a normal ISA and/or PnP card.
 
     CHANGES
 
@@ -49,16 +38,20 @@
     Updated to version 2.2.7 to match the first version of the kernel
     that the modification to ibmtr.c were incorporated into.
     
+    v2.2.17 July 2000 Burt Silverman (burts@us.ibm.com)
+    Address translation feature of PCMCIA controller is usable so
+    memory windows can be placed in High memory (meaning above
+    0xFFFFF.)
+
 ======================================================================*/
 
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
+#include <linux/malloc.h>
 #include <linux/string.h>
 #include <linux/timer.h>
-#include <linux/delay.h>
 #include <linux/module.h>
 #include <asm/io.h>
 #include <asm/system.h>
@@ -81,8 +74,9 @@
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
-"ibmtr_cs.c 1.10 1996/01/06 05:19:00 (Steve Kipisz)\n"
-"           2.2.7 1999/05/03 12:00:00 (Mike Phillips)\n" ;
+"ibmtr_cs.c 1.10   1996/01/06 05:19:00 (Steve Kipisz)\n"
+"           2.2.7  1999/05/03 12:00:00 (Mike Phillips)\n"
+"           2.4.2  2001/30/28 Midnight (Burt Silverman)\n";
 #else
 #define DEBUG(n, args...)
 #endif
@@ -96,13 +90,13 @@
 static int irq_list[4] = { -1 };
 
 /* MMIO base address */
-static u_long mmiobase;
+static u_long mmiobase = 0xce000;
 
 /* SRAM base address */
-static u_long srambase;
+static u_long srambase = 0xd0000;
 
 /* SRAM size 8,16,32,64 */
-static u_long sramsize = 16;
+static u_long sramsize = 64;
 
 /* Ringspeed 4,16 */
 static int ringspeed = 16;
@@ -117,7 +111,7 @@
 /*====================================================================*/
 
 static void ibmtr_config(dev_link_t *link);
-static void ibmtr_hw_setup(struct net_device *dev);
+static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
 static void ibmtr_release(u_long arg);
 static int ibmtr_event(event_t event, int priority,
                        event_callback_args_t *args);
@@ -130,18 +124,14 @@
 static dev_link_t *dev_list;
 
 extern int ibmtr_probe(struct net_device *dev);
-unsigned char pcmcia_reality_check(unsigned char gss);
-
 extern int trdev_init(struct net_device *dev);
 extern void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs);
-extern int tok_init_card(struct net_device *dev);
-extern unsigned char get_sram_size(struct tok_info *ti);
 
 /*====================================================================*/
 
 typedef struct ibmtr_dev_t {
     dev_link_t		link;
-    struct net_device	*dev; /* Changed for 2.2.0 */
+    struct net_device	*dev;
     dev_node_t          node;
     window_handle_t     sram_win_handle;
     struct tok_info	ti;
@@ -217,14 +207,13 @@
     link->conf.Present = PRESENT_OPTION;
 
     dev = init_trdev(NULL,0);
-    dev->priv = &info->ti;
-    link->irq.Instance = info->dev = dev;
-    
     if (dev == NULL) {
 	ibmtr_detach(link);
         return NULL;
     }
-
+    dev->priv = &info->ti;
+    link->irq.Instance = info->dev = dev;
+    
     dev->init = &ibmtr_probe;
 
     /* Register with Card Services */
@@ -262,7 +251,7 @@
 {
     struct ibmtr_dev_t *info = link->priv;
     dev_link_t **linkp;
-    struct net_device *dev; 
+    struct net_device *dev;
 
     DEBUG(0, "ibmtr_detach(0x%p)\n", link);
 
@@ -291,8 +280,10 @@
 
     /* Unlink device structure, free bits */
     *linkp = link->next;
-    if (link->dev)
+    if (info->dev) {
 	unregister_trdev(info->dev);
+	kfree(info->dev);
+    }
     kfree(info);
 
 } /* ibmtr_detach */
@@ -320,7 +311,6 @@
     memreq_t mem;
     int i, last_ret, last_fn;
     u_char buf[64];
-    unsigned char Shared_Ram_Base;
 
     DEBUG(0, "ibmtr_config(0x%p)\n", link);
 
@@ -361,41 +351,40 @@
 
     /* Allocate the MMIO memory window */
     req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
-    req.Attributes |= WIN_USE_WAIT|WIN_STRICT_ALIGN;
-    req.Base = mmiobase;
+    req.Attributes |= WIN_USE_WAIT;
+    req.Base = 0; 
     req.Size = 0x2000;
     req.AccessSpeed = 250;
     link->win = (window_handle_t)link->handle;
     CS_CHECK(RequestWindow, &link->win, &req);
 
-    mem.CardOffset = req.Base;
+    mem.CardOffset = mmiobase;
     mem.Page = 0;
     CS_CHECK(MapMemPage, link->win, &mem);
     ti->mmio = (u_long)ioremap(req.Base, req.Size);
 
     /* Allocate the SRAM memory window */
     req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
-    req.Attributes |= WIN_USE_WAIT|WIN_MAP_BELOW_1MB;
-    req.Base = srambase;
+    req.Attributes |= WIN_USE_WAIT;
+    req.Base = 0;
     req.Size = sramsize * 1024;
     req.AccessSpeed = 250;
     info->sram_win_handle = (window_handle_t)link->handle;
     CS_CHECK(RequestWindow, &info->sram_win_handle, &req);
 
-    mem.CardOffset = req.Base;
+    mem.CardOffset = srambase;
     mem.Page = 0;
     CS_CHECK(MapMemPage, info->sram_win_handle, &mem);
-    Shared_Ram_Base = req.Base >> 12;
-   
-    ti->sram = 0;
-    ti->sram_base = Shared_Ram_Base;
-    
+
+    ti->sram_base = mem.CardOffset >> 12;
+    ti->sram_virt = (u_long)ioremap(req.Base, req.Size);
+
     CS_CHECK(RequestConfiguration, link->handle, &link->conf);
 
     /*  Set up the Token-Ring Controller Configuration Register and
         turn on the card.  Check the "Local Area Network Credit Card
         Adapters Technical Reference"  SC30-3585 for this info.  */
-    ibmtr_hw_setup(dev);
+    ibmtr_hw_setup(dev, mmiobase);
 
     i = register_trdev(dev);
     
@@ -477,18 +466,20 @@
     struct net_device *dev = info->dev;
 
     DEBUG(1, "ibmtr_event(0x%06x)\n", event);
-    
+
     switch (event) {
     case CS_EVENT_CARD_REMOVAL:
         link->state &= ~DEV_PRESENT;
         if (link->state & DEV_CONFIG) {
+	    /* set flag to bypass normal interrupt code */
+	    ((struct tok_info *)dev->priv)->sram_virt |= 1;
 	    netif_device_detach(dev);
 	    mod_timer(&link->release, jiffies + HZ/20);
         }
         break;
     case CS_EVENT_CARD_INSERTION:
         link->state |= DEV_PRESENT;
-	ibmtr_config(link); 
+	ibmtr_config(link);
 	break;
     case CS_EVENT_PM_SUSPEND:
         link->state |= DEV_SUSPEND;
@@ -518,10 +509,9 @@
 
 /*====================================================================*/
 
-static void ibmtr_hw_setup(struct net_device *dev)
+static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase)
 {
-    struct tok_info *ti = dev->priv;
-    int i; 
+    int i;
 
     /* Bizarre IBM behavior, there are 16 bits of information we
        need to set, but the card only allows us to send 4 bits at a 
@@ -530,11 +520,11 @@
        the actual information */
 
     /* First nibble provides 4 bits of mmio */
-    i = ((int)ti->mmio >> 16) & 0x0F;
+    i = (mmiobase >> 16) & 0x0F;
     outb(i, dev->base_addr);
 
     /* Second nibble provides 3 bits of mmio */
-    i = 0x10 | (((int)ti->mmio >> 12) & 0x0E);
+    i = 0x10 | ((mmiobase >> 12) & 0x0E);
     outb(i, dev->base_addr);
 
     /* Third nibble, hard-coded values */
@@ -544,8 +534,7 @@
     /* Fourth nibble sets shared ram page size */
 
     /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */          
-        
-    i = (sramsize >> 4) & 0x07; 
+    i = (sramsize >> 4) & 0x07;
     i = ((i == 4) ? 3 : i) << 2;
     i |= 0x30;
 
@@ -555,28 +544,10 @@
 	i |= 1;
     outb(i, dev->base_addr);
 
-    /* X40 will release the card for use */
-
+    /* 0x40 will release the card for use */
     outb(0x40, dev->base_addr);
-    
-    return;
-}
 
-/*======================================================================
-  
-    A sweet little function that circumvents the problem with
-    ibmtr.c trying to use more memory than we can allocate for
-    the PCMCIA card.  ibmtr.c just assumes that if a card has 
-    64K of shared ram, the entire 64K must be mapped into memory,
-    whereas resources are sometimes a little tight in card services
-    so we fool ibmtr.c into thinking the card has less memory on
-    it than it has.
-    
-======================================================================*/
-
-unsigned char pcmcia_reality_check(unsigned char gss)
-{
-    return (gss < sramsize) ? sramsize : gss;
+    return;
 }
 
 /*====================================================================*/
@@ -584,7 +555,7 @@
 static int __init init_ibmtr_cs(void)
 {
     servinfo_t serv;
-    DEBUG(0, "%s\n", version);
+    DEBUG(0, "%s", version);
     CardServices(GetCardServicesInfo, &serv);
     if (serv.Revision != CS_RELEASE_CODE) {
         printk(KERN_NOTICE "ibmtr_cs: Card Services release "
diff -u --recursive --new-file v2.4.6/linux/drivers/net/ppp_async.c linux/drivers/net/ppp_async.c
--- v2.4.6/linux/drivers/net/ppp_async.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/ppp_async.c	Wed Jul  4 11:50:39 2001
@@ -96,7 +96,7 @@
 static void async_lcp_peek(struct asyncppp *ap, unsigned char *data,
 			   int len, int inbound);
 
-struct ppp_channel_ops async_ops = {
+static struct ppp_channel_ops async_ops = {
 	ppp_async_send,
 	ppp_async_ioctl
 };
@@ -308,7 +308,7 @@
 	write_wakeup: ppp_asynctty_wakeup,
 };
 
-int
+static int __init
 ppp_async_init(void)
 {
 	int err;
diff -u --recursive --new-file v2.4.6/linux/drivers/net/ppp_deflate.c linux/drivers/net/ppp_deflate.c
--- v2.4.6/linux/drivers/net/ppp_deflate.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/ppp_deflate.c	Wed Jul  4 11:50:39 2001
@@ -598,7 +598,7 @@
  * Module interface table
  *************************************************************/
 
-/* These are in ppp.c */
+/* These are in ppp_generic.c */
 extern int  ppp_register_compressor   (struct compressor *cp);
 extern void ppp_unregister_compressor (struct compressor *cp);
 
@@ -639,7 +639,7 @@
 	z_comp_stats,		/* decomp_stat */
 };
 
-int deflate_init(void)
+int __init deflate_init(void)
 {  
         int answer = ppp_register_compressor(&ppp_deflate);
         if (answer == 0)
@@ -649,7 +649,7 @@
         return answer;
 }
      
-void deflate_cleanup(void)
+void __exit deflate_cleanup(void)
 {
 	ppp_unregister_compressor(&ppp_deflate);
 	ppp_unregister_compressor(&ppp_deflate_draft);
diff -u --recursive --new-file v2.4.6/linux/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c
--- v2.4.6/linux/drivers/net/ppp_generic.c	Sun Apr 22 09:46:40 2001
+++ linux/drivers/net/ppp_generic.c	Wed Jul  4 11:50:39 2001
@@ -878,7 +878,7 @@
 	return err;
 }
 
-int
+static int
 ppp_net_init(struct net_device *dev)
 {
 	dev->hard_header_len = PPP_HDRLEN;
diff -u --recursive --new-file v2.4.6/linux/drivers/net/ppp_synctty.c linux/drivers/net/ppp_synctty.c
--- v2.4.6/linux/drivers/net/ppp_synctty.c	Fri Apr 20 11:54:24 2001
+++ linux/drivers/net/ppp_synctty.c	Wed Jul  4 11:50:39 2001
@@ -96,7 +96,7 @@
 static void ppp_sync_input(struct syncppp *ap, const unsigned char *buf,
 			   char *flags, int count);
 
-struct ppp_channel_ops sync_ops = {
+static struct ppp_channel_ops sync_ops = {
 	ppp_sync_send,
 	ppp_sync_ioctl
 };
@@ -365,7 +365,7 @@
 	write_wakeup: ppp_sync_wakeup,
 };
 
-int
+static int __init
 ppp_sync_init(void)
 {
 	int err;
diff -u --recursive --new-file v2.4.6/linux/drivers/net/pppoe.c linux/drivers/net/pppoe.c
--- v2.4.6/linux/drivers/net/pppoe.c	Wed May 16 10:31:27 2001
+++ linux/drivers/net/pppoe.c	Wed Jul  4 11:50:39 2001
@@ -410,23 +410,14 @@
 	return 0;
 }
 
-
-
-
 struct packet_type pppoes_ptype = {
-	__constant_htons(ETH_P_PPP_SES),
-	NULL,
-	pppoe_rcv,
-	NULL,
-	NULL
+	type:	__constant_htons(ETH_P_PPP_SES),
+	func:	pppoe_rcv,
 };
 
 struct packet_type pppoed_ptype = {
-	__constant_htons(ETH_P_PPP_DISC),
-	NULL,
-	pppoe_disc_rcv,
-	NULL,
-	NULL
+	type:	__constant_htons(ETH_P_PPP_DISC),
+	func:	pppoe_disc_rcv,
 };
 
 /***********************************************************************
diff -u --recursive --new-file v2.4.6/linux/drivers/net/rrunner.c linux/drivers/net/rrunner.c
--- v2.4.6/linux/drivers/net/rrunner.c	Wed Apr 18 14:40:04 2001
+++ linux/drivers/net/rrunner.c	Wed Jul  4 11:50:39 2001
@@ -117,6 +117,14 @@
 
 static int probed __initdata = 0;
 
+#if LINUX_VERSION_CODE >= 0x20400
+static struct pci_device_id rrunner_pci_tbl[] __initdata = {
+	{ PCI_VENDOR_ID_ESSENTIAL, PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER, PCI_ANY_ID, PCI_ANY_ID, },
+	{ }			/* Terminating entry */
+};
+MODULE_DEVICE_TABLE(pci, rrunner_pci_tbl);
+#endif /* LINUX_VERSION_CODE >= 0x20400 */
+
 #ifdef NEW_NETINIT
 int __init rr_hippi_probe (void)
 #else
@@ -137,9 +145,6 @@
 		return -ENODEV;
 	probed++;
 
-	if (!pci_present())		/* is PCI BIOS even present? */
-		return -ENODEV;
-
 	version_disp = 0;
 
 	while((pdev = pci_find_device(PCI_VENDOR_ID_ESSENTIAL,
@@ -176,6 +181,7 @@
 		sprintf(rrpriv->name, "RoadRunner serial HIPPI");
 
 		dev->irq = pdev->irq;
+		SET_MODULE_OWNER(dev);
 		dev->open = &rr_open;
 		dev->hard_start_xmit = &rr_start_xmit;
 		dev->stop = &rr_close;
@@ -1183,7 +1189,6 @@
 
 	netif_start_queue(dev);
 
-	MOD_INC_USE_COUNT;
 	return ecode;
 
  error:
@@ -1348,7 +1353,6 @@
 	free_irq(dev->irq, dev);
 	spin_unlock(&rrpriv->lock);
 
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/Makefile linux/drivers/net/sk98lin/Makefile
--- v2.4.6/linux/drivers/net/sk98lin/Makefile	Fri Dec 29 14:07:22 2000
+++ linux/drivers/net/sk98lin/Makefile	Wed Jul  4 11:50:39 2001
@@ -7,7 +7,7 @@
 
 obj-y :=     skge.o skaddr.o skgehwt.o skgeinit.o skgepnmi.o skgesirq.o \
              ski2c.o sklm80.o skqueue.o skrlmt.o sktimer.o skvpd.o \
-             skxmac2.o skcsum.o
+             skxmac2.o skproc.o skcsum.o
 obj-m := $(O_TARGET)
 
 # DBGDEF =  \
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/lm80.h linux/drivers/net/sk98lin/h/lm80.h
--- v2.4.6/linux/drivers/net/sk98lin/h/lm80.h	Tue Mar 20 12:04:59 2001
+++ linux/drivers/net/sk98lin/h/lm80.h	Wed Jul  4 11:50:39 2001
@@ -126,7 +126,7 @@
 #define LM80_IS_BTI		(1<<1)	/* state of BTI# pin */
 #define LM80_IS_FAN1		(1<<2)	/* count limit exceeded for Fan 1 */
 #define LM80_IS_FAN2		(1<<3)	/* count limit exceeded for Fan 2 */
-#define LM80_IS_CI		(1<<4)	/* Chassis Intrusion occurred */
+#define LM80_IS_CI		(1<<4)	/* Chassis Intrusion occured */
 #define LM80_IS_OS		(1<<5)	/* OS temperature limit exceeded */
 	/* bit 6 and 7 are reserved in LM80_ISRC_2 */
 #define LM80_IS_HT_IRQ_MD	(1<<6)	/* Hot temperature interrupt mode */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/skaddr.h linux/drivers/net/sk98lin/h/skaddr.h
--- v2.4.6/linux/drivers/net/sk98lin/h/skaddr.h	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/h/skaddr.h	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	skaddr.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.23 $
- * Date:	$Date: 2000/08/10 11:27:50 $
+ * Version:	$Revision: 1.24 $
+ * Date:	$Date: 2001/01/22 13:41:34 $
  * Purpose:	Header file for Address Management (MC, UC, Prom).
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2000 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,6 +26,9 @@
  * History:
  *
  *	$Log: skaddr.h,v $
+ *	Revision 1.24  2001/01/22 13:41:34  rassmann
+ *	Supporting two nets on dual-port adapters.
+ *	
  *	Revision 1.23  2000/08/10 11:27:50  rassmann
  *	Editorial changes.
  *	Preserving 32-bit alignment in structs for the adapter context.
@@ -158,6 +160,8 @@
 #define SK_ADDR_LOGICAL_ADDRESS		0
 #define SK_ADDR_VIRTUAL_ADDRESS		(SK_ADDR_LOGICAL_ADDRESS)	/* old */
 #define SK_ADDR_PHYSICAL_ADDRESS	1
+#define SK_ADDR_CLEAR_LOGICAL		2
+#define SK_ADDR_SET_LOGICAL			4
 
 /* ----- Override return values ----- */
 
@@ -195,18 +199,22 @@
 /* Macros */
 
 #ifndef SK_ADDR_EQUAL
+/*
+ * "&" instead of "&&" allows better optimization on IA-64.
+ * The replacement is safe here, as all bytes exist.
+ */
 #ifndef SK_ADDR_DWORD_COMPARE
 #define SK_ADDR_EQUAL(A1,A2)	( \
-	((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5] && \
-	((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4] && \
-	((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3] && \
-	((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2] && \
-	((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1] && \
-	((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0])
+	(((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \
+	(((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \
+	(((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \
+	(((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \
+	(((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \
+	(((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0]))
 #else	/* SK_ADDR_DWORD_COMPARE */
 #define SK_ADDR_EQUAL(A1,A2)	( \
-	*(SK_U32 *)&(((SK_U8 *)(A1))[2]) == *(SK_U32 *)&(((SK_U8 *)(A2))[2]) && \
-	*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0]))
+	(*(SK_U32 *)&(((SK_U8 *)(A1))[2]) == *(SK_U32 *)&(((SK_U8 *)(A2))[2])) & \
+	(*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0])))
 #endif	/* SK_ADDR_DWORD_COMPARE */
 #endif	/* SK_ADDR_EQUAL */
 
@@ -216,25 +224,31 @@
 	SK_U8	a[SK_MAC_ADDR_LEN];
 } SK_MAC_ADDR;
 
+
 /* SK_FILTER is used to ensure alignment of the filter. */
 typedef union s_InexactFilter {
 	SK_U8	Bytes[8];
 	SK_U64	Val;	/* Dummy entry for alignment only. */
 } SK_FILTER64;
 
+
+typedef struct s_AddrNet SK_ADDR_NET;
+
+
 typedef struct s_AddrPort {
 
 /* ----- Public part (read-only) ----- */
 
 	SK_MAC_ADDR	CurrentMacAddress;		/* Current physical MAC Address. */
 	SK_MAC_ADDR	PermanentMacAddress;	/* Permanent physical MAC Address. */
-	int		PromMode;					/* Promiscuous Mode. */
+	int			PromMode;				/* Promiscuous Mode. */
 
 /* ----- Private part ----- */
 
 	SK_MAC_ADDR	PreviousMacAddress;		/* Prev. phys. MAC Address. */
 	SK_BOOL		CurrentMacAddressSet;	/* CurrentMacAddress is set. */
 	SK_U8		Align01;
+
 	SK_U32		FirstExactMatchRlmt;
 	SK_U32		NextExactMatchRlmt;
 	SK_U32		FirstExactMatchDrv;
@@ -243,20 +257,30 @@
 	SK_FILTER64	InexactFilter;			/* For 64-bit hash register. */
 } SK_ADDR_PORT;
 
+
+struct s_AddrNet {
+/* ----- Public part (read-only) ----- */
+
+	SK_MAC_ADDR		CurrentMacAddress;		/* Logical MAC Address. */
+	SK_MAC_ADDR		PermanentMacAddress;	/* Logical MAC Address. */
+
+/* ----- Private part ----- */
+
+	SK_U32			ActivePort;				/* View of module ADDR. */
+	SK_BOOL			CurrentMacAddressSet;	/* CurrentMacAddress is set. */
+	SK_U8			Align01;
+	SK_U16			Align02;
+};
+
+
 typedef struct s_Addr {
 
 /* ----- Public part (read-only) ----- */
 
+	SK_ADDR_NET		Net[SK_MAX_NETS];
 	SK_ADDR_PORT	Port[SK_MAX_MACS];
-	SK_MAC_ADDR	PermanentMacAddress;	/* Logical MAC Address. */
-	SK_MAC_ADDR	CurrentMacAddress;		/* Logical MAC Address. */
 
 /* ----- Private part ----- */
-
-	SK_U32		ActivePort;				/* View of module ADDR. */
-	SK_BOOL		CurrentMacAddressSet;	/* CurrentMacAddress is set. */
-	SK_U8		Align01;
-	SK_U16		Align02;
 } SK_ADDR;
 
 /* function prototypes ********************************************************/
@@ -270,44 +294,44 @@
 extern	int	SkAddrInit(
 	SK_AC	*pAC,
 	SK_IOC	IoC,
-	int	Level);
+	int		Level);
 
 extern	int	SkAddrMcClear(
 	SK_AC	*pAC,
 	SK_IOC	IoC,
-	SK_U32	PortIdx,
-	int	Flags);
+	SK_U32	PortNumber,
+	int		Flags);
 
 extern	int	SkAddrMcAdd(
 	SK_AC		*pAC,
 	SK_IOC		IoC,
-	SK_U32		PortIdx,
+	SK_U32		PortNumber,
 	SK_MAC_ADDR	*pMc,
-	int		Flags);
+	int			Flags);
 
 extern	int	SkAddrMcUpdate(
 	SK_AC	*pAC,
 	SK_IOC	IoC,
-	SK_U32	PortIdx);
+	SK_U32	PortNumber);
 
 extern	int	SkAddrOverride(
 	SK_AC		*pAC,
 	SK_IOC		IoC,
-	SK_U32		PortIdx,
+	SK_U32		PortNumber,
 	SK_MAC_ADDR	*pNewAddr,
-	int		Flags);
+	int			Flags);
 
 extern	int	SkAddrPromiscuousChange(
 	SK_AC	*pAC,
 	SK_IOC	IoC,
-	SK_U32	PortIdx,
-	int	NewPromMode);
+	SK_U32	PortNumber,
+	int		NewPromMode);
 
 extern	int	SkAddrSwap(
 	SK_AC	*pAC,
 	SK_IOC	IoC,
-	SK_U32	FromPortIdx,
-	SK_U32	ToPortIdx);
+	SK_U32	FromPortNumber,
+	SK_U32	ToPortNumber);
 
 #else	/* defined(SK_KR_PROTO)) */
 
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/skcsum.h linux/drivers/net/sk98lin/h/skcsum.h
--- v2.4.6/linux/drivers/net/sk98lin/h/skcsum.h	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/h/skcsum.h	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	skcsum.h
  * Project:	GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
- * Version:	$Revision: 1.7 $
- * Date:	$Date: 2000/06/29 13:17:05 $
+ * Version:	$Revision: 1.9 $
+ * Date:	$Date: 2001/02/06 11:21:39 $
  * Purpose:	Store/verify Internet checksum in send/receive packets.
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,6 +26,12 @@
  * History:
  *
  *	$Log: skcsum.h,v $
+ *	Revision 1.9  2001/02/06 11:21:39  rassmann
+ *	Editorial changes.
+ *	
+ *	Revision 1.8  2001/02/06 11:15:36  rassmann
+ *	Supporting two nets on dual-port adapters.
+ *	
  *	Revision 1.7  2000/06/29 13:17:05  rassmann
  *	Corrected reception of a packet with UDP checksum == 0 (which means there
  *	is no UDP checksum).
@@ -193,13 +198,13 @@
  */
 typedef struct s_Csum {
 	/* Enabled receive SK_PROTO_XXX bit flags. */
-	unsigned ReceiveFlags;
+	unsigned ReceiveFlags[SK_MAX_NETS];
 #ifdef TX_CSUM
-	unsigned TransmitFlags;
+	unsigned TransmitFlags[SK_MAX_NETS];
 #endif /* TX_CSUM */
 
 	/* The protocol statistics structure; one per supported protocol. */
-	SKCS_PROTO_STATS ProtoStats[SKCS_NUM_PROTOCOLS];
+	SKCS_PROTO_STATS ProtoStats[SK_MAX_NETS][SKCS_NUM_PROTOCOLS];
 } SK_CSUM;
 
 /*
@@ -237,17 +242,20 @@
 	SK_AC		*pAc,
 	void		*pIpHeader,
 	unsigned	Checksum1,
-	unsigned	Checksum2);
+	unsigned	Checksum2,
+	int			NetNumber);
 
 extern void SkCsGetSendInfo(
-	SK_AC			*pAc,
-	void			*pIpHeader,
-	SKCS_PACKET_INFO	*pPacketInfo);
+	SK_AC				*pAc,
+	void				*pIpHeader,
+	SKCS_PACKET_INFO	*pPacketInfo,
+	int					NetNumber);
 
 extern void SkCsSetReceiveFlags(
 	SK_AC		*pAc,
 	unsigned	ReceiveFlags,
 	unsigned	*pChecksum1Offset,
-	unsigned	*pChecksum2Offset);
+	unsigned	*pChecksum2Offset,
+	int			NetNumber);
 
 #endif	/* __INC_SKCSUM_H */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/skdrv1st.h linux/drivers/net/sk98lin/h/skdrv1st.h
--- v2.4.6/linux/drivers/net/sk98lin/h/skdrv1st.h	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/sk98lin/h/skdrv1st.h	Wed Jul  4 11:50:39 2001
@@ -2,15 +2,15 @@
  *
  * Name:	skdrv1st.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.8 $
- * Date:	$Date: 2000/02/21 12:19:18 $
+ * Version:	$Revision: 1.9.2.1 $
+ * Date:	$Date: 2001/03/12 16:50:59 $
  * Purpose:	First header file for driver and all other modules
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
+ *	(C)Copyright 1998-2001 SysKonnect,
  *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -27,6 +27,14 @@
  * History:
  *
  *	$Log: skdrv1st.h,v $
+ *	Revision 1.9.2.1  2001/03/12 16:50:59  mlindner
+ *	chg: kernel 2.4 adaption
+ *	
+ *	Revision 1.9  2001/01/22 14:16:04  mlindner
+ *	added ProcFs functionality
+ *	Dual Net functionality integrated
+ *	Rlmt networks added
+ *	
  *	Revision 1.8  2000/02/21 12:19:18  cgoos
  *	Added default for SK_DEBUG_CHKMOD/_CHKCAT
  *	
@@ -105,7 +113,7 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
+#include <linux/malloc.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <asm/byteorder.h>
@@ -140,6 +148,7 @@
 // #define SK_RLMT_SLOW_LOOKAHEAD
 
 #define SK_MAX_MACS		2
+#define SK_MAX_NETS		2
 
 #define SK_IOC			char*
 
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/skdrv2nd.h linux/drivers/net/sk98lin/h/skdrv2nd.h
--- v2.4.6/linux/drivers/net/sk98lin/h/skdrv2nd.h	Tue Feb  8 18:58:25 2000
+++ linux/drivers/net/sk98lin/h/skdrv2nd.h	Wed Jul  4 11:50:39 2001
@@ -2,15 +2,15 @@
  *
  * Name:	skdrv2nd.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.7 $
- * Date:	$Date: 1999/09/28 12:38:21 $
+ * Version:	$Revision: 1.12.2.1 $
+ * Date:	$Date: 2001/03/12 16:50:59 $
  * Purpose:	Second header file for driver and all other modules
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
+ *	(C)Copyright 1998-2001 SysKonnect,
  *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -27,6 +27,32 @@
  * History:
  *
  *	$Log: skdrv2nd.h,v $
+ *	Revision 1.12.2.1  2001/03/12 16:50:59  mlindner
+ *	chg: kernel 2.4 adaption
+ *	
+ *	Revision 1.12  2001/03/01 12:52:15  mlindner
+ *	Fixed ring size
+ *
+ *	Revision 1.11  2001/02/19 13:28:02  mlindner
+ *	Changed PNMI parameter values
+ *
+ *	Revision 1.10  2001/01/22 14:16:04  mlindner
+ *	added ProcFs functionality
+ *	Dual Net functionality integrated
+ *	Rlmt networks added
+ *
+ *	Revision 1.1  2000/10/05 19:46:50  phargrov
+ *	Add directory src/vipk_devs_nonlbl/vipk_sk98lin/
+ *	This is the SysKonnect SK-98xx Gigabit Ethernet driver,
+ *	contributed by SysKonnect.
+ *
+ *	Revision 1.9  2000/02/21 10:39:55  cgoos
+ *	Added flag for jumbo support usage.
+ *
+ *	Revision 1.8  1999/11/22 13:50:44  cgoos
+ *	Changed license header to GPL.
+ *	Fixed two comments.
+ *
  *	Revision 1.7  1999/09/28 12:38:21  cgoos
  *	Added CheckQueue to SK_AC.
  *	
@@ -160,6 +186,11 @@
 #define SK_DRIVER_RESET(pAC, IoC)	0
 #define SK_DRIVER_SENDEVENT(pAC, IoC)	0
 #define SK_DRIVER_SELFTEST(pAC, IoC)	0
+/* For get mtu you must add an own function */
+#define SK_DRIVER_GET_MTU(pAc,IoC,i)	0
+#define SK_DRIVER_SET_MTU(pAc,IoC,i,v)	0
+#define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v)	0
+
 
 /* TX and RX descriptors *****************************************************/
 
@@ -344,6 +375,16 @@
 
 #define IRQ_HWE_MASK	0x00000FFF /* enable all HW irqs */
 
+typedef struct s_DevNet DEV_NET;
+
+struct s_DevNet {
+	int             PortNr;
+	int             NetNr;
+	int             Mtu;
+	int             Up;
+	SK_AC   *pAC;
+};  
+
 typedef struct s_TxPort		TX_PORT;
 
 struct s_TxPort {
@@ -397,7 +438,8 @@
 	SK_RLMT		Rlmt;		/* for rlmt module */
 	spinlock_t	SlowPathLock;	/* Normal IRQ lock */
 	SK_PNMI_STRUCT_DATA PnmiStruct;	/* structure to get all Pnmi-Data */
-	int		RlmtMode;	/* link check mode to set */
+	int			RlmtMode;	/* link check mode to set */
+	int			RlmtNets;	/* Number of nets */
 	
 	SK_IOC		IoBase;		/* register set of adapter */
 	int		BoardLevel;	/* level of active hw init (0-2) */
@@ -405,7 +447,7 @@
 	SK_U32		AllocFlag;	/* flag allocation of resources */
 	struct pci_dev	PciDev;		/* for access to pci config space */
 	SK_U32		PciDevId;	/* pci device id */
-	struct net_device	*dev;		/* pointer to device struct */
+	struct net_device	*dev[2];		/* pointer to device struct */
 	char		Name[30];	/* driver name */
 	struct net_device	*Next;		/* link all devices (for clearing) */
 	int		RxBufSize;	/* length of receive buffers */
@@ -424,6 +466,7 @@
 					/*  (may be more than HW can)*/
 
 	int		ActivePort;	/* the active XMAC port */
+	int		MaxPorts;		/* number of activated ports */
 	int		TxDescrPerRing;	/* # of descriptors per tx ring */
 	int		RxDescrPerRing;	/* # of descriptors per rx ring */
 
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/skgehw.h linux/drivers/net/sk98lin/h/skgehw.h
--- v2.4.6/linux/drivers/net/sk98lin/h/skgehw.h	Tue Mar 20 12:04:59 2001
+++ linux/drivers/net/sk98lin/h/skgehw.h	Wed Jul  4 11:50:39 2001
@@ -2,8 +2,8 @@
  *
  * Name:	skgehw.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.35 $
- * Date:	$Date: 2000/05/19 10:17:13 $
+ * Version:	$Revision: 1.36 $
+ * Date:	$Date: 2000/11/09 12:32:49 $
  * Purpose:	Defines and Macros for the Gigabit Ethernet Adapter Product
  *		Family
  *
@@ -11,8 +11,7 @@
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2000 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,6 +26,9 @@
  *
  * History:
  * $Log: skgehw.h,v $
+ * Revision 1.36  2000/11/09 12:32:49  rassmann
+ * Renamed variables.
+ *
  * Revision 1.35  2000/05/19 10:17:13  cgoos
  * Added inactivity check in PHY_READ (in DEBUG mode only).
  *
@@ -180,27 +182,27 @@
  */
 #define	PCI_VENDOR_ID	0x00	/* 16 bit	Vendor ID */
 #define	PCI_DEVICE_ID	0x02	/* 16 bit	Device ID */
-#define	PCI_COMMAND	0x04	/* 16 bit	Command */
-#define	PCI_STATUS	0x06	/* 16 bit	Status */
-#define	PCI_REV_ID	0x08	/*  8 bit	Revision ID */
+#define	PCI_COMMAND		0x04	/* 16 bit	Command */
+#define	PCI_STATUS		0x06	/* 16 bit	Status */
+#define	PCI_REV_ID		0x08	/*  8 bit	Revision ID */
 #define	PCI_CLASS_CODE	0x09	/* 24 bit	Class Code */
 #define	PCI_CACHE_LSZ	0x0c	/*  8 bit	Cache Line Size */
-#define	PCI_LAT_TIM	0x0d	/*  8 bit	Latency Timer */
+#define	PCI_LAT_TIM		0x0d	/*  8 bit	Latency Timer */
 #define	PCI_HEADER_T	0x0e	/*  8 bit	Header Type */
-#define	PCI_BIST	0x0f	/*  8 bit	Built-in selftest */
+#define	PCI_BIST		0x0f	/*  8 bit	Built-in selftest */
 #define	PCI_BASE_1ST	0x10	/* 32 bit	1st Base address */
 #define	PCI_BASE_2ND	0x14	/* 32 bit	2nd Base address */
 	/* Byte 18..2b:	reserved */
-#define	PCI_SUB_VID	0x2c	/* 16 bit	Subsystem Vendor ID */
-#define	PCI_SUB_ID	0x2e	/* 16 bit	Subsystem ID */
+#define	PCI_SUB_VID		0x2c	/* 16 bit	Subsystem Vendor ID */
+#define	PCI_SUB_ID		0x2e	/* 16 bit	Subsystem ID */
 #define	PCI_BASE_ROM	0x30	/* 32 bit	Expansion ROM Base Address */
 	/* Byte 34..33:	reserved */
-#define PCI_CAP_PTR	0x34	/*  8 bit 	Capabilities Ptr */
+#define PCI_CAP_PTR		0x34	/*  8 bit 	Capabilities Ptr */
 	/* Byte 35..3b:	reserved */
 #define	PCI_IRQ_LINE	0x3c	/*  8 bit	Interrupt Line */
-#define	PCI_IRQ_PIN	0x3d	/*  8 bit	Interrupt Pin */
-#define	PCI_MIN_GNT	0x3e	/*  8 bit	Min_Gnt */
-#define	PCI_MAX_LAT	0x3f	/*  8 bit	Max_Lat */
+#define	PCI_IRQ_PIN		0x3d	/*  8 bit	Interrupt Pin */
+#define	PCI_MIN_GNT		0x3e	/*  8 bit	Min_Gnt */
+#define	PCI_MAX_LAT		0x3f	/*  8 bit	Max_Lat */
 	/* Device Dependent Region */
 #define	PCI_OUR_REG_1	0x40	/* 32 bit 	Our Register 1 */
 #define	PCI_OUR_REG_2	0x44	/* 32 bit 	Our Register 2 */
@@ -233,34 +235,34 @@
 /*	PCI_DEVICE_ID	16 bit	Device ID */
 /* Values for Vendor ID and Device ID shall be patched into the code */
 /*	PCI_COMMAND	16 bit	Command */
-				/* Bit 15..10:	reserved */
-#define	PCI_FBTEN	(1<<9)	/* Bit 9:	Fast Back-To-Back enable */
-#define	PCI_SERREN	(1<<8)	/* Bit 8:	SERR enable */
-#define	PCI_ADSTEP	(1<<7)	/* Bit 7:	Address Stepping */
-#define	PCI_PERREN	(1<<6)	/* Bit 6:	Parity Report Response enable */
+								/* Bit 15..10:	reserved */
+#define	PCI_FBTEN		(1<<9)	/* Bit 9:	Fast Back-To-Back enable */
+#define	PCI_SERREN		(1<<8)	/* Bit 8:	SERR enable */
+#define	PCI_ADSTEP		(1<<7)	/* Bit 7:	Address Stepping */
+#define	PCI_PERREN		(1<<6)	/* Bit 6:	Parity Report Response enable */
 #define	PCI_VGA_SNOOP	(1<<5)	/* Bit 5:	VGA palette snoop */
-#define	PCI_MWIEN	(1<<4)	/* Bit 4:	Memory write an inv cycl ena */
-#define	PCI_SCYCEN	(1<<3)	/* Bit 3:	Special Cycle enable */
-#define	PCI_BMEN	(1<<2)	/* Bit 2:	Bus Master enable */
-#define	PCI_MEMEN	(1<<1)	/* Bit 1:	Memory Space Access enable */
-#define	PCI_IOEN	(1<<0)	/* Bit 0:	IO Space Access enable */
+#define	PCI_MWIEN		(1<<4)	/* Bit 4:	Memory write an inv cycl ena */
+#define	PCI_SCYCEN		(1<<3)	/* Bit 3:	Special Cycle enable */
+#define	PCI_BMEN		(1<<2)	/* Bit 2:	Bus Master enable */
+#define	PCI_MEMEN		(1<<1)	/* Bit 1:	Memory Space Access enable */
+#define	PCI_IOEN		(1<<0)	/* Bit 0:	IO Space Access enable */
 
 /*	PCI_STATUS	16 bit	Status */
-#define	PCI_PERR	(1<<15)	/* Bit 15:	Parity Error */
-#define	PCI_SERR	(1<<14)	/* Bit 14:	Signaled SERR */
-#define	PCI_RMABORT	(1<<13)	/* Bit 13:	Received Master Abort */
-#define	PCI_RTABORT	(1<<12)	/* Bit 12:	Received Target Abort */
-				/* Bit 11:	reserved */
-#define	PCI_DEVSEL	(3<<9)	/* Bit 10..9:	DEVSEL Timing */
+#define	PCI_PERR		(1<<15)	/* Bit 15:	Parity Error */
+#define	PCI_SERR		(1<<14)	/* Bit 14:	Signaled SERR */
+#define	PCI_RMABORT		(1<<13)	/* Bit 13:	Received Master Abort */
+#define	PCI_RTABORT		(1<<12)	/* Bit 12:	Received Target Abort */
+								/* Bit 11:	reserved */
+#define	PCI_DEVSEL		(3<<9)	/* Bit 10..9:	DEVSEL Timing */
 #define	PCI_DEV_FAST	(0<<9)	/*		fast */
 #define	PCI_DEV_MEDIUM	(1<<9)	/*		medium */
 #define	PCI_DEV_SLOW	(2<<9)	/*		slow */
 #define	PCI_DATAPERR	(1<<8)	/* Bit 8:	DATA Parity error detected */
-#define	PCI_FB2BCAP	(1<<7)	/* Bit 7:	Fast Back-to-Back Capability */
-#define	PCI_UDF		(1<<6)	/* Bit 6:	User Defined Features */
+#define	PCI_FB2BCAP		(1<<7)	/* Bit 7:	Fast Back-to-Back Capability */
+#define	PCI_UDF			(1<<6)	/* Bit 6:	User Defined Features */
 #define PCI_66MHZCAP	(1<<5)	/* Bit 5:	66 MHz PCI bus clock capable */
-#define PCI_NEWCAP	(1<<4)	/* Bit 4:	New cap. list implemented */
-				/* Bit 3..0:	reserved */
+#define PCI_NEWCAP		(1<<4)	/* Bit 4:	New cap. list implemented */
+								/* Bit 3..0:	reserved */
 
 #define PCI_ERRBITS	(PCI_PERR | PCI_SERR | PCI_RMABORT | PCI_RTABORT |\
 			PCI_DATAPERR)
@@ -275,59 +277,59 @@
 
 /*	PCI_HEADER_T	8 bit	Header Type */
 #define	PCI_HD_MF_DEV	(1<<7)	/* Bit 7:	0= single, 1= multi-func dev */
-#define	PCI_HD_TYPE	0x7f	/* Bit 6..0:	Header Layout 0= normal */
+#define	PCI_HD_TYPE		0x7f	/* Bit 6..0:	Header Layout 0= normal */
 
 /*	PCI_BIST	8 bit	Built-in selftest */
 /*	Built-in Self test not supported (optional) */
 
 /*	PCI_BASE_1ST	32 bit	1st Base address */
-#define	PCI_MEMSIZE	0x4000L		/* use 16 kB Memory Base */
+#define	PCI_MEMSIZE		0x4000L		/* use 16 kB Memory Base */
 #define	PCI_MEMBASE_MSK 0xffffc000L	/* Bit 31..14:	Memory Base Address */
 #define	PCI_MEMSIZE_MSK 0x00003ff0L	/* Bit 13.. 4:	Memory Size Req. */
-#define	PCI_PREFEN	(1L<<3)		/* Bit	3:	Prefetchable */
-#define	PCI_MEM_TYP	(3L<<2)		/* Bit	2.. 1:	Memory Type */
+#define	PCI_PREFEN		(1L<<3)		/* Bit	3:	Prefetchable */
+#define	PCI_MEM_TYP		(3L<<2)		/* Bit	2.. 1:	Memory Type */
 #define	PCI_MEM32BIT	(0L<<1)		/* Base addr anywhere in 32 Bit range */
-#define	PCI_MEM1M	(1L<<1)		/* Base addr below 1 MegaByte */
+#define	PCI_MEM1M		(1L<<1)		/* Base addr below 1 MegaByte */
 #define	PCI_MEM64BIT	(2L<<1)		/* Base addr anywhere in 64 Bit range */
 #define	PCI_MEMSPACE	(1L<<0)		/* Bit	0:	Memory Space Indic. */
 
 /*	PCI_BASE_2ND	32 bit	2nd Base address */
-#define	PCI_IOBASE	0xffffff00L	/* Bit 31..8:	I/O Base address */
-#define	PCI_IOSIZE	0x000000fcL	/* Bit	7..2:	I/O Size Requirements */
-					/* Bit	1:	reserved */
-#define	PCI_IOSPACE	(1L<<0)		/* Bit	0:	I/O Space Indicator */
+#define	PCI_IOBASE		0xffffff00L	/* Bit 31..8:	I/O Base address */
+#define	PCI_IOSIZE		0x000000fcL	/* Bit	7..2:	I/O Size Requirements */
+									/* Bit	1:	reserved */
+#define	PCI_IOSPACE		(1L<<0)		/* Bit	0:	I/O Space Indicator */
 
 /*	PCI_BASE_ROM	32 bit	Expansion ROM Base Address */
-#define	PCI_ROMBASE	(0xfffeL<<17)	/* Bit 31..17:	ROM BASE address (1st)*/
-#define	PCI_ROMBASZ	(0x1cL<<14)	/* Bit 16..14:	Treat as BASE or SIZE */
-#define	PCI_ROMSIZE	(0x38L<<11)	/* Bit 13..11:	ROM Size Requirements */
-					/* Bit 10.. 1:	reserved */
-#define	PCI_ROMEN	(0x1L<<0)	/* Bit 0:	Address Decode enable */
+#define	PCI_ROMBASE		(0xfffeL<<17)	/* Bit 31..17:	ROM BASE address (1st)*/
+#define	PCI_ROMBASZ		(0x1cL<<14)	/* Bit 16..14:	Treat as BASE or SIZE */
+#define	PCI_ROMSIZE		(0x38L<<11)	/* Bit 13..11:	ROM Size Requirements */
+									/* Bit 10.. 1:	reserved */
+#define	PCI_ROMEN		(0x1L<<0)	/* Bit 0:	Address Decode enable */
 
 /* Device Dependent Region */
 /*	PCI_OUR_REG_1		32 bit	Our Register 1 */
-					/* Bit 31..26:	reserved */
-#define PCI_VIO		(1L<<25)	/* Bit 25:	PCI IO Voltage, */
-					/*		0 = 3.3V / 1 = 5V */
-#define	PCI_EN_BOOT	(1L<<24)	/* Bit 24:	Enable BOOT via ROM */
-					/*		1 = Don't boot wth ROM*/
-					/*		0 = Boot with ROM */
-#define	PCI_EN_IO	(1L<<23)	/* Bit 23:	Mapping to IO space */
+									/* Bit 31..26:	reserved */
+#define PCI_VIO			(1L<<25)	/* Bit 25:	PCI IO Voltage, */
+									/*		0 = 3.3V / 1 = 5V */
+#define	PCI_EN_BOOT		(1L<<24)	/* Bit 24:	Enable BOOT via ROM */
+									/*		1 = Don't boot wth ROM*/
+									/*		0 = Boot with ROM */
+#define	PCI_EN_IO		(1L<<23)	/* Bit 23:	Mapping to IO space */
 #define	PCI_EN_FPROM	(1L<<22)	/* Bit 22:	FLASH mapped to mem? */
-					/*		1 = Map Flash to Mem */
-					/*		0 = Disable addr. dec*/
+									/*		1 = Map Flash to Mem */
+									/*		0 = Disable addr. dec*/
 #define	PCI_PAGESIZE	(3L<<20)	/* Bit 21..20:	FLASH Page Size	*/
-#define	PCI_PAGE_16	(0L<<20)	/*		16 k pages	*/
+#define	PCI_PAGE_16		(0L<<20)	/*		16 k pages	*/
 #define	PCI_PAGE_32K	(1L<<20)	/*		32 k pages	*/
 #define	PCI_PAGE_64K	(2L<<20)	/*		64 k pages	*/
 #define	PCI_PAGE_128K	(3L<<20)	/*		128 k pages	*/
-					/* Bit 19:	reserved	*/
-#define	PCI_PAGEREG	(7L<<16)	/* Bit 18..16:	Page Register	*/
-#define PCI_NOTAR	(1L<<15)	/* Bit 15:	No turnaround cycle */
+									/* Bit 19:	reserved	*/
+#define	PCI_PAGEREG		(7L<<16)	/* Bit 18..16:	Page Register	*/
+#define PCI_NOTAR		(1L<<15)	/* Bit 15:	No turnaround cycle */
 #define	PCI_FORCE_BE	(1L<<14)	/* Bit 14:	Assert all BEs on MR */
-#define	PCI_DIS_MRL	(1L<<13)	/* Bit 13:	Disable Mem R Line */
-#define	PCI_DIS_MRM	(1L<<12)	/* Bit 12:	Disable Mem R multip */
-#define	PCI_DIS_MWI	(1L<<11)	/* Bit 11:	Disable Mem W & inv */
+#define	PCI_DIS_MRL		(1L<<13)	/* Bit 13:	Disable Mem R Line */
+#define	PCI_DIS_MRM		(1L<<12)	/* Bit 12:	Disable Mem R multip */
+#define	PCI_DIS_MWI		(1L<<11)	/* Bit 11:	Disable Mem W & inv */
 #define	PCI_DISC_CLS	(1L<<10)	/* Bit 10:	Disc: cacheLsz bound */
 #define	PCI_BURST_DIS	(1L<<9)		/* Bit	9:	Burst Disable */
 #define	PCI_DIS_PCI_CLK	(1L<<8)		/* Bit	8:	Disable PCI clock driv*/
@@ -337,9 +339,9 @@
 
 /*	PCI_OUR_REG_2		32 bit	Our Register 2 */
 #define PCI_VPD_WR_THR	(0xffL<<24)	/* Bit 31..24:	VPD Write Threshold */
-#define	PCI_DEV_SEL	(0x7fL<<17)	/* Bit 23..17:	EEPROM Device Select */
+#define	PCI_DEV_SEL		(0x7fL<<17)	/* Bit 23..17:	EEPROM Device Select */
 #define	PCI_VPD_ROM_SZ	(7L<<14)	/* Bit 16..14:	VPD ROM Size	*/
-					/* Bit 13..12:	reserved	*/
+									/* Bit 13..12:	reserved	*/
 #define	PCI_PATCH_DIR	(0xfL<<8)	/* Bit 11.. 8:	Ext Patchs dir 3..0 */
 #define	PCI_PATCH_DIR_0	(1L<<8)
 #define	PCI_PATCH_DIR_1	(1L<<9)
@@ -352,27 +354,27 @@
 #define	PCI_EXT_PATCH_3	(1L<<7)
 #define	PCI_EN_DUMMY_RD	(1L<<3)		/* Bit	3:	Enable Dummy Read */
 #define PCI_REV_DESC	(1L<<2)		/* Bit	2:	Reverse Desc. Bytes */
-					/* Bit	1:	reserved */
+									/* Bit	1:	reserved */
 #define PCI_USEDATA64	(1L<<0)		/* Bit	0:	Use 64Bit Data bus ext*/
 
 
 /* Power Management Region */
 /*	PCI_PM_CAP_REG		16 bit	Power Management Capabilities */
-#define	PCI_PME_SUP	(0x1f<<11)	/* Bit 15..11:	PM Manag. Event Sup */
+#define	PCI_PME_SUP		(0x1f<<11)	/* Bit 15..11:	PM Manag. Event Sup */
 #define PCI_PM_D2_SUB	(1<<10)		/* Bit 10:	D2 Support Bit */
 #define PCI_PM_D1_SUB	(1<<9)		/* Bit	9:	D1 Support Bit */
-					/* Bit	8..6:	reserved */
-#define PCI_PM_DSI	(1<<5)		/* Bit	5:	Device Specific Init.*/
-#define PCI_PM_APS	(1<<4)		/* Bit	4:	Auxialiary Power Src */
+									/* Bit	8..6:	reserved */
+#define PCI_PM_DSI		(1<<5)		/* Bit	5:	Device Specific Init.*/
+#define PCI_PM_APS		(1<<4)		/* Bit	4:	Auxialiary Power Src */
 #define PCI_PME_CLOCK	(1<<3)		/* Bit	3:	PM Event Clock */
-#define PCI_PM_VER	(7<<0)		/* Bit	2..0:	PM PCI Spec. version */
+#define PCI_PM_VER		(7<<0)		/* Bit	2..0:	PM PCI Spec. version */
 
 /*	PCI_PM_CTL_STS		16 bit	Power Manag. Control/Status */
 #define	PCI_PME_STATUS	(1<<15)		/* Bit 15: 	PGA doesn't sup. PME# */
 #define PCI_PM_DAT_SCL	(3<<13)		/* Bit 14..13:	dat reg Scaling factor*/
 #define PCI_PM_DAT_SEL	(0xf<<9)	/* Bit 12.. 9:	PM data selector field*/
-#define PCI_PME_EN	(1<<8)		/* Bit	8:	PGA doesn't sup. PME# */
-					/* Bit	7.. 2:	reserved */
+#define PCI_PME_EN		(1<<8)		/* Bit	8:	PGA doesn't sup. PME# */
+									/* Bit	7.. 2:	reserved */
 #define PCI_PM_STATE	(3<<0)		/* Bit	1.. 0:	Power Management State*/
 #define PCI_PM_STATE_D0	(0<<0)		/* D0:	Operational (default) */
 #define	PCI_PM_STATE_D1	(1<<0)		/* D1:	not supported */
@@ -388,22 +390,22 @@
  *	Control Register File:
  *	Bank 0
  */
-#define	B0_RAP		0x0000	/*  8 bit	Register Address Port */
+#define	B0_RAP			0x0000	/*  8 bit	Register Address Port */
 	/* 0x0001 - 0x0003:	reserved */
-#define	B0_CTST		0x0004	/* 16 bit	Control/Status register */
-#define	B0_LED		0x0006	/*  8 Bit	LED register */
+#define	B0_CTST			0x0004	/* 16 bit	Control/Status register */
+#define	B0_LED			0x0006	/*  8 Bit	LED register */
 	/* 0x0007:		reserved */
-#define	B0_ISRC		0x0008	/* 32 bit	Interrupt Source Register */
-#define	B0_IMSK		0x000c	/* 32 bit	Interrupt Mask Register */
-#define B0_HWE_ISRC	0x0010	/* 32 bit	HW Error Interrupt Src Reg */
-#define B0_HWE_IMSK	0x0014	/* 32 bit	HW Error Interrupt Mask Reg */
-#define B0_SP_ISRC	0x0018	/* 32 bit	Special Interrupt Source Reg */
+#define	B0_ISRC			0x0008	/* 32 bit	Interrupt Source Register */
+#define	B0_IMSK			0x000c	/* 32 bit	Interrupt Mask Register */
+#define B0_HWE_ISRC		0x0010	/* 32 bit	HW Error Interrupt Src Reg */
+#define B0_HWE_IMSK		0x0014	/* 32 bit	HW Error Interrupt Mask Reg */
+#define B0_SP_ISRC		0x0018	/* 32 bit	Special Interrupt Source Reg */
 	/* 0x001c:		reserved */
 
 /* B0 XMAC 1 registers */
-#define	B0_XM1_IMSK	0x0020	/* 16 bit r/w	XMAC 1 Interrupt Mask Register*/
+#define	B0_XM1_IMSK		0x0020	/* 16 bit r/w	XMAC 1 Interrupt Mask Register*/
 	/* 0x0022 - 0x0027	reserved */
-#define B0_XM1_ISRC	0x0028	/* 16 bit ro	XMAC 1 Interrupt Status Reg */
+#define B0_XM1_ISRC		0x0028	/* 16 bit ro	XMAC 1 Interrupt Status Reg */
 	/* 0x002a - 0x002f	reserved */
 #define B0_XM1_PHY_ADDR 0x0030	/* 16 bit r/w	XMAC 1 PHY Address Register */
 	/* 0x0032 - 0x0033	reserved */
@@ -411,9 +413,9 @@
 	/* 0x0036 - 0x003f	reserved */
 
 /* B0 XMAC 2 registers */
-#define	B0_XM2_IMSK	0x0040	/* 16 bit r/w	XMAC 2 Interrupt Mask Register*/
+#define	B0_XM2_IMSK		0x0040	/* 16 bit r/w	XMAC 2 Interrupt Mask Register*/
 	/* 0x0042 - 0x0047	reserved */
-#define B0_XM2_ISRC	0x0048	/* 16 bit ro	XMAC 2 Interrupt Status Reg */
+#define B0_XM2_ISRC		0x0048	/* 16 bit ro	XMAC 2 Interrupt Status Reg */
 	/* 0x004a - 0x004f	reserved */
 #define B0_XM2_PHY_ADDR 0x0050	/* 16 bit r/w	XMAC 2 PHY Address Register */
 	/* 0x0052 - 0x0053	reserved */
@@ -421,12 +423,12 @@
 				/* 0x0056 - 0x005f	reserved */
 
 /* BMU Control Status Registers */
-#define	B0_R1_CSR	0x0060	/* 32 bit	BMU Ctrl/Stat Rx Queue 1 */
-#define	B0_R2_CSR	0x0064	/* 32 bit	BMU Ctrl/Stat Rx Queue 2 */
-#define	B0_XS1_CSR	0x0068	/* 32 bit	BMU Ctrl/Stat Sync Tx Queue 1 */
-#define	B0_XA1_CSR	0x006c	/* 32 bit	BMU Ctrl/Stat Async Tx Queue 1*/
-#define	B0_XS2_CSR	0x0070	/* 32 bit	BMU Ctrl/Stat Sync Tx Queue 2 */
-#define	B0_XA2_CSR	0x0074	/* 32 bit	BMU Ctrl/Stat Async Tx Queue 2*/
+#define	B0_R1_CSR		0x0060	/* 32 bit	BMU Ctrl/Stat Rx Queue 1 */
+#define	B0_R2_CSR		0x0064	/* 32 bit	BMU Ctrl/Stat Rx Queue 2 */
+#define	B0_XS1_CSR		0x0068	/* 32 bit	BMU Ctrl/Stat Sync Tx Queue 1 */
+#define	B0_XA1_CSR		0x006c	/* 32 bit	BMU Ctrl/Stat Async Tx Queue 1*/
+#define	B0_XS2_CSR		0x0070	/* 32 bit	BMU Ctrl/Stat Sync Tx Queue 2 */
+#define	B0_XA2_CSR		0x0074	/* 32 bit	BMU Ctrl/Stat Async Tx Queue 2*/
 	/* x0078 - 0x007f	reserved */
 
 /*
@@ -440,34 +442,34 @@
  */
 /* NA reg = 48 bit Network Address Register, 3x16 or 8x8 bit readable */
 
-#define	B2_MAC_1	0x0100	/* NA reg	 MAC Address 1 */
+#define	B2_MAC_1		0x0100	/* NA reg	 MAC Address 1 */
 	/* 0x0106 - 0x0107	reserved */
-#define	B2_MAC_2	0x0108	/* NA reg	 MAC Address 2 */
+#define	B2_MAC_2		0x0108	/* NA reg	 MAC Address 2 */
 	/* 0x010e - 0x010f	reserved */
-#define	B2_MAC_3	0x0110	/* NA reg	 MAC Address 3 */
+#define	B2_MAC_3		0x0110	/* NA reg	 MAC Address 3 */
 	/* 0x0116 - 0x0117	reserved */
-#define B2_CONN_TYP	0x0118	/*  8 bit	Connector type */
-#define B2_PMD_TYP	0x0119	/*  8 bit	PMD type */
-#define B2_MAC_CFG	0x011a	/*  8 bit	MAC Configuration */
-#define B2_CHIP_REV	0x011b	/*  8 bit 	Queen Chip Revision Number */
+#define B2_CONN_TYP		0x0118	/*  8 bit	Connector type */
+#define B2_PMD_TYP		0x0119	/*  8 bit	PMD type */
+#define B2_MAC_CFG		0x011a	/*  8 bit	MAC Configuration */
+#define B2_CHIP_REV		0x011b	/*  8 bit 	Queen Chip Revision Number */
 	/* Eprom registers are currently of no use */
-#define B2_E_0		0x011c	/*  8 bit	EPROM Byte 0 */
-#define B2_E_1		0x011d	/*  8 bit	EPROM Byte 1 */
-#define B2_E_2		0x011e	/*  8 bit	EPROM Byte 2 */
-#define B2_E_3		0x011f	/*  8 bit	EPROM Byte 3 */
-#define B2_FAR		0x0120	/* 32 bit	Flash-Prom Addr Reg/Cnt */
-#define B2_FDP		0x0124	/*  8 bit	Flash-Prom Data Port */
+#define B2_E_0			0x011c	/*  8 bit	EPROM Byte 0 */
+#define B2_E_1			0x011d	/*  8 bit	EPROM Byte 1 */
+#define B2_E_2			0x011e	/*  8 bit	EPROM Byte 2 */
+#define B2_E_3			0x011f	/*  8 bit	EPROM Byte 3 */
+#define B2_FAR			0x0120	/* 32 bit	Flash-Prom Addr Reg/Cnt */
+#define B2_FDP			0x0124	/*  8 bit	Flash-Prom Data Port */
 	/* 0x0125 - 0x0127:	reserved */
-#define B2_LD_CRTL	0x0128	/*  8 bit	EPROM loader control register */
-#define B2_LD_TEST	0x0129	/*  8 bit	EPROM loader test register */
+#define B2_LD_CRTL		0x0128	/*  8 bit	EPROM loader control register */
+#define B2_LD_TEST		0x0129	/*  8 bit	EPROM loader test register */
 	/* 0x012a - 0x012f:	reserved */
-#define B2_TI_INI	0x0130	/* 32 bit	Timer init value */
-#define B2_TI_VAL	0x0134	/* 32 bit	Timer value */
-#define B2_TI_CRTL	0x0138	/*  8 bit	Timer control */
-#define B2_TI_TEST	0x0139	/*  8 Bit	Timer Test */
+#define B2_TI_INI		0x0130	/* 32 bit	Timer init value */
+#define B2_TI_VAL		0x0134	/* 32 bit	Timer value */
+#define B2_TI_CRTL		0x0138	/*  8 bit	Timer control */
+#define B2_TI_TEST		0x0139	/*  8 Bit	Timer Test */
 	/* 0x013a - 0x013f:	reserved */
-#define B2_IRQM_INI	0x0140	/* 32 bit	IRQ Moderation Timer Init Reg.*/
-#define B2_IRQM_VAL	0x0144	/* 32 bit	IRQ Moderation Timer Value */
+#define B2_IRQM_INI		0x0140	/* 32 bit	IRQ Moderation Timer Init Reg.*/
+#define B2_IRQM_VAL		0x0144	/* 32 bit	IRQ Moderation Timer Value */
 #define B2_IRQM_CTRL	0x0148	/*  8 bit	IRQ Moderation Timer Control */
 #define B2_IRQM_TEST	0x0149	/*  8 bit	IRQ Moderation Timer Test */
 #define B2_IRQM_MSK 	0x014c	/* 32 bit	IRQ Moderation Mask */
@@ -476,22 +478,22 @@
 #define	B2_TST_CTRL1	0x0158	/*  8 bit	Test Control Register 1 */
 #define B2_TST_CTRL2	0x0159	/*  8 bit	Test Control Register 2 */
 	/* 0x015a - 0x015b:	reserved */
-#define B2_GP_IO	0x015c	/* 32 bit	General Purpose IO Register */
-#define B2_I2C_CTRL	0x0160	/* 32 bit	I2C HW Control Register */
-#define B2_I2C_DATA	0x0164	/* 32 bit	I2C HW Data Register */
-#define B2_I2C_IRQ	0x0168	/* 32 bit	I2C HW IRQ Register */
-#define B2_I2C_SW	0x016c	/* 32 bit	I2C SW Port Register */
-#define B2_BSC_INI	0x0170	/* 32 bit	Blink Source Counter Init Val */
-#define B2_BSC_VAL	0x0174	/* 32 bit	Blink Source Counter Value */
-#define B2_BSC_CTRL	0x0178	/*  8 bit	Blink Source Counter Control */
-#define B2_BSC_STAT	0x0179	/*  8 bit	Blink Source Counter Status */
-#define B2_BSC_TST	0x017a	/* 16 bit	Blink Source Counter Test Reg */
+#define B2_GP_IO		0x015c	/* 32 bit	General Purpose IO Register */
+#define B2_I2C_CTRL		0x0160	/* 32 bit	I2C HW Control Register */
+#define B2_I2C_DATA		0x0164	/* 32 bit	I2C HW Data Register */
+#define B2_I2C_IRQ		0x0168	/* 32 bit	I2C HW IRQ Register */
+#define B2_I2C_SW		0x016c	/* 32 bit	I2C SW Port Register */
+#define B2_BSC_INI		0x0170	/* 32 bit	Blink Source Counter Init Val */
+#define B2_BSC_VAL		0x0174	/* 32 bit	Blink Source Counter Value */
+#define B2_BSC_CTRL		0x0178	/*  8 bit	Blink Source Counter Control */
+#define B2_BSC_STAT		0x0179	/*  8 bit	Blink Source Counter Status */
+#define B2_BSC_TST		0x017a	/* 16 bit	Blink Source Counter Test Reg */
 	/* 0x017c - 0x017f:	reserved */
 
 /*
  *	Bank 3
  */
-#define B3_RAM_ADDR	0x0180	/* 32 bit	RAM Address, to read or write */
+#define B3_RAM_ADDR		0x0180	/* 32 bit	RAM Address, to read or write */
 #define B3_RAM_DATA_LO	0x0184	/* 32 bit	RAM Data Word (low dWord) */
 #define B3_RAM_DATA_HI	0x0188	/* 32 bit	RAM Data Word (high dWord) */
 	/* 0x018c - 0x018f:	reserved */
@@ -499,7 +501,7 @@
 /*
  * The HW-Spec. call this registers Timeout Value 0..11. But this names are
  * not usable in SW. Please notice these are NOT real timeouts, these are
- * the number of qWords transferred continously.
+ * the number of qWords transfered continously.
  */
 #define B3_RI_WTO_R1	0x0190	/* 8 bit RAM Iface WR Timeout Queue R1	(TO0) */
 #define B3_RI_WTO_XA1	0x0191	/* 8 bit RAM Iface WR Timeout Queue XA1	(TO1) */
@@ -515,8 +517,8 @@
 #define B3_RI_RTO_XS2	0x019b	/* 8 bit RAM Iface RD Timeout Queue XS2	(TO11)*/
 #define B3_RI_TO_VAL	0x019c	/* 8 bit RAM Iface Current Timeout Count Val */
 	/* 0x019d - 0x019f	reserved */
-#define B3_RI_CTRL	0x01a0	/* 16 bit	RAM Iface Control Register */
-#define B3_RI_TEST	0x01a2	/*  8 bit	RAM Iface Test Register */
+#define B3_RI_CTRL		0x01a0	/* 16 bit	RAM Iface Control Register */
+#define B3_RI_TEST		0x01a2	/*  8 bit	RAM Iface Test Register */
 	/* 0x01a3 - 0x01af	reserved */
 /* MAC Arbiter Registers */
 /* Please notice these are the number of qWord tranfered continously and */
@@ -569,42 +571,42 @@
  */
 
 /* Transmit Arbiter Registers MAC 1 and 2, user MR_ADDR() to address */
-#define TXA_ITI_INI	0x0200	/* 32 bit	Tx Arb Interval Timer Init Val*/
-#define TXA_ITI_VAL	0x0204	/* 32 bit	Tx Arb Interval Timer Value */
-#define TXA_LIM_INI	0x0208	/* 32 bit	Tx Arb Limit Counter Init Val */
-#define TXA_LIM_VAL	0x020c	/* 32 bit	Tx Arb Limit Counter Value */
-#define TXA_CTRL	0x0210	/*  8 bit	Tx Arbiter Control Register */
-#define TXA_TEST	0x0211	/*  8 bit	Tx Arbiter Test Register */
-#define TXA_STAT	0x0212	/*  8 bit	Tx Arbiter Status Register */
+#define TXA_ITI_INI		0x0200	/* 32 bit	Tx Arb Interval Timer Init Val*/
+#define TXA_ITI_VAL		0x0204	/* 32 bit	Tx Arb Interval Timer Value */
+#define TXA_LIM_INI		0x0208	/* 32 bit	Tx Arb Limit Counter Init Val */
+#define TXA_LIM_VAL		0x020c	/* 32 bit	Tx Arb Limit Counter Value */
+#define TXA_CTRL		0x0210	/*  8 bit	Tx Arbiter Control Register */
+#define TXA_TEST		0x0211	/*  8 bit	Tx Arbiter Test Register */
+#define TXA_STAT		0x0212	/*  8 bit	Tx Arbiter Status Register */
 	/* 0x0213 - 0x027f:	reserved */
 
 /*
  *	Bank 6
  */
 /* External registers */
-#define B6_EXT_REG	0x0300
+#define B6_EXT_REG		0x0300
 
 /*
  *	Bank 7
  */
 /* This is a copy of the Configuration register file (lower half) */
-#define B7_CFG_SPC	0x0380
+#define B7_CFG_SPC		0x0380
 
 /*
  *	Bank 8 - 15
  */
 /* Receive and Transmit Queue Registers, use Q_ADDR() to access */
-#define	B8_Q_REGS	0x0400
+#define	B8_Q_REGS		0x0400
 
 /* Queue Register Offsets, use Q_ADDR() to access */
-#define Q_D	0x00	/* 8*32	bit	Current Descriptor */
+#define Q_D		0x00	/* 8*32	bit	Current Descriptor */
 #define Q_DA_L	0x20	/* 32 bit	Current Descriptor Address Low dWord */
 #define Q_DA_H	0x24	/* 32 bit	Current Descriptor Address High dWord */
 #define Q_AC_L	0x28	/* 32 bit	Current Address Counter Low dWord */
 #define Q_AC_H	0x2c	/* 32 bit	Current Address Counter High dWord */
 #define Q_BC	0x30	/* 32 bit	Current Byte Counter */
 #define Q_CSR	0x34	/* 32 bit	BMU Control/Status Register */
-#define Q_F	0x38	/* 32 bit	Flag Register */
+#define Q_F		0x38	/* 32 bit	Flag Register */
 #define Q_T1	0x3c	/* 32 bit	Test Register 1 */
 #define Q_T1_TR	0x3c	/*  8 bit	Test Register 1 Transfer SM */
 #define Q_T1_WR	0x3d	/*  8 bit	Test Register 1 Write Descriptor SM */
@@ -642,64 +644,64 @@
  *	Bank 24 - 25
  */
 /* Receive MAC FIFO, Receive LED, and Link Sync regs, use MR_ADDR() to address*/
-#define RX_MFF_EA	0x0c00	/* 32 bit	Receive MAC FIFO End Address */
-#define RX_MFF_WP	0x0c04	/* 32 bit 	Receive MAC FIFO Write Pointer*/
+#define RX_MFF_EA		0x0c00	/* 32 bit	Receive MAC FIFO End Address */
+#define RX_MFF_WP		0x0c04	/* 32 bit 	Receive MAC FIFO Write Pointer*/
 	/* 0x0c08 - 0x0c0b	reserved */
-#define RX_MFF_RP	0x0c0c	/* 32 bit	Receive MAC FIFO Read Pointer */
-#define RX_MFF_PC	0x0c10	/* 32 bit	Receive MAC FIFO Packet Cnt */
-#define RX_MFF_LEV	0x0c14	/* 32 bit	Receive MAC FIFO Level */
+#define RX_MFF_RP		0x0c0c	/* 32 bit	Receive MAC FIFO Read Pointer */
+#define RX_MFF_PC		0x0c10	/* 32 bit	Receive MAC FIFO Packet Cnt */
+#define RX_MFF_LEV		0x0c14	/* 32 bit	Receive MAC FIFO Level */
 #define RX_MFF_CTRL1	0x0c18	/* 16 bit	Receive MAC FIFO Control Reg 1*/
 #define RX_MFF_STAT_TO	0x0c1a	/*  8 bit	Receive MAC Status Timeout */
 #define RX_MFF_TIST_TO	0x0c1b	/*  8 bit	Receive MAC Timestamp Timeout */
 #define RX_MFF_CTRL2	0x0c1c	/*  8 bit	Receive MAC FIFO Control Reg 2*/
-#define RX_MFF_TST1	0x0c1d	/*  8 bit	Receive MAC FIFO Test Reg 1 */
-#define RX_MFF_TST2	0x0c1e	/*  8 bit	Receive MAC FIFO Test Reg 2 */
+#define RX_MFF_TST1		0x0c1d	/*  8 bit	Receive MAC FIFO Test Reg 1 */
+#define RX_MFF_TST2		0x0c1e	/*  8 bit	Receive MAC FIFO Test Reg 2 */
 	/* 0x0c1f		reserved */
-#define RX_LED_INI	0x0c20	/* 32 bit	Receive LED Cnt Init Value */
-#define RX_LED_VAL	0x0c24	/* 32 bit	Receive LED Cnt Current Value */
-#define RX_LED_CTRL	0x0c28	/*  8 bit	Receive LED Cnt Control Reg */
-#define RX_LED_TST	0x0c29	/*  8 bit	Receive LED Cnt Test Register */
+#define RX_LED_INI		0x0c20	/* 32 bit	Receive LED Cnt Init Value */
+#define RX_LED_VAL		0x0c24	/* 32 bit	Receive LED Cnt Current Value */
+#define RX_LED_CTRL		0x0c28	/*  8 bit	Receive LED Cnt Control Reg */
+#define RX_LED_TST		0x0c29	/*  8 bit	Receive LED Cnt Test Register */
 	/* 0x0c2a - 0x0c2f	reserved */
 #define LNK_SYNC_INI	0x0c30	/* 32 bit	Link Sync Cnt Init Value */
 #define LNK_SYNC_VAL	0x0c34	/* 32 bit	Link Sync Cnt Current Value */
 #define LNK_SYNC_CTRL	0x0c38	/*  8 bit	Link Sync Cnt Control Register*/
 #define LNK_SYNC_TST	0x0c39	/*  8 bit	Link Sync Cnt Test Register */
 	/* 0x0c3a - 0x0c3b	reserved */
-#define LNK_LED_REG	0x0c3c	/*  8 bit	Link LED Register */
+#define LNK_LED_REG		0x0c3c	/*  8 bit	Link LED Register */
 	/* 0x0c3d - 0x0c7f	reserved */
 
 /*
  *	Bank 26 - 27
  */
 /* Transmit MAC FIFO and Transmit LED Registers, use MR_ADDR() to address */
-#define TX_MFF_EA	0x0d00	/* 32 bit	Transmit MAC FIFO End Address */
-#define TX_MFF_WP	0x0d04	/* 32 bit 	Transmit MAC FIFO WR Pointer */
-#define TX_MFF_WSP	0x0d08	/* 32 bit	Transmit MAC FIFO WR Shadow Pt*/
-#define TX_MFF_RP	0x0d0c	/* 32 bit	Transmit MAC FIFO RD Pointer */
-#define TX_MFF_PC	0x0d10	/* 32 bit	Transmit MAC FIFO Packet Cnt */
-#define TX_MFF_LEV	0x0d14	/* 32 bit	Transmit MAC FIFO Level */
+#define TX_MFF_EA		0x0d00	/* 32 bit	Transmit MAC FIFO End Address */
+#define TX_MFF_WP		0x0d04	/* 32 bit 	Transmit MAC FIFO WR Pointer */
+#define TX_MFF_WSP		0x0d08	/* 32 bit	Transmit MAC FIFO WR Shadow Pt*/
+#define TX_MFF_RP		0x0d0c	/* 32 bit	Transmit MAC FIFO RD Pointer */
+#define TX_MFF_PC		0x0d10	/* 32 bit	Transmit MAC FIFO Packet Cnt */
+#define TX_MFF_LEV		0x0d14	/* 32 bit	Transmit MAC FIFO Level */
 #define TX_MFF_CTRL1	0x0d18	/* 16 bit	Transmit MAC FIFO Ctrl Reg 1 */
-#define TX_MFF_WAF	0x0d1a	/*  8 bit	Transmit MAC Wait after flush*/
+#define TX_MFF_WAF		0x0d1a	/*  8 bit	Transmit MAC Wait after flush*/
 	/* 0x0c1b		reserved */
 #define TX_MFF_CTRL2	0x0d1c	/*  8 bit	Transmit MAC FIFO Ctrl Reg 2 */
-#define TX_MFF_TST1	0x0d1d	/*  8 bit	Transmit MAC FIFO Test Reg 1 */
-#define TX_MFF_TST2	0x0d1e	/*  8 bit	Transmit MAC FIFO Test Reg 2 */
+#define TX_MFF_TST1		0x0d1d	/*  8 bit	Transmit MAC FIFO Test Reg 1 */
+#define TX_MFF_TST2		0x0d1e	/*  8 bit	Transmit MAC FIFO Test Reg 2 */
 	/* 0x0d1f		reserved */
-#define TX_LED_INI	0x0d20	/* 32 bit	Transmit LED Cnt Init Value */
-#define TX_LED_VAL	0x0d24	/* 32 bit	Transmit LED Cnt Current Val */
-#define TX_LED_CTRL	0x0d28	/*  8 bit	Transmit LED Cnt Control Reg */
-#define TX_LED_TST	0x0d29	/*  8 bit	Transmit LED Cnt Test Register*/
+#define TX_LED_INI		0x0d20	/* 32 bit	Transmit LED Cnt Init Value */
+#define TX_LED_VAL		0x0d24	/* 32 bit	Transmit LED Cnt Current Val */
+#define TX_LED_CTRL		0x0d28	/*  8 bit	Transmit LED Cnt Control Reg */
+#define TX_LED_TST		0x0d29	/*  8 bit	Transmit LED Cnt Test Register*/
 	/* 0x0d2a - 0x0d7f	reserved */
 
 /*
  *	Bank 28
  */
 /* Descriptor Poll Timer Registers */
-#define B28_DPT_INI	0x0e00	/* 32 bit	Descriptor Poll Timer Init Val*/
-#define B28_DPT_VAL	0x0e04	/* 32 bit	Descriptor Poll Timer Curr Val*/
+#define B28_DPT_INI		0x0e00	/* 32 bit	Descriptor Poll Timer Init Val*/
+#define B28_DPT_VAL		0x0e04	/* 32 bit	Descriptor Poll Timer Curr Val*/
 #define B28_DPT_CTRL	0x0e08	/*  8 bit	Descriptor Poll Timer Ctrl Reg*/
 	/* 0x0e09:		reserved */
-#define B28_DPT_TST	0x0e0a	/*  8 bit	Descriptor Poll Timer Test Reg*/
+#define B28_DPT_TST		0x0e0a	/*  8 bit	Descriptor Poll Timer Test Reg*/
 	/* 0x0e0b - 0x0e8f:	reserved */
 
 /*
@@ -739,7 +741,7 @@
  */
 /*	B0_RAP		8 bit	Register Address Port */
 				/* Bit 7:	reserved */
-#define	RAP_RAP		0x3f	/* Bit 6..0:	0 = block 0, .., 6f = block 6f*/
+#define	RAP_RAP			0x3f	/* Bit 6..0:	0 = block 0, .., 6f = block 6f*/
 
 /*	B0_CTST		16 bit	Control/Status register */
 				/* Bit 15..10:	reserved */
@@ -749,70 +751,70 @@
 #define CS_CL_SW_IRQ	(1<<6)	/* Bit	6:	Clear IRQ SW Request	*/
 #define CS_STOP_DONE	(1<<5)	/* Bit	5:	Stop Master is finished */
 #define	CS_STOP_MAST	(1<<4)	/* Bit	4:	Command Bit to stop the master*/
-#define	CS_MRST_CLR	(1<<3)	/* Bit	3:	Clear Master reset	*/
-#define	CS_MRST_SET	(1<<2)	/* Bit	2:	Set Master reset	*/
-#define	CS_RST_CLR	(1<<1)	/* Bit	1:	Clear Software reset	*/
-#define	CS_RST_SET	(1<<0)	/* Bit	0:	Set Software reset	*/
+#define	CS_MRST_CLR		(1<<3)	/* Bit	3:	Clear Master reset	*/
+#define	CS_MRST_SET		(1<<2)	/* Bit	2:	Set Master reset	*/
+#define	CS_RST_CLR		(1<<1)	/* Bit	1:	Clear Software reset	*/
+#define	CS_RST_SET		(1<<0)	/* Bit	0:	Set Software reset	*/
 
 /*	B0_LED		 8 Bit	LED register */
 				/* Bit 7..2:	reserved */
-#define LED_STAT_ON	(1<<1)	/* Bit 1:	Status LED on	*/
+#define LED_STAT_ON		(1<<1)	/* Bit 1:	Status LED on	*/
 #define LED_STAT_OFF	(1<<0)	/* Bit 0:	Status LED off	*/
 
 /*	B0_ISRC		32 bit	Interrupt Source Register */
 /*	B0_IMSK		32 bit	Interrupt Mask Register */
 /*	B0_SP_ISRC	32 bit	Special Interrupt Source Reg */
 /*	B2_IRQM_MSK 	32 bit	IRQ Moderation Mask */
-#define IS_ALL_MSK	0xbfffffffL	/* 		All Interrupt bits */
-#define IS_HW_ERR	(1UL<<31)	/* Bit 31:	Interrupt HW Error */
-					/* Bit 30:	reserved */
+#define IS_ALL_MSK		0xbfffffffL	/* 		All Interrupt bits */
+#define IS_HW_ERR		(1UL<<31)	/* Bit 31:	Interrupt HW Error */
+									/* Bit 30:	reserved */
 #define IS_PA_TO_RX1	(1L<<29)	/* Bit 29:	Packet Arb Timeout Rx1*/
 #define IS_PA_TO_RX2	(1L<<28)	/* Bit 28:	Packet Arb Timeout Rx2*/
 #define IS_PA_TO_TX1	(1L<<27)	/* Bit 27:	Packet Arb Timeout Tx1*/
 #define IS_PA_TO_TX2	(1L<<26)	/* Bit 26:	Packet Arb Timeout Tx2*/
 #define IS_I2C_READY	(1L<<25)	/* Bit 25:	IRQ on end of I2C tx */
-#define IS_IRQ_SW	(1L<<24)	/* Bit 24:	SW forced IRQ	*/
-#define IS_EXT_REG	(1L<<23)	/* Bit 23:	IRQ from external reg */
-#define	IS_TIMINT	(1L<<22)	/* Bit 22:	IRQ from Timer	*/
-#define IS_MAC1		(1L<<21)	/* Bit 21:	IRQ from MAC 1	*/
+#define IS_IRQ_SW		(1L<<24)	/* Bit 24:	SW forced IRQ	*/
+#define IS_EXT_REG		(1L<<23)	/* Bit 23:	IRQ from external reg */
+#define	IS_TIMINT		(1L<<22)	/* Bit 22:	IRQ from Timer	*/
+#define IS_MAC1			(1L<<21)	/* Bit 21:	IRQ from MAC 1	*/
 #define IS_LNK_SYNC_M1	(1L<<20)	/* Bit 20:	Link Sync Cnt wrap M1 */
-#define IS_MAC2		(1L<<19)	/* Bit 19:	IRQ from MAC 2	*/
+#define IS_MAC2			(1L<<19)	/* Bit 19:	IRQ from MAC 2	*/
 #define IS_LNK_SYNC_M2	(1L<<18)	/* Bit 18:	Link Sync Cnt wrap M2 */
 /* Receive Queue 1 */
-#define	IS_R1_B		(1L<<17)	/* Bit 17:	Q_R1 End of Buffer */
-#define	IS_R1_F		(1L<<16)	/* Bit 16:	Q_R1 End of Frame */
-#define	IS_R1_C		(1L<<15)	/* Bit 15:	Q_R1 Encoding Error */
+#define	IS_R1_B			(1L<<17)	/* Bit 17:	Q_R1 End of Buffer */
+#define	IS_R1_F			(1L<<16)	/* Bit 16:	Q_R1 End of Frame */
+#define	IS_R1_C			(1L<<15)	/* Bit 15:	Q_R1 Encoding Error */
 /* Receive Queue 2 */
-#define	IS_R2_B		(1L<<14)	/* Bit 14:	Q_R2 End of Buffer */
-#define	IS_R2_F		(1L<<13)	/* Bit 13:	Q_R2 End of Frame */
-#define	IS_R2_C		(1L<<12)	/* Bit 12:	Q_R2 Encoding Error */
+#define	IS_R2_B			(1L<<14)	/* Bit 14:	Q_R2 End of Buffer */
+#define	IS_R2_F			(1L<<13)	/* Bit 13:	Q_R2 End of Frame */
+#define	IS_R2_C			(1L<<12)	/* Bit 12:	Q_R2 Encoding Error */
 /* Synchronous Transmit Queue 1 */
-#define	IS_XS1_B	(1L<<11)	/* Bit 11:	Q_XS1 End of Buffer */
-#define	IS_XS1_F	(1L<<10)	/* Bit 10:	Q_XS1 End of Frame */
-#define	IS_XS1_C	(1L<<9)		/* Bit	9:	Q_XS1 Encoding Error */
+#define	IS_XS1_B		(1L<<11)	/* Bit 11:	Q_XS1 End of Buffer */
+#define	IS_XS1_F		(1L<<10)	/* Bit 10:	Q_XS1 End of Frame */
+#define	IS_XS1_C		(1L<<9)		/* Bit	9:	Q_XS1 Encoding Error */
 /* Asynchronous Transmit Queue 1 */
-#define	IS_XA1_B	(1L<<8)		/* Bit	8:	Q_XA1 End of Buffer */
-#define	IS_XA1_F	(1L<<7)		/* Bit	7:	Q_XA1 End of Frame */
-#define	IS_XA1_C	(1L<<6)		/* Bit	6:	Q_XA1 Encoding Error */
+#define	IS_XA1_B		(1L<<8)		/* Bit	8:	Q_XA1 End of Buffer */
+#define	IS_XA1_F		(1L<<7)		/* Bit	7:	Q_XA1 End of Frame */
+#define	IS_XA1_C		(1L<<6)		/* Bit	6:	Q_XA1 Encoding Error */
 /* Synchronous Transmit Queue 2 */
-#define	IS_XS2_B	(1L<<5)		/* Bit	5:	Q_XS2 End of Buffer */
-#define	IS_XS2_F	(1L<<4)		/* Bit	4:	Q_XS2 End of Frame */
-#define	IS_XS2_C	(1L<<3)		/* Bit	3:	Q_XS2 Encoding Error */
+#define	IS_XS2_B		(1L<<5)		/* Bit	5:	Q_XS2 End of Buffer */
+#define	IS_XS2_F		(1L<<4)		/* Bit	4:	Q_XS2 End of Frame */
+#define	IS_XS2_C		(1L<<3)		/* Bit	3:	Q_XS2 Encoding Error */
 /* Asynchronous Transmit Queue 2 */
-#define	IS_XA2_B	(1L<<2)		/* Bit	2:	Q_XA2 End of Buffer */
-#define	IS_XA2_F	(1L<<1)		/* Bit	1:	Q_XA2 End of Frame */
-#define	IS_XA2_C	(1L<<0)		/* Bit	0:	Q_XA2 Encoding Error */
+#define	IS_XA2_B		(1L<<2)		/* Bit	2:	Q_XA2 End of Buffer */
+#define	IS_XA2_F		(1L<<1)		/* Bit	1:	Q_XA2 End of Frame */
+#define	IS_XA2_C		(1L<<0)		/* Bit	0:	Q_XA2 Encoding Error */
 
 
 /*	B0_HWE_ISRC	32 bit	HW Error Interrupt Src Reg */
 /*	B0_HWE_IMSK	32 bit	HW Error Interrupt Mask Reg */
 /*	B2_IRQM_HWE_MSK 32 bit	IRQ Moderation HW Error Mask */
-#define IS_ERR_MSK	0x00000fffL	/* 		All Error bits */
-					/* Bit 31..12:	reserved */
+#define IS_ERR_MSK		0x00000fffL	/* 		All Error bits */
+									/* Bit 31..12:	reserved */
 #define	IS_IRQ_MST_ERR	(1L<<11)	/* Bit 11:	IRQ master error */
-					/*	PERR,RMABORT,RTABORT,DATAPERR */
-#define	IS_IRQ_STAT	(1L<<10)	/* Bit 10:	IRQ status execption */
-					/*	RMABORT, RTABORT, DATAPERR */
+									/*	PERR,RMABORT,RTABORT,DATAPERR */
+#define	IS_IRQ_STAT		(1L<<10)	/* Bit 10:	IRQ status execption */
+									/*	RMABORT, RTABORT, DATAPERR */
 #define IS_NO_STAT_M1	(1L<<9)		/* Bit	9:	No Rx Status from MAC1*/
 #define IS_NO_STAT_M2	(1L<<8)		/* Bit	8:	No Rx Status from MAC2*/
 #define IS_NO_TIST_M1	(1L<<7)		/* Bit	7:	No Timestamp from MAC1*/
@@ -829,53 +831,53 @@
 /*	Values of connector and PMD type comply to SysKonnect internal std */
 
 /*	B2_MAC_CFG	 8 bit	MAC Configuration */
-				/* Bit 7..2:	reserved */
+								/* Bit 7..2:	reserved */
 #define	CFG_DIS_M2_CLK	(1<<1)	/* Bit 1:	Disable Clock for 2nd MAC */
-#define CFG_SNG_MAC	(1<<0)	/* Bit 0:	MAC Config: 1=2 MACs / 0=1 MAC*/
+#define CFG_SNG_MAC		(1<<0)	/* Bit 0:	MAC Config: 1=2 MACs / 0=1 MAC*/
 
 /*	B2_CHIP_REV	 8 bit 	Queen Chip Revision Number */
 #define FIRST_CHIP_REV	0x0a	/* Initial Revision Value */
 
 /*	B2_FAR		32 bit	Flash-Prom Addr Reg/Cnt */
-#define	FAR_ADDR	0x1ffffL	/* Bit 16..0:	FPROM Address mask */
+#define	FAR_ADDR		0x1ffffL	/* Bit 16..0:	FPROM Address mask */
 
 /*	B2_LD_CRTL	 8 bit	EPROM loader control register */
 /*	Bits are currently reserved */
 
 /*	B2_LD_TEST	 8 bit	EPROM loader test register */
-				/* Bit 7..4:	reserved */
-#define	LD_T_ON		(1<<3)	/* Bit 3:	Loader Testmode on */
-#define	LD_T_OFF	(1<<2)	/* Bit 2:	Loader Testmode off */
-#define	LD_T_STEP	(1<<1)	/* Bit 1:	Decrement FPROM addr. Counter */
-#define	LD_START	(1<<0)	/* Bit 0:	Start loading FPROM */
+								/* Bit 7..4:	reserved */
+#define	LD_T_ON			(1<<3)	/* Bit 3:	Loader Testmode on */
+#define	LD_T_OFF		(1<<2)	/* Bit 2:	Loader Testmode off */
+#define	LD_T_STEP		(1<<1)	/* Bit 1:	Decrement FPROM addr. Counter */
+#define	LD_START		(1<<0)	/* Bit 0:	Start loading FPROM */
 
 /*
  *	Timer Section
  */
 /*	B2_TI_CRTL	 8 bit	Timer control */
 /*	B2_IRQM_CTRL	 8 bit	IRQ Moderation Timer Control */
-				/* Bit 7..3:	reserved */
-#define TIM_START	(1<<2)	/* Bit 2:	Start Timer */
-#define TIM_STOP	(1<<1)	/* Bit 1:	Stop Timer */
-#define TIM_CLR_IRQ	(1<<0)	/* Bit 0:	Clear Timer IRQ, (!IRQM) */
+								/* Bit 7..3:	reserved */
+#define TIM_START		(1<<2)	/* Bit 2:	Start Timer */
+#define TIM_STOP		(1<<1)	/* Bit 1:	Stop Timer */
+#define TIM_CLR_IRQ		(1<<0)	/* Bit 0:	Clear Timer IRQ, (!IRQM) */
 
 /*	B2_TI_TEST	 8 Bit	Timer Test */
 /*	B2_IRQM_TEST	 8 bit	IRQ Moderation Timer Test */
 /*	B28_DPT_TST	 8 bit	Descriptor Poll Timer Test Reg */
-				/* Bit 7..3:	reserved */
-#define	TIM_T_ON	(1<<2)	/* Bit 2:	Test mode on */
-#define	TIM_T_OFF	(1<<1)	/* Bit 1:	Test mode off */
-#define	TIM_T_STEP	(1<<0)	/* Bit 0:	Test step */
+								/* Bit 7..3:	reserved */
+#define	TIM_T_ON		(1<<2)	/* Bit 2:	Test mode on */
+#define	TIM_T_OFF		(1<<1)	/* Bit 1:	Test mode off */
+#define	TIM_T_STEP		(1<<0)	/* Bit 0:	Test step */
 
 /*	B28_DPT_INI	32 bit	Descriptor Poll Timer Init Val */
 /*	B28_DPT_VAL	32 bit	Descriptor Poll Timer Curr Val */
-				/* Bit 31..24:	reserved */
-#define DPT_MSK	0x00ffffffL	/* Bit 23.. 0:	Desc Poll Timer Bits */
+								/* Bit 31..24:	reserved */
+#define DPT_MSK		0x00ffffffL	/* Bit 23.. 0:	Desc Poll Timer Bits */
 
 /*	B28_DPT_CTRL	 8 bit	Descriptor Poll Timer Ctrl Reg */
-				/* Bit 7..2:	reserved */
-#define DPT_START	(1<<1)	/* Bit 1:	Start Desciptor Poll Timer */
-#define DPT_STOP	(1<<0)	/* Bit 0:	Stop Desciptor Poll Timer */
+								/* Bit 7..2:	reserved */
+#define DPT_START		(1<<1)	/* Bit 1:	Start Desciptor Poll Timer */
+#define DPT_STOP		(1<<0)	/* Bit 0:	Stop Desciptor Poll Timer */
 
 
 /*	B2_TST_CTRL1	 8 bit	Test Control Register 1 */
@@ -889,7 +891,7 @@
 #define	TST_CFG_WRITE_OFF	(1<<0)	/* Bit 0: Disable Config Reg WR */
 
 /*	B2_TST_CTRL2	 8 bit	Test Control Register 2 */
-					/* Bit 7..4:	reserved */
+									/* Bit 7..4:	reserved */
 					/* force the following error on */
 					/* the next master read/write	*/
 #define TST_FRC_DPERR_MR64	(1<<3)	/* Bit 3:	DataPERR RD 64	*/
@@ -898,7 +900,7 @@
 #define TST_FRC_APERR_2M64	(1<<0)	/* Bit 0:	AddrPERR on 2. phase */
 
 /*	B2_GP_IO	32 bit	General Purpose IO Register */
-					/* Bit 31..26:	reserved */
+								/* Bit 31..26:	reserved */
 #define	GP_DIR_9	(1L<<25)	/* Bit 25:	IO_9 direct, 0=I/1=O */
 #define	GP_DIR_8	(1L<<24)	/* Bit 24:	IO_8 direct, 0=I/1=O */
 #define	GP_DIR_7	(1L<<23)	/* Bit 23:	IO_7 direct, 0=I/1=O */
@@ -909,7 +911,7 @@
 #define	GP_DIR_2	(1L<<18)	/* Bit 18:	IO_2 direct, 0=I/1=O */
 #define	GP_DIR_1	(1L<<17)	/* Bit 17:	IO_1 direct, 0=I/1=O */
 #define	GP_DIR_0	(1L<<16)	/* Bit 16:	IO_0 direct, 0=I/1=O */
-					/* Bit 15..10:	reserved */
+								/* Bit 15..10:	reserved */
 #define	GP_IO_9		(1L<<9)		/* Bit	9:	IO_9 pin */
 #define	GP_IO_8		(1L<<8)		/* Bit	8:	IO_8 pin */
 #define	GP_IO_7		(1L<<7)		/* Bit	7:	IO_7 pin */
@@ -922,31 +924,31 @@
 #define	GP_IO_0		(1L<<0)		/* Bit	0:	IO_0 pin */
 
 /*	B2_I2C_CTRL	32 bit	I2C HW Control Register */
-#define	I2C_FLAG	(1UL<<31)	/* Bit 31:	Start read/write if WR*/
+#define	I2C_FLAG		(1UL<<31)	/* Bit 31:	Start read/write if WR*/
 #define I2C_ADDR	(0x7fffL<<16)	/* Bit 30..16:	Addr to be RD/WR */
-#define	I2C_DEV_SEL	(0x7fL<<9)	/* Bit 15.. 9:	I2C Device Select */
-					/* Bit	8.. 5:	reserved	*/
+#define	I2C_DEV_SEL		(0x7fL<<9)	/* Bit 15.. 9:	I2C Device Select */
+									/* Bit	8.. 5:	reserved	*/
 #define I2C_BURST_LEN	(1L<<4)		/* Bit	4:	Burst Len, 1/4 bytes */
 #define I2C_DEV_SIZE	(7L<<1)		/* Bit	3.. 1:	I2C Device Size	*/
 #define I2C_025K_DEV	(0L<<1)		/*		0: 256 Bytes or smal. */
-#define I2C_05K_DEV	(1L<<1)		/* 		1: 512	Bytes	*/
-#define	I2C_1K_DEV	(2L<<1)		/*		2: 1024 Bytes	*/
-#define I2C_2K_DEV	(3L<<1)		/*		3: 2048	Bytes	*/
-#define	I2C_4K_DEV	(4L<<1)		/*		4: 4096 Bytes	*/
-#define	I2C_8K_DEV	(5L<<1)		/*		5: 8192 Bytes	*/
-#define	I2C_16K_DEV	(6L<<1)		/*		6: 16384 Bytes	*/
-#define	I2C_32K_DEV	(7L<<1)		/*		7: 32768 Bytes	*/
-#define I2C_STOP	(1L<<0)		/* Bit	0:	Interrupt I2C transfer*/
+#define I2C_05K_DEV		(1L<<1)		/* 		1: 512	Bytes	*/
+#define	I2C_1K_DEV		(2L<<1)		/*		2: 1024 Bytes	*/
+#define I2C_2K_DEV		(3L<<1)		/*		3: 2048	Bytes	*/
+#define	I2C_4K_DEV		(4L<<1)		/*		4: 4096 Bytes	*/
+#define	I2C_8K_DEV		(5L<<1)		/*		5: 8192 Bytes	*/
+#define	I2C_16K_DEV		(6L<<1)		/*		6: 16384 Bytes	*/
+#define	I2C_32K_DEV		(7L<<1)		/*		7: 32768 Bytes	*/
+#define I2C_STOP		(1L<<0)		/* Bit	0:	Interrupt I2C transfer*/
 
 /*	B2_I2C_IRQ	32 bit	I2C HW IRQ Register */
-				/* Bit 31..1	reserved */
-#define I2C_CLR_IRQ	(1<<0)	/* Bit 0:	Clear I2C IRQ */
+								/* Bit 31..1	reserved */
+#define I2C_CLR_IRQ		(1<<0)	/* Bit 0:	Clear I2C IRQ */
 
 /*	B2_I2C_SW	32 bit	I2C HW SW Port Register */
-				/* Bit 7..3:	reserved */
+								/* Bit 7..3:	reserved */
 #define	I2C_DATA_DIR	(1<<2)	/* Bit 2:	direction of I2C_DATA */
-#define I2C_DATA	(1<<1)	/* Bit 1:	I2C Data Port	*/
-#define	I2C_CLK		(1<<0)	/* Bit 0:	I2C Clock Port	*/
+#define I2C_DATA		(1<<1)	/* Bit 1:	I2C Data Port	*/
+#define	I2C_CLK			(1<<0)	/* Bit 0:	I2C Clock Port	*/
 
 /*
  * I2C Address
@@ -955,12 +957,12 @@
 
 
 /*	B2_BSC_CTRL	 8 bit	Blink Source Counter Control */
-				/* Bit 7..2:	reserved */
+							/* Bit 7..2:	reserved */
 #define BSC_START	(1<<1)	/* Bit 1:	Start Blink Source Counter */
 #define BSC_STOP	(1<<0)	/* Bit 0:	Stop Blink Source Counter */
 
 /*	B2_BSC_STAT	 8 bit	Blink Source Counter Status */
-				/* Bit 7..1:	reserved */
+							/* Bit 7..1:	reserved */
 #define BSC_SRC		(1<<0)	/* Bit 0:	Blink Source, 0=Off / 1=On */
 
 /*	B2_BSC_TST	16 bit	Blink Source Counter Test Reg */
@@ -975,30 +977,30 @@
 
 /* RAM Interface Registers */
 /*	B3_RI_CTRL	16 bit	RAM Iface Control Register */
-				/* Bit 15..10:	reserved */
+								/* Bit 15..10:	reserved */
 #define RI_CLR_RD_PERR	(1<<9)	/* Bit	9:	Clear IRQ RAM Read Parity Err */
 #define RI_CLR_WR_PERR	(1<<8)	/* Bit	8:	Clear IRQ RAM Write Parity Err*/
-				/* Bit	7..2:	reserved */
-#define RI_RST_CLR	(1<<1)	/* Bit	1:	Clear RAM Interface Reset */
-#define RI_RST_SET	(1<<0)	/* Bit	0:	Set RAM Interface Reset */
+								/* Bit	7..2:	reserved */
+#define RI_RST_CLR		(1<<1)	/* Bit	1:	Clear RAM Interface Reset */
+#define RI_RST_SET		(1<<0)	/* Bit	0:	Set RAM Interface Reset */
 
 /*	B3_RI_TEST	 8 bit	RAM Iface Test Register */
-				/* Bit 15..4:	reserved */
-#define RI_T_EV		(1<<3)	/* Bit	3:	Timeout Event occurred */
-#define RI_T_ON		(1<<2)	/* Bit	2:	Timeout Timer Test On */
-#define RI_T_OFF	(1<<1)	/* Bit	1:	Timeout Timer Test Off */
-#define RI_T_STEP	(1<<0)	/* Bit	0:	Timeout Timer Step */
+								/* Bit 15..4:	reserved */
+#define RI_T_EV			(1<<3)	/* Bit	3:	Timeout Event occured */
+#define RI_T_ON			(1<<2)	/* Bit	2:	Timeout Timer Test On */
+#define RI_T_OFF		(1<<1)	/* Bit	1:	Timeout Timer Test Off */
+#define RI_T_STEP		(1<<0)	/* Bit	0:	Timeout Timer Step */
 
 /* MAC Arbiter Registers */
 /*	B3_MA_TO_CTRL	16 bit	MAC Arbiter Timeout Ctrl Reg */
-				/* Bit 15..4:	reserved */
-#define MA_FOE_ON	(1<<3)	/* Bit	3:	XMAC Fast Output Enable ON */
-#define MA_FOE_OFF	(1<<2)	/* Bit	2:	XMAC Fast Output Enable OFF */
-#define MA_RST_CLR	(1<<1)	/* Bit	1:	Clear MAC Arbiter Reset */
-#define MA_RST_SET	(1<<0)	/* Bit	0:	Set MAC Arbiter Reset */
+								/* Bit 15..4:	reserved */
+#define MA_FOE_ON		(1<<3)	/* Bit	3:	XMAC Fast Output Enable ON */
+#define MA_FOE_OFF		(1<<2)	/* Bit	2:	XMAC Fast Output Enable OFF */
+#define MA_RST_CLR		(1<<1)	/* Bit	1:	Clear MAC Arbiter Reset */
+#define MA_RST_SET		(1<<0)	/* Bit	0:	Set MAC Arbiter Reset */
 
 /*	B3_MA_RC_CTRL	16 bit	MAC Arbiter Recovery Ctrl Reg */
-				/* Bit 15..8:	reserved */
+								/* Bit 15..8:	reserved */
 #define MA_ENA_REC_TX2	(1<<7)	/* Bit	7:	Enable Recovery Timer TX2 */
 #define MA_DIS_REC_TX2	(1<<6)	/* Bit	6:	Disable Recovery Timer TX2 */
 #define MA_ENA_REC_TX1	(1<<5)	/* Bit	5:	Enable Recovery Timer TX1 */
@@ -1010,7 +1012,7 @@
 
 /* Packet Arbiter Registers */
 /*	B3_PA_CTRL	16 bit	Packet Arbiter Ctrl Register */
-				/* Bit 15..14:	reserved */
+								/* Bit 15..14:	reserved */
 #define PA_CLR_TO_TX2	(1<<13)	/* Bit 13:	Clear IRQ Packet Timeout TX2 */
 #define PA_CLR_TO_TX1	(1<<12)	/* Bit 12:	Clear IRQ Packet Timeout TX1 */
 #define PA_CLR_TO_RX2	(1<<11)	/* Bit 11:	Clear IRQ Packet Timeout RX2 */
@@ -1023,30 +1025,30 @@
 #define PA_DIS_TO_RX2	(1<<4)	/* Bit	4:	Disable Timeout Timer RX2 */
 #define PA_ENA_TO_RX1	(1<<3)	/* Bit	3:	Enable Timeout Timer RX1 */
 #define PA_DIS_TO_RX1	(1<<2)	/* Bit	2:	Disable Timeout Timer RX1 */
-#define PA_RST_CLR	(1<<1)	/* Bit	1:	Clear MAC Arbiter Reset */
-#define PA_RST_SET	(1<<0)	/* Bit	0:	Set MAC Arbiter Reset */
+#define PA_RST_CLR		(1<<1)	/* Bit	1:	Clear MAC Arbiter Reset */
+#define PA_RST_SET		(1<<0)	/* Bit	0:	Set MAC Arbiter Reset */
 
 #define PA_ENA_TO_ALL	(PA_ENA_TO_RX1 | PA_ENA_TO_RX2 |\
-			 PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
+						PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
 
 /* Rx/Tx Path related Arbiter Test Registers */
 /*	B3_MA_TO_TEST	16 bit	MAC Arbiter Timeout Test Reg */
 /*	B3_MA_RC_TEST	16 bit	MAC Arbiter Recovery Test Reg */
 /*	B3_PA_TEST	16 bit	Packet Arbiter Test Register */
 /*			Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
-#define TX2_T_EV	(1<<15)	/* Bit 15: 	TX2 Timeout/Recv Event occurred*/
+#define TX2_T_EV	(1<<15)	/* Bit 15: 	TX2 Timeout/Recv Event occured*/
 #define TX2_T_ON	(1<<14)	/* Bit 14:	TX2 Timeout/Recv Timer Test On*/
 #define TX2_T_OFF	(1<<13)	/* Bit 13:	TX2 Timeout/Recv Timer Tst Off*/
 #define TX2_T_STEP	(1<<12)	/* Bit 12:	TX2 Timeout/Recv Timer Step */
-#define TX1_T_EV	(1<<11)	/* Bit 11:	TX1 Timeout/Recv Event occurred*/
+#define TX1_T_EV	(1<<11)	/* Bit 11:	TX1 Timeout/Recv Event occured*/
 #define TX1_T_ON	(1<<10)	/* Bit 10:	TX1 Timeout/Recv Timer Test On*/
 #define TX1_T_OFF	(1<<9)	/* Bit	9:	TX1 Timeout/Recv Timer Tst Off*/
 #define TX1_T_STEP	(1<<8)	/* Bit	8:	TX1 Timeout/Recv Timer Step */
-#define RX2_T_EV	(1<<7)	/* Bit	7:	RX2 Timeout/Recv Event occurred*/
+#define RX2_T_EV	(1<<7)	/* Bit	7:	RX2 Timeout/Recv Event occured*/
 #define RX2_T_ON	(1<<6)	/* Bit	6:	RX2 Timeout/Recv Timer Test On*/
 #define RX2_T_OFF	(1<<5)	/* Bit	5:	RX2 Timeout/Recv Timer Tst Off*/
 #define RX2_T_STEP	(1<<4)	/* Bit	4:	RX2 Timeout/Recv Timer Step */
-#define RX1_T_EV	(1<<3)	/* Bit	3:	RX1 Timeout/Recv Event occurred*/
+#define RX1_T_EV	(1<<3)	/* Bit	3:	RX1 Timeout/Recv Event occured*/
 #define RX1_T_ON	(1<<2)	/* Bit	2:	RX1 Timeout/Recv Timer Test On*/
 #define RX1_T_OFF	(1<<1)	/* Bit	1:	RX1 Timeout/Recv Timer Tst Off*/
 #define RX1_T_STEP	(1<<0)	/* Bit	0:	RX1 Timeout/Recv Timer Step */
@@ -1057,7 +1059,7 @@
 /*	TXA_ITI_VAL	32 bit	Tx Arb Interval Timer Value */
 /*	TXA_LIM_INI	32 bit	Tx Arb Limit Counter Init Val */
 /*	TXA_LIM_VAL	32 bit	Tx Arb Limit Counter Value */
-					/* Bit 31..24:	reserved */
+								/* Bit 31..24:	reserved */
 #define	TXA_MAX_VAL	0x00ffffffL	/* Bit 23.. 0:	Max TXA Timer/Cnt Val */
 
 /*	TXA_CTRL	 8 bit	Tx Arbiter Control Register */
@@ -1066,9 +1068,9 @@
 #define TXA_ENA_ALLOC	(1<<5)	/* Bit 5:	Enable alloc of free bandwidth*/
 #define TXA_DIS_ALLOC	(1<<4)	/* Bit 4:	Disabl alloc of free bandwidth*/
 #define TXA_START_RC	(1<<3)	/* Bit 3:	Start sync Rate Control */
-#define TXA_STOP_RC	(1<<2)	/* Bit 2:	Stop sync Rate Control */
-#define TXA_ENA_ARB	(1<<1)	/* Bit 1:	Enable Tx Arbiter */
-#define TXA_DIS_ARB	(1<<0)	/* Bit 0:	Disable Tx Arbiter */
+#define TXA_STOP_RC		(1<<2)	/* Bit 2:	Stop sync Rate Control */
+#define TXA_ENA_ARB		(1<<1)	/* Bit 1:	Enable Tx Arbiter */
+#define TXA_DIS_ARB		(1<<0)	/* Bit 0:	Disable Tx Arbiter */
 
 /*	TXA_TEST	 8 bit	Tx Arbiter Test Register */
 				/* Bit 7..6:	reserved */
@@ -1080,12 +1082,12 @@
 #define TXA_LIM_T_STEP	(1<<0)	/* Bit 0:	Tx Arb Limit Timer Step */
 
 /*	TXA_STAT	 8 bit	Tx Arbiter Status Register */
-				/* Bit 7..1:	reserved */
-#define	TXA_PRIO_XS	(1<<0)	/* Bit 0:	sync queue has prio to send */
+								/* Bit 7..1:	reserved */
+#define	TXA_PRIO_XS		(1<<0)	/* Bit 0:	sync queue has prio to send */
 
 /*	Q_BC	32 bit	Current Byte Counter */
 				/* Bit 31..16:	reserved */
-#define BC_MAX		0xffff	/* Bit 15.. 0:	Byte counter */
+#define BC_MAX			0xffff	/* Bit 15.. 0:	Byte counter */
 
 /* BMU Control Status Registers */
 /*	B0_R1_CSR	32 bit	BMU Ctrl/Stat Rx Queue 1 */
@@ -1095,47 +1097,47 @@
 /*	B0_XA2_CSR	32 bit	BMU Ctrl/Stat Sync Tx Queue 2 */
 /*	B0_XS2_CSR	32 bit	BMU Ctrl/Stat Async Tx Queue 2 */
 /*	Q_CSR	32 bit	BMU Control/Status Register */
-					/* Bit 31..25:	reserved */
-#define CSR_SV_IDLE	(1L<<24)	/* Bit 24: 	BMU SM Idle */
-					/* Bit 23..22:	reserved */
+									/* Bit 31..25:	reserved */
+#define CSR_SV_IDLE		(1L<<24)	/* Bit 24: 	BMU SM Idle */
+									/* Bit 23..22:	reserved */
 #define	CSR_DESC_CLR	(1L<<21)	/* Bit 21:	Clear Reset for Descr */
 #define	CSR_DESC_SET	(1L<<20)	/* Bit 20:	Set Reset for Descr */
 #define	CSR_FIFO_CLR	(1L<<19)	/* Bit 19:	Clear Reset for FIFO */
 #define	CSR_FIFO_SET	(1L<<18)	/* Bit 18:	Set Reset for FIFO */
-#define	CSR_HPI_RUN	(1L<<17)	/* Bit 17:	Release HPI SM */
-#define	CSR_HPI_RST	(1L<<16)	/* Bit 16:	Reset HPI SM to Idle */
-#define	CSR_SV_RUN	(1L<<15)	/* Bit 15:	Release Supervisor SM */
-#define	CSR_SV_RST	(1L<<14)	/* Bit 14:	Reset Supervisor SM */
+#define	CSR_HPI_RUN		(1L<<17)	/* Bit 17:	Release HPI SM */
+#define	CSR_HPI_RST		(1L<<16)	/* Bit 16:	Reset HPI SM to Idle */
+#define	CSR_SV_RUN		(1L<<15)	/* Bit 15:	Release Supervisor SM */
+#define	CSR_SV_RST		(1L<<14)	/* Bit 14:	Reset Supervisor SM */
 #define	CSR_DREAD_RUN	(1L<<13)	/* Bit 13:	Release Descr Read SM */
 #define	CSR_DREAD_RST	(1L<<12)	/* Bit 12:	Reset Descr Read SM */
 #define	CSR_DWRITE_RUN	(1L<<11)	/* Bit 11:	Rel. Descr Write SM */
 #define	CSR_DWRITE_RST	(1L<<10)	/* Bit 10:	Reset Descr Write SM */
 #define	CSR_TRANS_RUN	(1L<<9)		/* Bit	9:	Release Transfer SM */
 #define	CSR_TRANS_RST	(1L<<8)		/* Bit	8:	Reset Transfer SM */
-#define CSR_ENA_POL	(1L<<7)		/* Bit	7:	Enable Descr Polling */
-#define CSR_DIS_POL	(1L<<6)		/* Bit	6:	Disable Descr Polling */
-#define CSR_STOP	(1L<<5)		/* Bit	5:	Stop Rx/Tx Queue */
-#define	CSR_START	(1L<<4)		/* Bit	4:	Start Rx/Tx Queue */
+#define CSR_ENA_POL		(1L<<7)		/* Bit	7:	Enable Descr Polling */
+#define CSR_DIS_POL		(1L<<6)		/* Bit	6:	Disable Descr Polling */
+#define CSR_STOP		(1L<<5)		/* Bit	5:	Stop Rx/Tx Queue */
+#define	CSR_START		(1L<<4)		/* Bit	4:	Start Rx/Tx Queue */
 #define	CSR_IRQ_CL_P	(1L<<3)		/* Bit	3: (Rx)	Clear Parity IRQ */
 #define	CSR_IRQ_CL_B	(1L<<2)		/* Bit	2:	Clear EOB IRQ */
 #define	CSR_IRQ_CL_F	(1L<<1)		/* Bit	1:	Clear EOF IRQ */
 #define	CSR_IRQ_CL_C	(1L<<0)		/* Bit	0:	Clear ERR IRQ */
 
 #define CSR_SET_RESET	(CSR_DESC_SET|CSR_FIFO_SET|CSR_HPI_RST|CSR_SV_RST|\
-			CSR_DREAD_RST|CSR_DWRITE_RST|CSR_TRANS_RST)
+						CSR_DREAD_RST|CSR_DWRITE_RST|CSR_TRANS_RST)
 #define CSR_CLR_RESET	(CSR_DESC_CLR|CSR_FIFO_CLR|CSR_HPI_RUN|CSR_SV_RUN|\
-			CSR_DREAD_RUN|CSR_DWRITE_RUN|CSR_TRANS_RUN)
+						CSR_DREAD_RUN|CSR_DWRITE_RUN|CSR_TRANS_RUN)
 
 
 /*	Q_F	32 bit	Flag Register */
 					/* Bit 28..31:	reserved */
-#define F_ALM_FULL	(1L<<27) (Rx)	/* Bit 27: (Rx)	FIFO almost full */
-#define F_EMPTY		(1L<<27) (Tx)	/* Bit 27: (Tx)	FIFO empty flag */
-#define F_FIFO_EOF	(1L<<26)	/* Bit 26: 	Fag bit in FIFO */
+#define F_ALM_FULL		(1L<<27) (Rx)	/* Bit 27: (Rx)	FIFO almost full */
+#define F_EMPTY			(1L<<27) (Tx)	/* Bit 27: (Tx)	FIFO empty flag */
+#define F_FIFO_EOF		(1L<<26)	/* Bit 26: 	Fag bit in FIFO */
 #define F_WM_REACHED	(1L<<25)	/* Bit 25: 	Watermark reached */
-					/* Bit 24:	reserved */
+									/* Bit 24:	reserved */
 #define F_FIFO_LEVEL	(0x1fL<<16)	/* Bit 23..16:	# of Qwords in FIFO */
-					/* Bit 15..11: 	reserved */
+									/* Bit 15..11: 	reserved */
 #define F_WATER_MARK	0x0007ffL	/* Bit 10.. 0:	Watermark */
 
 /*	Q_T1	32 bit	Test Register 1 */
@@ -1169,9 +1171,9 @@
 #define	T2_STEP01	(1<<0)	/* Bit 0:	Inc AC/Dec BC by 1 */
 
 /*	Q_T3	32 bit	Test Register 3	*/
-				/* Bit 31..7:	reserved */
+							/* Bit 31..7:	reserved */
 #define	T3_MUX		(7<<4)	/* Bit 6.. 4:	Mux Position */
-				/* Bit 3:	reserved */
+							/* Bit 3:	reserved */
 #define	T3_VRAM		(7<<0)	/* Bit 2.. 0:	Virtual RAM Buffer Address */
 
 /* RAM Buffer Register Offsets */
@@ -1190,7 +1192,7 @@
 #define RB_MSK	0x0007ffff	/* Bit 18.. 0:	RAM Buffer Pointer Bits */
 
 /*	RB_TST2		8 bit	RAM Buffer Test Register 2 */
-				/* Bit 4..7:	reserved */
+							/* Bit 4..7:	reserved */
 #define	RB_PC_DEC	(1<<3)	/* Bit 3:	Packet Counter Decrem */
 #define RB_PC_T_ON	(1<<2)	/* Bit 2:	Packet Counter Test On */
 #define RB_PC_T_OFF	(1<<1)	/* Bit 1:	Packet Counter Tst Off */
@@ -1201,19 +1203,19 @@
 #define RB_WP_T_ON	(1<<6)	/* Bit 6:	Write Pointer Test On */
 #define RB_WP_T_OFF	(1<<5)	/* Bit 5:	Write Pointer Test Off */
 #define RB_WP_INC	(1<<4)	/* Bit 4:	Write Pointer Increm */
-				/* Bit 3:	reserved */
+							/* Bit 3:	reserved */
 #define RB_RP_T_ON	(1<<2)	/* Bit 2:	Read Pointer Test On */
 #define RB_RP_T_OFF	(1<<1)	/* Bit 1:	Read Pointer Test Off */
 #define RB_RP_DEC	(1<<0)	/* Bit 0:	Read Pointer Decrement */
 
 /*	RB_CTRL		8 bit	RAM Buffer Control Register */
-				/* Bit	7..6:	reserved */
+								/* Bit	7..6:	reserved */
 #define RB_ENA_STFWD	(1<<5)	/* Bit	5:	Enable Store & Forward */
 #define RB_DIS_STFWD	(1<<4)	/* Bit	4:	Disab. Store & Forward */
 #define RB_ENA_OP_MD	(1<<3)	/* Bit	3:	Enable Operation Mode */
 #define RB_DIS_OP_MD	(1<<2)	/* Bit	2:	Disab. Operation Mode */
-#define RB_RST_CLR	(1<<1)	/* Bit	1:	Clr RAM Buf STM Reset */
-#define RB_RST_SET	(1<<0)	/* Bit	0:	Set RAM Buf STM Reset */
+#define RB_RST_CLR		(1<<1)	/* Bit	1:	Clr RAM Buf STM Reset */
+#define RB_RST_SET		(1<<0)	/* Bit	0:	Set RAM Buf STM Reset */
 
 
 /* Receive and Transmit MAC FIFO Registers, use MR_ADDR() to address */
@@ -1228,11 +1230,11 @@
 /*	TX_MFF_RP	32 bit	Transmit MAC FIFO Read Pointer */
 /*	TX_MFF_PC	32 bit	Transmit MAC FIFO Packet Cnt */
 /*	TX_MFF_LEV	32 bit	Transmit MAC FIFO Level */
-				/* Bit 31..6:	reserved */
+							/* Bit 31..6:	reserved */
 #define MFF_MSK		0x007fL	/* Bit	5..0:	MAC FIFO Address/Pointer Bits */
 
 /*	RX_MFF_CTRL1	16 bit	Receive MAC FIFO Control Reg 1 */
-					/* Bit 15..14:	reserved */
+									/* Bit 15..14:	reserved */
 #define MFF_ENA_RDY_PAT	(1<<13)		/* Bit 13:	Enable Ready Patch */
 #define MFF_DIS_RDY_PAT	(1<<12)		/* Bit 12:	Disable Ready Patch */
 #define MFF_ENA_TIM_PAT	(1<<11)		/* Bit 11:	Enable Timing Patch */
@@ -1252,15 +1254,15 @@
 
 /*	TX_MFF_CTRL1	16 bit	Transmit MAC FIFO Control Reg 1 */
 #define MFF_CLR_PERR	(1<<15)		/* Bit 15:	Clear Parity Error IRQ*/
-					/* Bit 14:	reserved */
+									/* Bit 14:	reserved */
 #define MFF_ENA_PKT_REC	(1<<13)		/* Bit 13:	Enable Packet Recovery*/
 #define MFF_DIS_PKT_REC (1<<12)		/* Bit 12:	Disable Packet Recov. */
 /*	MFF_ENA_TIM_PAT	 (see RX_MFF_CTRL1)Bit 11:	Enable Timing Patch */
 /*	MFF_DIS_TIM_PAT	 (see RX_MFF_CTRL1)Bit 10:	Disable Timing Patch */
 /*	MFF_ENA_ALM_FUL	 (see RX_MFF_CTRL1)Bit	9:	Enable AlmostFull Sign*/
 /*	MFF_DIS_ALM_FUL	 (see RX_MFF_CTRL1)Bit	8:	Disab. AlmostFull Sign*/
-#define	MFF_ENA_W4E	(1<<7)		/* Bit	7:	Enable Wait for Empty */
-#define MFF_DIS_W4E	(1<<6)		/* Bit	6:	Disab. Wait for Empty */
+#define	MFF_ENA_W4E		(1<<7)		/* Bit	7:	Enable Wait for Empty */
+#define MFF_DIS_W4E		(1<<6)		/* Bit	6:	Disab. Wait for Empty */
 /*	MFF_ENA_FLUSH	 (see RX_MFF_CTRL1)Bit	5:	Enable Frame Flushing */
 /*	MFF_DIS_FLUSH	 (see RX_MFF_CTRL1)Bit	4:	Disab. Frame Flushing */
 #define MFF_ENA_LOOPB	(1<<3)		/* Bit	3:	Enable Loopback */
@@ -1272,61 +1274,61 @@
 
 /*	RX_MFF_TST2	 8 bit	Receive MAC FIFO Test Register 2 */
 /*	TX_MFF_TST2	 8 bit	Transmit MAC FIFO Test Register 2 */
-				/* Bit 7:	reserved */
+								/* Bit 7:	reserved */
 #define MFF_WSP_T_ON	(1<<6)	/* Bit 6: (Tx)	Write Shadow Pt TestOn */
 #define MFF_WSP_T_OFF	(1<<5)	/* Bit 5: (Tx)	Write Shadow Pt TstOff */
-#define MFF_WSP_INC	(1<<4)	/* Bit 4: (Tx)	Write Shadow Pt Increm */
-#define	MFF_PC_DEC	(1<<3)	/* Bit 3:	Packet Counter Decrem  */
-#define MFF_PC_T_ON	(1<<2)	/* Bit 2:	Packet Counter Test On */
+#define MFF_WSP_INC		(1<<4)	/* Bit 4: (Tx)	Write Shadow Pt Increm */
+#define	MFF_PC_DEC		(1<<3)	/* Bit 3:	Packet Counter Decrem  */
+#define MFF_PC_T_ON		(1<<2)	/* Bit 2:	Packet Counter Test On */
 #define MFF_PC_T_OFF	(1<<1)	/* Bit 1:	Packet Counter Tst Off */
-#define MFF_PC_INC	(1<<0)	/* Bit 0:	Packet Counter Increm  */
+#define MFF_PC_INC		(1<<0)	/* Bit 0:	Packet Counter Increm  */
 
 /*	RX_MFF_TST1	 8 bit	Receive MAC FIFO Test Register 1 */
 /*	TX_MFF_TST1	 8 bit	Transmit MAC FIFO Test Register 1 */
-				/* Bit 7:	reserved */
-#define MFF_WP_T_ON	(1<<6)	/* Bit 6:	Write Pointer Test On */
+					/* Bit 7:	reserved */
+#define MFF_WP_T_ON		(1<<6)	/* Bit 6:	Write Pointer Test On */
 #define MFF_WP_T_OFF	(1<<5)	/* Bit 5:	Write Pointer Test Off */
-#define MFF_WP_INC	(1<<4)	/* Bit 4:	Write Pointer Increm */
-				/* Bit 3:	reserved */
-#define MFF_RP_T_ON	(1<<2)	/* Bit 2:	Read Pointer Test On */
+#define MFF_WP_INC		(1<<4)	/* Bit 4:	Write Pointer Increm */
+								/* Bit 3:	reserved */
+#define MFF_RP_T_ON		(1<<2)	/* Bit 2:	Read Pointer Test On */
 #define MFF_RP_T_OFF	(1<<1)	/* Bit 1:	Read Pointer Test Off */
-#define MFF_RP_DEC	(1<<0)	/* Bit 0:	Read Pointer Decrement */
+#define MFF_RP_DEC		(1<<0)	/* Bit 0:	Read Pointer Decrement */
 
 /*	RX_MFF_CTRL2	 8 bit	Receive MAC FIFO Control Reg 2 */
 /*	TX_MFF_CTRL2	 8 bit	Transmit MAC FIFO Control Reg 2 */
-				/* Bit 7..4:	reserved */
+								/* Bit 7..4:	reserved */
 #define MFF_ENA_OP_MD	(1<<3)	/* Bit 3:	Enable Operation Mode */
 #define MFF_DIS_OP_MD	(1<<2)	/* Bit 2:	Disab. Operation Mode */
-#define MFF_RST_CLR	(1<<1)	/* Bit 1:	Clear MAC FIFO Reset */
-#define MFF_RST_SET	(1<<0)	/* Bit 0:	Set MAC FIFO Reset */
+#define MFF_RST_CLR		(1<<1)	/* Bit 1:	Clear MAC FIFO Reset */
+#define MFF_RST_SET		(1<<0)	/* Bit 0:	Set MAC FIFO Reset */
 
 
 /* Receive, Transmit, and Link LED Counter Registers */
-/*	RX_LED_CTRL	 8 bit	Receive LED Cnt Control Reg */
-/*	TX_LED_CTRL	 8 bit	Transmit LED Cnt Control Reg */
-/*	LNK_SYNC_CTRL	 8 bit	Link Sync Cnt Control Register */
-				/* Bit 7..3:	reserved */
+/*	RX_LED_CTRL		8 bit	Receive LED Cnt Control Reg */
+/*	TX_LED_CTRL		8 bit	Transmit LED Cnt Control Reg */
+/*	LNK_SYNC_CTRL	8 bit	Link Sync Cnt Control Register */
+							/* Bit 7..3:	reserved */
 #define LED_START	(1<<2)	/* Bit 2:	Start Timer */
 #define LED_STOP	(1<<1)	/* Bit 1:	Stop Timer */
 #define LED_STATE	(1<<0)	/* Bit 0:(Rx/Tx)LED State, 1=LED on */
 #define LED_CLR_IRQ	(1<<0)	/* Bit 0:(Lnk) 	Clear Link IRQ */
 
-/*	RX_LED_TST	 8 bit	Receive LED Cnt Test Register */
-/*	TX_LED_TST	 8 bit	Transmit LED Cnt Test Register */
-/*	LNK_SYNC_TST	 8 bit	Link Sync Cnt Test Register */
-				/* Bit 7..3:	reserved */
+/*	RX_LED_TST		8 bit	Receive LED Cnt Test Register */
+/*	TX_LED_TST		8 bit	Transmit LED Cnt Test Register */
+/*	LNK_SYNC_TST	8 bit	Link Sync Cnt Test Register */
+							/* Bit 7..3:	reserved */
 #define LED_T_ON	(1<<2)	/* Bit 2:	LED Counter Testmode On */
 #define LED_T_OFF	(1<<1)	/* Bit 1:	LED Counter Testmode Off */
 #define LED_T_STEP	(1<<0)	/* Bit 0:	LED Counter Step */
 
 /*	LNK_LED_REG	 8 bit	Link LED Register */
-				/* Bit 7..6:	reserved */
-#define LED_BLK_ON	(1<<5)	/* Bit 5:	Link LED Blinking On */
-#define LED_BLK_OFF	(1<<4)	/* Bit 4:	Link LED Blinking Off */
-#define LED_SYNC_ON	(1<<3)	/* Bit 3:	Use Sync Wire to switch LED */
+								/* Bit 7..6:	reserved */
+#define LED_BLK_ON		(1<<5)	/* Bit 5:	Link LED Blinking On */
+#define LED_BLK_OFF		(1<<4)	/* Bit 4:	Link LED Blinking Off */
+#define LED_SYNC_ON		(1<<3)	/* Bit 3:	Use Sync Wire to switch LED */
 #define LED_SYNC_OFF	(1<<2)	/* Bit 2:	Disable Sync Wire Input */
-#define LED_ON		(1<<1)	/* Bit 1:	switch LED on */
-#define LED_OFF		(1<<0)	/* Bit 0:	switch LED off */
+#define LED_ON			(1<<1)	/* Bit 1:	switch LED on */
+#define LED_OFF			(1<<0)	/* Bit 0:	switch LED off */
 
 
 /* Receive and Transmit Descriptors ******************************************/
@@ -1334,42 +1336,42 @@
 /* Transmit Descriptor struct */
 typedef	struct s_HwTxd {
 	SK_U32 volatile	TxCtrl;	/* Transmit Buffer Control Field */
-	SK_U32	TxNext ;	/* Physical Address Pointer to the next TxD */
-	SK_U32	TxAdrLo ;	/* Physical Tx Buffer Address lower dword */
-	SK_U32	TxAdrHi ;	/* Physical Tx Buffer Address upper dword */
-	SK_U32	TxStat ;	/* Transmit Frame Status Word */
+	SK_U32	TxNext;			/* Physical Address Pointer to the next TxD */
+	SK_U32	TxAdrLo;		/* Physical Tx Buffer Address lower dword */
+	SK_U32	TxAdrHi;		/* Physical Tx Buffer Address upper dword */
+	SK_U32	TxStat;			/* Transmit Frame Status Word */
 #ifndef	SK_USE_REV_DESC
-	SK_U16	TxTcpOffs ;	/* TCP Checksum Calculation Start Value */
-	SK_U16	TxRes1 ;	/* 16 bit reserved field */
-	SK_U16	TxTcpWp ;	/* TCP Checksum Write Position */
-	SK_U16	TxTcpSp ;	/* TCP Checksum Calculation Start Position */
+	SK_U16	TxTcpOffs;		/* TCP Checksum Calculation Start Value */
+	SK_U16	TxRes1;			/* 16 bit reserved field */
+	SK_U16	TxTcpWp;		/* TCP Checksum Write Position */
+	SK_U16	TxTcpSp;		/* TCP Checksum Calculation Start Position */
 #else	/* SK_USE_REV_DESC */
-	SK_U16	TxRes1 ;	/* 16 bit reserved field */
-	SK_U16	TxTcpOffs ;	/* TCP Checksum Calculation Start Value */
-	SK_U16	TxTcpSp ;	/* TCP Checksum Calculation Start Position */
-	SK_U16	TxTcpWp ;	/* TCP Checksum Write Position */
+	SK_U16	TxRes1;			/* 16 bit reserved field */
+	SK_U16	TxTcpOffs;		/* TCP Checksum Calculation Start Value */
+	SK_U16	TxTcpSp;		/* TCP Checksum Calculation Start Position */
+	SK_U16	TxTcpWp;		/* TCP Checksum Write Position */
 #endif	/* SK_USE_REV_DESC */
-	SK_U32  TxRes2;		/* 32 bit reserved field */
+	SK_U32  TxRes2;			/* 32 bit reserved field */
 } SK_HWTXD;
 
 /* Receive Descriptor struct */
 typedef	struct s_HwRxd {
 	SK_U32 volatile RxCtrl;	/* Receive Buffer Control Field */
-	SK_U32	RxNext ;	/* Physical Address Pointer to the next TxD */
-	SK_U32	RxAdrLo ;	/* Physical Receive Buffer Address lower dword*/
-	SK_U32	RxAdrHi ;	/* Physical Receive Buffer Address upper dword*/
-	SK_U32	RxStat ;	/* Receive Frame Status Word */
-	SK_U32	RxTiSt ;	/* Receive Timestamp provided by the XMAC */
+	SK_U32	RxNext;		/* Physical Address Pointer to the next TxD */
+	SK_U32	RxAdrLo;	/* Physical Receive Buffer Address lower dword*/
+	SK_U32	RxAdrHi;	/* Physical Receive Buffer Address upper dword*/
+	SK_U32	RxStat;		/* Receive Frame Status Word */
+	SK_U32	RxTiSt;		/* Receive Timestamp provided by the XMAC */
 #ifndef	SK_USE_REV_DESC	
-	SK_U16	RxTcpSum1 ;	/* TCP Checksum 1 */
-	SK_U16	RxTcpSum2 ;	/* TCP Checksum 2 */
-	SK_U16	RxTcpSp1 ;	/* TCP Checksum Calculation Start Position 1 */
-	SK_U16	RxTcpSp2 ;	/* TCP Checksum Calculation Start Position 2 */
+	SK_U16	RxTcpSum1;	/* TCP Checksum 1 */
+	SK_U16	RxTcpSum2;	/* TCP Checksum 2 */
+	SK_U16	RxTcpSp1;	/* TCP Checksum Calculation Start Position 1 */
+	SK_U16	RxTcpSp2;	/* TCP Checksum Calculation Start Position 2 */
 #else	/* SK_USE_REV_DESC */
-	SK_U16	RxTcpSum2 ;	/* TCP Checksum 2 */
-	SK_U16	RxTcpSum1 ;	/* TCP Checksum 1 */
-	SK_U16	RxTcpSp2 ;	/* TCP Checksum Calculation Start Position 2 */
-	SK_U16	RxTcpSp1 ;	/* TCP Checksum Calculation Start Position 1 */
+	SK_U16	RxTcpSum2;	/* TCP Checksum 2 */
+	SK_U16	RxTcpSum1;	/* TCP Checksum 1 */
+	SK_U16	RxTcpSp2;	/* TCP Checksum Calculation Start Position 2 */
+	SK_U16	RxTcpSp1;	/* TCP Checksum Calculation Start Position 1 */
 #endif	/* SK_USE_REV_DESC */
 } SK_HWRXD;
 
@@ -1387,23 +1389,23 @@
 /* Descriptor Bit Definition */
 /*	TxCtrl		Transmit Buffer Control Field */
 /*	RxCtrl		Receive Buffer Control Field */
-#define	BMU_OWN		(1UL<<31)	/* Bit 31:	OWN bit: 0=host/1=BMU */
-#define	BMU_STF		(1L<<30)	/* Bit 30:	Start of Frame ? */
-#define	BMU_EOF		(1L<<29)	/* Bit 29:	End of Frame ?	*/
-#define	BMU_IRQ_EOB	(1L<<28)	/* Bit 28:	Req "End of Buff" IRQ */
-#define	BMU_IRQ_EOF	(1L<<27)	/* Bit 27:	Req "End of Frame" IRQ*/
+#define	BMU_OWN			(1UL<<31)	/* Bit 31:	OWN bit: 0=host/1=BMU */
+#define	BMU_STF			(1L<<30)	/* Bit 30:	Start of Frame ? */
+#define	BMU_EOF			(1L<<29)	/* Bit 29:	End of Frame ?	*/
+#define	BMU_IRQ_EOB		(1L<<28)	/* Bit 28:	Req "End of Buff" IRQ */
+#define	BMU_IRQ_EOF		(1L<<27)	/* Bit 27:	Req "End of Frame" IRQ*/
 /* TxCtrl specific bits */
-#define BMU_STFWD	(1L<<26)	/* Bit 26: (Tx)	Store&Forward Frame */
-#define BMU_NO_FCS	(1L<<25)	/* Bit 25: (Tx) disable XMAC FCS gener*/
-#define BMU_SW		(1L<<24)	/* Bit 24: (Tx)	1 bit res. for SW use */
+#define BMU_STFWD		(1L<<26)	/* Bit 26: (Tx)	Store&Forward Frame */
+#define BMU_NO_FCS		(1L<<25)	/* Bit 25: (Tx) disable XMAC FCS gener*/
+#define BMU_SW			(1L<<24)	/* Bit 24: (Tx)	1 bit res. for SW use */
 /* RxCtrl specific bits */
-#define	BMU_DEV_0	(1L<<26)	/* Bit 26: (Rx)	transfer data to Dev0 */
+#define	BMU_DEV_0		(1L<<26)	/* Bit 26: (Rx)	transfer data to Dev0 */
 #define BMU_STAT_VAL	(1L<<25)	/* Bit 25: (Rx)	RxStat Valid */
 #define BMU_TIST_VAL	(1L<<24)	/* Bit 24: (Rx)	RxTiSt Valid */
-					/* Bit 23..16:	BMU Check Opcodes */
-#define	BMU_CHECK	0x00550000L	/* 		Default BMU check */
+									/* Bit 23..16:	BMU Check Opcodes */
+#define	BMU_CHECK		0x00550000L	/* 		Default BMU check */
 #define	BMU_TCP_CHECK	0x00560000L	/* 		Descr with TCP ext */
-#define	BMU_BBC		0x0000FFFFL	/* Bit 15..0:	Buffer Byte Counter */
+#define	BMU_BBC			0x0000FFFFL	/* Bit 15..0:	Buffer Byte Counter */
 
 /*	TxStat		Transmit Frame Status Word */
 /*	RxStat		Receive Frame Status Word */
@@ -1420,8 +1422,8 @@
  * FlashProm specification
  */
 #define	MAX_PAGES	0x20000L	/* Every byte has a single page */
-#define	MAX_FADDR	1		/* 1 byte per page */
-#define	SKFDDI_PSZ	8		/* address PROM size */
+#define	MAX_FADDR	1			/* 1 byte per page */
+#define	SKFDDI_PSZ	8			/* address PROM size */
 
 /* macros ********************************************************************/
 
@@ -1507,7 +1509,7 @@
  *		(p)Val	Value or pointer to the value which should be read or
  *			written.
  *
- * usage:	XM_OUT16(IoC, MAC_1, XM_MMU_CMD, Value) ;
+ * usage:	XM_OUT16(IoC, MAC_1, XM_MMU_CMD, Value);
  */
 
 #ifdef	SK_LITTLE_ENDIAN
@@ -1520,19 +1522,19 @@
 
 #define	XMA(Mac,Reg)	(((0x1000 << (Mac)) + 0x1000) | ((Reg) << 1))
 
-#define XM_IN16(IoC,Mac,Reg,pVal)	SK_IN16((IoC),XMA((Mac),(Reg)),(pVal))
-#define XM_OUT16(IoC,Mac,Reg,Val)	SK_OUT16((IoC),XMA((Mac),(Reg)),(Val))
+#define XM_IN16(IoC,Mac,Reg,pVal)	SK_IN16((IoC), XMA((Mac), (Reg)), (pVal))
+#define XM_OUT16(IoC,Mac,Reg,Val)	SK_OUT16((IoC), XMA((Mac), (Reg)), (Val))
 
-#define XM_IN32(IoC,Mac,Reg,pVal) {					\
-	SK_IN16((IoC),XMA((Mac),(Reg)),					\
+#define XM_IN32(IoC,Mac,Reg,pVal) {						\
+	SK_IN16((IoC), XMA((Mac), (Reg)),					\
 		(SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_LO]);		\
-	SK_IN16((IoC),XMA((Mac),(Reg+2)),				\
+	SK_IN16((IoC), XMA((Mac), (Reg+2)),					\
 		(SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_HI]);		\
 }
 
-#define XM_OUT32(IoC,Mac,Reg,Val) {					\
-	SK_OUT16((IoC),XMA((Mac),(Reg)), (SK_U16)((Val) & 0x0000ffffL));\
-	SK_OUT16((IoC),XMA((Mac),(Reg+2)),(SK_U16)(((Val)>>16) & 0x0000ffffL));\
+#define XM_OUT32(IoC,Mac,Reg,Val) {											\
+	SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)((Val) & 0x0000ffffL));		\
+	SK_OUT16((IoC), XMA((Mac), (Reg+2)),(SK_U16)(((Val)>>16) & 0x0000ffffL));	\
 }
 
 /*
@@ -1540,67 +1542,67 @@
  */
 
 #define XM_INADDR(IoC, Mac, Reg, pVal) {				\
-	SK_U16	Word;							\
-	SK_U8	*pByte;							\
+	SK_U16	Word;										\
+	SK_U8	*pByte;										\
 	pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];				\
 	SK_IN16((IoC), XMA((Mac), (Reg)), &Word);			\
-	pByte[0] = (SK_U8) (Word  & 0x00ff);				\
-	pByte[1] = (SK_U8) ((Word >> 8) & 0x00ff);			\
+	pByte[0] = (SK_U8)(Word  & 0x00ff);					\
+	pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);			\
 	SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word);			\
-	pByte[2] = (SK_U8) (Word  & 0x00ff);				\
-	pByte[3] = (SK_U8) ((Word >> 8) & 0x00ff);			\
+	pByte[2] = (SK_U8)(Word  & 0x00ff);					\
+	pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);			\
 	SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word);			\
-	pByte[4] = (SK_U8) (Word  & 0x00ff);				\
-	pByte[5] = (SK_U8) ((Word >> 8) & 0x00ff);			\
+	pByte[4] = (SK_U8)(Word  & 0x00ff);					\
+	pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);			\
 }
 
 #define XM_OUTADDR(IoC, Mac, Reg, pVal) {				\
-	SK_U8	*pByte;							\
+	SK_U8	*pByte;										\
 	pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];				\
 	SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)			\
-		 (((SK_U16)(pByte[0]) & 0x00ff)|			\
-		 (((SK_U16)(pByte[1]) << 8) & 0xff00)));		\
-	SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)			\
-		 (((SK_U16)(pByte[2]) & 0x00ff)|			\
-		 (((SK_U16)(pByte[3]) << 8) & 0xff00)));		\
-	SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16)			\
-		 (((SK_U16)(pByte[4]) & 0x00ff)|			\
-		 (((SK_U16)(pByte[5]) << 8) & 0xff00)));		\
+		(((SK_U16)(pByte[0]) & 0x00ff) |				\
+		(((SK_U16)(pByte[1]) << 8) & 0xff00)));			\
+	SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)		\
+		(((SK_U16)(pByte[2]) & 0x00ff) |				\
+		(((SK_U16)(pByte[3]) << 8) & 0xff00)));			\
+	SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16)		\
+		(((SK_U16)(pByte[4]) & 0x00ff) |				\
+		(((SK_U16)(pByte[5]) << 8) & 0xff00)));			\
 }
 
 #define XM_INHASH(IoC, Mac, Reg, pVal) {				\
-	SK_U16	Word;							\
-	SK_U8	*pByte;							\
+	SK_U16	Word;										\
+	SK_U8	*pByte;										\
 	pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];				\
 	SK_IN16((IoC), XMA((Mac), (Reg)), &Word);			\
-	pByte[0] = (SK_U8) (Word  & 0x00ff);				\
-	pByte[1] = (SK_U8) ((Word >> 8) & 0x00ff);			\
+	pByte[0] = (SK_U8)(Word  & 0x00ff);					\
+	pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);			\
 	SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word);			\
-	pByte[2] = (SK_U8) (Word  & 0x00ff);				\
-	pByte[3] = (SK_U8) ((Word >> 8) & 0x00ff);			\
+	pByte[2] = (SK_U8)(Word  & 0x00ff);					\
+	pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);			\
 	SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word);			\
-	pByte[4] = (SK_U8) (Word  & 0x00ff);				\
-	pByte[5] = (SK_U8) ((Word >> 8) & 0x00ff);			\
+	pByte[4] = (SK_U8)(Word  & 0x00ff);					\
+	pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);			\
 	SK_IN16((IoC), XMA((Mac), (Reg+6)), &Word);			\
-	pByte[6] = (SK_U8) (Word  & 0x00ff);				\
-	pByte[7] = (SK_U8) ((Word >> 8) & 0x00ff);			\
+	pByte[6] = (SK_U8)(Word  & 0x00ff);					\
+	pByte[7] = (SK_U8)((Word >> 8) & 0x00ff);			\
 }
 
 #define XM_OUTHASH(IoC, Mac, Reg, pVal) {				\
-	SK_U8	*pByte;							\
+	SK_U8	*pByte;										\
 	pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];				\
 	SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)			\
-		 (((SK_U16)(pByte[0]) & 0x00ff)|			\
-		 (((SK_U16)(pByte[1]) << 8) & 0xff00)));		\
-	SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)			\
-		 (((SK_U16)(pByte[2]) & 0x00ff)|			\
-		 (((SK_U16)(pByte[3]) << 8) & 0xff00)));		\
-	SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16)			\
-		 (((SK_U16)(pByte[4]) & 0x00ff)|			\
-		 (((SK_U16)(pByte[5]) << 8) & 0xff00)));		\
-	SK_OUT16((IoC), XMA((Mac), (Reg+6)), (SK_U16)			\
-		 (((SK_U16)(pByte[6]) & 0x00ff)|			\
-		 (((SK_U16)(pByte[7]) << 8) & 0xff00)));		\
+		(((SK_U16)(pByte[0]) & 0x00ff)|					\
+		(((SK_U16)(pByte[1]) << 8) & 0xff00)));			\
+	SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)		\
+		(((SK_U16)(pByte[2]) & 0x00ff)|					\
+		(((SK_U16)(pByte[3]) << 8) & 0xff00)));			\
+	SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16)		\
+		(((SK_U16)(pByte[4]) & 0x00ff)|					\
+		(((SK_U16)(pByte[5]) << 8) & 0xff00)));			\
+	SK_OUT16((IoC), XMA((Mac), (Reg+6)), (SK_U16)		\
+		(((SK_U16)(pByte[6]) & 0x00ff)|					\
+		(((SK_U16)(pByte[7]) << 8) & 0xff00)));			\
 }
 
 /*
@@ -1637,56 +1639,56 @@
  *          comes back. This is checked in DEBUG mode.
  */
 #ifndef DEBUG
-#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) {			\
-	SK_U16 Mmu;  							\
-									\
-	XM_OUT16((IoC),(Mac), XM_PHY_ADDR, (PhyReg)|(pPort)->PhyAddr);	\
-	XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));			\
-	if ((pPort)->PhyType != SK_PHY_XMAC) {				\
-		do {  							\
-			XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);	\
-		} while ((Mmu & XM_MMU_PHY_RDY) == 0);			\
-		XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));		\
-	}  								\
+#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) {						\
+	SK_U16 Mmu;  														\
+																		\
+	XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);	\
+	XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));							\
+	if ((pPort)->PhyType != SK_PHY_XMAC) {								\
+		do {  															\
+			XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);					\
+		} while ((Mmu & XM_MMU_PHY_RDY) == 0);							\
+		XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));						\
+	}  																	\
 }
 #else
-#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) {			\
-	SK_U16 Mmu;  							\
-	int __i = 0;							\
-									\
-	XM_OUT16((IoC),(Mac), XM_PHY_ADDR, (PhyReg)|(pPort)->PhyAddr);	\
-	XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));			\
-	if ((pPort)->PhyType != SK_PHY_XMAC) {				\
-		do {  							\
-			XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);	\
-			__i++;						\
-			if (__i > 10000) {				\
-				SK_DBG_PRINTF("*****************************\n"); \
-				SK_DBG_PRINTF("PHY_READ on uninitialized PHY\n"); \
-				SK_DBG_PRINTF("*****************************\n"); \
-				break;					\
-			}						\
-		} while ((Mmu & XM_MMU_PHY_RDY) == 0);			\
-		XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));		\
-	}  								\
+#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) {						\
+	SK_U16 Mmu;  														\
+	int __i = 0;														\
+																		\
+	XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);	\
+	XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));							\
+	if ((pPort)->PhyType != SK_PHY_XMAC) {								\
+		do {  															\
+			XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);					\
+			__i++;														\
+			if (__i > 100000) {											\
+				SK_DBG_PRINTF("*****************************\n");		\
+				SK_DBG_PRINTF("PHY_READ on uninitialized PHY\n");		\
+				SK_DBG_PRINTF("*****************************\n");		\
+				break;													\
+			}															\
+		} while ((Mmu & XM_MMU_PHY_RDY) == 0);							\
+		XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));						\
+	}  																	\
 }
 #endif
 
-#define PHY_WRITE(IoC, pPort, Mac, PhyReg, Val) {			\
-	SK_U16 Mmu;							\
-									\
-	if ((pPort)->PhyType != SK_PHY_XMAC) {				\
-		do {  							\
-			XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);	\
-		} while ((Mmu & XM_MMU_PHY_BUSY) != 0);			\
-	}  								\
-	XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg)|(pPort)->PhyAddr);	\
-	XM_OUT16((IoC), (Mac), XM_PHY_DATA, (Val));			\
-	if ((pPort)->PhyType != SK_PHY_XMAC) {				\
-		do {  							\
-			XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);	\
-		} while ((Mmu & XM_MMU_PHY_BUSY) != 0);			\
-	}  								\
+#define PHY_WRITE(IoC, pPort, Mac, PhyReg, Val) {						\
+	SK_U16 Mmu;															\
+																		\
+	if ((pPort)->PhyType != SK_PHY_XMAC) {								\
+		do {  															\
+			XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);					\
+		} while ((Mmu & XM_MMU_PHY_BUSY) != 0);							\
+	}  																	\
+	XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);	\
+	XM_OUT16((IoC), (Mac), XM_PHY_DATA, (Val));							\
+	if ((pPort)->PhyType != SK_PHY_XMAC) {								\
+		do {  															\
+			XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);					\
+		} while ((Mmu & XM_MMU_PHY_BUSY) != 0);							\
+	}  																	\
 }
 
 /*
@@ -1731,7 +1733,7 @@
  *	Mode	Mode to set for this LED
  */
 #define SK_HWAC_LINK_LED(pAC, IoC, Port, Mode) \
-SK_OUT8(IoC, MR_ADDR(Port,LNK_LED_REG), Mode); 
+	SK_OUT8(IoC, MR_ADDR(Port,LNK_LED_REG), Mode); 
 
  
 /* typedefs *******************************************************************/
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/skgehwt.h linux/drivers/net/sk98lin/h/skgehwt.h
--- v2.4.6/linux/drivers/net/sk98lin/h/skgehwt.h	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/h/skgehwt.h	Wed Jul  4 11:50:39 2001
@@ -1,23 +1,32 @@
 /******************************************************************************
  *
  * Name:	skhwt.h
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.5 $
- * Date:	$Date: 1999/11/22 13:54:24 $
+ * Project:	Genesis, PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 1.4 $
+ * Date:	$Date: 1998/08/19 09:50:58 $
  * Purpose:	Defines for the hardware timer functions
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
+ *	(C)Copyright 1989-1998 SysKonnect,
  *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	All Rights Reserved
  *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
+ *	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT
+ *	The copyright notice above does not evidence any
+ *	actual or intended publication of such source code.
+ *
+ *	This Module contains Proprietary Information of SysKonnect
+ *	and should be treated as Confidential.
+ *
+ *	The information in this file is provided for the exclusive use of
+ *	the licensees of SysKonnect.
+ *	Such users have the right to use, modify, and incorporate this code
+ *	into products for purposes authorized by the license agreement
+ *	provided they include this notice and the associated copyright notice
+ *	with any such product.
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -27,9 +36,6 @@
  * History:
  *
  *	$Log: skgehwt.h,v $
- *	Revision 1.5  1999/11/22 13:54:24  cgoos
- *	Changed license header to GPL.
- *	
  *	Revision 1.4  1998/08/19 09:50:58  gklug
  *	fix: remove struct keyword from c-code (see CCC) add typedefs
  *	
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/skgeinit.h linux/drivers/net/sk98lin/h/skgeinit.h
--- v2.4.6/linux/drivers/net/sk98lin/h/skgeinit.h	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/h/skgeinit.h	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	skgeinit.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.46 $
- * Date:	$Date: 2000/08/10 11:28:00 $
+ * Version:	$Revision: 1.51 $
+ * Date:	$Date: 2001/02/09 12:26:38 $
  * Purpose:	Structures and prototypes for the GE Init Module
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2000 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,6 +26,22 @@
  * History:
  *
  *	$Log: skgeinit.h,v $
+ *	Revision 1.51  2001/02/09 12:26:38  cgoos
+ *	Inserted #ifdef DIAG for half duplex workaround timer.
+ *	
+ *	Revision 1.50  2001/02/07 07:56:40  rassmann
+ *	Corrected copyright.
+ *	
+ *	Revision 1.49  2001/01/31 15:32:18  gklug
+ *	fix: problem with autosensing an SR8800 switch
+ *	add: counter for autoneg timeouts
+ *	
+ *	Revision 1.48  2000/11/09 11:30:10  rassmann
+ *	WA: Waiting after releasing reset until BCom chip is accessible.
+ *	
+ *	Revision 1.47  2000/10/18 12:22:40  cgoos
+ *	Added workaround for half duplex hangup.
+ *	
  *	Revision 1.46  2000/08/10 11:28:00  rassmann
  *	Editorial changes.
  *	Preserving 32-bit alignment in structs for the adapter context.
@@ -440,6 +455,12 @@
  */
 #define	SK_MAX_LRESTART	3	/* Max. 3 times the link is restarted */
 
+/*
+ * define max. autonegotiation timeouts before link detection in sense mode is
+ * reset.
+ */
+#define	SK_MAX_ANEG_TO	10	/* Max. 10 times the sense mode is reset */
+
 /* structures *****************************************************************/
 
 /*
@@ -453,8 +474,13 @@
 	SK_U64	PPrevRx;		/* Previous RxOk Counter checking */
 	SK_U64	PPrevFcs;		/* Previous FCS Error Counter checking */
 	SK_U64	PRxLim;			/* Previous RxOk Counter checking */
+	SK_U64	LastOctets;		/* For half duplex hang check */
+#ifndef SK_DIAG
+	SK_TIMER	HalfDupChkTimer;
+#endif
 	int		PLinkResCt;		/* Link Restart Counter */
 	int		PAutoNegTimeOut;/* AutoNegotiation timeout current value */
+	int		PAutoNegTOCt;	/* AutoNeg Timeout Counter */
 	int		PRxQSize;		/* Port Rx Queue Size in kB */
 	int		PXSQSize;		/* Port Synchronous Transmit Queue Size in kB */
 	int		PXAQSize;		/* Port Asynchronous Transmit Queue Size in kB*/
@@ -467,13 +493,17 @@
 	int		PRxQOff;		/* Rx Queue Address Offset */
 	int		PXsQOff;		/* Synchronous Tx Queue Address Offset */
 	int		PXaQOff;		/* Asynchronous Tx Queue Address Offset */
+	int		PhyType;		/* PHY used on this port */
+	SK_U16	PhyAddr;		/* MDIO/MDC PHY address */
 	SK_U16	PRxCmd;			/* Port Receive Command Configuration Value */
 	SK_U16	PIsave;			/* Saved Interrupt status word */
 	SK_U16	PSsave;			/* Saved PHY status word */
+	SK_U16	Align01;
 	SK_BOOL	PHWLinkUp;		/* The hardware Link is up (wireing) */
 	SK_BOOL	PState;			/* Is port initialized ? */
 	SK_BOOL	PLinkBroken;	/* Is Link broken ? */
 	SK_BOOL	PCheckPar;		/* Do we check for parity errors ? */
+	SK_BOOL	HalfDupTimerActive;
 	SK_U8	PLinkCap;		/* Link Capabilities */
 	SK_U8	PLinkModeConf;	/* Link Mode configured */
 	SK_U8	PLinkMode;		/* Link Mode currently used */
@@ -486,8 +516,7 @@
 	SK_U8	PMSStatus;		/* Master/Slave Status */
 	SK_U8	PAutoNegFail;	/* Autonegotiation fail flag */
 	SK_U8	PLipaAutoNeg;	/* Autonegotiation possible with Link Partner */
-	SK_U16	PhyAddr;		/* MDIO/MDC PHY address */
-	int	PhyType;	/* PHY used on this port */
+	SK_U8	Align02;
 } SK_GEPORT;
 
 /*
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/skgepnm2.h linux/drivers/net/sk98lin/h/skgepnm2.h
--- v2.4.6/linux/drivers/net/sk98lin/h/skgepnm2.h	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/h/skgepnm2.h	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	skgepnm2.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.28 $
- * Date:	$Date: 2000/08/03 15:12:48 $
+ * Version:	$Revision: 1.30 $
+ * Date:	$Date: 2001/02/06 10:03:41 $
  * Purpose:	Defines for Private Network Management Interface
  *
  ****************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,6 +26,14 @@
  * History:
  *
  *	$Log: skgepnm2.h,v $
+ *	Revision 1.30  2001/02/06 10:03:41  mkunz
+ *	- Pnmi V4 dual net support added. Interface functions and macros extended
+ *	- Vpd bug fixed
+ *	- OID_SKGE_MTU added
+ *	
+ *	Revision 1.29  2001/01/22 13:41:37  rassmann
+ *	Supporting two nets on dual-port adapters.
+ *	
  *	Revision 1.28  2000/08/03 15:12:48  rwahl
  *	- Additional comment for MAC statistic data structure.
  *	
@@ -159,8 +166,6 @@
 /*
  * VPD releated defines
  */
-#define SK_PNMI_VPD_ARR_SIZE	40
-#define SK_PNMI_VPD_STR_SIZE	5
 
 #define SK_PNMI_VPD_RW		1
 #define SK_PNMI_VPD_RO		2
@@ -201,7 +206,8 @@
 	int		Access;
 	int		(* Func)(SK_AC *pAc, SK_IOC pIo, int action,
 				SK_U32 Id, char* pBuf, unsigned int* pLen,
-				SK_U32 Instance, unsigned int TableIndex);
+				SK_U32 Instance, unsigned int TableIndex,
+                                SK_U32 NetNumber);
 	SK_U16		Param;
 } SK_PNMI_TAB_ENTRY;
 
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/skgepnmi.h linux/drivers/net/sk98lin/h/skgepnmi.h
--- v2.4.6/linux/drivers/net/sk98lin/h/skgepnmi.h	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/h/skgepnmi.h	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	skgepnmi.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.44 $
- * Date:	$Date: 2000/09/07 07:35:27 $
+ * Version:	$Revision: 1.48 $
+ * Date:	$Date: 2001/02/23 14:34:24 $
  * Purpose:	Defines for Private Network Management Interface
  *
  ****************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,6 +26,25 @@
  * History:
  *
  *	$Log: skgepnmi.h,v $
+ *	Revision 1.48  2001/02/23 14:34:24  mkunz
+ *	Changed macro PHYS2INST. Added pAC to Interface
+ *	
+ *	Revision 1.47  2001/02/07 08:28:23  mkunz
+ *	- Added Oids: 	OID_SKGE_DIAG_ACTION
+ *					OID_SKGE_DIAG_RESULT
+ *					OID_SKGE_MULTICAST_LIST
+ *					OID_SKGE_CURRENT_PACKET_FILTER
+ *					OID_SKGE_INTERMEDIATE_SUPPORT
+ *	- Changed value of OID_SKGE_MTU
+ *	
+ *	Revision 1.46  2001/02/06 10:01:41  mkunz
+ *	- Pnmi V4 dual net support added. Interface functions and macros extended
+ *	- Vpd bug fixed
+ *	- OID_SKGE_MTU added
+ *	
+ *	Revision 1.45  2001/01/22 13:41:37  rassmann
+ *	Supporting two nets on dual-port adapters.
+ *	
  *	Revision 1.44  2000/09/07 07:35:27  rwahl
  *	- removed NDIS counter specific data type.
  *	- fixed spelling for OID_SKGE_RLMT_PORT_PREFERRED.
@@ -48,13 +66,13 @@
  *	Revision 1.40  2000/03/31 13:51:34  rwahl
  *	Added SK_UPTR cast to offset calculation for PNMI struct fields;
  *	missing cast caused compiler warnings by Win64 compiler.
- *	
+ *
  *	Revision 1.39  1999/12/06 10:09:47  rwahl
  *	Added new error log message.
  *	
  *	Revision 1.38  1999/11/22 13:57:55  cgoos
  *	Changed license header to GPL.
- *	
+ *
  *	Revision 1.37  1999/09/14 14:25:32  rwahl
  *	Set MDB version for 1000Base-T (sensors, Master/Slave) changes.
  *	
@@ -112,7 +130,7 @@
  *	
  *	Revision 1.22  1998/11/03 12:05:51  mhaveman
  *	Added pAC parameter to counter macors.
- *	
+ *
  *	Revision 1.21  1998/11/02 10:47:36  mhaveman
  *	Added syslog messages for internal errors.
  *	
@@ -187,7 +205,7 @@
 #include "h/ski2c.h"
 #include "h/skaddr.h"
 #include "h/skrlmt.h"
-
+#include "h/skvpd.h"
 
 /*
  * Management Database Version
@@ -198,22 +216,23 @@
 /*
  * Event definitions
  */
-#define SK_PNMI_EVT_SIRQ_OVERFLOW	1	/* Counter overflow */
-#define SK_PNMI_EVT_SEN_WAR_LOW		2	/* Lower war thres exceeded */
-#define SK_PNMI_EVT_SEN_WAR_UPP		3	/* Upper war thres exceeded */
-#define SK_PNMI_EVT_SEN_ERR_LOW		4	/* Lower err thres exceeded */
-#define SK_PNMI_EVT_SEN_ERR_UPP		5	/* Upper err thres exceeded */
-#define SK_PNMI_EVT_CHG_EST_TIMER	6	/* Timer event for RLMT Chg */
+#define SK_PNMI_EVT_SIRQ_OVERFLOW		1	/* Counter overflow */
+#define SK_PNMI_EVT_SEN_WAR_LOW			2	/* Lower war thres exceeded */
+#define SK_PNMI_EVT_SEN_WAR_UPP			3	/* Upper war thres exceeded */
+#define SK_PNMI_EVT_SEN_ERR_LOW			4	/* Lower err thres exceeded */
+#define SK_PNMI_EVT_SEN_ERR_UPP			5	/* Upper err thres exceeded */
+#define SK_PNMI_EVT_CHG_EST_TIMER		6	/* Timer event for RLMT Chg */
 #define SK_PNMI_EVT_UTILIZATION_TIMER	7	/* Timer event for Utiliza. */
-#define SK_PNMI_EVT_CLEAR_COUNTER	8	/* Clear statistic counters */
-#define SK_PNMI_EVT_XMAC_RESET		9	/* XMAC will be reset */
+#define SK_PNMI_EVT_CLEAR_COUNTER		8	/* Clear statistic counters */
+#define SK_PNMI_EVT_XMAC_RESET			9	/* XMAC will be reset */
 
-#define SK_PNMI_EVT_RLMT_PORT_UP	10	/* Port came logically up */
-#define SK_PNMI_EVT_RLMT_PORT_DOWN	11	/* Port went logically down */
-#define SK_PNMI_EVT_RLMT_PORT_SWITCH	12	/* Switched active port */
+#define SK_PNMI_EVT_RLMT_PORT_UP		10	/* Port came logically up */
+#define SK_PNMI_EVT_RLMT_PORT_DOWN		11	/* Port went logically down */
 #define SK_PNMI_EVT_RLMT_SEGMENTATION	13	/* Two SP root bridges found */
 #define SK_PNMI_EVT_RLMT_ACTIVE_DOWN	14	/* Port went logically down */
-#define SK_PNMI_EVT_RLMT_ACTIVE_UP	15	/* Port came logically up */
+#define SK_PNMI_EVT_RLMT_ACTIVE_UP		15	/* Port came logically up */
+#define SK_PNMI_EVT_RLMT_SET_NETS		16	/* 1. Parameter is number of nets
+												1 = single net; 2 = dual net */
 
 /*
  * Return values
@@ -225,6 +244,7 @@
 #define SK_PNMI_ERR_READ_ONLY		4
 #define SK_PNMI_ERR_UNKNOWN_OID		5
 #define SK_PNMI_ERR_UNKNOWN_INST	6
+#define SK_PNMI_ERR_UNKNOWN_NET 	7
 
 
 /*
@@ -355,7 +375,7 @@
 #define OID_SKGE_CHKSM_RX_ERR_CTS	0xFF020113
 #define OID_SKGE_CHKSM_TX_OK_CTS	0xFF020114
 #define OID_SKGE_CHKSM_TX_UNABLE_CTS	0xFF020115
-			
+
 #define OID_SKGE_STAT_TX		0xFF020120
 #define OID_SKGE_STAT_TX_OCTETS		0xFF020121
 #define OID_SKGE_STAT_TX_BROADCAST	0xFF020122
@@ -412,7 +432,10 @@
 #define OID_SKGE_STAT_RX_1023		0xFF020155
 #define OID_SKGE_STAT_RX_MAX		0xFF020156
 #define OID_SKGE_STAT_RX_LONGFRAMES	0xFF020157
-			
+
+#define OID_SKGE_DIAG_ACTION		0xFF01011D
+#define OID_SKGE_DIAG_RESULT		0xFF01011E
+#define OID_SKGE_MTU		0xFF01011F
 #define OID_SKGE_PHYS_CUR_ADDR		0xFF010120
 #define OID_SKGE_PHYS_FAC_ADDR		0xFF010121
 #define OID_SKGE_PMD			0xFF010122
@@ -427,7 +450,9 @@
 #define OID_SKGE_PHY_OPERATION_CAP	0xFF01012B
 #define OID_SKGE_PHY_OPERATION_MODE	0xFF01012C
 #define OID_SKGE_PHY_OPERATION_STATUS	0xFF01012D
-			
+#define OID_SKGE_MULTICAST_LIST		0xFF01012E
+#define OID_SKGE_CURRENT_PACKET_FILTER		0xFF01012F
+
 #define OID_SKGE_TRAP			0xFF010130
 #define OID_SKGE_TRAP_NUMBER		0xFF010131
 
@@ -435,11 +460,12 @@
 #define OID_SKGE_RLMT_PORT_NUMBER	0xFF010141
 #define OID_SKGE_RLMT_PORT_ACTIVE	0xFF010142
 #define OID_SKGE_RLMT_PORT_PREFERRED	0xFF010143
+#define OID_SKGE_INTERMEDIATE_SUPPORT		0xFF010160
 #define OID_SKGE_RLMT_CHANGE_CTS	0xFF020160
 #define OID_SKGE_RLMT_CHANGE_TIME	0xFF020161
 #define OID_SKGE_RLMT_CHANGE_ESTIM	0xFF020162
 #define OID_SKGE_RLMT_CHANGE_THRES	0xFF020163
-			
+
 #define OID_SKGE_RLMT_PORT_INDEX	0xFF020164
 #define OID_SKGE_RLMT_STATUS		0xFF020165
 #define OID_SKGE_RLMT_TX_HELLO_CTS	0xFF020166
@@ -447,7 +473,7 @@
 #define OID_SKGE_RLMT_TX_SP_REQ_CTS	0xFF020168
 #define OID_SKGE_RLMT_RX_SP_CTS		0xFF020169
 
-#define OID_SKGE_RLMT_MONITOR_NUMBER	0xFF010150			
+#define OID_SKGE_RLMT_MONITOR_NUMBER	0xFF010150
 #define OID_SKGE_RLMT_MONITOR_INDEX	0xFF010151
 #define OID_SKGE_RLMT_MONITOR_ADDR	0xFF010152
 #define OID_SKGE_RLMT_MONITOR_ERRS	0xFF010153
@@ -471,7 +497,7 @@
 #define OID_SKGE_ERR_RECOVERY_CTS	0xFF02017E
 #define OID_SKGE_SYSUPTIME		0xFF02017F
 
-#define OID_SKGE_ALL_DATA		0xFF020190			
+#define OID_SKGE_ALL_DATA		0xFF020190
 
 
 #define	OID_SKGE_TRAP_SEN_WAR_LOW	500
@@ -600,26 +626,27 @@
 #define SK_PNMI_SET_DRIVER_VER(pAC,v)	((pAC)->Pnmi.pDriverVersion = \
 	(char *)(v))
 
-#define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v) \
+
+#define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \
 	{ \
-		(pAC)->Pnmi.TxSwQueueLen = (SK_U64)(v); \
-		if ((pAC)->Pnmi.TxSwQueueLen > (pAC)->Pnmi.TxSwQueueMax) { \
-			(pAC)->Pnmi.TxSwQueueMax = (pAC)->Pnmi.TxSwQueueLen; \
+		(pAC)->Pnmi.Port[p].TxSwQueueLen = (SK_U64)(v); \
+		if ((pAC)->Pnmi.Port[p].TxSwQueueLen > (pAC)->Pnmi.Port[p].TxSwQueueMax) { \
+			(pAC)->Pnmi.Port[p].TxSwQueueMax = (pAC)->Pnmi.Port[p].TxSwQueueLen; \
 		} \
 	}
-#define SK_PNMI_CNT_TX_RETRY(pAC)	(((pAC)->Pnmi.TxRetryCts)++)
-#define SK_PNMI_CNT_RX_INTR(pAC)	(((pAC)->Pnmi.RxIntrCts)++)
-#define SK_PNMI_CNT_TX_INTR(pAC)	(((pAC)->Pnmi.TxIntrCts)++)
-#define SK_PNMI_CNT_NO_RX_BUF(pAC)	(((pAC)->Pnmi.RxNoBufCts)++)
-#define SK_PNMI_CNT_NO_TX_BUF(pAC)	(((pAC)->Pnmi.TxNoBufCts)++)
-#define SK_PNMI_CNT_USED_TX_DESCR(pAC,v) \
-	((pAC)->Pnmi.TxUsedDescrNo=(SK_U64)(v));
-#define SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,v) \
+#define SK_PNMI_CNT_TX_RETRY(pAC,p)	(((pAC)->Pnmi.Port[p].TxRetryCts)++)
+#define SK_PNMI_CNT_RX_INTR(pAC,p)	(((pAC)->Pnmi.Port[p].RxIntrCts)++)
+#define SK_PNMI_CNT_TX_INTR(pAC,p)	(((pAC)->Pnmi.Port[p].TxIntrCts)++)
+#define SK_PNMI_CNT_NO_RX_BUF(pAC,p)	(((pAC)->Pnmi.Port[p].RxNoBufCts)++)
+#define SK_PNMI_CNT_NO_TX_BUF(pAC,p)	(((pAC)->Pnmi.Port[p].TxNoBufCts)++)
+#define SK_PNMI_CNT_USED_TX_DESCR(pAC,v,p) \
+	((pAC)->Pnmi.Port[p].TxUsedDescrNo=(SK_U64)(v));
+#define SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,v,p) \
 	{ \
-		((pAC)->Pnmi.RxDeliveredCts)++; \
-		(pAC)->Pnmi.RxOctetsDeliveredCts += (SK_U64)(v); \
+		((pAC)->Pnmi.Port[p].RxDeliveredCts)++; \
+		(pAC)->Pnmi.Port[p].RxOctetsDeliveredCts += (SK_U64)(v); \
 	}
-#define SK_PNMI_CNT_ERR_RECOVERY(pAC)	(((pAC)->Pnmi.ErrRecoveryCts)++);
+#define SK_PNMI_CNT_ERR_RECOVERY(pAC,p)	(((pAC)->Pnmi.Port[p].ErrRecoveryCts)++);
 
 #define SK_PNMI_CNT_SYNC_OCTETS(pAC,p,v) \
 	{ \
@@ -643,14 +670,18 @@
 #define SK_PNMI_PORT_LOG2INST(l)	((unsigned int)(l) + 1)
 #define SK_PNMI_PORT_PHYS2LOG(p)	((unsigned int)(p) + 1)
 #define SK_PNMI_PORT_LOG2PHYS(pAC,l)	((unsigned int)(l) - 1)
-#define SK_PNMI_PORT_PHYS2INST(p)	((unsigned int)(p) + 2)
+#define SK_PNMI_PORT_PHYS2INST(pAC,p)	\
+	(pAC->Pnmi.DualNetActiveFlag ? 2 : ((unsigned int)(p) + 2))
 #define SK_PNMI_PORT_INST2PHYS(pAC,i)	((unsigned int)(i) - 2)
 
 /*
  * Structure definition for SkPnmiGetStruct and SkPnmiSetStruct
  */
-#define SK_PNMI_VPD_ENTRIES		20
-#define SK_PNMI_VPD_DATALEN		128
+#define SK_PNMI_VPD_KEY_SIZE	5
+#define SK_PNMI_VPD_BUFSIZE		(VPD_SIZE)
+#define SK_PNMI_VPD_ENTRIES		(VPD_SIZE / 4)
+#define SK_PNMI_VPD_DATALEN		128 /*  Number of data bytes */
+
 #define SK_PNMI_MULTICAST_LISTLEN	64
 #define SK_PNMI_SENSOR_ENTRIES		(SK_MAX_SENSORS)
 #define SK_PNMI_CHECKSUM_ENTRIES	3
@@ -663,7 +694,7 @@
 #define SK_PNMI_TRAP_QUEUE_LEN		512
 
 typedef struct s_PnmiVpd {
-	char			VpdKey[5];
+	char			VpdKey[SK_PNMI_VPD_KEY_SIZE];
 	char			VpdValue[SK_PNMI_VPD_DATALEN];
 	SK_U8			VpdAccess;
 	SK_U8			VpdAction;
@@ -795,7 +826,7 @@
 	SK_U32			MgmtDBVersion;
 	SK_PNMI_REQUEST_STATUS	ReturnStatus;
 	SK_U32			VpdFreeBytes;
-	char			VpdEntriesList[SK_PNMI_VPD_DATALEN];
+	char			VpdEntriesList[SK_PNMI_VPD_ENTRIES * SK_PNMI_VPD_KEY_SIZE];
 	SK_U32			VpdEntriesNumber;
 	SK_PNMI_VPD		Vpd[SK_PNMI_VPD_ENTRIES];
 	SK_U32			PortNumber;
@@ -805,6 +836,7 @@
 	char			HwDescr[SK_PNMI_STRINGLEN1];
 	char			HwVersion[SK_PNMI_STRINGLEN2];
 	SK_U16			Chipset;
+	SK_U32			MtuSize;
 	SK_U32			Action;
 	SK_U32			TestResult;
 	SK_U8			BusType;
@@ -885,8 +917,24 @@
 	SK_U64			StatSyncOctetsCts;
 	SK_U64			StatRxLongFrameCts;
 	SK_BOOL			ActiveFlag;
+	SK_U64			TxSwQueueLen;
+	SK_U64			TxSwQueueMax;
+	SK_U64			TxRetryCts;
+	SK_U64			RxIntrCts;
+	SK_U64			TxIntrCts;
+	SK_U64			RxNoBufCts;
+	SK_U64			TxNoBufCts;
+	SK_U64			TxUsedDescrNo;
+	SK_U64			RxDeliveredCts;
+	SK_U64			RxOctetsDeliveredCts;
+	SK_U64			RxHwErrorsCts;
+	SK_U64			TxHwErrorsCts;
+	SK_U64			InErrorsCts;
+	SK_U64			OutErrorsCts;
+	SK_U64			ErrRecoveryCts;
 } SK_PNMI_PORT;
 
+
 typedef struct s_PnmiData {
 	SK_PNMI_PORT		Port[SK_MAX_MACS];
 	SK_U64			VirtualCounterOffset[SK_PNMI_CNT_NO];
@@ -917,19 +965,8 @@
 	char			PciBusWidth;
 	char			PMD;
 	char			Connector;
-
-	SK_U64			TxSwQueueLen;
-	SK_U64			TxSwQueueMax;
-	SK_U64			TxRetryCts;
-	SK_U64			RxIntrCts;
-	SK_U64			TxIntrCts;
-	SK_U64			RxNoBufCts;
-	SK_U64			TxNoBufCts;
-	SK_U64			TxUsedDescrNo;
-	SK_U64			RxDeliveredCts;
-	SK_U64			RxOctetsDeliveredCts;
-	SK_U64			ErrRecoveryCts;
 	SK_U64			StartUpTime;
+	SK_BOOL			DualNetActiveFlag;
 } SK_PNMI;
 
 
@@ -938,17 +975,17 @@
  */
 extern int SkPnmiInit(SK_AC *pAc, SK_IOC IoC, int level);
 extern int SkPnmiGetVar(SK_AC *pAc, SK_IOC IoC, SK_U32 Id, void* pBuf,
-	unsigned int* pLen, SK_U32 Instance);
+	unsigned int* pLen, SK_U32 Instance, SK_U32 NetIndex);
 extern int SkPnmiPreSetVar(SK_AC *pAc, SK_IOC IoC, SK_U32 Id,
-	void* pBuf, unsigned int *pLen, SK_U32 Instance);
+	void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
 extern int SkPnmiSetVar(SK_AC *pAc, SK_IOC IoC, SK_U32 Id, void* pBuf,
-	unsigned int *pLen, SK_U32 Instance);
+	unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
 extern int SkPnmiGetStruct(SK_AC *pAc, SK_IOC IoC, void* pBuf,
-	unsigned int *pLen);
+	unsigned int *pLen, SK_U32 NetIndex);
 extern int SkPnmiPreSetStruct(SK_AC *pAc, SK_IOC IoC, void* pBuf,
-	unsigned int *pLen);
+	unsigned int *pLen, SK_U32 NetIndex);
 extern int SkPnmiSetStruct(SK_AC *pAc, SK_IOC IoC, void* pBuf,
-	unsigned int *pLen);
+	unsigned int *pLen, SK_U32 NetIndex);
 extern int SkPnmiEvent(SK_AC *pAc, SK_IOC IoC, SK_U32 Event,
 	SK_EVPARA Param);
 
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/skgesirq.h linux/drivers/net/sk98lin/h/skgesirq.h
--- v2.4.6/linux/drivers/net/sk98lin/h/skgesirq.h	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/h/skgesirq.h	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	skgesirq.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.20 $
- * Date:	$Date: 1999/12/06 10:00:44 $
+ * Version:	$Revision: 1.22 $
+ * Date:	$Date: 2000/11/09 11:30:10 $
  * Purpose:	SK specific Gigabit Ethernet special IRQ functions
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2000 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -26,6 +25,12 @@
  *
  * History:
  *	$Log: skgesirq.h,v $
+ *	Revision 1.22  2000/11/09 11:30:10  rassmann
+ *	WA: Waiting after releasing reset until BCom chip is accessible.
+ *	
+ *	Revision 1.21  2000/10/18 12:22:40  cgoos
+ *	Added workaround for half duplex hangup.
+ *	
  *	Revision 1.20  1999/12/06 10:00:44  cgoos
  *	Added SET event for role.
  *	
@@ -106,9 +111,12 @@
 #define SK_HWEV_SET_LMODE	6	/* Set Link Mode by PNMI */
 #define SK_HWEV_SET_FLOWMODE	7	/* Set Flow Control Mode by PNMI */
 #define SK_HWEV_SET_ROLE	8	/* Set Master/Slave (Role) by PNMI */
+#define SK_HWEV_HALFDUP_CHK	9	/* Set Master/Slave (Role) by PNMI */
 
 #define	SK_WA_ACT_TIME		(5000000L)	/* 5 sec */
 #define	SK_WA_INA_TIME		(100000L)	/* 100 msec */
+
+#define	SK_HALFDUP_CHK_TIME	(10000L)	/* 10 msec */
 
 /*
  * Define the error numbers and messages
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/ski2c.h linux/drivers/net/sk98lin/h/ski2c.h
--- v2.4.6/linux/drivers/net/sk98lin/h/ski2c.h	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/h/ski2c.h	Wed Jul  4 11:50:39 2001
@@ -2,8 +2,8 @@
  *
  * Name:	ski2c.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.29 $
- * Date:	$Date: 2000/08/03 14:28:17 $
+ * Version:	$Revision: 1.30 $
+ * Date:	$Date: 2001/04/05 11:38:09 $
  * Purpose:	Defines to access Voltage and Temperature Sensor
  *		(taken from Monalisa (taken from Concentrator))
  *
@@ -28,6 +28,10 @@
  * History:
  *
  *	$Log: ski2c.h,v $
+ *	Revision 1.30  2001/04/05 11:38:09  rassmann
+ *	Set SenState to idle in SkI2cWaitIrq().
+ *	Changed error message in SkI2cWaitIrq().
+ *	
  *	Revision 1.29  2000/08/03 14:28:17  rassmann
  *	- Added function to wait for I2C being ready before resetting the board.
  *	- Replaced one duplicate "out of range" message with correct one.
@@ -182,24 +186,26 @@
 #define	SKERR_I2C_E014MSG	"WARNING: fan sensor out of range"
 #define	SKERR_I2C_E015		(SKERR_I2C_E014+1)
 #define	SKERR_I2C_E015MSG	"ERROR: fan sensor out of range"
+#define	SKERR_I2C_E016		(SKERR_I2C_E015+1)
+#define	SKERR_I2C_E016MSG	"I2C: active transfer does not complete.\n"
 
 /*
  * Define Timeout values
  */
-#define	SK_I2C_TIM_LONG		2000000L	/* 2 second */
-#define	SK_I2C_TIM_SHORT	100000L		/* 100 milli second */
+#define	SK_I2C_TIM_LONG		2000000L	/* 2 seconds */
+#define	SK_I2C_TIM_SHORT	 100000L	/* 100 milliseconds */
 
 /*
  * Define trap and error log hold times
  */
 #ifndef	SK_SEN_ERR_TR_HOLD
-#define	SK_SEN_ERR_TR_HOLD	(4*SK_TICKS_PER_SEC)
+#define	SK_SEN_ERR_TR_HOLD		(4*SK_TICKS_PER_SEC)
 #endif
 #ifndef	SK_SEN_ERR_LOG_HOLD
-#define	SK_SEN_ERR_LOG_HOLD	(60*SK_TICKS_PER_SEC)
+#define	SK_SEN_ERR_LOG_HOLD		(60*SK_TICKS_PER_SEC)
 #endif
 #ifndef	SK_SEN_WARN_TR_HOLD
-#define	SK_SEN_WARN_TR_HOLD	(15*SK_TICKS_PER_SEC)
+#define	SK_SEN_WARN_TR_HOLD		(15*SK_TICKS_PER_SEC)
 #endif
 #ifndef	SK_SEN_WARN_LOG_HOLD
 #define	SK_SEN_WARN_LOG_HOLD	(15*60*SK_TICKS_PER_SEC)
@@ -268,3 +274,4 @@
 
 #endif
 #endif	/* n_SKI2C_H */
+
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/skqueue.h linux/drivers/net/sk98lin/h/skqueue.h
--- v2.4.6/linux/drivers/net/sk98lin/h/skqueue.h	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/h/skqueue.h	Wed Jul  4 11:50:39 2001
@@ -1,23 +1,32 @@
 /******************************************************************************
  *
  * Name:	skqueue.h
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.13 $
- * Date:	$Date: 1999/11/22 13:59:05 $
+ * Project:	Genesis, PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 1.12 $
+ * Date:	$Date: 1998/09/08 08:48:01 $
  * Purpose:	Defines for the Event queue
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
+ *	(C)Copyright 1989-1998 SysKonnect,
  *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	All Rights Reserved
  *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
+ *	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT
+ *	The copyright notice above does not evidence any
+ *	actual or intended publication of such source code.
+ *
+ *	This Module contains Proprietary Information of SysKonnect
+ *	and should be treated as Confidential.
+ *
+ *	The information in this file is provided for the exclusive use of
+ *	the licensees of SysKonnect.
+ *	Such users have the right to use, modify, and incorporate this code
+ *	into products for purposes authorized by the license agreement
+ *	provided they include this notice and the associated copyright notice
+ *	with any such product.
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -27,9 +36,6 @@
  * History:
  *
  *	$Log: skqueue.h,v $
- *	Revision 1.13  1999/11/22 13:59:05  cgoos
- *	Changed license header to GPL.
- *	
  *	Revision 1.12  1998/09/08 08:48:01  gklug
  *	add: init level handling
  *	
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/skrlmt.h linux/drivers/net/sk98lin/h/skrlmt.h
--- v2.4.6/linux/drivers/net/sk98lin/h/skrlmt.h	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/h/skrlmt.h	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	skrlmt.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.27 $
- * Date:	$Date: 1999/11/22 13:59:56 $
+ * Version:	$Revision: 1.32 $
+ * Date:	$Date: 2001/02/14 14:06:31 $
  * Purpose:	Header file for Redundant Link ManagemenT.
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,14 +26,26 @@
  * History:
  *
  *	$Log: skrlmt.h,v $
+ *	Revision 1.32  2001/02/14 14:06:31  rassmann
+ *	Editorial changes.
+ *	
+ *	Revision 1.31  2001/02/05 14:25:26  rassmann
+ *	Prepared RLMT for transparent operation.
+ *	
+ *	Revision 1.30  2001/01/22 13:41:39  rassmann
+ *	Supporting two nets on dual-port adapters.
+ *	
+ *	Revision 1.29  2000/11/17 08:58:00  rassmann
+ *	Moved CheckSwitch from SK_RLMT_PACKET_RECEIVED to SK_RLMT_TIM event.
+ *	
+ *	Revision 1.28  2000/11/09 12:24:34  rassmann
+ *	Editorial changes.
+ *	
  *	Revision 1.27  1999/11/22 13:59:56  cgoos
  *	Changed license header to GPL.
  *	
  *	Revision 1.26  1999/10/04 14:01:19  rassmann
- *	Corrected reaction to reception of BPDU frames.
- *	Added parameter descriptions to "For Readme" section skrlmt.txt.
- *	Clarified usage of lookahead result *pForRlmt.
- *	Requested driver to present RLMT packets as soon as poosible.
+ *	Corrected reaction to reception of BPDU frames (#10441).
  *	
  *	Revision 1.25  1999/07/20 12:53:39  rassmann
  *	Fixed documentation errors for lookahead macros.
@@ -149,7 +160,7 @@
 #define __INC_SKRLMT_H
 
 #ifdef __cplusplus
-xxxx	/* not supported yet - force error */
+#error C++ is not yet supported.
 extern "C" {
 #endif	/* cplusplus */
 
@@ -169,128 +180,140 @@
 
 /* ----- PORT states ----- */
 
-#define SK_RLMT_PS_INIT		0	/* Port state: Init. */
+#define SK_RLMT_PS_INIT			0	/* Port state: Init. */
 #define SK_RLMT_PS_LINK_DOWN	1	/* Port state: Link down. */
-#define SK_RLMT_PS_DOWN		2	/* Port state: Port down. */
-#define SK_RLMT_PS_GOING_UP	3	/* Port state: Going up. */
-#define SK_RLMT_PS_UP		4	/* Port state: Up. */
+#define SK_RLMT_PS_DOWN			2	/* Port state: Port down. */
+#define SK_RLMT_PS_GOING_UP		3	/* Port state: Going up. */
+#define SK_RLMT_PS_UP			4	/* Port state: Up. */
 
 /* ----- RLMT states ----- */
 
-#define SK_RLMT_RS_INIT		0	/* RLMT state: Init. */
-#define SK_RLMT_RS_NET_DOWN	1	/* RLMT state: Net down. */
-#define SK_RLMT_RS_NET_UP	2	/* RLMT state: Net up. */
+#define SK_RLMT_RS_INIT			0	/* RLMT state: Init. */
+#define SK_RLMT_RS_NET_DOWN		1	/* RLMT state: Net down. */
+#define SK_RLMT_RS_NET_UP		2	/* RLMT state: Net up. */
 
 /* ----- PORT events ----- */
 
-#define SK_RLMT_LINK_UP		1001	/* Link came up. */
-#define SK_RLMT_LINK_DOWN	1002	/* Link went down. */
-#define SK_RLMT_PORT_ADDR	1003	/* Port address changed. */
+#define SK_RLMT_LINK_UP			1001	/* Link came up. */
+#define SK_RLMT_LINK_DOWN		1002	/* Link went down. */
+#define SK_RLMT_PORT_ADDR		1003	/* Port address changed. */
 
 /* ----- RLMT events ----- */
 
-#define SK_RLMT_START		2001	/* Start RLMT. */
-#define SK_RLMT_STOP		2002	/* Stop RLMT. */
+#define SK_RLMT_START			2001	/* Start RLMT. */
+#define SK_RLMT_STOP			2002	/* Stop RLMT. */
 #define SK_RLMT_PACKET_RECEIVED	2003	/* Packet was received for RLMT. */
-#define SK_RLMT_STATS_CLEAR	2004	/* Clear statistics. */
+#define SK_RLMT_STATS_CLEAR		2004	/* Clear statistics. */
 #define SK_RLMT_STATS_UPDATE	2005	/* Update statistics. */
 #define SK_RLMT_PREFPORT_CHANGE	2006	/* Change preferred port. */
-#define SK_RLMT_MODE_CHANGE	2007	/* New RlmtMode. */
+#define SK_RLMT_MODE_CHANGE		2007	/* New RlmtMode. */
+#define SK_RLMT_SET_NETS		2008	/* Number of Nets (1 or 2). */
 
 /* ----- RLMT mode bits ----- */
 
-#define SK_RLMT_CHECK_LINK	1	/* Check Link. */
-#define SK_RLMT_CHECK_LOC_LINK	2	/* Check other link on same adapter. */
-#define SK_RLMT_CHECK_SEG	4	/* Check segmentation. */
+/*
+ * CAUTION:	These defines are private to RLMT.
+ *			Please use the RLMT mode defines below.
+ */
+
+#define SK_RLMT_CHECK_LINK		  1		/* Check Link. */
+#define SK_RLMT_CHECK_LOC_LINK	  2		/* Check other link on same adapter. */
+#define SK_RLMT_CHECK_SEG		  4		/* Check segmentation. */
 
 #ifndef RLMT_CHECK_REMOTE
 #define SK_RLMT_CHECK_OTHERS	SK_RLMT_CHECK_LOC_LINK
 #else	/* RLMT_CHECK_REMOTE */
-#define SK_RLMT_CHECK_REM_LINK	8	/* Check link(s) on other adapter(s). */
+#define SK_RLMT_CHECK_REM_LINK	  8		/* Check link(s) on other adapter(s). */
 #define SK_RLMT_MAX_REMOTE_PORTS_CHECKED	3
-#define SK_RLMT_CHECK_OTHERS	(SK_RLMT_CHECK_LOC_LINK | \
-				 SK_RLMT_CHECK_REM_LINK)
+#define SK_RLMT_CHECK_OTHERS	\
+		(SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
 #endif	/* RLMT_CHECK_REMOTE */
 
+#ifndef SK_RLMT_ENABLE_TRANSPARENT
+#define SK_RLMT_TRANSPARENT		  0		/* RLMT transparent - inactive. */
+#else	/* SK_RLMT_ENABLE_TRANSPARENT */
+#define SK_RLMT_TRANSPARENT		128		/* RLMT transparent. */
+#endif	/* SK_RLMT_ENABLE_TRANSPARENT */
+
 /* ----- RLMT modes ----- */
 
 /* Check Link State. */
 #define SK_RLMT_MODE_CLS	(SK_RLMT_CHECK_LINK)
 
 /* Check Local Ports: check other links on the same adapter. */
-#define SK_RLMT_MODE_CLP	(SK_RLMT_CHECK_LINK | \
-				 SK_RLMT_CHECK_LOC_LINK)
+#define SK_RLMT_MODE_CLP	(SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK)
 
 /* Check Local Ports and Segmentation Status. */
-#define SK_RLMT_MODE_CLPSS	(SK_RLMT_CHECK_LINK | \
-				 SK_RLMT_CHECK_LOC_LINK | \
-				 SK_RLMT_CHECK_SEG)
+#define SK_RLMT_MODE_CLPSS	\
+		(SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_SEG)
 
 #ifdef RLMT_CHECK_REMOTE
 /* Check Local and Remote Ports: check links (local or remote). */
 	Name of define TBD!
-#define SK_RLMT_MODE_CRP	(SK_RLMT_CHECK_LINK | \
-				 SK_RLMT_CHECK_LOC_LINK | \
-				 SK_RLMT_CHECK_REM_LINK)
+#define SK_RLMT_MODE_CRP	\
+		(SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
 
 /* Check Local and Remote Ports and Segmentation Status. */
 	Name of define TBD!
-#define SK_RLMT_MODE_CRPSS	(SK_RLMT_CHECK_LINK | \
-				 SK_RLMT_CHECK_LOC_LINK | \
-				 SK_RLMT_CHECK_REM_LINK | \
-				 SK_RLMT_CHECK_SEG)
+#define SK_RLMT_MODE_CRPSS	\
+		(SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | \
+		SK_RLMT_CHECK_REM_LINK | SK_RLMT_CHECK_SEG)
 #endif	/* RLMT_CHECK_REMOTE */
 
 /* ----- RLMT lookahead result bits ----- */
 
-#define SK_RLMT_RX_RLMT		1	/* Give packet to RLMT. */
-#define SK_RLMT_RX_PROTOCOL	2	/* Give packet to protocol. */
+#define SK_RLMT_RX_RLMT			1	/* Give packet to RLMT. */
+#define SK_RLMT_RX_PROTOCOL		2	/* Give packet to protocol. */
 
 /* Macros */
 
 #if 0
 SK_AC		*pAC		/* adapter context */
-SK_U32		PortIdx		/* receiving port */
-unsigned	PacketLength	/* received packet's length */
-SK_BOOL		IsBc		/* Flag: broadcast received */
-unsigned	*pOffset	/* Result: offset of bytes to present
-				   to SK_RLMT_LOOKAHEAD */
-unsigned	*pNumBytes	/* Result: #Bytes to present
-				   to SK_RLMT_LOOKAHEAD */
+SK_U32		PortNum		/* receiving port */
+unsigned	PktLen		/* received packet's length */
+SK_BOOL		IsBc		/* Flag: packet is broadcast */
+unsigned	*pOffset	/* offs. of bytes to present to SK_RLMT_LOOKAHEAD */
+unsigned	*pNumBytes	/* #Bytes to present to SK_RLMT_LOOKAHEAD */
 #endif	/* 0 */
 
-
-#define SK_RLMT_PRE_LOOKAHEAD(pAC,PortIdx,PacketLength,IsBc,pOffset,pNumBytes) { \
+#define SK_RLMT_PRE_LOOKAHEAD(pAC,PortNum,PktLen,IsBc,pOffset,pNumBytes) { \
 	SK_AC	*_pAC; \
-	SK_U32	_PortIdx; \
+	SK_U32	_PortNum; \
 	_pAC = (pAC); \
-	_PortIdx = (SK_U32)(PortIdx); \
-	_pAC->Rlmt.Port[_PortIdx].PacketsRx++; \
-	_pAC->Rlmt.Port[_PortIdx].PacketsPerTimeSlot++; \
-	if ((IsBc) && _pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS) { \
-		*(pOffset) = 6; \
-		*(pNumBytes) = 6; \
+	_PortNum = (SK_U32)(PortNum); \
+	/* _pAC->Rlmt.Port[_PortNum].PacketsRx++; */ \
+	_pAC->Rlmt.Port[_PortNum].PacketsPerTimeSlot++; \
+	if ((_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_TRANSPARENT) != 0) { \
+		*(pNumBytes) = 0; \
+	} \
+	else if (IsBc) { \
+		if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode != SK_RLMT_MODE_CLS) { \
+			*(pNumBytes) = 6; \
+			*(pOffset) = 6; \
+		} \
+		else { \
+			*(pNumBytes) = 0; \
+		} \
 	} \
 	else { \
-		*(pOffset) = 0; \
-		if ((PacketLength) > SK_RLMT_MAX_TX_BUF_SIZE) { \
-			_pAC->Rlmt.Port[_PortIdx].DataPacketsPerTimeSlot++; \
+		if ((PktLen) > SK_RLMT_MAX_TX_BUF_SIZE) { \
+			/* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
 			*(pNumBytes) = 0; \
 		} \
 		else { \
 			*(pNumBytes) = 6; \
+			*(pOffset) = 0; \
 		} \
 	} \
 }
 
 #if 0
 SK_AC		*pAC		/* adapter context */
-SK_U32		PortIdx		/* receiving port */
+SK_U32		PortNum		/* receiving port */
 SK_U8		*pLaPacket,	/* received packet's data (points to pOffset) */
-SK_BOOL		IsBc		/* Flag: broadcast received */
-SK_BOOL		IsMc		/* Flag: multicast received */
-unsigned	*pForRlmt	/* Result: bits SK_RLMT_RX_RLMT,
-				   SK_RLMT_RX_PROTOCOL */
+SK_BOOL		IsBc		/* Flag: packet is broadcast */
+SK_BOOL		IsMc		/* Flag: packet is multicast */
+unsigned	*pForRlmt	/* Result: bits SK_RLMT_RX_RLMT, SK_RLMT_RX_PROTOCOL */
 SK_RLMT_LOOKAHEAD() expects *pNumBytes from
 packet offset *pOffset (s.a.) at *pLaPacket.
 
@@ -298,29 +321,28 @@
 BC, MC, or UC, you should use constants for IsBc and IsMc, so that your compiler
 can trash unneeded parts of the if construction.
 #endif	/* 0 */
-#define SK_RLMT_LOOKAHEAD(pAC,PortIdx,pLaPacket,IsBc,IsMc,pForRlmt) { \
+
+#define SK_RLMT_LOOKAHEAD(pAC,PortNum,pLaPacket,IsBc,IsMc,pForRlmt) { \
 	SK_AC	*_pAC; \
-	SK_U32	_PortIdx; \
+	SK_U32	_PortNum; \
 	SK_U8	*_pLaPacket; \
 	_pAC = (pAC); \
-	_PortIdx = (SK_U32)(PortIdx); \
+	_PortNum = (SK_U32)(PortNum); \
 	_pLaPacket = (SK_U8 *)(pLaPacket); \
 	if (IsBc) {\
-		if (!SK_ADDR_EQUAL( \
-			_pLaPacket, \
-			_pAC->Addr.CurrentMacAddress.a)) { \
-			_pAC->Rlmt.Port[_PortIdx].BcTimeStamp = \
-				SkOsGetTime(_pAC); \
+		if (!SK_ADDR_EQUAL(_pLaPacket, _pAC->Addr.Net[_pAC->Rlmt.Port[ \
+			_PortNum].Net->NetNumber].CurrentMacAddress.a)) { \
+			_pAC->Rlmt.Port[_PortNum].BcTimeStamp = SkOsGetTime(_pAC); \
+			_pAC->Rlmt.CheckSwitch = SK_TRUE; \
 		} \
-		_pAC->Rlmt.Port[_PortIdx].DataPacketsPerTimeSlot++; \
+		/* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
 		*(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
 	} \
 	else if (IsMc) { \
 		if (SK_ADDR_EQUAL(_pLaPacket, BridgeMcAddr.a)) { \
-			_pAC->Rlmt.Port[_PortIdx].BpduPacketsPerTimeSlot++; \
-			if (_pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_SEG) { \
-				*(pForRlmt) = SK_RLMT_RX_RLMT | \
-					SK_RLMT_RX_PROTOCOL; \
+			_pAC->Rlmt.Port[_PortNum].BpduPacketsPerTimeSlot++; \
+			if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_CHECK_SEG) { \
+				*(pForRlmt) = SK_RLMT_RX_RLMT | SK_RLMT_RX_PROTOCOL; \
 			} \
 			else { \
 				*(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
@@ -330,18 +352,18 @@
 			*(pForRlmt) = SK_RLMT_RX_RLMT; \
 		} \
 		else { \
-			_pAC->Rlmt.Port[_PortIdx].DataPacketsPerTimeSlot++; \
+			/* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
 			*(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
 		} \
 	} \
 	else { \
 		if (SK_ADDR_EQUAL( \
 			_pLaPacket, \
-			_pAC->Addr.Port[_PortIdx].CurrentMacAddress.a)) { \
+			_pAC->Addr.Port[_PortNum].CurrentMacAddress.a)) { \
 			*(pForRlmt) = SK_RLMT_RX_RLMT; \
 		} \
 		else { \
-			_pAC->Rlmt.Port[_PortIdx].DataPacketsPerTimeSlot++; \
+			/* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
 			*(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
 		} \
 	} \
@@ -350,107 +372,143 @@
 #ifdef SK_RLMT_FAST_LOOKAHEAD
 Error: SK_RLMT_FAST_LOOKAHEAD no longer used. Use new macros for lookahead.
 #endif	/* SK_RLMT_FAST_LOOKAHEAD */
+#ifdef SK_RLMT_SLOW_LOOKAHEAD
+Error: SK_RLMT_SLOW_LOOKAHEAD no longer used. Use new macros for lookahead.
+#endif	/* SK_RLMT_SLOW_LOOKAHEAD */
 
 /* typedefs *******************************************************************/
 
+#ifdef SK_RLMT_MBUF_PRIVATE
+typedef struct s_RlmtMbuf {
+	some content
+} SK_RLMT_MBUF;
+#endif	/* SK_RLMT_MBUF_PRIVATE */
+
+
+#ifdef SK_LA_INFO
+typedef struct s_Rlmt_PacketInfo {
+	unsigned	PacketLength;			/* Length of packet. */
+	unsigned	PacketType;				/* Directed/Multicast/Broadcast. */
+} SK_RLMT_PINFO;
+#endif	/* SK_LA_INFO */
+
+
 typedef struct s_RootId {
-	SK_U8		Id[8];		/* Root Bridge Id. */
+	SK_U8		Id[8];					/* Root Bridge Id. */
 } SK_RLMT_ROOT_ID;
 
+
 typedef struct s_port {
 	SK_MAC_ADDR	CheckAddr;
 	SK_BOOL		SuspectTx;
 } SK_PORT_CHECK;
 
+
+typedef struct s_RlmtNet SK_RLMT_NET;
+
+
 typedef struct s_RlmtPort {
 
 /* ----- Public part (read-only) ----- */
 
-	SK_U8		PortState;	/* Current state of this port. */
+	SK_U8			PortState;				/* Current state of this port. */
 
 	/* For PNMI */
-
-	SK_BOOL		LinkDown;
-	SK_BOOL		PortDown;
-
-	SK_U64		TxHelloCts;
-	SK_U64		RxHelloCts;
-	SK_U64		TxSpHelloReqCts;
-	SK_U64		RxSpHelloCts;
+	SK_BOOL			LinkDown;
+	SK_BOOL			PortDown;
+	SK_U8			Align01;
+
+	SK_U32			PortNumber;				/* Number of port on adapter. */
+	SK_RLMT_NET *	Net;					/* Net port belongs to. */
+
+	SK_U64			TxHelloCts;
+	SK_U64			RxHelloCts;
+	SK_U64			TxSpHelloReqCts;
+	SK_U64			RxSpHelloCts;
 
 /* ----- Private part ----- */
 
-	SK_BOOL		PortStarted;		/* Port is started. */
-	SK_BOOL		PortNoRx;		/* NoRx for >= 1 time slot. */
-	SK_U32		CheckingState;		/* Checking State. */
-
-	SK_U64		PacketsRx;		/* Total packets received. */
-	SK_U32		PacketsPerTimeSlot;	/* Packets rxed between TOs. */
-	SK_U32		DataPacketsPerTimeSlot;	/* Data packets ... */
-#if 0
-	SK_U32		RlmtAcksPerTimeSlot;	/* RLMT Acks rxed in TS. */
-	SK_U32		RlmtChksPerTimeSlot;	/* RLMT Chks rxed in TS. */
-#endif	/* 0 */
-	SK_U32		BpduPacketsPerTimeSlot;	/* BPDU packets rxed in TS. */
-	SK_U64		BcTimeStamp;		/* Time of last BC receive. */
-	SK_U64		GuTimeStamp;		/* Time of entering GOING_UP. */
-
-	SK_TIMER	UpTimer;		/* Timer struct Link/Port up. */
-	SK_TIMER	DownRxTimer;		/* Timer struct down rx. */
-	SK_TIMER	DownTxTimer;		/* Timer struct down tx. */
-
-	SK_U8		Random[4];		/* Random value. */
-	unsigned	PortsChecked;		/* #ports checked. */
-	unsigned	PortsSuspect;		/* #ports checked that are s. */
+/*	SK_U64			PacketsRx; */				/* Total packets received. */
+	SK_U32			PacketsPerTimeSlot;		/* Packets rxed between TOs. */
+/*	SK_U32			DataPacketsPerTimeSlot; */	/* Data packets ... */
+	SK_U32			BpduPacketsPerTimeSlot;	/* BPDU packets rxed in TS. */
+	SK_U64			BcTimeStamp;			/* Time of last BC receive. */
+	SK_U64			GuTimeStamp;			/* Time of entering GOING_UP. */
+
+	SK_TIMER		UpTimer;				/* Timer struct Link/Port up. */
+	SK_TIMER		DownRxTimer;			/* Timer struct down rx. */
+	SK_TIMER		DownTxTimer;			/* Timer struct down tx. */
+
+	SK_U32			CheckingState;			/* Checking State. */
+
+	SK_ADDR_PORT *	AddrPort;
+
+	SK_U8			Random[4];				/* Random value. */
+	unsigned		PortsChecked;			/* #ports checked. */
+	unsigned		PortsSuspect;			/* #ports checked that are s. */
 	SK_PORT_CHECK	PortCheck[1];
 /*	SK_PORT_CHECK	PortCheck[SK_MAX_MACS - 1]; */
 
-	SK_BOOL		RootIdSet;
-	SK_RLMT_ROOT_ID	Root;			/* Root Bridge Id. */
+	SK_BOOL			PortStarted;			/* Port is started. */
+	SK_BOOL			PortNoRx;				/* NoRx for >= 1 time slot. */
+	SK_BOOL			RootIdSet;
+	SK_RLMT_ROOT_ID	Root;					/* Root Bridge Id. */
 } SK_RLMT_PORT;
 
-#ifdef SK_RLMT_MBUF_PRIVATE
-typedef struct s_RlmtMbuf {
-	some content
-} SK_RLMT_MBUF;
-#endif	/* SK_RLMT_MBUF_PRIVATE */
 
-#ifdef SK_LA_INFO
-typedef struct s_Rlmt_PacketInfo {
-	unsigned	PacketLength;	/* Length of packet. */
-	unsigned	PacketType;	/* Directed/Multicast/Broadcast. */
-} SK_RLMT_PINFO;
-#endif	/* SK_LA_INFO */
-
-typedef struct s_Rlmt {
+struct s_RlmtNet {
 
 /* ----- Public part (read-only) ----- */
 
-	SK_U8		RlmtState;		/* Current RLMT state. */
-	SK_RLMT_PORT	Port[SK_MAX_MACS];	/* Array of available ports. */
-	SK_U32		PrefPort;		/* Preferred port. */
+	SK_U32			NetNumber;			/* Number of net. */
+
+	SK_RLMT_PORT *	Port[SK_MAX_MACS];	/* Ports that belong to this net. */
+	SK_U32			NumPorts;			/* Number of ports. */
+	SK_U32			PrefPort;			/* Preferred port. */
 
 	/* For PNMI */
 
-	SK_U32		RlmtMode;		/* Check ... */
-	SK_U32		MacActive;		/* Active port. */
-	SK_U32		MacPreferred;		/* 0xFFFFFFFF: Automatic. */
+	SK_U32			RlmtMode;			/* Check ... */
+	SK_U32			ActivePort;			/* Active port. */
+	SK_U32			Preference;		/* 0xFFFFFFFF: Automatic. */
+
+	SK_U8			RlmtState;			/* Current RLMT state. */
+
+/* ----- Private part ----- */
+	SK_BOOL			RootIdSet;
+	SK_U16			Align01;
+
+	int				LinksUp;			/* #Links up. */
+	int				PortsUp;			/* #Ports up. */
+	SK_U32			TimeoutValue;		/* RLMT timeout value. */
+
+	SK_U32			CheckingState;		/* Checking State. */
+	SK_RLMT_ROOT_ID	Root;				/* Root Bridge Id. */
+
+	SK_TIMER		LocTimer;			/* Timer struct. */
+	SK_TIMER		SegTimer;			/* Timer struct. */
+};
+
+
+typedef struct s_Rlmt {
+
+/* ----- Public part (read-only) ----- */
+
+	SK_U32			NumNets;			/* Number of nets. */
+	SK_U32			NetsStarted;		/* Number of nets started. */
+	SK_RLMT_NET		Net[SK_MAX_NETS];	/* Array of available nets. */
+	SK_RLMT_PORT	Port[SK_MAX_MACS];	/* Array of available ports. */
 
 /* ----- Private part ----- */
+	SK_BOOL			CheckSwitch;
+	SK_U8			Align01;
+	SK_U16			Align02;
 
-	int		LinksUp;		/* #Links up. */
-	int		PortsUp;		/* #Ports up. */
-	SK_U32		TimeoutValue;		/* RLMT timeout value. */
-	SK_TIMER	LocTimer;		/* Timer struct. */
-
-	SK_U32		CheckingState;		/* Checking State. */
-	SK_BOOL		RootIdSet;
-	SK_RLMT_ROOT_ID	Root;			/* Root Bridge Id. */
-	SK_TIMER	SegTimer;		/* Timer struct. */
 } SK_RLMT;
 
+
 extern	SK_MAC_ADDR	BridgeMcAddr;
-extern	SK_MAC_ADDR     SkRlmtMcAddr;
+extern	SK_MAC_ADDR	SkRlmtMcAddr;
 
 /* function prototypes ********************************************************/
 
@@ -464,16 +522,7 @@
 extern	void	SkRlmtInit(
 	SK_AC	*pAC,
 	SK_IOC	IoC,
-	int	Level);
-
-#ifdef SK_RLMT_SLOW_LOOKAHEAD
-extern	SK_BOOL	SkRlmtLookaheadPacket(
-	SK_AC		*pAC,
-	SK_U32		PortIdx,
-	SK_U8		*pLaPacket,
-	unsigned	PacketLength,
-	unsigned	LaLength);
-#endif	/* SK_RLMT_SLOW_LOOKAHEAD */
+	int		Level);
 
 extern	int	SkRlmtEvent(
 	SK_AC		*pAC,
@@ -481,11 +530,11 @@
 	SK_U32		Event,
 	SK_EVPARA	Para);
 
-#else	/* defined(SK_KR_PROTO)) */
+#else	/* defined(SK_KR_PROTO) */
 
 /* Non-ANSI/C++ compliant function prototypes */
 
-xxxx	/* not supported yet - force error */
+#error KR-style function prototypes are not yet provided.
 
 #endif	/* defined(SK_KR_PROTO)) */
 
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/sktimer.h linux/drivers/net/sk98lin/h/sktimer.h
--- v2.4.6/linux/drivers/net/sk98lin/h/sktimer.h	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/h/sktimer.h	Wed Jul  4 11:50:39 2001
@@ -1,23 +1,32 @@
 /******************************************************************************
  *
  * Name:	sktimer.h
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.9 $
- * Date:	$Date: 1999/11/22 14:00:29 $
+ * Project:	Genesis, PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 1.8 $
+ * Date:	$Date: 1998/09/08 08:48:02 $
  * Purpose:	Defines for the timer functions
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
+ *	(C)Copyright 1989-1998 SysKonnect,
  *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	All Rights Reserved
  *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
+ *	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT
+ *	The copyright notice above does not evidence any
+ *	actual or intended publication of such source code.
+ *
+ *	This Module contains Proprietary Information of SysKonnect
+ *	and should be treated as Confidential.
+ *
+ *	The information in this file is provided for the exclusive use of
+ *	the licensees of SysKonnect.
+ *	Such users have the right to use, modify, and incorporate this code
+ *	into products for purposes authorized by the license agreement
+ *	provided they include this notice and the associated copyright notice
+ *	with any such product.
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -27,9 +36,6 @@
  * History:
  *
  *	$Log: sktimer.h,v $
- *	Revision 1.9  1999/11/22 14:00:29  cgoos
- *	Changed license header to GPL.
- *	
  *	Revision 1.8  1998/09/08 08:48:02  gklug
  *	add: init level handling
  *	
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/skversion.h linux/drivers/net/sk98lin/h/skversion.h
--- v2.4.6/linux/drivers/net/sk98lin/h/skversion.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/sk98lin/h/skversion.h	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * Name:	version.h
+ * Project:	GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 1.1 $
+ * Date:	$Date: 2001/03/06 09:25:00 $
+ * Purpose:	SK specific Error log support
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *	(C)Copyright 1998,1999 SysKonnect,
+ *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ *
+ *	The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *	$Log: skversion.h,v $
+ *	Revision 1.1  2001/03/06 09:25:00  mlindner
+ *	first version
+ *	
+ *	
+ *
+ ******************************************************************************/
+ 
+ 
+static const char SysKonnectFileId[] = "@(#)" __FILE__ " (C) SysKonnect GmbH.";
+static const char SysKonnectBuildNumber[] =
+	"@(#)SK-BUILD: 4.06 PL: 01"; 
+
+#define BOOT_STRING	"sk98lin: Network Device Driver v4.06\n" \
+			"Copyright (C) 2000-2001 SysKonnect GmbH."
+
+#define VER_STRING	"4.06"
+
+
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/skvpd.h linux/drivers/net/sk98lin/h/skvpd.h
--- v2.4.6/linux/drivers/net/sk98lin/h/skvpd.h	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/h/skvpd.h	Wed Jul  4 11:50:39 2001
@@ -2,15 +2,15 @@
  *
  * Name:	skvpd.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.10 $
- * Date:	$Date: 2000/08/10 11:29:07 $
+ * Version:	$Revision: 1.9 $
+ * Date:	$Date: 1999/11/22 14:02:27 $
  * Purpose:	Defines and Macros for VPD handling
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2000 SysKonnect,
+ *	(C)Copyright 1998,1999 SysKonnect,
  *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -27,12 +27,6 @@
  * History:
  *
  *	$Log: skvpd.h,v $
- *	Revision 1.10  2000/08/10 11:29:07  rassmann
- *	Editorial changes.
- *	Preserving 32-bit alignment in structs for the adapter context.
- *	Removed unused function VpdWriteDword() (#if 0).
- *	Made VpdReadKeyword() available for SKDIAG only.
- *	
  *	Revision 1.9  1999/11/22 14:02:27  cgoos
  *	Changed license header to GPL.
  *	
@@ -121,42 +115,40 @@
 
 /* VPD status */
 	/* bit 7..1 reserved */
-#define VPD_VALID	(1<<0)	/* VPD data buffer, vpd_free_ro, */
-							/* and vpd_free_rw valid	 */
+#define VPD_VALID	(1<<0)		/* VPD data buffer, vpd_free_ro, */
+					/* and vpd_free_rw valid	 */
 
 /*
  * VPD structs
  */
 typedef	struct s_vpd_status {
-	unsigned short	Align01;			/* Alignment */
-	unsigned short	vpd_status;			/* VPD status, description see above */
-	int				vpd_free_ro;		/* unused bytes in read only area */
-	int				vpd_free_rw;		/* bytes available in read/write area */
+	unsigned short	vpd_status ;	/* VPD status, description see above */
+	int		vpd_free_ro ;	/* unused bytes in read only area */
+	int		vpd_free_rw ;	/* bytes available in read/write area */
 } SK_VPD_STATUS;
 
 typedef	struct s_vpd {
-	SK_VPD_STATUS	v;					/* VPD status structure */
-	char			vpd_buf[VPD_SIZE];	/* VPD buffer */
+	SK_VPD_STATUS	v ;			/* VPD status structure */
+	char		vpd_buf[VPD_SIZE] ;	/* VPD buffer */
 } SK_VPD;
 
 typedef	struct s_vpd_para {
-	unsigned int	p_len;	/* parameter length */
-	char			*p_val;	/* points to the value */
+	unsigned int	p_len ;		/* parameter length */
+	char		*p_val ;	/* points to the value */
 } SK_VPD_PARA;
 
 /*
  * structure of Large Resource Type Identifiers
  */
-
-/* was removed because of alignment problems */
+/* was removed, because of alignment problems */
 
 /*
  * sturcture of VPD keywords
  */
 typedef	struct s_vpd_key {
-	char			p_key[2];	/* 2 bytes ID string */
-	unsigned char	p_len;		/* 1 byte length */
-	char			p_val;		/* start of the value string */
+	char		p_key[2] ;	/* 2 bytes ID string */
+	unsigned char	p_len ;		/* 1 byte length */
+	char		p_val ;		/* start of the value string */
 } SK_VPD_KEY;
 
 
@@ -180,39 +172,39 @@
 #define VPD_IN32(pAC,IoC,Addr,pVal)	SK_IN32(IoC,PCI_C(Addr),pVal)
 #endif	/* VPD_DO_IO */
 #else	/* SKDIAG */
-#define VPD_OUT8(pAC,Ioc,Addr,Val) {			\
+#define VPD_OUT8(pAC,Ioc,Addr,Val) {				\
 		if ((pAC)->DgT.DgUseCfgCycle)			\
-			SkPciWriteCfgByte(pAC,Addr,Val);	\
-		else									\
+			SkPciWriteCfgByte(pAC,Addr,Val) ;	\
+		else						\
 			SK_OUT8(pAC,PCI_C(Addr),Val);		\
 		}
-#define VPD_OUT16(pAC,Ioc,Addr,Val) {			\
+#define VPD_OUT16(pAC,Ioc,Addr,Val) {				\
 		if ((pAC)->DgT.DgUseCfgCycle)			\
-			SkPciWriteCfgWord(pAC,Addr,Val);	\
+			SkPciWriteCfgWord(pAC,Addr,Val) ;	\
 		else						\
 			SK_OUT16(pAC,PCI_C(Addr),Val);		\
 		}
-#define VPD_OUT32(pAC,Ioc,Addr,Val) {			\
+#define VPD_OUT32(pAC,Ioc,Addr,Val) {				\
 		if ((pAC)->DgT.DgUseCfgCycle)			\
-			SkPciWriteCfgDWord(pAC,Addr,Val);	\
+			SkPciWriteCfgDWord(pAC,Addr,Val) ;	\
 		else						\
 			SK_OUT32(pAC,PCI_C(Addr),Val); 		\
 		}
-#define VPD_IN8(pAC,Ioc,Addr,pVal) {			\
+#define VPD_IN8(pAC,Ioc,Addr,pVal) {				\
 		if ((pAC)->DgT.DgUseCfgCycle) 			\
-			SkPciReadCfgByte(pAC,Addr,pVal);	\
+			SkPciReadCfgByte(pAC,Addr,pVal) ;	\
 		else						\
 			SK_IN8(pAC,PCI_C(Addr),pVal); 		\
 		}
-#define VPD_IN16(pAC,Ioc,Addr,pVal) {			\
+#define VPD_IN16(pAC,Ioc,Addr,pVal) {				\
 		if ((pAC)->DgT.DgUseCfgCycle) 			\
-			SkPciReadCfgWord(pAC,Addr,pVal);	\
+			SkPciReadCfgWord(pAC,Addr,pVal) ;	\
 		else						\
 			SK_IN16(pAC,PCI_C(Addr),pVal); 		\
 		}
-#define VPD_IN32(pAC,Ioc,Addr,pVal) {			\
+#define VPD_IN32(pAC,Ioc,Addr,pVal) {				\
 		if ((pAC)->DgT.DgUseCfgCycle)			\
-			SkPciReadCfgDWord(pAC,Addr,pVal);	\
+			SkPciReadCfgDWord(pAC,Addr,pVal) ;	\
 		else						\
 			SK_IN32(pAC,PCI_C(Addr),pVal);		\
 		}
@@ -221,52 +213,50 @@
 /* function prototypes ********************************************************/
 
 #ifndef	SK_KR_PROTO
-#ifdef SKDIAG
 extern SK_U32	VpdReadDWord(
 	SK_AC		*pAC,
 	SK_IOC		IoC,
-	int			addr);
-#endif	/* SKDIAG */
+	int		addr) ;
 
 extern int	VpdSetupPara(
 	SK_AC		*pAC,
 	char		*key,
 	char		*buf,
-	int			len,
-	int			type,
-	int			op);
+	int		len,
+	int		type,
+	int		op) ;
 
 extern SK_VPD_STATUS	*VpdStat(
 	SK_AC		*pAC,
-	SK_IOC		IoC);
+	SK_IOC		IoC) ;
 
 extern int	VpdKeys(
 	SK_AC		*pAC,
 	SK_IOC		IoC,
 	char		*buf,
-	int			*len,
-	int			*elements);
+	int		*len,
+	int		*elements) ;
 
 extern int	VpdRead(
 	SK_AC		*pAC,
 	SK_IOC		IoC,
 	char		*key,
 	char		*buf,
-	int			*len);
+	int		*len) ;
 
 extern	SK_BOOL	VpdMayWrite(
-	char		*key);
+	char		*key) ;
 
 extern int	VpdWrite(
 	SK_AC		*pAC,
 	SK_IOC		IoC,
 	char		*key,
-	char		*buf);
+	char		*buf) ;
 
 extern int	VpdDelete(
 	SK_AC		*pAC,
 	SK_IOC		IoC,
-	char		*key);
+	char		*key) ;
 
 extern int	VpdUpdate(
 	SK_AC		*pAC,
@@ -275,34 +265,34 @@
 extern void	VpdErrLog(
 	SK_AC		*pAC,
 	SK_IOC		IoC,
-	char		*msg);
+	char		*msg) ;
 
 #ifdef	SKDIAG
 extern int	VpdReadBlock(
 	SK_AC		*pAC,
 	SK_IOC		IoC,
 	char		*buf,
-	int			addr,
-	int			len);
+	int		addr,
+	int		len) ;
 
 extern int	VpdWriteBlock(
 	SK_AC		*pAC,
 	SK_IOC		IoC,
 	char		*buf,
-	int			addr,
-	int			len);
+	int		addr,
+	int		len) ;
 #endif	/* SKDIAG */
 #else	/* SK_KR_PROTO */
-extern SK_U32	VpdReadDWord();
-extern int	VpdSetupPara();
-extern SK_VPD_STATUS	*VpdStat();
-extern int	VpdKeys();
-extern int	VpdRead();
-extern SK_BOOL	VpdMayWrite();
-extern int	VpdWrite();
-extern int	VpdDelete();
-extern int	VpdUpdate();
-extern void	VpdErrLog();
+extern SK_U32	VpdReadDWord() ;
+extern int	VpdSetupPara() ;
+extern SK_VPD_STATUS	*VpdStat() ;
+extern int	VpdKeys() ;
+extern int	VpdRead() ;
+extern SK_BOOL	VpdMayWrite() ;
+extern int	VpdWrite() ;
+extern int	VpdDelete() ;
+extern int	VpdUpdate() ;
+extern void	VpdErrLog() ;
 #endif	/* SK_KR_PROTO */
 
 #endif	/* __INC_SKVPD_H_ */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/h/xmac_ii.h linux/drivers/net/sk98lin/h/xmac_ii.h
--- v2.4.6/linux/drivers/net/sk98lin/h/xmac_ii.h	Tue Mar 20 12:04:59 2001
+++ linux/drivers/net/sk98lin/h/xmac_ii.h	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	xmac_ii.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.27 $
- * Date:	$Date: 2000/05/17 11:00:46 $
+ * Version:	$Revision: 1.28 $
+ * Date:	$Date: 2000/11/09 12:32:49 $
  * Purpose:	Defines and Macros for XaQti's Gigabit Ethernet Controller
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2000 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,6 +26,9 @@
  * History:
  *
  *	$Log: xmac_ii.h,v $
+ *	Revision 1.28  2000/11/09 12:32:49  rassmann
+ *	Renamed variables.
+ *	
  *	Revision 1.27  2000/05/17 11:00:46  malthoff
  *	Add bit for enable/disable power management in BCOM chip.
  *	
@@ -145,40 +147,40 @@
  * Note:	NA reg	= Network Address e.g DA, SA etc.
  *
  */
-#define XM_MMU_CMD	0x0000	/* 16 bit r/w	MMU Command Register */
+#define XM_MMU_CMD	0x0000		/* 16 bit r/w	MMU Command Register */
 	/* 0x0004:		reserved */
-#define XM_POFF		0x0008	/* 32 bit r/w	Packet Offset Register */
-#define XM_BURST	0x000c	/* 32 bit r/w	Burst Register for half duplex*/
+#define XM_POFF		0x0008		/* 32 bit r/w	Packet Offset Register */
+#define XM_BURST	0x000c		/* 32 bit r/w	Burst Register for half duplex*/
 #define XM_1L_VLAN_TAG	0x0010	/* 16 bit r/w	One Level VLAN Tag ID */
 #define XM_2L_VLAN_TAG	0x0014	/* 16 bit r/w	Two Level VLAN Tag ID */
 	/* 0x0018 - 0x001e:	reserved */
-#define XM_TX_CMD	0x0020	/* 16 bit r/w	Transmit Command Register */
+#define XM_TX_CMD	0x0020		/* 16 bit r/w	Transmit Command Register */
 #define	XM_TX_RT_LIM	0x0024	/* 16 bit r/w	Transmit Retry Limit Register */
-#define XM_TX_STIME	0x0028	/* 16 bit r/w	Transmit Slottime Register */
-#define XM_TX_IPG	0x002c	/* 16 bit r/w	Transmit Inter Packet Gap */
-#define XM_RX_CMD	0x0030	/* 16 bit r/w	Receive Command Register */
-#define XM_PHY_ADDR	0x0034	/* 16 bit r/w	PHY Address Register */
-#define	XM_PHY_DATA	0x0038	/* 16 bit r/w	PHY Data Register */
+#define XM_TX_STIME	0x0028		/* 16 bit r/w	Transmit Slottime Register */
+#define XM_TX_IPG	0x002c		/* 16 bit r/w	Transmit Inter Packet Gap */
+#define XM_RX_CMD	0x0030		/* 16 bit r/w	Receive Command Register */
+#define XM_PHY_ADDR	0x0034		/* 16 bit r/w	PHY Address Register */
+#define	XM_PHY_DATA	0x0038		/* 16 bit r/w	PHY Data Register */
 	/* 0x003c: 		reserved */
-#define XM_GP_PORT	0x0040	/* 32 bit r/w	General Purpose Port Register */
-#define XM_IMSK		0x0044	/* 16 bit r/w	Interrupt Mask Register */
-#define XM_ISRC		0x0048	/* 16 bit ro	Interrupt Status Register */
-#define XM_HW_CFG	0x004c	/* 16 bit r/w	Hardware Config Register */
+#define XM_GP_PORT	0x0040		/* 32 bit r/w	General Purpose Port Register */
+#define XM_IMSK		0x0044		/* 16 bit r/w	Interrupt Mask Register */
+#define XM_ISRC		0x0048		/* 16 bit ro	Interrupt Status Register */
+#define XM_HW_CFG	0x004c		/* 16 bit r/w	Hardware Config Register */
 	/* 0x0050 - 0x005e:	reserved */
-#define XM_TX_LO_WM	0x0060	/* 16 bit r/w	Tx FIFO Low Water Mark */
-#define XM_TX_HI_WM	0x0062	/* 16 bit r/w	Tx FIFO High Water Mark */
-#define XM_TX_THR	0x0064	/* 16 bit r/w	Tx Request Threshold */
-#define	XM_HT_THR	0x0066	/* 16 bit r/w	Host Request Threshold */
-#define	XM_PAUSE_DA	0x0068	/* NA reg r/w	Pause Destination Address */
+#define XM_TX_LO_WM	0x0060		/* 16 bit r/w	Tx FIFO Low Water Mark */
+#define XM_TX_HI_WM	0x0062		/* 16 bit r/w	Tx FIFO High Water Mark */
+#define XM_TX_THR	0x0064		/* 16 bit r/w	Tx Request Threshold */
+#define	XM_HT_THR	0x0066		/* 16 bit r/w	Host Request Threshold */
+#define	XM_PAUSE_DA	0x0068		/* NA reg r/w	Pause Destination Address */
 	/* 0x006e: 		reserved */
-#define XM_CTL_PARA	0x0070	/* 32 bit r/w	Control Parameter Register */
+#define XM_CTL_PARA	0x0070		/* 32 bit r/w	Control Parameter Register */
 #define XM_MAC_OPCODE	0x0074	/* 16 bit r/w	Opcode for MAC control frames */
 #define XM_MAC_PTIME	0x0076	/* 16 bit r/w	Pause time for MAC ctrl frames*/
-#define XM_TX_STAT	0x0078	/* 32 bit ro	Tx Status LIFO Register */
+#define XM_TX_STAT	0x0078		/* 32 bit ro	Tx Status LIFO Register */
 
 	/* 0x0080 - 0x00fc:	16 NA reg r/w	Exakt Match Address Registers */
 	/* 				use the XM_EMX() macro to address */
-#define XM_EXM_START	0x0080		/* r/w	Start Address of the EXM Regs */
+#define XM_EXM_START	0x0080	/* r/w	Start Address of the EXM Regs */
 
 	/*
 	 * XM_EXM(Reg)
@@ -191,18 +193,18 @@
 	 */
 #define XM_EXM(Reg)	(XM_EXM_START + ((Reg) << 3))
 
-#define XM_SRC_CHK	0x0100	/* NA reg r/w	Source Check Address Register */
-#define XM_SA		0x0108	/* NA reg r/w	Station Address Register */
-#define XM_HSM		0x0110	/* 64 bit r/w	Hash Match Address Registers */
-#define XM_RX_LO_WM	0x0118	/* 16 bit r/w	Receive Low Water Mark */
-#define XM_RX_HI_WM	0x011a	/* 16 bit r/w	Receive High Water Mark */
-#define XM_RX_THR	0x011c	/* 32 bit r/w	Receive Request Threshold */
-#define XM_DEV_ID	0x0120	/* 32 bit ro	Device ID Register */
-#define XM_MODE		0x0124	/* 32 bit r/w	Mode Register */
-#define XM_LSA		0x0128	/* NA reg ro	Last Source Register */
+#define XM_SRC_CHK		0x0100	/* NA reg r/w	Source Check Address Register */
+#define XM_SA			0x0108	/* NA reg r/w	Station Address Register */
+#define XM_HSM			0x0110	/* 64 bit r/w	Hash Match Address Registers */
+#define XM_RX_LO_WM		0x0118	/* 16 bit r/w	Receive Low Water Mark */
+#define XM_RX_HI_WM		0x011a	/* 16 bit r/w	Receive High Water Mark */
+#define XM_RX_THR		0x011c	/* 32 bit r/w	Receive Request Threshold */
+#define XM_DEV_ID		0x0120	/* 32 bit ro	Device ID Register */
+#define XM_MODE			0x0124	/* 32 bit r/w	Mode Register */
+#define XM_LSA			0x0128	/* NA reg ro	Last Source Register */
 	/* 0x012e:		reserved */
-#define XM_TS_READ	0x0130	/* 32 bit ro	TimeStamp Read Regeister */
-#define XM_TS_LOAD	0x0134	/* 32 bit ro	TimeStamp Load Value */
+#define XM_TS_READ		0x0130	/* 32 bit ro	TimeStamp Read Regeister */
+#define XM_TS_LOAD		0x0134	/* 32 bit ro	TimeStamp Load Value */
 	/* 0x0138 - 0x01fe:	reserved */
 #define XM_STAT_CMD	0x0200	/* 16 bit r/w	Statistics Command Register */
 #define	XM_RX_CNT_EV	0x0204	/* 32 bit ro	Rx Counter Event Register */
@@ -210,13 +212,13 @@
 #define XM_RX_EV_MSK	0x020c	/* 32 bit r/w	Rx Counter Event Mask */
 #define XM_TX_EV_MSK	0x0210	/* 32 bit r/w	Tx Counter Event Mask */
 	/* 0x0204 - 0x027e:	reserved */
-#define XM_TXF_OK	0x0280	/* 32 bit ro	Frames Transmitted OK Conuter */
+#define XM_TXF_OK		0x0280	/* 32 bit ro	Frames Transmitted OK Conuter */
 #define XM_TXO_OK_HI	0x0284	/* 32 bit ro	Octets Transmitted OK High Cnt*/
 #define XM_TXO_OK_LO	0x0288	/* 32 bit ro	Octets Transmitted OK Low Cnt */
 #define XM_TXF_BC_OK	0x028c	/* 32 bit ro	Broadcast Frames Xmitted OK */
 #define XM_TXF_MC_OK	0x0290	/* 32 bit ro	Multicast Frames Xmitted OK */
 #define XM_TXF_UC_OK	0x0294	/* 32 bit ro	Unicast Frames Xmitted OK */
-#define XM_TXF_LONG	0x0298	/* 32 bit ro	Tx Long Frame Counter */
+#define XM_TXF_LONG		0x0298	/* 32 bit ro	Tx Long Frame Counter */
 #define XM_TXE_BURST	0x029c	/* 32 bit ro	Tx Burst Event Counter */
 #define XM_TXF_MPAUSE	0x02a0	/* 32 bit ro	Tx Pause MAC Ctrl Frame Cnt */
 #define XM_TXF_MCTRL	0x02a4	/* 32 bit ro	Tx MAC Ctrl Frame Counter */
@@ -224,20 +226,20 @@
 #define XM_TXF_MUL_COL	0x02ac	/* 32 bit ro	Tx Multiple Collision Counter */
 #define XM_TXF_ABO_COL	0x02b0	/* 32 bit ro	Tx aborted due to Exessive Col*/
 #define XM_TXF_LAT_COL	0x02b4	/* 32 bit ro	Tx Late Collision Counter */
-#define XM_TXF_DEF	0x02b8	/* 32 bit ro	Tx Deferred Frame Counter */
+#define XM_TXF_DEF		0x02b8	/* 32 bit ro	Tx Deferred Frame Counter */
 #define XM_TXF_EX_DEF	0x02bc	/* 32 bit ro	Tx Excessive Deferall Counter */
 #define XM_TXE_FIFO_UR	0x02c0	/* 32 bit ro	Tx FIFO Underrun Event Cnt */
 #define XM_TXE_CS_ERR	0x02c4	/* 32 bit ro	Tx Carrier Sence Error Cnt */
-#define XM_TXP_UTIL	0x02c8	/* 32 bit ro	Tx Utilization in % */
+#define XM_TXP_UTIL		0x02c8	/* 32 bit ro	Tx Utilization in % */
 	/* 0x02cc - 0x02ce:	reserved */
-#define XM_TXF_64B	0x02d0	/* 32 bit ro	64 Byte Tx Frame Counter */
-#define XM_TXF_127B	0x02d4	/* 32 bit ro	65-127 Byte Tx Frame Counter */
-#define XM_TXF_255B	0x02d8	/* 32 bit ro	128-255 Byte Tx Frame Counter */
-#define XM_TXF_511B	0x02dc	/* 32 bit ro	256-511 Byte Tx Frame Counter */
+#define XM_TXF_64B		0x02d0	/* 32 bit ro	64 Byte Tx Frame Counter */
+#define XM_TXF_127B		0x02d4	/* 32 bit ro	65-127 Byte Tx Frame Counter */
+#define XM_TXF_255B		0x02d8	/* 32 bit ro	128-255 Byte Tx Frame Counter */
+#define XM_TXF_511B		0x02dc	/* 32 bit ro	256-511 Byte Tx Frame Counter */
 #define XM_TXF_1023B	0x02e0	/* 32 bit ro	512-1023 Byte Tx Frame Counter*/
 #define XM_TXF_MAX_SZ	0x02e4	/* 32 bit ro	1024-MaxSize Byte Tx Frame Cnt*/
 	/* 0x02e8 - 0x02fe:	reserved */
-#define XM_RXF_OK	0x0300	/* 32 bit ro	Frames Received OK */
+#define XM_RXF_OK		0x0300	/* 32 bit ro	Frames Received OK */
 #define XM_RXO_OK_HI	0x0304	/* 32 bit ro	Octets Received OK High Cnt */
 #define XM_RXO_OK_LO	0x0308	/* 32 bit ro	Octets Received OK Low Counter*/
 #define XM_RXF_BC_OK	0x030c	/* 32 bit ro	Broadcast Frames Received OK */
@@ -256,17 +258,17 @@
 #define XM_RXF_LEN_ERR	0x0340	/* 32 bit ro	Rx in Range Length Error */
 #define XM_RXE_SYM_ERR	0x0344	/* 32 bit ro	Rx Symbol Error Counter */
 #define XM_RXE_SHT_ERR	0x0348	/* 32 bit ro	Rx Short Event Error Cnt */
-#define XM_RXE_RUNT	0x034c	/* 32 bit ro	Rx Runt Event Counter */
+#define XM_RXE_RUNT		0x034c	/* 32 bit ro	Rx Runt Event Counter */
 #define XM_RXF_LNG_ERR	0x0350	/* 32 bit ro	Rx Frame too Long Error Cnt */
 #define XM_RXF_FCS_ERR	0x0354	/* 32 bit ro	Rx Frame Check Seq. Error Cnt */
 	/* 0x0358 - 0x035a:	reserved */
 #define XM_RXF_CEX_ERR	0x035c	/* 32 bit ro	Rx Carrier Ext Error Frame Cnt*/
-#define XM_RXP_UTIL	0x0360	/* 32 bit ro	Rx Utilization in % */
+#define XM_RXP_UTIL		0x0360	/* 32 bit ro	Rx Utilization in % */
 	/* 0x0364 - 0x0366:	reserved */
-#define XM_RXF_64B	0x0368	/* 32 bit ro	64 Byte Rx Frame Counter */
-#define XM_RXF_127B	0x036c	/* 32 bit ro	65-127 Byte Rx Frame Counter */
-#define XM_RXF_255B	0x0370	/* 32 bit ro	128-255 Byte Rx Frame Counter */
-#define XM_RXF_511B	0x0374	/* 32 bit ro	256-511 Byte Rx Frame Counter */
+#define XM_RXF_64B		0x0368	/* 32 bit ro	64 Byte Rx Frame Counter */
+#define XM_RXF_127B		0x036c	/* 32 bit ro	65-127 Byte Rx Frame Counter */
+#define XM_RXF_255B		0x0370	/* 32 bit ro	128-255 Byte Rx Frame Counter */
+#define XM_RXF_511B		0x0374	/* 32 bit ro	256-511 Byte Rx Frame Counter */
 #define XM_RXF_1023B	0x0378	/* 32 bit ro	512-1023 Byte Rx Frame Counter*/
 #define XM_RXF_MAX_SZ	0x037c	/* 32 bit ro	1024-MaxSize Byte Rx Frame Cnt*/
 	/* 0x02e8 - 0x02fe:	reserved */
@@ -277,19 +279,19 @@
  * XMAC Bit Definitions
  *
  * If the bit access behaviour differs from the register access behaviour
- * (r/w, ro) this is documented after the bit number. The following bit
+ * (r/w, ro) this is docomented after the bit number. The following bit
  * access behaviours are used:
  *	(sc)	self clearing
  *	(ro)	read only
  */
 
 /*	XM_MMU_CMD	16 bit r/w	MMU Comamnd Register */
-				/* Bit 15..13:	reserved */
+								/* Bit 15..13:	reserved */
 #define XM_MMU_PHY_RDY	(1<<12)	/* Bit 12:	PHY Read Ready */
 #define XM_MMU_PHY_BUSY	(1<<11)	/* Bit 11:	PHY Busy */
 #define XM_MMU_IGN_PF	(1<<10)	/* Bit 10:	Ignore Pause Frame */
 #define XM_MMU_MAC_LB	(1<<9)	/* Bit	9:	Enable MAC Loopback */
-				/* Bit	8:	reserved */
+								/* Bit	8:	reserved */
 #define XM_MMU_FRC_COL	(1<<7)	/* Bit	7:	Force Collision */
 #define XM_MMU_SIM_COL	(1<<6)	/* Bit	6:	Simulate Collision */
 #define XM_MMU_NO_PRE	(1<<5)	/* Bit	5:	No MDIO Preamble */
@@ -301,8 +303,8 @@
 
 
 /*	XM_TX_CMD	16 bit r/w	Transmit Command Register */
-				/* Bit 15..7:	reserved */
-#define XM_TX_BK2BK	(1<<6)	/* Bit	6:	Ignor Carrier Sense (tx Bk2Bk)*/
+								/* Bit 15..7:	reserved */
+#define XM_TX_BK2BK		(1<<6)	/* Bit	6:	Ignor Carrier Sense (tx Bk2Bk)*/
 #define XM_TX_ENC_BYP	(1<<5)	/* Bit	5:	Set Encoder in Bypass Mode */
 #define XM_TX_SAM_LINE	(1<<4)	/* Bit	4: (sc)	Start utilization calculation */
 #define XM_TX_NO_GIG_MD	(1<<3)	/* Bit	3:	Disable Carrier Extension */
@@ -312,28 +314,28 @@
 
 
 /*	XM_TX_RT_LIM	16 bit r/w	Transmit Retry Limit Register */
-				/* Bit 15..5:	reserved */
+								/* Bit 15..5:	reserved */
 #define	XM_RT_LIM_MSK	0x1f	/* Bit	4..0:	Tx Retry Limit */
 
 
 /*	XM_TX_STIME	16 bit r/w	Transmit Slottime Register */
-				/* Bit 15..7:	reserved */
+								/* Bit 15..7:	reserved */
 #define XM_STIME_MSK	0x7f	/* Bit	6..0:	Tx Slottime bits */
 
 
 /*	XM_TX_IPG	16 bit r/w	Transmit Inter Packet Gap */
-				/* Bit 15..8:	reserved */
-#define XM_IPG_MSK	0xff	/* Bit	7..0:	IPG value bits */
+								/* Bit 15..8:	reserved */
+#define XM_IPG_MSK		0xff	/* Bit	7..0:	IPG value bits */
 
 
 /*	XM_RX_CMD	16 bit r/w	Receive Command Register */
-				/* Bit 15..9:	reserved */
+								/* Bit 15..9:	reserved */
 #define XM_RX_LENERR_OK (1<<8)	/* Bit	8	don't set Rx Err bit for */
-				/*		inrange error packets */
+								/*		inrange error packets */
 #define XM_RX_BIG_PK_OK	(1<<7)	/* Bit	7	don't set Rx Err bit for */
-				/*		jumbo packets */
+								/*		jumbo packets */
 #define XM_RX_IPG_CAP	(1<<6)	/* Bit	6	repl. type field with IPG */
-#define XM_RX_TP_MD	(1<<5)	/* Bit	5:	Enable transparent Mode */
+#define XM_RX_TP_MD		(1<<5)	/* Bit	5:	Enable transparent Mode */
 #define XM_RX_STRIP_FCS	(1<<4)	/* Bit	4:	Enable FCS Stripping */
 #define XM_RX_SELF_RX	(1<<3)	/* Bit	3: 	Enable Rx of own packets */
 #define XM_RX_SAM_LINE	(1<<2)	/* Bit	2: (sc)	Start utilization calculation */
@@ -342,24 +344,24 @@
 
 
 /*	XM_PHY_ADDR	16 bit r/w	PHY Address Register */
-				/* Bit 15..5:	reserved */
+								/* Bit 15..5:	reserved */
 #define	XM_PHY_ADDR_SZ	0x1f	/* Bit	4..0:	PHY Address bits */
 
 
 /*	XM_GP_PORT	32 bit r/w	General Purpose Port Register */
-				/* Bit 31..7:	reserved */
-#define	XM_GP_ANIP	(1L<<6)	/* Bit	6: (ro)	Auto Negotiation in Progress */
+								/* Bit 31..7:	reserved */
+#define	XM_GP_ANIP		(1L<<6)	/* Bit	6: (ro)	Auto Negotiation in Progress */
 #define XM_GP_FRC_INT	(1L<<5)	/* Bit	5: (sc)	Force Interrupt */
-				/* Bit	4:	reserved */
+								/* Bit	4:	reserved */
 #define XM_GP_RES_MAC	(1L<<3)	/* Bit	3: (sc)	Reset MAC and FIFOs */
 #define XM_GP_RES_STAT	(1L<<2)	/* Bit	2: (sc)	Reset the statistics module */
-				/* Bit	1:	reserved */
+								/* Bit	1:	reserved */
 #define XM_GP_INP_ASS	(1L<<0)	/* Bit	0: (ro) GP Input Pin asserted */
 
 
 /*	XM_IMSK		16 bit r/w	Interrupt Mask Register */
 /*	XM_ISRC		16 bit ro	Interrupt Status Register */
-				/* Bit 15:	reserved */
+								/* Bit 15:	reserved */
 #define XM_IS_LNK_AE	(1<<14) /* Bit 14:	Link Asynchronous Event */
 #define XM_IS_TX_ABORT	(1<<13) /* Bit 13:	Transmit Abort, late Col. etc */
 #define XM_IS_FRC_INT	(1<<12) /* Bit 12:	Force INT bit set in GP */
@@ -367,7 +369,7 @@
 #define XM_IS_LIPA_RC	(1<<10)	/* Bit 10:	Link Partner requests config */
 #define XM_IS_RX_PAGE	(1<<9)	/* Bit	9:	Page Received */
 #define XM_IS_TX_PAGE	(1<<8)	/* Bit	8:	Next Page Loaded for Transmit */
-#define XM_IS_AND	(1<<7)	/* Bit	7:	Auto Negotiation Done */
+#define XM_IS_AND		(1<<7)	/* Bit	7:	Auto Negotiation Done */
 #define XM_IS_TSC_OV	(1<<6)	/* Bit	6:	Time Stamp Counter Overflow */
 #define XM_IS_RXC_OV	(1<<5)	/* Bit	5:	Rx Counter Event Overflow */
 #define XM_IS_TXC_OV	(1<<4)	/* Bit	4:	Tx Counter Event Overflow */
@@ -377,42 +379,41 @@
 #define XM_IS_RX_COMP	(1<<0)	/* Bit	0:	Frame Rx Complete */
 
 #define XM_DEF_MSK	(~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE |\
-			XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV |\
-			XM_IS_TXF_UR))
+			XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_TXF_UR))
 
 
 /*	XM_HW_CFG	16 bit r/w	Hardware Config Register */
-				/* Bit 15.. 4:	reserved */
+								/* Bit 15.. 4:	reserved */
 #define	XM_HW_GEN_EOP	(1<<3)	/* Bit	3:	generate End of Packet pulse */
 #define XM_HW_COM4SIG	(1<<2)	/* Bit	2:	use Comma Detect for Sig. Det.*/
-				/* Bit	1:	reserved */
+								/* Bit	1:	reserved */
 #define XM_HW_GMII_MD	(1<<0)	/* Bit	0:	GMII Interface selected */
 
 
 /*	XM_TX_LO_WM	16 bit r/w	Tx FIFO Low Water Mark */
 /*	XM_TX_HI_WM	16 bit r/w	Tx FIFO High Water Mark */
-				/* Bit 15..10	reserved */
+								/* Bit 15..10	reserved */
 #define	XM_TX_WM_MSK	0x01ff	/* Bit	9.. 0	Tx FIFO Watermark bits */
 
 /*	XM_TX_THR	16 bit r/w	Tx Request Threshold */
 /*	XM_HT_THR	16 bit r/w	Host Request Threshold */
 /*	XM_RX_THR	16 bit r/w	Receive Request Threshold */
-				/* Bit 15..11	reserved */
-#define	XM_THR_MSK	0x03ff	/* Bit 10.. 0	Tx FIFO Watermark bits */
+								/* Bit 15..11	reserved */
+#define	XM_THR_MSK		0x03ff	/* Bit 10.. 0	Tx FIFO Watermark bits */
 
 
 /*	XM_TX_STAT	32 bit ro	Tx Status LIFO Register */
-#define XM_ST_VALID	(1UL<<31)	/* Bit 31:	Status Valid */
+#define XM_ST_VALID		(1UL<<31)	/* Bit 31:	Status Valid */
 #define XM_ST_BYTE_CNT	(0x3fffL<<17)	/* Bit 30..17:	Tx frame Length */
 #define XM_ST_RETRY_CNT	(0x1fL<<12)	/* Bit 16..12:	Retry Count */
 #define XM_ST_EX_COL	(1L<<11)	/* Bit 11:	Excessive Collisions */
 #define XM_ST_EX_DEF	(1L<<10)	/* Bit 10:	Excessive Deferral */
-#define XM_ST_BURST	(1L<<9)		/* Bit	9:	p. xmitted in burst md*/
-#define XM_ST_DEFER	(1L<<8)		/* Bit	8:	packet was defered */
-#define XM_ST_BC	(1L<<7)		/* Bit	7:	Broadcast packet */
-#define XM_ST_MC	(1L<<6)		/* Bit	6:	Multicast packet */
-#define XM_ST_UC	(1L<<5)		/* Bit	5:	Unicast packet */
-#define XM_ST_TX_UR	(1L<<4)		/* Bit	4:	FIFO Underrun occurred */
+#define XM_ST_BURST		(1L<<9)		/* Bit	9:	p. xmitted in burst md*/
+#define XM_ST_DEFER		(1L<<8)		/* Bit	8:	packet was defered */
+#define XM_ST_BC		(1L<<7)		/* Bit	7:	Broadcast packet */
+#define XM_ST_MC		(1L<<6)		/* Bit	6:	Multicast packet */
+#define XM_ST_UC		(1L<<5)		/* Bit	5:	Unicast packet */
+#define XM_ST_TX_UR		(1L<<4)		/* Bit	4:	FIFO Underrun occured */
 #define XM_ST_CS_ERR	(1L<<3)		/* Bit	3:	Carrier Sense Error */
 #define XM_ST_LAT_COL	(1L<<2)		/* Bit	2:	Late Collision Error */
 #define XM_ST_MUL_COL	(1L<<1)		/* Bit	1:	Multiple Collisions */
@@ -420,8 +421,8 @@
 
 /*	XM_RX_LO_WM	16 bit r/w	Receive Low Water Mark */
 /*	XM_RX_HI_WM	16 bit r/w	Receive High Water Mark */
-				/* Bit 15..11:	reserved */
-#define	XM_RX_WM_MSK	0x03ff	/* Bit 11.. 0:	Rx FIFO Watermark bits */
+									/* Bit 15..11:	reserved */
+#define	XM_RX_WM_MSK	0x03ff		/* Bit 11.. 0:	Rx FIFO Watermark bits */
 
 
 /*	XM_DEV_ID	32 bit ro	Device ID Register */
@@ -430,25 +431,25 @@
 
 
 /*	XM_MODE		32 bit r/w	Mode Register */
-					/* Bit 31..27:	reserved */
+									/* Bit 31..27:	reserved */
 #define XM_MD_ENA_REJ	(1L<<26)	/* Bit 26:	Enable Frame Reject */
 #define XM_MD_SPOE_E	(1L<<25)	/* Bit 25:	Send Pause on Edge */
-					/* 		extern generated */
+									/* 		extern generated */
 #define XM_MD_TX_REP	(1L<<24)	/* Bit 24:	Transmit Repeater Mode*/
 #define XM_MD_SPOFF_I	(1L<<23)	/* Bit 23:	Send Pause on FIFOfull*/
-					/*		intern generated */
+									/*		intern generated */
 #define XM_MD_LE_STW	(1L<<22)	/* Bit 22:	Rx Stat Word in Lit En*/
 #define XM_MD_TX_CONT	(1L<<21)	/* Bit 21:	Send Continuous */
 #define XM_MD_TX_PAUSE	(1L<<20)	/* Bit 20: (sc)	Send Pause Frame */
-#define XM_MD_ATS	(1L<<19)	/* Bit 19:	Append Time Stamp */
+#define XM_MD_ATS		(1L<<19)	/* Bit 19:	Append Time Stamp */
 #define XM_MD_SPOL_I	(1L<<18)	/* Bit 18:	Send Pause on Low */
-					/*		intern generated */
+									/*		intern generated */
 #define XM_MD_SPOH_I	(1L<<17)	/* Bit 17:	Send Pause on High */
-					/*		intern generated */
-#define XM_MD_CAP	(1L<<16)	/* Bit 16:	Check Address Pair */
+									/*		intern generated */
+#define XM_MD_CAP		(1L<<16)	/* Bit 16:	Check Address Pair */
 #define XM_MD_ENA_HSH	(1L<<15)	/* Bit 15:	Enable Hashing */
-#define XM_MD_CSA	(1L<<14)	/* Bit 14:	Check Station Address */
-#define XM_MD_CAA	(1L<<13)	/* Bit 13:	Check Address Array */
+#define XM_MD_CSA		(1L<<14)	/* Bit 14:	Check Station Address */
+#define XM_MD_CAA		(1L<<13)	/* Bit 13:	Check Address Array */
 #define XM_MD_RX_MCTRL	(1L<<12)	/* Bit 12:	Rx MAC Control Frames */
 #define XM_MD_RX_RUNT	(1L<<11)	/* Bit 11:	Rx Runt Frames */
 #define XM_MD_RX_IRLE	(1L<<10)	/* Bit 10:	Rx in Range Len Err F */
@@ -460,16 +461,15 @@
 #define XM_MD_DIS_BC	(1L<<4)		/* Bit	4:	Disable Rx Boradcast */
 #define XM_MD_ENA_PROM	(1L<<3)		/* Bit	3:	Enable Promiscuous */
 #define XM_MD_ENA_BE	(1L<<2)		/* Bit	2:	Enable Big Endian */
-#define XM_MD_FTF	(1L<<1)		/* Bit	1: (sc)	Flush Tx FIFO */
-#define XM_MD_FRF	(1L<<0)		/* Bit	0: (sc)	Flush Rx FIFO */
+#define XM_MD_FTF		(1L<<1)		/* Bit	1: (sc)	Flush Tx FIFO */
+#define XM_MD_FRF		(1L<<0)		/* Bit	0: (sc)	Flush Rx FIFO */
 
 #define	XM_PAUSE_MODE	(XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
 #define XM_DEF_MODE	(XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
-			 XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA |\
-			 XM_MD_CAA)
+			 XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA)
 
 /*	XM_STAT_CMD	16 bit r/w	Statistics Command Register */
-				/* Bit 16..6:	reserved */
+								/* Bit 16..6:	reserved */
 #define XM_SC_SNP_RXC	(1<<5)	/* Bit	5: (sc)	Snap Rx Counters */
 #define XM_SC_SNP_TXC	(1<<4)	/* Bit	4: (sc)	Snap Tx Counters */
 #define XM_SC_CP_RXC	(1<<3)	/* Bit	3: 	Copy Rx Counters Continuously */
@@ -482,28 +482,28 @@
 /*	XM_RX_EV_MSK	32 bit r/w	Rx Counter Event Mask */
 #define	XMR_MAX_SZ_OV	(1UL<<31)	/* Bit 31:	1024-MaxSize Rx Cnt Ov*/
 #define XMR_1023B_OV	(1L<<30)	/* Bit 30:	512-1023Byte Rx Cnt Ov*/
-#define XMR_511B_OV	(1L<<29)	/* Bit 29:	256-511 Byte Rx Cnt Ov*/
-#define XMR_255B_OV	(1L<<28)	/* Bit 28:	128-255 Byte Rx Cnt Ov*/
-#define XMR_127B_OV	(1L<<27)	/* Bit 27:	65-127 Byte Rx Cnt Ov */
-#define XMR_64B_OV	(1L<<26)	/* Bit 26:	64 Byte Rx Cnt Ov */
-#define XMR_UTIL_OV	(1L<<25)	/* Bit 25:	Rx Util Cnt Overflow */
-#define XMR_UTIL_UR	(1L<<24)	/* Bit 24:	Rx Util Cnt Underrun */
+#define XMR_511B_OV		(1L<<29)	/* Bit 29:	256-511 Byte Rx Cnt Ov*/
+#define XMR_255B_OV		(1L<<28)	/* Bit 28:	128-255 Byte Rx Cnt Ov*/
+#define XMR_127B_OV		(1L<<27)	/* Bit 27:	65-127 Byte Rx Cnt Ov */
+#define XMR_64B_OV		(1L<<26)	/* Bit 26:	64 Byte Rx Cnt Ov */
+#define XMR_UTIL_OV		(1L<<25)	/* Bit 25:	Rx Util Cnt Overflow */
+#define XMR_UTIL_UR		(1L<<24)	/* Bit 24:	Rx Util Cnt Underrun */
 #define XMR_CEX_ERR_OV	(1L<<23)	/* Bit 23:	CEXT Err Cnt Ov */
-					/* Bit 22:	reserved */
+									/* Bit 22:	reserved */
 #define XMR_FCS_ERR_OV	(1L<<21)	/* Bit 21:	Rx FCS Error Cnt Ov */
 #define XMR_LNG_ERR_OV	(1L<<20)	/* Bit 20:	Rx too Long Err Cnt Ov*/
-#define XMR_RUNT_OV	(1L<<19)	/* Bit 19:	Runt Event Cnt Ov */
+#define XMR_RUNT_OV		(1L<<19)	/* Bit 19:	Runt Event Cnt Ov */
 #define XMR_SHT_ERR_OV	(1L<<18)	/* Bit 18:	Rx Short Ev Err Cnt Ov*/
 #define XMR_SYM_ERR_OV	(1L<<17)	/* Bit 17:	Rx Sym Err Cnt Ov */
-					/* Bit 16:	reserved */
+									/* Bit 16:	reserved */
 #define XMR_CAR_ERR_OV	(1L<<15)	/* Bit 15:	Rx Carr Ev Err Cnt Ov */
 #define XMR_JAB_PKT_OV	(1L<<14)	/* Bit 14:	Rx Jabb Packet Cnt Ov */
-#define XMR_FIFO_OV	(1L<<13)	/* Bit 13:	Rx FIFO Ov Ev Cnt Ov */
+#define XMR_FIFO_OV		(1L<<13)	/* Bit 13:	Rx FIFO Ov Ev Cnt Ov */
 #define XMR_FRA_ERR_OV	(1L<<12)	/* Bit 12:	Rx Framing Err Cnt Ov */
 #define XMR_FMISS_OV	(1L<<11)	/* Bit 11:	Rx Missed Ev Cnt Ov */
-#define XMR_BURST	(1L<<10)	/* Bit 10:	Rx Burst Event Cnt Ov */
-#define XMR_INV_MOC	(1L<<9)		/* Bit	9:	Rx with inv. MAC OC Ov*/
-#define XMR_INV_MP	(1L<<8)		/* Bit	8:	Rx inv Pause Frame Ov */
+#define XMR_BURST		(1L<<10)	/* Bit 10:	Rx Burst Event Cnt Ov */
+#define XMR_INV_MOC		(1L<<9)		/* Bit	9:	Rx with inv. MAC OC Ov*/
+#define XMR_INV_MP		(1L<<8)		/* Bit	8:	Rx inv Pause Frame Ov */
 #define XMR_MCTRL_OV	(1L<<7)		/* Bit	7:	Rx MAC Ctrl-F Cnt Ov */
 #define XMR_MPAUSE_OV	(1L<<6)		/* Bit	6:	Rx Pause MAC Ctrl-F Ov*/
 #define XMR_UC_OK_OV	(1L<<5)		/* Bit	5:	Rx Unicast Frame CntOv*/
@@ -511,39 +511,39 @@
 #define XMR_BC_OK_OV	(1L<<3)		/* Bit	3:	Rx Broadcast Cnt Ov */
 #define XMR_OK_LO_OV	(1L<<2)		/* Bit	2:	Octets Rx OK Low CntOv*/
 #define XMR_OK_HI_OV	(1L<<1)		/* Bit	1:	Octets Rx OK Hi Cnt Ov*/
-#define XMR_OK_OV	(1L<<0)		/* Bit	0:	Frames Received Ok Ov */
+#define XMR_OK_OV		(1L<<0)		/* Bit	0:	Frames Received Ok Ov */
 
 #define XMR_DEF_MSK	0x00000006L	/* all bits excepting 1 and 2 */
 
 /*	XM_TX_CNT_EV	32 bit ro	Tx Counter Event Register */
 /*	XM_TX_EV_MSK	32 bit r/w	Tx Counter Event Mask */
-					/* Bit 31..26:	reserved */
+									/* Bit 31..26:	reserved */
 #define XMT_MAX_SZ_OV	(1L<<25)	/* Bit 25:	1024-MaxSize Tx Cnt Ov*/
 #define XMT_1023B_OV	(1L<<24)	/* Bit 24:	512-1023Byte Tx Cnt Ov*/
-#define XMT_511B_OV	(1L<<23)	/* Bit 23:	256-511 Byte Tx Cnt Ov*/
-#define XMT_255B_OV	(1L<<22)	/* Bit 22:	128-255 Byte Tx Cnt Ov*/
-#define XMT_127B_OV	(1L<<21)	/* Bit 21:	65-127 Byte Tx Cnt Ov */
-#define XMT_64B_OV	(1L<<20)	/* Bit 20:	64 Byte Tx Cnt Ov */
-#define XMT_UTIL_OV	(1L<<19)	/* Bit 19:	Tx Util Cnt Overflow */
-#define XMT_UTIL_UR	(1L<<18)	/* Bit 18:	Tx Util Cnt Underrun */
+#define XMT_511B_OV		(1L<<23)	/* Bit 23:	256-511 Byte Tx Cnt Ov*/
+#define XMT_255B_OV		(1L<<22)	/* Bit 22:	128-255 Byte Tx Cnt Ov*/
+#define XMT_127B_OV		(1L<<21)	/* Bit 21:	65-127 Byte Tx Cnt Ov */
+#define XMT_64B_OV		(1L<<20)	/* Bit 20:	64 Byte Tx Cnt Ov */
+#define XMT_UTIL_OV		(1L<<19)	/* Bit 19:	Tx Util Cnt Overflow */
+#define XMT_UTIL_UR		(1L<<18)	/* Bit 18:	Tx Util Cnt Underrun */
 #define XMT_CS_ERR_OV	(1L<<17)	/* Bit 17:	Tx Carr Sen Err Cnt Ov*/
 #define XMT_FIFO_UR_OV	(1L<<16)	/* Bit 16:	Tx FIFO Ur Ev Cnt Ov */
 #define XMT_EX_DEF_OV	(1L<<15)	/* Bit 15:	Tx Ex Deferall Cnt Ov */
-#define XMT_DEF		(1L<<14)	/* Bit 14:	Tx Deferred Cnt Ov */
+#define XMT_DEF			(1L<<14)	/* Bit 14:	Tx Deferred Cnt Ov */
 #define XMT_LAT_COL_OV	(1L<<13)	/* Bit 13:	Tx Late Col Cnt Ov */
 #define XMT_ABO_COL_OV	(1L<<12)	/* Bit 12:	Tx abo dueto Ex Col Ov*/
 #define XMT_MUL_COL_OV	(1L<<11)	/* Bit 11:	Tx Mult Col Cnt Ov */
-#define XMT_SNG_COL	(1L<<10)	/* Bit 10:	Tx Single Col Cnt Ov */
+#define XMT_SNG_COL		(1L<<10)	/* Bit 10:	Tx Single Col Cnt Ov */
 #define XMT_MCTRL_OV	(1L<<9)		/* Bit	9:	Tx MAC Ctrl Counter Ov*/
-#define XMT_MPAUSE	(1L<<8)		/* Bit	8:	Tx Pause MAC Ctrl-F Ov*/
-#define XMT_BURST	(1L<<7)		/* Bit	7:	Tx Burst Event Cnt Ov */
-#define XMT_LONG	(1L<<6)		/* Bit	6:	Tx Long Frame Cnt Ov */
+#define XMT_MPAUSE		(1L<<8)		/* Bit	8:	Tx Pause MAC Ctrl-F Ov*/
+#define XMT_BURST		(1L<<7)		/* Bit	7:	Tx Burst Event Cnt Ov */
+#define XMT_LONG		(1L<<6)		/* Bit	6:	Tx Long Frame Cnt Ov */
 #define XMT_UC_OK_OV	(1L<<5)		/* Bit	5:	Tx Unicast Cnt Ov */
 #define XMT_MC_OK_OV	(1L<<4)		/* Bit	4:	Tx Multicast Cnt Ov */
 #define XMT_BC_OK_OV	(1L<<3)		/* Bit	3:	Tx Broadcast Cnt Ov */
 #define XMT_OK_LO_OV	(1L<<2)		/* Bit	2:	Octets Tx OK Low CntOv*/
 #define XMT_OK_HI_OV	(1L<<1)		/* Bit	1:	Octets Tx OK Hi Cnt Ov*/
-#define XMT_OK_OV	(1L<<0)		/* Bit	0:	Frames Tx Ok Ov */
+#define XMT_OK_OV		(1L<<0)		/* Bit	0:	Frames Tx Ok Ov */
 
 #define XMT_DEF_MSK	0x00000006L	/* all bits excepting 1 and 2 */
 
@@ -553,10 +553,10 @@
 #define XMR_FS_LEN	(0x3fffUL<<18)	/* Bit 31..18:	Rx Frame Length */
 #define XMR_FS_2L_VLAN	(1L<<17)	/* Bit 17:	tagged wh 2Lev VLAN ID*/
 #define XMR_FS_1L_VLAN	(1L<<16)	/* Bit 16:	tagged wh 1Lev VLAN ID*/
-#define XMR_FS_BC	(1L<<15)	/* Bit 15:	Broadcast Frame */
-#define XMR_FS_MC	(1L<<14)	/* Bit 14:	Multicast Frame */
-#define XMR_FS_UC	(1L<<13)	/* Bit 13:	Unicast Frame */
-					/* Bit 12:	reserved */
+#define XMR_FS_BC		(1L<<15)	/* Bit 15:	Broadcast Frame */
+#define XMR_FS_MC		(1L<<14)	/* Bit 14:	Multicast Frame */
+#define XMR_FS_UC		(1L<<13)	/* Bit 13:	Unicast Frame */
+									/* Bit 12:	reserved */
 #define XMR_FS_BURST	(1L<<11)	/* Bit 11:	Burst Mode */
 #define XMR_FS_CEX_ERR	(1L<<10)	/* Bit 10:	Carrier Ext. Error */
 #define XMR_FS_802_3	(1L<<9)		/* Bit	9:	802.3 Frame */
@@ -564,10 +564,10 @@
 #define XMR_FS_CAR_ERR	(1L<<7)		/* Bit	7:	Carrier Event Error */
 #define XMR_FS_LEN_ERR	(1L<<6)		/* Bit	6:	In-Range Length Error */
 #define XMR_FS_FRA_ERR	(1L<<5)		/* Bit	5:	Framing Error */
-#define XMR_FS_RUNT	(1L<<4)		/* Bit	4:	Runt Error */
+#define XMR_FS_RUNT		(1L<<4)		/* Bit	4:	Runt Error */
 #define XMR_FS_LNG_ERR	(1L<<3)		/* Bit	3:	Gaint Error */
 #define XMR_FS_FCS_ERR	(1L<<2)		/* Bit	2:	Frame Check Sequ Err */
-#define XMR_FS_ERR	(1L<<1)		/* Bit	1:	Frame Error */
+#define XMR_FS_ERR		(1L<<1)		/* Bit	1:	Frame Error */
 #define XMR_FS_MCTRL	(1L<<0)		/* Bit	0:	MAC Control Packet */
 
 /*
@@ -661,8 +661,8 @@
  */
 #define	PHY_NAT_CTRL		0x00	/* 16 bit r/w	PHY Control Register */
 #define	PHY_NAT_STAT		0x01	/* 16 bit r/w	PHY Status Register */
-#define	PHY_NAT_ID0		0x02	/* 16 bit ro	PHY ID0 Register */
-#define	PHY_NAT_ID1		0x03	/* 16 bit ro	PHY ID1 Register */
+#define	PHY_NAT_ID0			0x02	/* 16 bit ro	PHY ID0 Register */
+#define	PHY_NAT_ID1			0x03	/* 16 bit ro	PHY ID1 Register */
 #define	PHY_NAT_AUNE_ADV	0x04	/* 16 bit r/w	Autonegotiation Advertisement */
 #define	PHY_NAT_AUNE_LP		0x05	/* 16 bit ro	Link Partner Ability Reg */
 #define	PHY_NAT_AUNE_EXP	0x06	/* 16 bit ro	Autonegotiation Expansion Reg */
@@ -695,16 +695,16 @@
 /*****	PHY_BCOM_CTRL	16 bit r/w	PHY Control Register *****/
 /*****	PHY_LONE_CTRL	16 bit r/w	PHY Control Register *****/
 #define	PHY_CT_RESET	(1<<15)	/* Bit 15: (sc)	clear all PHY releated regs */
-#define PHY_CT_LOOP	(1<<14)	/* Bit 14:	enable Loopback over PHY */
+#define PHY_CT_LOOP		(1<<14)	/* Bit 14:	enable Loopback over PHY */
 #define PHY_CT_SPS_LSB	(1<<13) /* Bit 13: (BC,L1) Speed select, lower bit */
-#define PHY_CT_ANE	(1<<12)	/* Bit 12:	Autonegotiation Enabled */
+#define PHY_CT_ANE		(1<<12)	/* Bit 12:	Autonegotiation Enabled */
 #define PHY_CT_PDOWN	(1<<11)	/* Bit 11: (BC,L1) Power Down Mode */
-#define PHY_CT_ISOL	(1<<10)	/* Bit 10: (BC,L1) Isolate Mode */
+#define PHY_CT_ISOL		(1<<10)	/* Bit 10: (BC,L1) Isolate Mode */
 #define PHY_CT_RE_CFG	(1<<9)	/* Bit	9: (sc) Restart Autonegotiation */
 #define PHY_CT_DUP_MD	(1<<8)	/* Bit	8:	Duplex Mode */
 #define PHY_CT_COL_TST	(1<<7)	/* Bit	7: (BC,L1) Collsion Test enabled */
 #define PHY_CT_SPS_MSB	(1<<6)	/* Bit	6: (BC,L1) Speed select, upper bit */
-				/* Bit	5..0:	reserved */
+								/* Bit	5..0:	reserved */
 
 #define PHY_B_CT_SP1000	(1<<6)	/* Bit  6:	enable speed of 1000 MBit/s */
 #define PHY_B_CT_SP100	(1<<13)	/* Bit 13:	enable speed of  100 MBit/s */
@@ -718,10 +718,10 @@
 /*****	PHY_XMAC_STAT	16 bit r/w	PHY Status Register *****/
 /*****	PHY_BCOM_STAT	16 bit r/w	PHY Status Register *****/
 /*****	PHY_LONE_STAT	16 bit r/w	PHY Status Register *****/
-				/* Bit 15..9:	reserved */
+								/* Bit 15..9:	reserved */
 				/*	(BC/L1) 100/10 MBit/s cap bits ignored*/
 #define PHY_ST_EXT_ST	(1<<8)	/* Bit	8:	Extended Status Present */
-				/* Bit	7:	reserved */
+								/* Bit	7:	reserved */
 #define PHY_ST_PRE_SUB	(1<<6)	/* Bit	6: (BC/L1) preamble suppression */
 #define PHY_ST_AN_OVER	(1<<5)	/* Bit	5:	Autonegotiation Over */
 #define PHY_ST_REM_FLT	(1<<4)	/* Bit	4:	Remode Fault Condition Occured*/
@@ -734,9 +734,9 @@
 /*	PHY_XMAC_ID1		16 bit ro	PHY ID1 Register */
 /*	PHY_BCOM_ID1		16 bit ro	PHY ID1 Register */
 /*	PHY_LONE_ID1		16 bit ro	PHY ID1 Register */
-#define	PHY_I1_OUI	(0x3f<<10)	/* Bit 15..10:	Organiz. Unique ID */
+#define	PHY_I1_OUI		(0x3f<<10)	/* Bit 15..10:	Organiz. Unique ID */
 #define PHY_I1_MOD_NUM	(0x3f<<4)	/* Bit	9.. 4:	Model Number */
-#define PHY_I1_REV	(0x0f<<0)	/* Bit	3.. 0:	Revision Number */
+#define PHY_I1_REV		(0x0f<<0)	/* Bit	3.. 0:	Revision Number */
 
 
 /*****	PHY_XMAC_AUNE_ADV	16 bit r/w	Autoneg Advertisement *****/
@@ -744,43 +744,43 @@
 #define PHY_AN_NXT_PG	(1<<15)	/* Bit 15:	Request Next Page */
 #define PHY_X_AN_ACK	(1<<14)	/* Bit 14: (ro)	Acknowledge Received */
 #define PHY_X_AN_RFB	(3<<12)	/* Bit 13..12:	Remode Fault Bits */
-				/* Bit 11.. 9:	reserved */
+								/* Bit 11.. 9:	reserved */
 #define PHY_X_AN_PAUSE	(3<<7)	/* Bit	8.. 7:	Pause Bits */
-#define PHY_X_AN_HD	(1<<6)	/* Bit	6:	Half Duplex */
-#define PHY_X_AN_FD	(1<<5)	/* Bit	5:	Full Duplex */
-				/* Bit	4.. 0:	reserved */
+#define PHY_X_AN_HD		(1<<6)	/* Bit	6:	Half Duplex */
+#define PHY_X_AN_FD		(1<<5)	/* Bit	5:	Full Duplex */
+								/* Bit	4.. 0:	reserved */
 
 /*****	PHY_BCOM_AUNE_ADV	16 bit r/w	Autoneg Advertisement *****/
 /*****	PHY_BCOM_AUNE_LP	16 bit ro	Link Partner Ability Reg *****/
-/*	PHY_AN_NXT_PG	(see XMAC) Bit 15:	Request Next Page */
-				/* Bit 14:	reserved */
-#define PHY_B_AN_RF	(1<<13)	/* Bit 13:	Remote Fault */
-				/* Bit 12:	reserved */
+/*	PHY_AN_NXT_PG		(see XMAC) Bit 15:	Request Next Page */
+								/* Bit 14:	reserved */
+#define PHY_B_AN_RF		(1<<13)	/* Bit 13:	Remote Fault */
+								/* Bit 12:	reserved */
 #define PHY_B_AN_ASP	(1<<11)	/* Bit 11:	Asymetric Pause */
-#define PHY_B_AN_PC	(1<<10)	/* Bit 10:	Pause Capable */
-				/* Bit	9..5:	100/10 BT cap bits ingnored */
+#define PHY_B_AN_PC		(1<<10)	/* Bit 10:	Pause Capable */
+								/* Bit	9..5:	100/10 BT cap bits ingnored */
 #define PHY_B_AN_SEL	(0x1f<<0)/* Bit 4..0:	Selector Field, 00001=Ethernet*/
 
 /*****	PHY_LONE_AUNE_ADV	16 bit r/w	Autoneg Advertisement *****/
 /*****	PHY_LONE_AUNE_LP	16 bit ro	Link Partner Ability Reg *****/
-/*	PHY_AN_NXT_PG	(see XMAC) Bit 15:	Request Next Page */
-				/* Bit 14:	reserved */
-#define PHY_L_AN_RF	(1<<13)	/* Bit 13:	Remote Fault */
-				/* Bit 12:	reserved */
+/*	PHY_AN_NXT_PG		(see XMAC) Bit 15:	Request Next Page */
+								/* Bit 14:	reserved */
+#define PHY_L_AN_RF		(1<<13)	/* Bit 13:	Remote Fault */
+								/* Bit 12:	reserved */
 #define PHY_L_AN_ASP	(1<<11)	/* Bit 11:	Asymetric Pause */
-#define PHY_L_AN_PC	(1<<10)	/* Bit 10:	Pause Capable */
-				/* Bit	9..5:	100/10 BT cap bits ingnored */
+#define PHY_L_AN_PC		(1<<10)	/* Bit 10:	Pause Capable */
+								/* Bit	9..5:	100/10 BT cap bits ingnored */
 #define PHY_L_AN_SEL	(0x1f<<0)/* Bit 4..0:	Selector Field, 00001=Ethernet*/
 
 /*****	PHY_NAT_AUNE_ADV	16 bit r/w	Autoneg Advertisement *****/
 /*****	PHY_NAT_AUNE_LP	16 bit ro	Link Partner Ability Reg *****/
-/*	PHY_AN_NXT_PG	(see XMAC) Bit 15:	Request Next Page */
-				/* Bit 14:	reserved */
-#define PHY_N_AN_RF	(1<<13)	/* Bit 13:	Remote Fault */
-				/* Bit 12:	reserved */
+/*	PHY_AN_NXT_PG		(see XMAC) Bit 15:	Request Next Page */
+								/* Bit 14:	reserved */
+#define PHY_N_AN_RF		(1<<13)	/* Bit 13:	Remote Fault */
+								/* Bit 12:	reserved */
 #define PHY_N_AN_100F	(1<<11)	/* Bit 11:	100Base-T2 FD Support */
 #define PHY_N_AN_100H	(1<<10)	/* Bit 10:	100Base-T2 HD Support */
-				/* Bit	9..5:	100/10 BT cap bits ingnored */
+								/* Bit	9..5:	100/10 BT cap bits ingnored */
 #define PHY_N_AN_SEL	(0x1f<<0)/* Bit 4..0:	Selector Field, 00001=Ethernet*/
 
 /* field type definition for PHY_x_AN_SEL */
@@ -791,22 +791,22 @@
 #define PHY_AN_LP_NP	(1<<3)	/* Bit	3:	Link Partner can Next Page */
 #define PHY_AN_LOC_NP	(1<<2)	/* Bit	2:	Local PHY can Next Page */
 #define PHY_AN_RX_PG	(1<<1)	/* Bit	1:	Page Received */
-				/* Bit	0:	reserved */
+								/* Bit	0:	reserved */
 
 /*****	PHY_BCOM_AUNE_EXP	16 bit ro	Autoneg Expansion Reg *****/
-				/* Bit 15..5:	reserved */
+								/* Bit 15..5:	reserved */
 #define PHY_B_AN_PDF	(1<<4)	/* Bit	4:	Parallel Detection Fault */
-/*	PHY_AN_LP_NP	(see XMAC) Bit	3:	Link Partner can Next Page */
-/*	PHY_AN_LOC_NP	(see XMAC) Bit	2:	Local PHY can Next Page */
-/*	PHY_AN_RX_PG	(see XMAC) Bit	1:	Page Received */
+/*	PHY_AN_LP_NP		(see XMAC) Bit	3:	Link Partner can Next Page */
+/*	PHY_AN_LOC_NP		(see XMAC) Bit	2:	Local PHY can Next Page */
+/*	PHY_AN_RX_PG		(see XMAC) Bit	1:	Page Received */
 #define PHY_B_AN_LP_CAP	(1<<0)	/* Bit	0:	Link Partner Autoneg Cap. */ 	
 
 /*****	PHY_LONE_AUNE_EXP	16 bit ro	Autoneg Expansion Reg *****/
-#define PHY_L_AN_BP	(1<<5)	/* Bit	5:	Base Page Indication */
+#define PHY_L_AN_BP		(1<<5)	/* Bit	5:	Base Page Indication */
 #define PHY_L_AN_PDF	(1<<4)	/* Bit	4:	Parallel Detection Fault */
-/*	PHY_AN_LP_NP	(see XMAC) Bit	3:	Link Partner can Next Page */
-/*	PHY_AN_LOC_NP	(see XMAC) Bit	2:	Local PHY can Next Page */
-/*	PHY_AN_RX_PG	(see XMAC) Bit	1:	Page Received */
+/*	PHY_AN_LP_NP		(see XMAC) Bit	3:	Link Partner can Next Page */
+/*	PHY_AN_LOC_NP		(see XMAC) Bit	2:	Local PHY can Next Page */
+/*	PHY_AN_RX_PG		(see XMAC) Bit	1:	Page Received */
 #define PHY_B_AN_LP_CAP	(1<<0)	/* Bit	0:	Link Partner Autoneg Cap. */ 	
 
 
@@ -816,35 +816,35 @@
 /*****	PHY_XMAC_NEPG_LP	16 bit ro	Next Page Link Partner *****/
 /*****	PHY_BCOM_NEPG_LP	16 bit ro	Next Page Link Partner *****/
 /*****	PHY_LONE_NEPG_LP	16 bit ro	Next Page Link Partner *****/
-#define PHY_NP_MORE	(1<<15)	/* Bit 15:	More, Next Pages to follow */
-#define PHY_NP_ACK1	(1<<14)	/* Bit 14: (ro)	Ack 1, for receiving a message*/
+#define PHY_NP_MORE		(1<<15)	/* Bit 15:	More, Next Pages to follow */
+#define PHY_NP_ACK1		(1<<14)	/* Bit 14: (ro)	Ack 1, for receiving a message*/
 #define PHY_NP_MSG_VAL	(1<<13)	/* Bit 13:	Message Page valid */
-#define PHY_NP_ACK2	(1<<12)	/* Bit 12:	Ack 2, comply with msg content*/
-#define PHY_NP_TOG	(1<<11)	/* Bit 11:	Toggle Bit, ensure sync */
-#define PHY_NP_MSG	0x07ff	/* Bit 10..0:	Message from/to Link Partner */
+#define PHY_NP_ACK2		(1<<12)	/* Bit 12:	Ack 2, comply with msg content*/
+#define PHY_NP_TOG		(1<<11)	/* Bit 11:	Toggle Bit, ensure sync */
+#define PHY_NP_MSG		0x07ff	/* Bit 10..0:	Message from/to Link Partner */
 
 /*
  * XMAC-Specific
  */
 /*****	PHY_XMAC_EXT_STAT	16 bit r/w	Extended Status Register *****/
-#define PHY_X_EX_FD	(1<<15)	/* Bit 15:	Device Supports Full Duplex */
-#define PHY_X_EX_HD	(1<<14)	/* Bit 14:	Device Supports Half Duplex */
-				/* Bit 13..0:	reserved */
+#define PHY_X_EX_FD		(1<<15)	/* Bit 15:	Device Supports Full Duplex */
+#define PHY_X_EX_HD		(1<<14)	/* Bit 14:	Device Supports Half Duplex */
+								/* Bit 13..0:	reserved */
 
 /*****	PHY_XMAC_RES_ABI	16 bit ro	PHY Resolved Ability *****/
-				/* Bit 15..9:	reserved */
+								/* Bit 15..9:	reserved */
 #define PHY_X_RS_PAUSE	(3<<7)	/* Bit	8..7:	selected Pause Mode */
-#define PHY_X_RS_HD	(1<<6)	/* Bit	6:	Half Duplex Mode selected */
-#define PHY_X_RS_FD	(1<<5)	/* Bit	5:	Full Duplex Mode selected */
+#define PHY_X_RS_HD		(1<<6)	/* Bit	6:	Half Duplex Mode selected */
+#define PHY_X_RS_FD		(1<<5)	/* Bit	5:	Full Duplex Mode selected */
 #define PHY_X_RS_ABLMIS (1<<4)	/* Bit	4:	duplex or pause cap mismatch */
 #define PHY_X_RS_PAUMIS (1<<3)	/* Bit	3:	pause capability missmatch */
-				/* Bit	2..0:	reserved */
+								/* Bit	2..0:	reserved */
 /*
  * Remote Fault Bits (PHY_X_AN_RFB) encoding
  */
-#define X_RFB_OK	(0<<12)	/* Bit 12..13	No errors, Link OK */
-#define X_RFB_LF	(1<<12)	/* Bit 12..13	Link Failure */
-#define X_RFB_OFF	(2<<12)	/* Bit 12..13	Offline */
+#define X_RFB_OK		(0<<12)	/* Bit 12..13	No errors, Link OK */
+#define X_RFB_LF		(1<<12)	/* Bit 12..13	Link Failure */
+#define X_RFB_OFF		(2<<12)	/* Bit 12..13	Offline */
 #define X_RFB_AN_ERR	(3<<12)	/* Bit 12..13	Autonegotiation Error */
 
 /*
@@ -866,7 +866,7 @@
 #define PHY_B_1000C_RD		(1<<10)	/* Bit	10:	Repeater/DTE */
 #define PHY_B_1000C_AFD		(1<<9)	/* Bit	9:	Advertise Full Duplex */
 #define PHY_B_1000C_AHD		(1<<8)	/* Bit	8:	Advertise Half Duplex */
-					/* Bit	7..0:	reserved */
+									/* Bit	7..0:	reserved */
 
 /***** PHY_BCOM_1000T_STAT	16 bit ro	1000Base-T Status Reg *****/
 #define PHY_B_1000S_MSF		(1<<15)	/* Bit	15:	Master/Slave Fault */
@@ -875,7 +875,7 @@
 #define PHY_B_1000S_RRS		(1<<12)	/* Bit	12:	Remote Receiver Status */
 #define PHY_B_1000S_LP_FD	(1<<11)	/* Bit	11:	Link Partner can FD */
 #define PHY_B_1000S_LP_HD	(1<<10)	/* Bit	10:	Link Partner can HD */
-					/* Bit	9..8:	reserved */
+									/* Bit	9..8:	reserved */
 #define PHY_B_1000S_IEC		(255<<0)/* Bit	7..0:	Idle Error Count */
 
 /*****	PHY_BCOM_EXT_STAT	16 bit ro	Extended Status Register *****/
@@ -883,7 +883,7 @@
 #define PHY_B_ES_X_HD_CAP	(1<<14)	/* Bit 14:	1000Base-X HD capable */
 #define PHY_B_ES_T_FD_CAP	(1<<13)	/* Bit 13:	1000Base-T FD capable */
 #define PHY_B_ES_T_HD_CAP	(1<<12)	/* Bit 12:	1000Base-T HD capable */
-					/* Bit 11..0:	reserved */
+									/* Bit 11..0:	reserved */
 
 /*****	PHY_BCOM_P_EXT_CTRL	16 bit r/w	PHY Extended Control Reg *****/
 #define PHY_B_PEC_MAC_PHY	(1<<15)	/* Bit 15:	10BIT/GMI-Interface */
@@ -892,36 +892,36 @@
 #define PHY_B_PEC_INT_DIS	(1<<12)	/* Bit 12:	Interrupts Disabled */
 #define PHY_B_PEC_F_INT		(1<<11)	/* Bit 11:	Force Interrupt */
 #define PHY_B_PEC_BY_45		(1<<10)	/* Bit 10:	Bypass 4B5B-Decoder */
-#define PHY_B_PEC_BY_SCR	(1<<9)	/* Bit 9:	Bypass Scrambler */
-#define PHY_B_PEC_BY_MLT3	(1<<8)	/* Bit 8:	Bypass MLT3 Encoder */
-#define PHY_B_PEC_BY_RXA	(1<<7)	/* Bit 7:	Bypass Rx Alignm. */
-#define PHY_B_PEC_RES_SCR	(1<<6)	/* Bit 6:	Reset Scrambler */
-#define PHY_B_PEC_EN_LTR	(1<<5)	/* Bit 5:	Ena LED Traffic Mode */
-#define PHY_B_PEC_LED_ON	(1<<4)	/* Bit 4:	Force LED's on */
-#define PHY_B_PEC_LED_OFF	(1<<3)	/* Bit 3:	Force LED's off */
-#define PHY_B_PEC_EX_IPG	(1<<2)	/* Bit 2:	Extend Tx IPG Mode */
-#define PHY_B_PEC_3_LED		(1<<1)	/* Bit 1:	Three Link LED mode */
-#define PHY_B_PEC_HIGH_LA	(1<<0)	/* Bit 0:	GMII Fifo Elasticy */
+#define PHY_B_PEC_BY_SCR	(1<<9)	/* Bit  9:	Bypass Scrambler */
+#define PHY_B_PEC_BY_MLT3	(1<<8)	/* Bit  8:	Bypass MLT3 Encoder */
+#define PHY_B_PEC_BY_RXA	(1<<7)	/* Bit  7:	Bypass Rx Alignm. */
+#define PHY_B_PEC_RES_SCR	(1<<6)	/* Bit  6:	Reset Scrambler */
+#define PHY_B_PEC_EN_LTR	(1<<5)	/* Bit  5:	Ena LED Traffic Mode */
+#define PHY_B_PEC_LED_ON	(1<<4)	/* Bit  4:	Force LED's on */
+#define PHY_B_PEC_LED_OFF	(1<<3)	/* Bit  3:	Force LED's off */
+#define PHY_B_PEC_EX_IPG	(1<<2)	/* Bit  2:	Extend Tx IPG Mode */
+#define PHY_B_PEC_3_LED		(1<<1)	/* Bit  1:	Three Link LED mode */
+#define PHY_B_PEC_HIGH_LA	(1<<0)	/* Bit  0:	GMII Fifo Elasticy */
 
 /*****	PHY_BCOM_P_EXT_STAT	16 bit ro	PHY Extended Status Reg *****/
-					/* Bit 15..14:	reserved */
+									/* Bit 15..14:	reserved */
 #define PHY_B_PES_CROSS_STAT	(1<<13)	/* Bit 13:	MDI Crossover Status */
 #define PHY_B_PES_INT_STAT	(1<<12)	/* Bit 12:	Interrupt Status */
 #define PHY_B_PES_RRS		(1<<11)	/* Bit 11:	Remote Receiver Stat. */
 #define PHY_B_PES_LRS		(1<<10)	/* Bit 10:	Local Receiver Stat. */
-#define PHY_B_PES_LOCKED	(1<<9)	/* Bit 9:	Locked */
-#define PHY_B_PES_LS		(1<<8)	/* Bit 8:	Link Status */
-#define PHY_B_PES_RF		(1<<7)	/* Bit 7:	Remote Fault */
-#define PHY_B_PES_CE_ER		(1<<6)	/* Bit 6:	Carrier Ext Error */
-#define PHY_B_PES_BAD_SSD	(1<<5)	/* Bit 5:	Bad SSD */
-#define PHY_B_PES_BAD_ESD	(1<<4)	/* Bit 4:	Bad ESD */
-#define PHY_B_PES_RX_ER		(1<<3)	/* Bit 3:	Receive Error */
-#define PHY_B_PES_TX_ER		(1<<2)	/* Bit 2:	Transmit Error */
-#define PHY_B_PES_LOCK_ER	(1<<1)	/* Bit 1:	Lock Error */
-#define PHY_B_PES_MLT3_ER	(1<<0)	/* Bit 0:	MLT3 code Error */
+#define PHY_B_PES_LOCKED	(1<<9)	/* Bit  9:	Locked */
+#define PHY_B_PES_LS		(1<<8)	/* Bit  8:	Link Status */
+#define PHY_B_PES_RF		(1<<7)	/* Bit  7:	Remote Fault */
+#define PHY_B_PES_CE_ER		(1<<6)	/* Bit  6:	Carrier Ext Error */
+#define PHY_B_PES_BAD_SSD	(1<<5)	/* Bit  5:	Bad SSD */
+#define PHY_B_PES_BAD_ESD	(1<<4)	/* Bit  4:	Bad ESD */
+#define PHY_B_PES_RX_ER		(1<<3)	/* Bit  3:	Receive Error */
+#define PHY_B_PES_TX_ER		(1<<2)	/* Bit  2:	Transmit Error */
+#define PHY_B_PES_LOCK_ER	(1<<1)	/* Bit  1:	Lock Error */
+#define PHY_B_PES_MLT3_ER	(1<<0)	/* Bit  0:	MLT3 code Error */
 
 /*****	PHY_BCOM_FC_CTR		16 bit r/w	False Carrier Counter *****/
-					/* Bit 15..8:	reserved */
+									/* Bit 15..8:	reserved */
 #define PHY_B_FC_CTR		(255<<0)/* Bit 7..0:	False Carrier Counter */
 
 /*****	PHY_BCOM_RNO_CTR	16 bit r/w	Receive NOT_OK Counter *****/
@@ -932,15 +932,15 @@
 #define PHY_B_AC_L_SQE		(1<<15)	/* Bit 15:	Low Squelch */
 #define PHY_B_AC_LONG_PACK	(1<<14)	/* Bit 14:	Rx Long Packets */
 #define PHY_B_AC_ER_CTRL	(3<<12)	/* Bit 13..12:	Edgerate Control */
-					/* Bit 11:	reserved */
+									/* Bit 11:	reserved */
 #define PHY_B_AC_TX_TST		(1<<10) /* Bit 10:	tx test bit, always 1 */
-					/* Bit  9.. 8:	reserved */
+									/* Bit  9.. 8:	reserved */
 #define PHY_B_AC_DIS_PRF	(1<<7)	/* Bit  7:	dis part resp filter */
-					/* Bit  6:	reserved */
+									/* Bit  6:	reserved */
 #define PHY_B_AC_DIS_PM		(1<<5)	/* Bit  5:	dis power management */
-					/* Bit  4:	reserved */
+									/* Bit  4:	reserved */
 #define PHY_B_AC_DIAG		(1<<3)	/* Bit  3:	Diagnostic Mode */
-					/* Bit  2.. 0:	reserved */
+									/* Bit  2.. 0:	reserved */
 
 /*****	PHY_BCOM_AUX_STAT	16 bit ro	Auxiliary Status Reg *****/
 #define PHY_B_AS_AN_C		(1<<15)	/* Bit 15:	AutoNeg complete */
@@ -949,37 +949,36 @@
 #define PHY_B_AS_ANAB_D		(1<<12)	/* Bit 12:	AN Ability Detect */
 #define PHY_B_AS_NPW		(1<<11)	/* Bit 11:	AN Next Page Wait */
 #define PHY_B_AS_AN_RES		(7<<8)	/* Bit 10..8:	AN HDC */
-#define PHY_B_AS_PDF		(1<<7)	/* Bit 7:	Parallel Detect. Fault*/
-#define PHY_B_AS_RF		(1<<6)	/* Bit 6:	Remote Fault */
-#define PHY_B_AS_ANP_R		(1<<5)	/* Bit 5:	AN Page Received */
-#define PHY_B_AS_LP_ANAB	(1<<4)	/* Bit 4:	LP AN Ability */
-#define PHY_B_AS_LP_NPAB	(1<<3)	/* Bit 3:	LP Next Page Ability */
-#define PHY_B_AS_LS		(1<<2)	/* Bit 2:	Link Status */
-#define PHY_B_AS_PRR		(1<<1)	/* Bit 1:	Pause Resolution-Rx */
-#define PHY_B_AS_PRT		(1<<0)	/* Bit 0:	Pause Resolution-Tx */
+#define PHY_B_AS_PDF		(1<<7)	/* Bit  7:	Parallel Detect. Fault*/
+#define PHY_B_AS_RF			(1<<6)	/* Bit  6:	Remote Fault */
+#define PHY_B_AS_ANP_R		(1<<5)	/* Bit  5:	AN Page Received */
+#define PHY_B_AS_LP_ANAB	(1<<4)	/* Bit  4:	LP AN Ability */
+#define PHY_B_AS_LP_NPAB	(1<<3)	/* Bit  3:	LP Next Page Ability */
+#define PHY_B_AS_LS			(1<<2)	/* Bit  2:	Link Status */
+#define PHY_B_AS_PRR		(1<<1)	/* Bit  1:	Pause Resolution-Rx */
+#define PHY_B_AS_PRT		(1<<0)	/* Bit  0:	Pause Resolution-Tx */
 
 /*****	PHY_BCOM_INT_STAT	16 bit ro	Interrupt Status Reg *****/
 /*****	PHY_BCOM_INT_MASK	16 bit r/w	Interrupt Mask Reg *****/
-					/* Bit 15:	reserved */
+									/* Bit 15:	reserved */
 #define PHY_B_IS_PSE		(1<<14)	/* Bit 14:	Pair Swap Error */
 #define PHY_B_IS_MDXI_SC	(1<<13)	/* Bit 13:	MDIX Status Change */
 #define PHY_B_IS_HCT		(1<<12)	/* Bit 12:	counter above 32k */
-#define PHY_B_IS_LCT		(1<<11)	/* Bit 11:	all counter below 128 */
+#define PHY_B_IS_LCT		(1<<11)	/* Bit 11:	counter above 128 */
 #define PHY_B_IS_AN_PR		(1<<10)	/* Bit 10:	Page Received */
-#define PHY_B_IS_NO_HDCL	(1<<9)	/* Bit 9:	No HCD Link */
-#define PHY_B_IS_NO_HDC		(1<<8)	/* Bit 8:	No HCD */
-#define PHY_B_IS_NEG_USHDC	(1<<7)	/* Bit 7:	Negotiated Unsup. HCD */
-#define PHY_B_IS_SCR_S_ER	(1<<6)	/* Bit 6:	Scrambler Sync Error */
-#define PHY_B_IS_RRS_CHANGE	(1<<5)	/* Bit 5:	Remote Rx Stat Change */
-#define PHY_B_IS_LRS_CHANGE	(1<<4)	/* Bit 4:	Local Rx Stat Change */
-#define PHY_B_IS_DUP_CHANGE	(1<<3)	/* Bit 3:	Duplex Mode Change */
-#define PHY_B_IS_LSP_CHANGE	(1<<2)	/* Bit 2:	Link Speed Change */
-#define PHY_B_IS_LST_CHANGE	(1<<1)	/* Bit 1:	Link Status Changed */
-#define PHY_B_IS_CRC_ER		(1<<0)	/* Bit 0:	CRC Error */
+#define PHY_B_IS_NO_HDCL	(1<<9)	/* Bit  9:	No HCD Link */
+#define PHY_B_IS_NO_HDC		(1<<8)	/* Bit  8:	No HCD */
+#define PHY_B_IS_NEG_USHDC	(1<<7)	/* Bit  7:	Negotiated Unsup. HCD */
+#define PHY_B_IS_SCR_S_ER	(1<<6)	/* Bit  6:	Scrambler Sync Error */
+#define PHY_B_IS_RRS_CHANGE	(1<<5)	/* Bit  5:	Remote Rx Stat Change */
+#define PHY_B_IS_LRS_CHANGE	(1<<4)	/* Bit  4:	Local Rx Stat Change */
+#define PHY_B_IS_DUP_CHANGE	(1<<3)	/* Bit  3:	Duplex Mode Change */
+#define PHY_B_IS_LSP_CHANGE	(1<<2)	/* Bit  2:	Link Speed Change */
+#define PHY_B_IS_LST_CHANGE	(1<<1)	/* Bit  1:	Link Status Changed */
+#define PHY_B_IS_CRC_ER		(1<<0)	/* Bit  0:	CRC Error */
 
 #define PHY_B_DEF_MSK	(~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
 
-
 /*
  * Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding
  */
@@ -1005,7 +1004,7 @@
 #define PHY_L_1000C_RD		(1<<10)	/* Bit	10:	Repeater/DTE */
 #define PHY_L_1000C_AFD		(1<<9)	/* Bit	9:	Advertise Full Duplex */
 #define PHY_L_1000C_AHD		(1<<8)	/* Bit	8:	Advertise Half Duplex */
-					/* Bit	7..0:	reserved */
+									/* Bit	7..0:	reserved */
 
 /*****	PHY_LONE_1000T_STAT	16 bit ro	1000Base-T Status Reg *****/
 #define PHY_L_1000S_MSF		(1<<15)	/* Bit	15:	Master/Slave Fault */
@@ -1014,7 +1013,7 @@
 #define PHY_L_1000S_RRS		(1<<12)	/* Bit	12:	Remote Receiver Status*/
 #define PHY_L_1000S_LP_FD	(1<<11)	/* Bit	11:	Link Partner can FD */
 #define PHY_L_1000S_LP_HD	(1<<10)	/* Bit	10:	Link Partner can HD */
-					/* Bit	9..8:	reserved */
+									/* Bit	9..8:	reserved */
 #define PHY_B_1000S_IEC		(255<<0)/* Bit	7..0:	Idle Error Count */
 
 /*****	PHY_LONE_EXT_STAT	16 bit ro	Extended Status Register *****/
@@ -1022,11 +1021,11 @@
 #define PHY_L_ES_X_HD_CAP	(1<<14)	/* Bit 14:	1000Base-X HD capable */
 #define PHY_L_ES_T_FD_CAP	(1<<13)	/* Bit 13:	1000Base-T FD capable */
 #define PHY_L_ES_T_HD_CAP	(1<<12)	/* Bit 12:	1000Base-T HD capable */
-					/* Bit 11..0:	reserved */
+									/* Bit 11..0:	reserved */
 
 /*****	PHY_LONE_PORT_CFG	16 bit r/w	Port Configuration Reg *****/
 #define PHY_L_PC_REP_MODE	(1<<15)	/* Bit 15:	Repeater Mode */
-					/* Bit 14:	reserved */
+									/* Bit 14:	reserved */
 #define PHY_L_PC_TX_DIS		(1<<13)	/* Bit 13:	Tx output Disabled */
 #define PHY_L_PC_BY_SCR		(1<<12)	/* Bit 12:	Bypass Scrambler */
 #define PHY_L_PC_BY_45		(1<<11)	/* Bit 11:	Bypass 4B5B-Decoder */
@@ -1049,7 +1048,7 @@
 #define PHY_L_QS_COL_STAT	(1<<11)	/* Bit 11:	Collision */
 #define PHY_L_QS_L_STAT		(1<<10)	/* Bit 10:	Link is up */
 #define PHY_L_QS_DUP_MOD	(1<<9)	/* Bit 9:	Full/Half Duplex */
-#define PHY_L_QS_AN		(1<<8)	/* Bit 8:	AutoNeg is On */
+#define PHY_L_QS_AN			(1<<8)	/* Bit 8:	AutoNeg is On */
 #define PHY_L_QS_AN_C		(1<<7)	/* Bit 7:	AN is Complete */
 #define PHY_L_QS_LLE		(7<<4)	/* Bit 6:	Line Length Estim. */
 #define PHY_L_QS_PAUSE		(1<<3)	/* Bit 3:	LP advertised Pause */
@@ -1059,24 +1058,24 @@
 
 /*****	PHY_LONE_INT_ENAB	16 bit r/w	Interrupt Enable Reg *****/
 /*****	PHY_LONE_INT_STAT	16 bit ro	Interrupt Status Reg *****/
-					/* Bit 15..14:	reserved */
+									/* Bit 15..14:	reserved */
 #define PHY_L_IS_AN_F		(1<<13)	/* Bit 13:	Autoneg fault */
-					/* Bit 12:	not described */
+									/* Bit 12:	not described */
 #define PHY_L_IS_CROSS		(1<<11)	/* Bit 11:	Crossover used */
 #define PHY_L_IS_POL		(1<<10)	/* Bit 10:	Polarity correct. used*/
-#define PHY_L_IS_SS		(1<<9)	/* Bit 9:	Smart Speed Downgrade*/
+#define PHY_L_IS_SS			(1<<9)	/* Bit 9:	Smart Speed Downgrade*/
 #define PHY_L_IS_CFULL		(1<<8)	/* Bit 8:	Counter Full */
 #define PHY_L_IS_AN_C		(1<<7)	/* Bit 7:	AutoNeg Complete */
 #define PHY_L_IS_SPEED		(1<<6)	/* Bit 6:	Speed Changed */
 #define PHY_L_IS_DUP		(1<<5)	/* Bit 5:	Duplex Changed */
-#define PHY_L_IS_LS		(1<<4)	/* Bit 4:	Link Status Changed */
+#define PHY_L_IS_LS			(1<<4)	/* Bit 4:	Link Status Changed */
 #define PHY_L_IS_ISOL		(1<<3)	/* Bit 3:	Isolate Occured */
 #define PHY_L_IS_MDINT		(1<<2)	/* Bit 2: (ro)	STAT: MII Int Pending */
 #define PHY_L_IS_INTEN		(1<<1)	/* Bit 1:	ENAB: Enable IRQs */
 #define PHY_L_IS_FORCE		(1<<0)	/* Bit 0:	ENAB: Force Interrupt */
 
-#define PHY_L_DEF_MSK		(PHY_L_IS_LS | PHY_L_IS_ISOL | \
-				PHY_L_IS_INTEN)	/* int. mask */
+/* int. mask */
+#define PHY_L_DEF_MSK		(PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN)
 
 /*****	PHY_LONE_LED_CFG	16 bit r/w	LED Configuration Reg *****/
 #define PHY_L_LC_LEDC		(3<<14)	/* Bit 15..14:	Col/Blink/On/Off */
@@ -1091,12 +1090,12 @@
 
 /*****	PHY_LONE_PORT_CTRL	16 bit r/w	Port Control Reg *****/
 #define PHY_L_PC_TX_TCLK	(1<<15)	/* Bit 15:	Enable TX_TCLK */
-					/* Bit 14:	reserved */
+									/* Bit 14:	reserved */
 #define PHY_L_PC_ALT_NP		(1<<13)	/* Bit 14:	Alternate Next Page */
 #define PHY_L_PC_GMII_ALT	(1<<12)	/* Bit 13:	Alternate GMII driver */
-					/* Bit 11:	reserved */
+									/* Bit 11:	reserved */
 #define PHY_L_PC_TEN_CRS	(1<<10)	/* Bit 10:	Extend CRS*/
-					/* Bit 9..0:	not described */
+									/* Bit 9..0:	not described */
 
 /*****	PHY_LONE_CIM		16 bit ro	CIM Reg *****/
 #define PHY_L_CIM_ISOL		(255<<8)/* Bit 15..8:	Isolate Count */
@@ -1123,7 +1122,7 @@
 #define PHY_N_1000C_AFD		(1<<9)	/* Bit	9:	Advertise Full Duplex */
 #define PHY_N_1000C_AHD		(1<<8)	/* Bit	8:	Advertise Half Duplex */
 #define PHY_N_1000C_APC		(1<<7)	/* Bit	7:	Asymetric Pause Cap. */
-					/* Bit	6..0:	reserved */
+									/* Bit	6..0:	reserved */
 
 /***** PHY_NAT_1000T_STAT	16 bit ro	1000Base-T Status Reg *****/
 #define PHY_N_1000S_MSF		(1<<15)	/* Bit	15:	Master/Slave Fault */
@@ -1133,7 +1132,7 @@
 #define PHY_N_1000S_LP_FD	(1<<11)	/* Bit	11:	Link Partner can FD */
 #define PHY_N_1000S_LP_HD	(1<<10)	/* Bit	10:	Link Partner can HD */
 #define PHY_N_1000C_LP_APC	(1<<9)	/* Bit	9:	LP Asym. Pause Cap. */
-					/* Bit	8:	reserved */
+									/* Bit	8:	reserved */
 #define PHY_N_1000S_IEC		(255<<0)/* Bit	7..0:	Idle Error Count */
 
 /*****	PHY_NAT_EXT_STAT	16 bit ro	Extended Status Register *****/
@@ -1141,7 +1140,7 @@
 #define PHY_N_ES_X_HD_CAP	(1<<14)	/* Bit 14:	1000Base-X HD capable */
 #define PHY_N_ES_T_FD_CAP	(1<<13)	/* Bit 13:	1000Base-T FD capable */
 #define PHY_N_ES_T_HD_CAP	(1<<12)	/* Bit 12:	1000Base-T HD capable */
-					/* Bit 11..0:	reserved */
+									/* Bit 11..0:	reserved */
 
 /* todo: those are still missing */
 /*****	PHY_NAT_EXT_CTRL1	16 bit ro	Extended Control Reg1 *****/
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/skaddr.c linux/drivers/net/sk98lin/skaddr.c
--- v2.4.6/linux/drivers/net/sk98lin/skaddr.c	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/skaddr.c	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	skaddr.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.36 $
- * Date:	$Date: 2000/08/07 11:10:39 $
+ * Version:	$Revision: 1.40 $
+ * Date:	$Date: 2001/02/14 14:04:59 $
  * Purpose:	Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2000 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,6 +26,18 @@
  * History:
  *
  *	$Log: skaddr.c,v $
+ *	Revision 1.40  2001/02/14 14:04:59  rassmann
+ *	Editorial changes.
+ *	
+ *	Revision 1.39  2001/01/30 10:30:04  rassmann
+ *	Editorial changes.
+ *	
+ *	Revision 1.38  2001/01/25 16:26:52  rassmann
+ *	Ensured that logical address overrides are done on net's active port.
+ *	
+ *	Revision 1.37  2001/01/22 13:41:34  rassmann
+ *	Supporting two nets on dual-port adapters.
+ *	
  *	Revision 1.36  2000/08/07 11:10:39  rassmann
  *	Editorial changes.
  *	
@@ -172,7 +183,7 @@
 
 #ifndef	lint
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skaddr.c,v 1.36 2000/08/07 11:10:39 rassmann Exp $ (C) SysKonnect.";
+	"@(#) $Id: skaddr.c,v 1.40 2001/02/14 14:04:59 rassmann Exp $ (C) SysKonnect.";
 #endif	/* !defined(lint) */
 
 #define __SKADDR_C
@@ -300,7 +311,9 @@
 		break;
 
 	case SK_INIT_IO:
-		pAC->Addr.ActivePort = pAC->Rlmt.MacActive;
+		for (i = 0; i < SK_MAX_NETS; i++) {
+			pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort;
+		}
 		
 #ifdef DEBUG
 		for (i = 0; i < SK_MAX_MACS; i++) {
@@ -313,23 +326,33 @@
 
 		/* Read permanent logical MAC address from Control Register File. */
 		for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
-			InAddr = (SK_U8 *)&pAC->Addr.PermanentMacAddress.a[j];
+			InAddr = (SK_U8 *)&pAC->Addr.Net[0].PermanentMacAddress.a[j];
 			SK_IN8(IoC, B2_MAC_1 + j, InAddr);
 		}
 
-		if (!pAC->Addr.CurrentMacAddressSet) {
-			/*
-			 * Set the current logical MAC address
-			 * to the permanent one.
-			 */
-			pAC->Addr.CurrentMacAddress =
-				pAC->Addr.PermanentMacAddress;
-			pAC->Addr.CurrentMacAddressSet = SK_TRUE;
+		if (!pAC->Addr.Net[0].CurrentMacAddressSet) {
+			/* Set the current logical MAC address to the permanent one. */
+			pAC->Addr.Net[0].CurrentMacAddress =
+				pAC->Addr.Net[0].PermanentMacAddress;
+			pAC->Addr.Net[0].CurrentMacAddressSet = SK_TRUE;
 		}
 
 		/* Set the current logical MAC address. */
-		pAC->Addr.Port[pAC->Addr.ActivePort].Exact[0] =
-			pAC->Addr.CurrentMacAddress;
+		pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] =
+			pAC->Addr.Net[0].CurrentMacAddress;
+
+#if SK_MAX_NETS > 1
+		/* Set logical MAC address for net 2 to (log | 3). */
+		if (!pAC->Addr.Net[1].CurrentMacAddressSet) {
+			pAC->Addr.Net[1].PermanentMacAddress =
+				pAC->Addr.Net[0].PermanentMacAddress;
+			pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3;
+			/* Set the current logical MAC address to the permanent one. */
+			pAC->Addr.Net[1].CurrentMacAddress =
+				pAC->Addr.Net[1].PermanentMacAddress;
+			pAC->Addr.Net[1].CurrentMacAddressSet = SK_TRUE;
+		}
+#endif	/* SK_MAX_NETS > 1 */
 
 #ifdef xDEBUG
 		SK_DBG_MSG(
@@ -365,10 +388,7 @@
 		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
 			pAPort = &pAC->Addr.Port[i];
 
-			/*
-			 * Read permanent port addresses from
-			 * Control Register File.
-			 */
+			/* Read permanent port addresses from Control Register File. */
 			for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
 				InAddr = (SK_U8 *)&pAPort->PermanentMacAddress.a[j];
 				SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr);
@@ -376,9 +396,8 @@
 
 			if (!pAPort->CurrentMacAddressSet) {
 				/*
-				 * Set the current and previous physical
-				 * MAC address of this port to its permanent
-				 * MAC address.
+				 * Set the current and previous physical MAC address
+				 * of this port to its permanent MAC address.
 				 */
 				pAPort->CurrentMacAddress = pAPort->PermanentMacAddress;
 				pAPort->PreviousMacAddress = pAPort->PermanentMacAddress;
@@ -460,35 +479,35 @@
 int	SkAddrMcClear(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* I/O context */
-SK_U32	PortIdx,	/* Index of affected port */
+SK_U32	PortNumber,	/* Index of affected port */
 int		Flags)		/* permanent/non-perm, sw-only */
 {
 	int i;
 
-	if (PortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
+	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {
 		return (SK_ADDR_ILLEGAL_PORT);
 	}
 
 	if (Flags & SK_ADDR_PERMANENT) {
 
 		/* Clear RLMT multicast addresses. */
-		pAC->Addr.Port[PortIdx].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
+		pAC->Addr.Port[PortNumber].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
 	}
 	else {	/* not permanent => DRV */
 
 		/* Clear InexactFilter. */
 
 		for (i = 0; i < 8; i++) {
-			pAC->Addr.Port[PortIdx].InexactFilter.Bytes[i] = 0;
+			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
 		}
 
 		/* Clear DRV multicast addresses. */
 
-		pAC->Addr.Port[PortIdx].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
+		pAC->Addr.Port[PortNumber].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
 	}
 
 	if (!(Flags & SK_MC_SW_ONLY)) {
-		(void)SkAddrMcUpdate(pAC, IoC, PortIdx);
+		(void)SkAddrMcUpdate(pAC, IoC, PortNumber);
 	}
 
 	return (SK_ADDR_SUCCESS);
@@ -563,7 +582,7 @@
 int	SkAddrMcAdd(
 SK_AC		*pAC,		/* adapter context */
 SK_IOC		IoC,		/* I/O context */
-SK_U32		PortIdx,	/* Port Index */
+SK_U32		PortNumber,	/* Port Number */
 SK_MAC_ADDR	*pMc,		/* multicast address to be added */
 int			Flags)		/* permanent/non-permanent */
 {
@@ -573,56 +592,57 @@
 	unsigned HashBit;
 #endif	/* !defined(SK_ADDR_CHEAT) */
 
-	if (PortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
+	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {
 		return (SK_ADDR_ILLEGAL_PORT);
 	}
 
 	if (Flags & SK_ADDR_PERMANENT) {
 #ifdef DEBUG
-		if (pAC->Addr.Port[PortIdx].NextExactMatchRlmt <
+		if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt <
 			SK_ADDR_FIRST_MATCH_RLMT) {
-			Next0[PortIdx] |= 1;
+			Next0[PortNumber] |= 1;
 			return (SK_MC_RLMT_OVERFLOW);
 		}
 #endif	/* DEBUG */
 		
-		if (pAC->Addr.Port[PortIdx].NextExactMatchRlmt >
+		if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt >
 			SK_ADDR_LAST_MATCH_RLMT) {
 			return (SK_MC_RLMT_OVERFLOW);
 		}
 
 		/* Set an RLMT multicast address. */
 
-		pAC->Addr.Port[PortIdx].Exact[
-			pAC->Addr.Port[PortIdx].NextExactMatchRlmt++] = *pMc;
+		pAC->Addr.Port[PortNumber].Exact[
+			pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc;
 
 		return (SK_MC_FILTERING_EXACT);
 	}
 
+#if 0
 	/* Not PERMANENT => DRV */
-	if (PortIdx != pAC->Addr.ActivePort) {
-
+	if (PortNumber != pAC->Addr.ActivePort) {
 		/* Only RLMT is allowed to do this. */
 		return (SK_MC_ILLEGAL_PORT);
 	}
+#endif	/* 0 */
 
 #ifdef DEBUG
-	if (pAC->Addr.Port[PortIdx].NextExactMatchDrv <
+	if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <
 		SK_ADDR_FIRST_MATCH_DRV) {
-			Next0[PortIdx] |= 2;
+			Next0[PortNumber] |= 2;
 		return (SK_MC_RLMT_OVERFLOW);
 	}
 #endif	/* DEBUG */
 	
-	if (pAC->Addr.Port[PortIdx].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
+	if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
 
 		/* Set exact match entry. */
-		pAC->Addr.Port[PortIdx].Exact[
-			pAC->Addr.Port[PortIdx].NextExactMatchDrv++] = *pMc;
+		pAC->Addr.Port[PortNumber].Exact[
+			pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc;
 
 		/* Clear InexactFilter. */
 		for (i = 0; i < 8; i++) {
-			pAC->Addr.Port[PortIdx].InexactFilter.Bytes[i] = 0;
+			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
 		}
 	}
 	else {
@@ -638,21 +658,21 @@
 		HashBit = 63 - SkCrc32McHash(&pMc->a[0]);
 
 		/* Add bit to InexactFilter. */
-		pAC->Addr.Port[PortIdx].InexactFilter.Bytes[HashBit / 8] |=
+		pAC->Addr.Port[PortNumber].InexactFilter.Bytes[HashBit / 8] |=
 			1 << (HashBit % 8);
 #else	/* SK_ADDR_CHEAT */
 		/* Set all bits in InexactFilter. */
 		for (i = 0; i < 8; i++) {
-			pAC->Addr.Port[PortIdx].InexactFilter.Bytes[i] = 0xFF;
+			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
 		}
 #endif	/* SK_ADDR_CHEAT */
 	}
 
 	for (Inexact = 0, i = 0; i < 8; i++) {
-		Inexact |= pAC->Addr.Port[PortIdx].InexactFilter.Bytes[i];
+		Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
 	}
 
-	if (Inexact == 0 && pAC->Addr.Port[PortIdx].PromMode == 0) {
+	if (Inexact == 0 && pAC->Addr.Port[PortNumber].PromMode == 0) {
 		return (SK_MC_FILTERING_EXACT);
 	}
 	else {
@@ -685,7 +705,7 @@
 int	SkAddrMcUpdate(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* I/O context */
-SK_U32	PortIdx)	/* Port Index */
+SK_U32	PortNumber)	/* Port Number */
 {
 	SK_U32			i;
 	SK_U8			Inexact;
@@ -693,7 +713,7 @@
 	SK_U16			LoMode;		/* Lower 16 bits of XMAC Mode Reg. */
 	SK_ADDR_PORT	*pAPort;
 
-	if (PortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
+	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {
 		return (SK_ADDR_ILLEGAL_PORT);
 	}
 
@@ -701,25 +721,23 @@
 		pAC,
 		SK_DBGMOD_ADDR,
 		SK_DBGCAT_CTRL,
-		("SkAddrMcUpdate on Port %u.\n", PortIdx))
+		("SkAddrMcUpdate on Port %u.\n", PortNumber))
 	
-	pAPort = &pAC->Addr.Port[PortIdx];
+	pAPort = &pAC->Addr.Port[PortNumber];
 
 #ifdef DEBUG
 		SK_DBG_MSG(
 			pAC,
 			SK_DBGMOD_ADDR,
 			SK_DBGCAT_CTRL,
-			("Next0 on Port %d: %d\n", PortIdx, Next0[PortIdx]))
+			("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
 #endif	/* DEBUG */
 
-	for (i = 0;		/* Also program the logical MAC address. */
-		i < pAPort->NextExactMatchRlmt;
-		i++) {
-
+	/* Start with 0 to also program the logical MAC address. */
+	for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
 		/* Set exact match address i on HW. */
 		OutAddr = (SK_U16 *)&pAPort->Exact[i].a[0];
-		XM_OUTADDR(IoC, PortIdx, XM_EXM(i), OutAddr);
+		XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
 	}
 
 	/* Clear other permanent exact match addresses on HW. */
@@ -727,14 +745,14 @@
 		SkXmClrExactAddr(
 			pAC,
 			IoC,
-			PortIdx,
+			PortNumber,
 			pAPort->NextExactMatchRlmt,
 			SK_ADDR_LAST_MATCH_RLMT);
 	}
 
 	for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) {
 		OutAddr = (SK_U16 *)&pAPort->Exact[i].a[0];
-		XM_OUTADDR(IoC, PortIdx, XM_EXM(i), OutAddr);
+		XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
 	}
 
 	/* Clear other non-permanent exact match addresses on HW. */
@@ -742,7 +760,7 @@
 		SkXmClrExactAddr(
 			pAC,
 			IoC,
-			PortIdx,
+			PortNumber,
 			pAPort->NextExactMatchDrv,
 			SK_ADDR_LAST_MATCH_DRV);
 	}
@@ -753,54 +771,52 @@
 
 	if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
 		/* Set all bits in 64-bit hash register. */
-		XM_OUTHASH(IoC, PortIdx, XM_HSM, &OnesHash);
+		XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
 
 		/* Set bit 15 in mode register. */
-		XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 		LoMode |= XM_MD_ENA_HSH;
-		XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+		XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);
 	}
 	else if (Inexact != 0) {
 		/* Set 64-bit hash register to InexactFilter. */
-		XM_OUTHASH(IoC, PortIdx, XM_HSM, &pAPort->InexactFilter.Bytes[0]);
+		XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]);
 
 		/* Set bit 15 in mode register. */
-		XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 		LoMode |= XM_MD_ENA_HSH;
-		XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+		XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);
 	}
 	else {
 		/* Clear bit 15 in mode register. */
-		XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 		LoMode &= ~XM_MD_ENA_HSH;
-		XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+		XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);
 	}
 
 	if (pAPort->PromMode != SK_PROM_MODE_NONE) {
-		(void)SkAddrPromiscuousChange(pAC, IoC, PortIdx, pAPort->PromMode);
+		(void)SkAddrPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
 	}
 
 	/* Set port's current MAC address. */
 	OutAddr = (SK_U16 *)&pAPort->CurrentMacAddress.a[0];
-	XM_OUTADDR(IoC, PortIdx, XM_SA, OutAddr);
+	XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
 
-#ifdef DEBUG
-	for (i = 0;		/* Also program the logical MAC address. */
-		i < pAPort->NextExactMatchRlmt;
-		i++) {
+#ifdef xDEBUG
+	for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
 		SK_U8		InAddr8[6];
 		SK_U16		*InAddr;
 
-		/* Get exact match address i from port PortIdx. */
+		/* Get exact match address i from port PortNumber. */
 		InAddr = (SK_U16 *)&InAddr8[0];
-		XM_INADDR(IoC, PortIdx, XM_EXM(i), InAddr);
+		XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr);
 		SK_DBG_MSG(
 			pAC,
-			SK_DBGMOD_RLMT,
+			SK_DBGMOD_ADDR,
 			SK_DBGCAT_CTRL,
 			("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x --  %02x %02x %02x %02x %02x %02x.\n",
 				i,
-				PortIdx,
+				PortNumber,
 				InAddr8[0],
 				InAddr8[1],
 				InAddr8[2],
@@ -846,52 +862,70 @@
 int	SkAddrOverride(
 SK_AC		*pAC,		/* adapter context */
 SK_IOC		IoC,		/* I/O context */
-SK_U32		PortIdx,	/* Port Index */
+SK_U32		PortNumber,	/* Port Number */
 SK_MAC_ADDR	*pNewAddr,	/* new MAC address */
 int			Flags)		/* logical/physical MAC address */
 {
+	SK_EVPARA	Para;
+	SK_U32		NetNumber;
 	SK_U32		i;
 	SK_U16		*OutAddr;
-	SK_EVPARA	Para;
-#if 0
-	SK_MAC_ADDR	NewAddr;	/* new MAC address */
-	SK_U8		AddrBits;
-#endif	/* 0 */
 
-	if (PortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
+	NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber;
+
+	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {
 		return (SK_ADDR_ILLEGAL_PORT);
 	}
 
-	if (pNewAddr->a[0] & SK_MC_BIT) {
+	if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) {
 		return (SK_ADDR_MULTICAST_ADDRESS);
 	}
 
-#if 0
-DANGEROUS!
-	if (Flags & SK_ADDR_PHYSICAL_ADDRESS) {	/* Physical address. */
-		if (!pAC->Addr.Port[PortIdx].CurrentMacAddressSet) {
-			pAC->Addr.Port[PortIdx].PreviousMacAddress = *pNewAddr;
-			pAC->Addr.Port[PortIdx].CurrentMacAddress = *pNewAddr;
-			pAC->Addr.Port[PortIdx].CurrentMacAddressSet = SK_TRUE;
-			return (SK_ADDR_SUCCESS);
-		}
+	if (!pAC->Addr.Net[NetNumber].CurrentMacAddressSet) {
+		return (SK_ADDR_TOO_EARLY);
 	}
-	else {
-		if (!pAC->Addr.CurrentMacAddressSet) {
-			pAC->Addr.CurrentMacAddress = *pNewAddr;
-			pAC->Addr.CurrentMacAddressSet = SK_TRUE;
-			return (SK_ADDR_SUCCESS);
+
+	if (Flags & SK_ADDR_SET_LOGICAL) {	/* Activate logical MAC address. */
+		/* Parameter *pNewAddr is ignored. */
+		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
+			if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
+				return (SK_ADDR_TOO_EARLY);
+			}
 		}
-	}
-DANGEROUS!
-#endif	/* 0 */
 
-	if (!pAC->Addr.CurrentMacAddressSet) {
-		return (SK_ADDR_TOO_EARLY);
+		/* Set PortNumber to number of net's active port. */
+		PortNumber = pAC->Rlmt.Net[NetNumber].
+			Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
+
+		pAC->Addr.Port[PortNumber].Exact[0] =
+			pAC->Addr.Net[NetNumber].CurrentMacAddress;
+
+		/* Write address to first exact match entry of active port. */
+		(void)SkAddrMcUpdate(pAC, IoC, PortNumber);
 	}
+	else if (Flags & SK_ADDR_CLEAR_LOGICAL) {
+		/* Deactivate logical MAC address. */
+		/* Parameter *pNewAddr is ignored. */
+		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
+			if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
+				return (SK_ADDR_TOO_EARLY);
+			}
+		}
+
+		/* Set PortNumber to number of net's active port. */
+		PortNumber = pAC->Rlmt.Net[NetNumber].
+			Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
+
+		for (i = 0; i < SK_MAC_ADDR_LEN; i++ ) {
+			pAC->Addr.Port[PortNumber].Exact[0].a[i] = 0;
+		}
 
-	if (Flags & SK_ADDR_PHYSICAL_ADDRESS) {	/* Physical MAC address. */
-		if (SK_ADDR_EQUAL(pNewAddr->a, pAC->Addr.CurrentMacAddress.a)) {
+		/* Write address to first exact match entry of active port. */
+		(void)SkAddrMcUpdate(pAC, IoC, PortNumber);
+	}
+	else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) {	/* Physical MAC address. */
+		if (SK_ADDR_EQUAL(pNewAddr->a,
+			pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
 			return (SK_ADDR_DUPLICATE_ADDRESS);
 		}
 
@@ -900,10 +934,9 @@
 				return (SK_ADDR_TOO_EARLY);
 			}
 
-			if (SK_ADDR_EQUAL(
-				pNewAddr->a,
+			if (SK_ADDR_EQUAL(pNewAddr->a,
 				pAC->Addr.Port[i].CurrentMacAddress.a)) {
-				if (i == PortIdx) {
+				if (i == PortNumber) {
 					return (SK_ADDR_SUCCESS);
 				}
 				else {
@@ -912,20 +945,22 @@
 			}
 		}
 
-		pAC->Addr.Port[PortIdx].PreviousMacAddress =
-			pAC->Addr.Port[PortIdx].CurrentMacAddress;
-		pAC->Addr.Port[PortIdx].CurrentMacAddress = *pNewAddr;
+		pAC->Addr.Port[PortNumber].PreviousMacAddress =
+			pAC->Addr.Port[PortNumber].CurrentMacAddress;
+		pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
 
 		/* Change port's address. */
 		OutAddr = (SK_U16 *)pNewAddr;
-		XM_OUTADDR(IoC, PortIdx, XM_SA, OutAddr);
+		XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
 
 		/* Report address change to RLMT. */
-		Para.Para32[0] = PortIdx;
+		Para.Para32[0] = PortNumber;
+		Para.Para32[0] = -1;
 		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
 	}
 	else {	/* Logical MAC address. */
-		if (SK_ADDR_EQUAL(pNewAddr->a, pAC->Addr.CurrentMacAddress.a)) {
+		if (SK_ADDR_EQUAL(pNewAddr->a,
+			pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
 			return (SK_ADDR_SUCCESS);
 		}
 		
@@ -934,15 +969,18 @@
 				return (SK_ADDR_TOO_EARLY);
 			}
 
-			if (SK_ADDR_EQUAL(
-				pNewAddr->a,
+			if (SK_ADDR_EQUAL(pNewAddr->a,
 				pAC->Addr.Port[i].CurrentMacAddress.a)) {
 				return (SK_ADDR_DUPLICATE_ADDRESS);
 			}
 		}
 
-		pAC->Addr.CurrentMacAddress = *pNewAddr;
-		pAC->Addr.Port[PortIdx].Exact[0] = *pNewAddr;
+		/* Set PortNumber to number of net's active port. */
+		PortNumber = pAC->Rlmt.Net[NetNumber].
+			Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
+
+		pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr;
+		pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr;
 
 #ifdef DEBUG
 		SK_DBG_MSG(
@@ -950,27 +988,27 @@
 			SK_DBGMOD_ADDR,
 			SK_DBGCAT_CTRL,
 			("Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n",
-				pAC->Addr.PermanentMacAddress.a[0],
-				pAC->Addr.PermanentMacAddress.a[1],
-				pAC->Addr.PermanentMacAddress.a[2],
-				pAC->Addr.PermanentMacAddress.a[3],
-				pAC->Addr.PermanentMacAddress.a[4],
-				pAC->Addr.PermanentMacAddress.a[5]))
+				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[0],
+				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[1],
+				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2],
+				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3],
+				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4],
+				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5]))
 		SK_DBG_MSG(
 			pAC,
 			SK_DBGMOD_ADDR,
 			SK_DBGCAT_CTRL,
 			("New logical MAC Address: %02X %02X %02X %02X %02X %02X\n",
-				pAC->Addr.CurrentMacAddress.a[0],
-				pAC->Addr.CurrentMacAddress.a[1],
-				pAC->Addr.CurrentMacAddress.a[2],
-				pAC->Addr.CurrentMacAddress.a[3],
-				pAC->Addr.CurrentMacAddress.a[4],
-				pAC->Addr.CurrentMacAddress.a[5]))
+				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0],
+				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[1],
+				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2],
+				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3],
+				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4],
+				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5]))
 #endif	/* DEBUG */
 
 		/* Write address to first exact match entry of active port. */
-		(void)SkAddrMcUpdate(pAC, IoC, PortIdx);
+		(void)SkAddrMcUpdate(pAC, IoC, PortNumber);
 	}
 
 	return (SK_ADDR_SUCCESS);
@@ -998,7 +1036,7 @@
 int	SkAddrPromiscuousChange(
 SK_AC	*pAC,			/* adapter context */
 SK_IOC	IoC,			/* I/O context */
-SK_U32	PortIdx,		/* port whose promiscuous mode changes */
+SK_U32	PortNumber,		/* port whose promiscuous mode changes */
 int		NewPromMode)	/* new promiscuous mode */
 {
 	int			i;
@@ -1009,31 +1047,31 @@
 	SK_U16		LoMode;		/* Lower 16 bits of XMAC Mode Register. */
 	int			CurPromMode = SK_PROM_MODE_NONE;
 
-	if (PortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
+	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {
 		return (SK_ADDR_ILLEGAL_PORT);
 	}
 
 	/* Read CurPromMode from Hardware. */
-	XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+	XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 
 	if (LoMode & XM_MD_ENA_PROM) {
 		CurPromMode |= SK_PROM_MODE_LLC;
 	}
 	
 	for (Inexact = 0xFF, i = 0; i < 8; i++) {
-		Inexact &= pAC->Addr.Port[PortIdx].InexactFilter.Bytes[i];
+		Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
 	}
 	if (Inexact == 0xFF) {
-		CurPromMode |= (pAC->Addr.Port[PortIdx].PromMode & SK_PROM_MODE_ALL_MC);
+		CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
 	}
 	else {
 		/* Read InexactModeBit (bit 15 in mode register). */
-		XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 		
 		InexactModeBit = (LoMode & XM_MD_ENA_HSH) != 0;
 
 		/* Read 64-bit hash register from HW. */
-		XM_INHASH(IoC, PortIdx, XM_HSM, &HwInexactFilter.Bytes[0]);
+		XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]);
 
 		for (HwInexact = 0xFF, i = 0; i < 8; i++) {
 			HwInexact &= HwInexactFilter.Bytes[i];
@@ -1044,7 +1082,7 @@
 		}
 	}
 
-	pAC->Addr.Port[PortIdx].PromMode = NewPromMode;
+	pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
 
 	if (NewPromMode == CurPromMode) {
 		return (SK_ADDR_SUCCESS);
@@ -1053,43 +1091,43 @@
 	if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
 		!(CurPromMode & SK_PROM_MODE_ALL_MC)) {	/* All MC. */
 		/* Set all bits in 64-bit hash register. */
-		XM_OUTHASH(IoC, PortIdx, XM_HSM, &OnesHash);
+		XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
 
 		/* Set bit 15 in mode register. */
-		XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 		LoMode |= XM_MD_ENA_HSH;
-		XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+		XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);
 	}
 	else if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
 		!(NewPromMode & SK_PROM_MODE_ALL_MC)) {	/* Norm MC. */
 		for (Inexact = 0, i = 0; i < 8; i++) {
-			Inexact |= pAC->Addr.Port[PortIdx].InexactFilter.Bytes[i];
+			Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
 		}
 		if (Inexact == 0) {
 			/* Clear bit 15 in mode register. */
-			XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+			XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 			LoMode &= ~XM_MD_ENA_HSH;
-			XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+			XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);
 		}
 		else {
 			/* Set 64-bit hash register to InexactFilter. */
 			XM_OUTHASH(
 				IoC,
-				PortIdx,
+				PortNumber,
 				XM_HSM,
-				&pAC->Addr.Port[PortIdx].InexactFilter.Bytes[0]);
+				&pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
 
 			/* Set bit 15 in mode register. */
-			XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+			XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 			LoMode |= XM_MD_ENA_HSH;
-			XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+			XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);
 		}
 	}
 
 	if ((NewPromMode & SK_PROM_MODE_LLC) &&
 		!(CurPromMode & SK_PROM_MODE_LLC)) {	/* Prom. LLC */
 		/* Set promiscuous bit in mode register. */
-		XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 
 #if 0
 		/* Receive MAC frames. */
@@ -1097,12 +1135,12 @@
 #endif	/* 0 */
 
 		LoMode |= XM_MD_ENA_PROM;
-		XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+		XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);
 	}
 	else if ((CurPromMode & SK_PROM_MODE_LLC) &&
 		!(NewPromMode & SK_PROM_MODE_LLC)) {	/* Norm. LLC. */
 		/* Clear promiscuous bit in mode register. */
-		XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 
 #if 0
 		/* Don't receive MAC frames. */
@@ -1110,7 +1148,7 @@
 #endif	/* 0 */
 		
 		LoMode &= ~XM_MD_ENA_PROM;
-		XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+		XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);
 	}
 	
 	return (SK_ADDR_SUCCESS);
@@ -1135,19 +1173,23 @@
 int	SkAddrSwap(
 SK_AC	*pAC,			/* adapter context */
 SK_IOC	IoC,			/* I/O context */
-SK_U32	FromPortIdx,	/* Port1 Index */
-SK_U32	ToPortIdx)		/* Port2 Index */
+SK_U32	FromPortNumber,	/* Port1 Index */
+SK_U32	ToPortNumber)		/* Port2 Index */
 {
 	int			i;
 	SK_U8		Byte;
 	SK_MAC_ADDR	MacAddr;
 	SK_U32		DWord;
 
-	if (FromPortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
+	if (FromPortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {
+		return (SK_ADDR_ILLEGAL_PORT);
+	}
+
+	if (ToPortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {
 		return (SK_ADDR_ILLEGAL_PORT);
 	}
 
-	if (ToPortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
+	if (pAC->Rlmt.Port[FromPortNumber].Net != pAC->Rlmt.Port[ToPortNumber].Net) {
 		return (SK_ADDR_ILLEGAL_PORT);
 	}
 
@@ -1164,47 +1206,56 @@
 	 */
 
 	for (i = 0; i < SK_ADDR_EXACT_MATCHES; i++) {
-		MacAddr = pAC->Addr.Port[FromPortIdx].Exact[i];
-		pAC->Addr.Port[FromPortIdx].Exact[i] =
-			pAC->Addr.Port[ToPortIdx].Exact[i];
-		pAC->Addr.Port[ToPortIdx].Exact[i] = MacAddr;
+		MacAddr = pAC->Addr.Port[FromPortNumber].Exact[i];
+		pAC->Addr.Port[FromPortNumber].Exact[i] =
+			pAC->Addr.Port[ToPortNumber].Exact[i];
+		pAC->Addr.Port[ToPortNumber].Exact[i] = MacAddr;
 	}
 
 	for (i = 0; i < 8; i++) {
-		Byte = pAC->Addr.Port[FromPortIdx].InexactFilter.Bytes[i];
-		pAC->Addr.Port[FromPortIdx].InexactFilter.Bytes[i] =
-			pAC->Addr.Port[ToPortIdx].InexactFilter.Bytes[i];
-		pAC->Addr.Port[ToPortIdx].InexactFilter.Bytes[i] = Byte;
-	}
-
-	i = pAC->Addr.Port[FromPortIdx].PromMode;
-	pAC->Addr.Port[FromPortIdx].PromMode = pAC->Addr.Port[ToPortIdx].PromMode;
-	pAC->Addr.Port[ToPortIdx].PromMode = i;
-
-	DWord = pAC->Addr.Port[FromPortIdx].FirstExactMatchRlmt;
-	pAC->Addr.Port[FromPortIdx].FirstExactMatchRlmt =
-		pAC->Addr.Port[ToPortIdx].FirstExactMatchRlmt;
-	pAC->Addr.Port[ToPortIdx].FirstExactMatchRlmt = DWord;
-
-	DWord = pAC->Addr.Port[FromPortIdx].NextExactMatchRlmt;
-	pAC->Addr.Port[FromPortIdx].NextExactMatchRlmt =
-		pAC->Addr.Port[ToPortIdx].NextExactMatchRlmt;
-	pAC->Addr.Port[ToPortIdx].NextExactMatchRlmt = DWord;
-
-	DWord = pAC->Addr.Port[FromPortIdx].FirstExactMatchDrv;
-	pAC->Addr.Port[FromPortIdx].FirstExactMatchDrv =
-		pAC->Addr.Port[ToPortIdx].FirstExactMatchDrv;
-	pAC->Addr.Port[ToPortIdx].FirstExactMatchDrv = DWord;
-
-	DWord = pAC->Addr.Port[FromPortIdx].NextExactMatchDrv;
-	pAC->Addr.Port[FromPortIdx].NextExactMatchDrv =
-		pAC->Addr.Port[ToPortIdx].NextExactMatchDrv;
-	pAC->Addr.Port[ToPortIdx].NextExactMatchDrv = DWord;
-
-	pAC->Addr.ActivePort = ToPortIdx;
+		Byte = pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i];
+		pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i] =
+			pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i];
+		pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte;
+	}
+
+	i = pAC->Addr.Port[FromPortNumber].PromMode;
+	pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode;
+	pAC->Addr.Port[ToPortNumber].PromMode = i;
+
+	DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt;
+	pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt =
+		pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt;
+	pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord;
+
+	DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt;
+	pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt =
+		pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt;
+	pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord;
+
+	DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv;
+	pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv =
+		pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv;
+	pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord;
+
+	DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv;
+	pAC->Addr.Port[FromPortNumber].NextExactMatchDrv =
+		pAC->Addr.Port[ToPortNumber].NextExactMatchDrv;
+	pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord;
+
+	/* CAUTION: Solution works if only ports of one adapter are in use. */
+	for (i = 0; (SK_U32)i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].
+		Net->NetNumber].NumPorts; i++) {
+		if (pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
+			Port[i]->PortNumber == ToPortNumber) {
+			pAC->Addr.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
+				ActivePort = i;
+			/* 20001207 RA: Was "ToPortNumber;". */
 
-	(void)SkAddrMcUpdate(pAC, IoC, FromPortIdx);
-	(void)SkAddrMcUpdate(pAC, IoC, ToPortIdx);
+		}
+	}
+	(void)SkAddrMcUpdate(pAC, IoC, FromPortNumber);
+	(void)SkAddrMcUpdate(pAC, IoC, ToPortNumber);
 
 	return (SK_ADDR_SUCCESS);
 }	/* SkAddrSwap */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/skcsum.c linux/drivers/net/sk98lin/skcsum.c
--- v2.4.6/linux/drivers/net/sk98lin/skcsum.c	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/skcsum.c	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	skcsum.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.7 $
- * Date:	$Date: 2000/06/29 13:17:05 $
+ * Version:	$Revision: 1.8 $
+ * Date:	$Date: 2001/02/06 11:15:36 $
  * Purpose:	Store/verify Internet checksum in send/receive packets.
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2000 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,6 +26,9 @@
  * History:
  *
  *	$Log: skcsum.c,v $
+ *	Revision 1.8  2001/02/06 11:15:36  rassmann
+ *	Supporting two nets on dual-port adapters.
+ *	
  *	Revision 1.7  2000/06/29 13:17:05  rassmann
  *	Corrected reception of a packet with UDP checksum == 0 (which means there
  *	is no UDP checksum).
@@ -63,7 +65,7 @@
 
 #ifndef lint
 static const char SysKonnectFileId[] = "@(#)"
-	"$Id: skcsum.c,v 1.7 2000/06/29 13:17:05 rassmann Exp $"
+	"$Id: skcsum.c,v 1.8 2001/02/06 11:15:36 rassmann Exp $"
 	" (C) SysKonnect.";
 #endif	/* !lint */
 
@@ -249,7 +251,8 @@
 void SkCsGetSendInfo(
 SK_AC				*pAc,			/* Adapter context struct. */
 void				*pIpHeader,		/* IP header. */
-SKCS_PACKET_INFO	*pPacketInfo)	/* Packet information struct. */
+SKCS_PACKET_INFO	*pPacketInfo,	/* Packet information struct. */
+int					NetNumber)		/* Net number */
 {
 	/* Internet Header Version found in IP header. */
 	unsigned InternetHeaderVersion;
@@ -291,7 +294,7 @@
 			("Tx: Unknown Internet Header Version %u.\n",
 			InternetHeaderVersion));
 		pPacketInfo->ProtocolFlags = 0;
-		pAc->Csum.ProtoStats[SKCS_PROTO_STATS_IP].TxUnableCts++;
+		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;
 		return;
 	}
 
@@ -312,13 +315,13 @@
 		SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,
 			("Tx: Invalid IP Header Length %u.\n", IpHeaderLength));
 		pPacketInfo->ProtocolFlags = 0;
-		pAc->Csum.ProtoStats[SKCS_PROTO_STATS_IP].TxUnableCts++;
+		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;
 		return;
 	}
 
 	/* This is an IPv4 frame with a header of valid length. */
 
-	pAc->Csum.ProtoStats[SKCS_PROTO_STATS_IP].TxOkCts++;
+	pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxOkCts++;
 
 	/* Check if we should calculate the IP header checksum. */
 
@@ -347,14 +350,14 @@
 		/* TCP/IP frame. */
 		ProtocolFlags &= SKCS_PROTO_TCP | SKCS_PROTO_IP;
 		NextLevelProtoStats =
-			&pAc->Csum.ProtoStats[SKCS_PROTO_STATS_TCP];
+			&pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];
 	}
 	else if ((ProtocolFlags & SKCS_PROTO_UDP) != 0 &&
 		NextLevelProtocol == SKCS_PROTO_ID_UDP) {
 		/* UDP/IP frame. */
 		ProtocolFlags &= SKCS_PROTO_UDP | SKCS_PROTO_IP;
 		NextLevelProtoStats =
-			&pAc->Csum.ProtoStats[SKCS_PROTO_STATS_UDP];
+			&pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];
 	}
 	else {
 		/*
@@ -475,7 +478,8 @@
 SK_AC		*pAc,		/* Adapter context struct. */
 void		*pIpHeader,	/* IP header. */
 unsigned	Checksum1,	/* Hardware checksum 1. */
-unsigned	Checksum2)	/* Hardware checksum 2. */
+unsigned	Checksum2,	/* Hardware checksum 2. */
+int			NetNumber)	/* Net number */
 {
 	/* Internet Header Version found in IP header. */
 	unsigned InternetHeaderVersion;
@@ -522,7 +526,7 @@
 		SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,
 			("Rx: Unknown Internet Header Version %u.\n",
 			InternetHeaderVersion));
-		pAc->Csum.ProtoStats[SKCS_PROTO_STATS_IP].RxUnableCts++;
+		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxUnableCts++;
 		return (SKCS_STATUS_UNKNOWN_IP_VERSION);
 	}
 
@@ -541,7 +545,7 @@
 	if (IpHeaderLength < 5*4) {
 		SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,
 			("Rx: Invalid IP Header Length %u.\n", IpHeaderLength));
-		pAc->Csum.ProtoStats[SKCS_PROTO_STATS_IP].RxErrCts++;
+		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;
 		return (SKCS_STATUS_IP_CSUM_ERROR);
 	}
 
@@ -590,7 +594,7 @@
 		SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
 
 	if (IpHeaderChecksum != 0xFFFF) {
-		pAc->Csum.ProtoStats[SKCS_PROTO_STATS_IP].RxErrCts++;
+		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;
 		/* the NDIS tester wants to know the upper level protocol too */
 		if (NextLevelProtocol == SKCS_PROTO_ID_TCP) {
 			return(SKCS_STATUS_IP_CSUM_ERROR_TCP);
@@ -609,15 +613,17 @@
 	 * frame.
 	 */
 
-	if ((pAc->Csum.ReceiveFlags & SKCS_PROTO_TCP) != 0 &&
+	if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_TCP) != 0 &&
 		NextLevelProtocol == SKCS_PROTO_ID_TCP) {
 		/* TCP/IP frame. */
-		NextLevelProtoStats = &pAc->Csum.ProtoStats[SKCS_PROTO_STATS_TCP];
+		NextLevelProtoStats =
+			&pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];
 	}
-	else if ((pAc->Csum.ReceiveFlags & SKCS_PROTO_UDP) != 0 &&
+	else if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_UDP) != 0 &&
 		NextLevelProtocol == SKCS_PROTO_ID_UDP) {
 		/* UDP/IP frame. */
-		NextLevelProtoStats = &pAc->Csum.ProtoStats[SKCS_PROTO_STATS_UDP];
+		NextLevelProtoStats =
+			&pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];
 	}
 	else {
 		/*
@@ -755,11 +761,12 @@
 SK_AC		*pAc,				/* Adapter context struct. */
 unsigned	ReceiveFlags,		/* New receive flags. */
 unsigned	*pChecksum1Offset,	/* Offset for hardware checksum 1. */
-unsigned	*pChecksum2Offset)	/* Offset for hardware checksum 2. */
+unsigned	*pChecksum2Offset,	/* Offset for hardware checksum 2. */
+int			NetNumber)
 {
 	/* Save the receive flags. */
 
-	pAc->Csum.ReceiveFlags = ReceiveFlags;
+	pAc->Csum.ReceiveFlags[NetNumber] = ReceiveFlags;
 
 	/* First checksum start offset is the IP header. */
 	*pChecksum1Offset = SKCS_MAC_HEADER_SIZE;
@@ -871,23 +878,26 @@
 SK_EVPARA	Param)	/* Event dependent parameter. */
 {
 	int ProtoIndex;
+	int	NetNumber;
 
 	switch (Event) {
 	/*
 	 * Clear protocol statistics.
 	 *
 	 * Param - Protocol index, or -1 for all protocols.
+	 *		 - Net number.
 	 */
 	case SK_CSUM_EVENT_CLEAR_PROTO_STATS:
 
-		ProtoIndex = (int) Param.Para32[0];
+		ProtoIndex = (int)Param.Para32[0];
+		NetNumber = (int)Param.Para32[1];
 		if (ProtoIndex < 0) {	/* Clear for all protocols. */
-			memset(&pAc->Csum.ProtoStats[0], 0,
-				sizeof(pAc->Csum.ProtoStats));
+			memset(&pAc->Csum.ProtoStats[NetNumber][0], 0,
+				sizeof(pAc->Csum.ProtoStats[NetNumber]));
 		}
 		else {					/* Clear for individual protocol. */
-			memset(&pAc->Csum.ProtoStats[ProtoIndex], 0,
-				sizeof(pAc->Csum.ProtoStats[ProtoIndex]));
+			memset(&pAc->Csum.ProtoStats[NetNumber][ProtoIndex], 0,
+				sizeof(pAc->Csum.ProtoStats[NetNumber][ProtoIndex]));
 		}
 		break;
 	default:
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/skge.c linux/drivers/net/sk98lin/skge.c
--- v2.4.6/linux/drivers/net/sk98lin/skge.c	Wed Apr 18 14:40:05 2001
+++ linux/drivers/net/sk98lin/skge.c	Wed Jul  4 11:50:39 2001
@@ -1,20 +1,21 @@
-;/******************************************************************************
+/******************************************************************************
  *
- * Name:      	skge.c
+ * Name:    skge.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.29 $
- * Date:       	$Date: 2000/02/21 13:31:56 $
+ * Version:	$Revision: 1.29.2.6 $
+ * Date:       	$Date: 2001/05/21 07:59:29 $
  * Purpose:	The main driver source module
  *
  ******************************************************************************/
  
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	Driver for SysKonnect Gigabit Ethernet Server Adapters:
  *
+ *	SK-9861 (single link 1000Base-SX, VF45 Volition Plug)
+ *	SK-9862 (dual link   1000Base-SX, VF45 Volition Plug)
  *	SK-9841 (single link 1000Base-LX)
  *	SK-9842 (dual link   1000Base-LX)
  *	SK-9843 (single link 1000Base-SX)
@@ -25,6 +26,7 @@
  *	Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and 
  *	SysKonnects GEnesis Solaris driver
  *	Author: Christoph Goos (cgoos@syskonnect.de)
+ *	        Mirko Lindner (mlindner@syskonnect.de)
  *
  *	Address all question to: linux@syskonnect.de
  *
@@ -46,6 +48,27 @@
  * History:
  *
  *	$Log: skge.c,v $
+ *	Revision 1.29.2.6  2001/05/21 07:59:29  mlindner
+ *	fix: MTU init problems
+ *	
+ *	Revision 1.29.2.5  2001/05/08 11:25:08  mlindner
+ *	fix: removed VLAN error message
+ *	
+ *	Revision 1.29.2.4  2001/05/04 13:31:43  gklug
+ *	fix: do not handle eth_copy on bad fragments received.
+ *	
+ *	Revision 1.29.2.3  2001/04/23 08:06:43  mlindner
+ *	Fix: error handling
+ *	
+ *	Revision 1.29.2.2  2001/03/15 12:04:54  mlindner
+ *	Fixed memory problem
+ *	
+ *	Revision 1.29.2.1  2001/03/12 16:41:44  mlindner
+ *	add: procfs function
+ *	add: dual-net function
+ *	add: RLMT networks
+ *	add: extended PNMI features
+ *	
  *	Kernel 2.4.x specific:
  *	Revision 1.xx  2000/09/12 13:31:56  cgoos
  *	Fixed missign "dev=NULL in skge_probe.
@@ -109,7 +132,7 @@
  *	Transmit descriptor polling was not reenabled after SkGePortInit.
  *	
  *	Revision 1.16  1999/07/27 15:17:29  cgoos
- *	Added some "\n" in output strings (removed while debugging...).
+ *	Added some "\n" in output strings (removed while debuging...).
  *	
  *	Revision 1.15  1999/07/23 12:09:30  cgoos
  *	Performance optimization, rx checksumming, large frame support.
@@ -242,25 +265,17 @@
  *
  ******************************************************************************/
 
-static const char SysKonnectFileId[] = "@(#)" __FILE__ " (C) SysKonnect.";
-static const char SysKonnectBuildNumber[] =
-	"@(#)SK-BUILD: 3.05 (20000907) PL: 01"; 
+#include	"h/skversion.h"
 
 #include	<linux/module.h>
 #include	<linux/init.h>
+#include 	<linux/proc_fs.h>
 
 #include	"h/skdrv1st.h"
 #include	"h/skdrv2nd.h"
 
 /* defines ******************************************************************/
-
-#define BOOT_STRING	"sk98lin: Network Device Driver v3.05\n" \
-			"Copyright (C) 1999-2000 SysKonnect"
-
-#define VER_STRING	"3.05"
-
-
-/* for debugging on x86 only */
+/* for debuging on x86 only */
 /* #define BREAKPOINT() asm(" int $3"); */
 
 /* use of a transmit complete interrupt */
@@ -292,8 +307,7 @@
 // #define ROLE_A	{"Auto", }
 // #define ROLE_B	{"Auto", }
 // #define PREF_PORT	{"A", }
-// #define RLMT_MODE	{"CheckLink", }
-
+// #define RLMT_MODE	{"CheckLinkState", }
 
 #define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
 #define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
@@ -333,7 +347,18 @@
 static void	SetQueueSizes(SK_AC	*pAC);
 static int	SkGeChangeMtu(struct net_device *dev, int new_mtu);
 static void	PortReInitBmu(SK_AC*, int);
-static int	SkGeIocMib(SK_AC*, unsigned int, int);
+static int	SkGeIocMib(DEV_NET*, unsigned int, int);
+
+
+/*Extern */
+
+extern struct proc_dir_entry *pSkRootDir;
+
+//extern struct proc_dir_entry Our_Proc_Dir;
+extern int proc_read(char *buffer, char **buffer_location,
+	off_t offset, int buffer_length, int *eof, void *data);
+
+
 #ifdef DEBUG
 static void	DumpMsg(struct sk_buff*, char*);
 static void	DumpData(char*, int);
@@ -343,13 +368,27 @@
 
 /* global variables *********************************************************/
 static const char *BootString = BOOT_STRING;
-static struct net_device *root_dev;
+static struct net_device *root_dev = NULL;
 static int probed __initdata = 0;
+struct inode_operations SkInodeOps;
+//static struct file_operations SkFileOps;  /* with open/relase */
 
 /* local variables **********************************************************/
 static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
 static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
 
+
+
+void proc_fill_inode(struct inode *inode, int fill)
+{
+	if (fill)
+		MOD_INC_USE_COUNT;
+	else
+		MOD_DEC_USE_COUNT;
+}
+
+
+
 /*****************************************************************************
  *
  * 	skge_probe - find all SK-98xx adapters
@@ -365,12 +404,14 @@
  */
 static int __init skge_probe (void)
 {
-	int boards_found = 0;
-	int		version_disp = 0;
+	int 		boards_found = 0;
+	int			version_disp = 0;
 	SK_AC		*pAC;
-	struct pci_dev	*pdev = NULL;
-	unsigned long	base_address;
+	DEV_NET		*pNet = NULL;
+	struct 		pci_dev	*pdev = NULL;
+	unsigned long		base_address;
 	struct net_device *dev = NULL;
+	struct proc_dir_entry	*pProcFile;
 
 	if (probed)
 		return -ENODEV;
@@ -388,27 +429,46 @@
 	if (!pci_present())		/* is PCI support present? */
 		return -ENODEV;
 
+        pSkRootDir = create_proc_entry("sk98lin",
+                S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net); 
+
+	pSkRootDir->owner = THIS_MODULE;
+
 	while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT,
 				      PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) {
-		if (pci_enable_device(pdev))
-			continue;
 
 		dev = NULL;
-		dev = init_etherdev(dev, sizeof(SK_AC));
+		pNet = NULL;
+
+		if (pci_enable_device(pdev))
+			continue;
 
-		if (dev == NULL) {
+		if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == 0) {
 			printk(KERN_ERR "Unable to allocate etherdev "
 			       "structure!\n");
 			break;
 		}
 
-		pAC = dev->priv;
+		pNet = dev->priv;
+		pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
+		if (pNet->pAC == NULL){
+			kfree(dev->priv);
+			printk(KERN_ERR "Unable to allocate adapter "
+			       "structure!\n");
+			break;
+		}
+
+		memset(pNet->pAC, 0, sizeof(SK_AC));
+		pAC = pNet->pAC;
 		pAC->PciDev = *pdev;
 		pAC->PciDevId = pdev->device;
-		pAC->dev = dev;
+		pAC->dev[0] = dev;
+		pAC->dev[1] = dev;
 		sprintf(pAC->Name, "SysKonnect SK-98xx");
 		pAC->CheckQueue = SK_FALSE;
-
+		
+		pNet->Mtu = 1500;
+		pNet->Up = 0;
 		dev->irq = pdev->irq;
 
 		dev->open =		&SkGeOpen;
@@ -419,14 +479,20 @@
 		dev->set_mac_address =	&SkGeSetMacAddr;
 		dev->do_ioctl =		&SkGeIoctl;
 		dev->change_mtu =	&SkGeChangeMtu;
-		
+
+		pProcFile = create_proc_entry(dev->name, 
+			S_IFREG | 0444, pSkRootDir);
+		pProcFile->read_proc = proc_read;
+		pProcFile->write_proc = NULL;
+		pProcFile->nlink = 1;
+		pProcFile->size = sizeof(dev->name+1);
+		pProcFile->data = (void*)pProcFile;
+
 		/*
 		 * Dummy value.
 		 */
 		dev->base_addr = 42;
-
 		pci_set_master(pdev);
-
 		base_address = pci_resource_start (pdev, 0);
 
 #ifdef SK_BIG_ENDIAN
@@ -446,24 +512,28 @@
 		 * Remap the regs into kernel space.
 		 */
 
-
 		pAC->IoBase = (char*)ioremap(base_address, 0x4000);
 		if (!pAC->IoBase){
 			printk(KERN_ERR "%s:  Unable to map I/O register, "
 			       "SK 98xx No. %i will be disabled.\n",
 			       dev->name, boards_found);
+			kfree(dev);
 			break;
 		}
 		pAC->Index = boards_found;
 
 		if (SkGeBoardInit(dev, pAC)) {
 			FreeResources(dev);
+			kfree(dev);
 			continue;
 		}
 
-                memcpy((caddr_t) &dev->dev_addr,
-			(caddr_t) &pAC->Addr.CurrentMacAddress, 6);
- 
+		memcpy((caddr_t) &dev->dev_addr,
+			(caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
+
+		pNet->PortNr = 0;
+		pNet->NetNr = 0;
+
 		boards_found++;
 
 		/*
@@ -499,10 +569,12 @@
 static void FreeResources(struct net_device *dev)
 {
 SK_U32 AllocFlag;
-SK_AC	*pAC;
+DEV_NET		*pNet;
+SK_AC		*pAC;
 
 	if (dev->priv) {
-		pAC = (SK_AC*) dev->priv;
+		pNet = (DEV_NET*) dev->priv;
+		pAC = pNet->pAC;
 		AllocFlag = pAC->AllocFlag;
 		if (AllocFlag & SK_ALLOC_IRQ) {
 			free_irq(dev->irq, dev);
@@ -517,13 +589,6 @@
 	
 } /* FreeResources */
 
-
-static struct pci_device_id skge_pci_tbl[] __initdata = {
-	{ PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE, PCI_ANY_ID, PCI_ANY_ID, },
-	{ }			/* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, skge_pci_tbl);
-
 MODULE_AUTHOR("Christoph Goos <cgoos@syskonnect.de>");
 MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
 MODULE_PARM(AutoNeg_A,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
@@ -602,8 +667,8 @@
 #endif
 
 
-static int debug; /* not used */
-static int options[SK_MAX_CARD_PARAM]; /* not used */
+static int debug = 0; /* not used */
+static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */
 
 
 /*****************************************************************************
@@ -620,7 +685,6 @@
 static int __init skge_init_module(void)
 {
 	int cards;
-
 	root_dev = NULL;
 	
 	/* just to avoid warnings ... */
@@ -647,21 +711,28 @@
  */
 static void __exit skge_cleanup_module(void)
 {
-SK_AC	*pAC;
+DEV_NET		*pNet;
+SK_AC		*pAC;
 struct net_device *next;
 unsigned long Flags;
 SK_EVPARA EvPara;
 
 	while (root_dev) {
-		pAC = (SK_AC*)root_dev->priv;
+		pNet = (DEV_NET*) root_dev->priv;
+		pAC = pNet->pAC;
 		next = pAC->Next;
 
 		netif_stop_queue(root_dev);
 		SkGeYellowLED(pAC, pAC->IoBase, 0);
-		
+
 		if(pAC->BoardLevel == 2) {
 			/* board is still alive */
 			spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+			EvPara.Para32[0] = 0;
+			EvPara.Para32[1] = -1;
+			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+			EvPara.Para32[0] = 1;
+			EvPara.Para32[1] = -1;
 			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
 			SkEventDispatcher(pAC, pAC->IoBase);
 			/* disable interrupts */
@@ -671,15 +742,20 @@
 			pAC->BoardLevel = 0;
 			/* We do NOT check here, if IRQ was pending, of course*/
 		}
-	
+
 		if(pAC->BoardLevel == 1) {
 			/* board is still alive */
 			SkGeDeInit(pAC, pAC->IoBase); 
 			pAC->BoardLevel = 0;
 		}
-		
+
+		if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
+			unregister_netdev(pAC->dev[1]);
+			kfree(pAC->dev[1]);
+		}
+
 		FreeResources(root_dev);
-		
+
 		root_dev->get_stats = NULL;
 		/* 
 		 * otherwise unregister_netdev calls get_stats with
@@ -687,9 +763,13 @@
 		 */
 		unregister_netdev(root_dev);
 		kfree(root_dev);
-
+		kfree(pAC);
 		root_dev = next;
 	}
+
+	/* clear proc-dir */
+	remove_proc_entry(pSkRootDir->name, proc_net);
+
 } /* skge_cleanup_module */
 
 module_init(skge_init_module);
@@ -757,8 +837,6 @@
 
 	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 
-	GetConfiguration(pAC);
-
 	/* level 1 init common modules here (HW init) */
 	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
 	if (SkGeInit(pAC, pAC->IoBase, 1) != 0) {
@@ -773,6 +851,12 @@
 	SkRlmtInit( pAC, pAC->IoBase, 1);
 	SkTimerInit(pAC, pAC->IoBase, 1);
 
+	GetConfiguration(pAC);
+	if (pAC->RlmtNets == 2) {
+		pAC->GIni.GIPortUsage = SK_MUL_LINK;
+	}
+
+
 	pAC->BoardLevel = 1;
 	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 
@@ -801,7 +885,7 @@
 
 	SkCsSetReceiveFlags(pAC,
 		SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP,
-		&pAC->CsOfs1, &pAC->CsOfs2);
+		&pAC->CsOfs1, &pAC->CsOfs2, 0);
 	pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1;
 
 	BoardInitMem(pAC);
@@ -814,11 +898,13 @@
 
 	/* Print configuration settings */
 	printk("      PrefPort:%c  RlmtMode:%s\n",
-		'A' + pAC->Rlmt.PrefPort,
-		(pAC->RlmtMode==0)  ? "ChkLink" :
-		((pAC->RlmtMode==1) ? "ChkLink" :
-		((pAC->RlmtMode==3) ? "ChkOth" :
-		((pAC->RlmtMode==7) ? "ChkSeg" : "Error"))));
+		'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
+		(pAC->RlmtMode==0)  ? "Check Link State" :
+		((pAC->RlmtMode==1) ? "Check Link State" : 
+		((pAC->RlmtMode==3) ? "Check Local Port" : 
+		((pAC->RlmtMode==7) ? "Check Segmentation" : 
+		((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
+
 
 	SkGeYellowLED(pAC, pAC->IoBase, 1);
 
@@ -1103,10 +1189,13 @@
 static void SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs)
 {
 struct net_device *dev = (struct net_device *)dev_id;
+
+DEV_NET		*pNet;
 SK_AC		*pAC;
 SK_U32		IntSrc;		/* interrupts source register contents */	
 
-	pAC = (SK_AC*) dev->priv;
+	pNet = (DEV_NET*) dev->priv;
+	pAC = pNet->pAC;
 	
 	/*
 	 * Check and process if its our interrupt
@@ -1129,21 +1218,21 @@
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF RX1 IRQ\n"));
 			ReceiveIrq(pAC, &pAC->RxPort[0]);
-			SK_PNMI_CNT_RX_INTR(pAC);
+			SK_PNMI_CNT_RX_INTR(pAC,0);
 		}
 		if (IntSrc & IRQ_EOF_RX2) {
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF RX2 IRQ\n"));
 			ReceiveIrq(pAC, &pAC->RxPort[1]);
-			SK_PNMI_CNT_RX_INTR(pAC);
+			SK_PNMI_CNT_RX_INTR(pAC,1);
 		}
 #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
 		if (IntSrc & IRQ_EOF_AS_TX1) {
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF AS TX1 IRQ\n"));
-			SK_PNMI_CNT_TX_INTR(pAC);
+			SK_PNMI_CNT_TX_INTR(pAC,0);
 			spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
 			FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
 			spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
@@ -1152,7 +1241,7 @@
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF AS TX2 IRQ\n"));
-			SK_PNMI_CNT_TX_INTR(pAC);
+			SK_PNMI_CNT_TX_INTR(pAC,1);
 			spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
 			FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
 			spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
@@ -1162,7 +1251,7 @@
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF SY TX1 IRQ\n"));
-			SK_PNMI_CNT_TX_INTR(pAC);
+			SK_PNMI_CNT_TX_INTR(pAC,0);
 			spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
 			FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
 			spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
@@ -1172,7 +1261,7 @@
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF SY TX2 IRQ\n"));
-			SK_PNMI_CNT_TX_INTR(pAC);
+			SK_PNMI_CNT_TX_INTR(pAC,1);
 			spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
 			FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH);
 			spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
@@ -1210,8 +1299,12 @@
 	 * came in after handling the ring (OUTs may be delayed
 	 * in hardware buffers, but are through after IN)
 	 */
-	ReceiveIrq(pAC, &pAC->RxPort[pAC->ActivePort]);
-//	ReceiveIrq(pAC, &pAC->RxPort[1]);
+	// ReceiveIrq(pAC, &pAC->RxPort[pAC->ActivePort]);
+	ReceiveIrq(pAC, &pAC->RxPort[0]);
+	ReceiveIrq(pAC, &pAC->RxPort[1]);
+	
+
+
 
 #if 0
 // #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
@@ -1257,10 +1350,12 @@
 static void SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs)
 {
 struct net_device *dev = (struct net_device *)dev_id;
+DEV_NET		*pNet;
 SK_AC		*pAC;
 SK_U32		IntSrc;		/* interrupts source register contents */	
 
-	pAC = (SK_AC*) dev->priv;
+	pNet = (DEV_NET*) dev->priv;
+	pAC = pNet->pAC;
 	
 	/*
 	 * Check and process if its our interrupt
@@ -1283,14 +1378,14 @@
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF RX1 IRQ\n"));
 			ReceiveIrq(pAC, &pAC->RxPort[0]);
-			SK_PNMI_CNT_RX_INTR(pAC);
+			SK_PNMI_CNT_RX_INTR(pAC,0);
 		}
 #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
 		if (IntSrc & IRQ_EOF_AS_TX1) {
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF AS TX1 IRQ\n"));
-			SK_PNMI_CNT_TX_INTR(pAC);
+			SK_PNMI_CNT_TX_INTR(pAC,0);
 			spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
 			FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
 			spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
@@ -1300,7 +1395,7 @@
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF SY TX1 IRQ\n"));
-			SK_PNMI_CNT_TX_INTR(pAC);
+			SK_PNMI_CNT_TX_INTR(pAC,1);
 			spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
 			FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
 			spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
@@ -1376,12 +1471,14 @@
 static int SkGeOpen(
 struct net_device	*dev)
 {
-SK_AC		*pAC;		/* pointer to adapter context struct */
+DEV_NET			*pNet;
+SK_AC			*pAC;
 unsigned int	Flags;		/* for spin lock */
 int		i;
-SK_EVPARA	EvPara;		/* an event parameter union */
+SK_EVPARA		EvPara;		/* an event parameter union */
 
-	pAC = (SK_AC*) dev->priv;
+	pNet = (DEV_NET*) dev->priv;
+	pAC = pNet->pAC;
 	
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
@@ -1389,7 +1486,7 @@
 	if (pAC->BoardLevel == 0) {
 		/* level 1 init common modules here */
 		if (SkGeInit(pAC, pAC->IoBase, 1) != 0) {
-			printk("%s: HWInit(1) failed\n", pAC->dev->name);
+			printk("%s: HWInit(1) failed\n", pAC->dev[pNet->PortNr]->name);
 			return (-1);
 		}
 		SkI2cInit	(pAC, pAC->IoBase, 1);
@@ -1400,26 +1497,27 @@
 		SkTimerInit	(pAC, pAC->IoBase, 1);
 		pAC->BoardLevel = 1;
 	}
-		
-	/* level 2 init modules here */
-	SkGeInit	(pAC, pAC->IoBase, 2);
-	SkI2cInit	(pAC, pAC->IoBase, 2);
-	SkEventInit	(pAC, pAC->IoBase, 2);
-	SkPnmiInit	(pAC, pAC->IoBase, 2);
-	SkAddrInit	(pAC, pAC->IoBase, 2);
-	SkRlmtInit	(pAC, pAC->IoBase, 2);
-	SkTimerInit	(pAC, pAC->IoBase, 2);
-	pAC->BoardLevel = 2;
-	
+
+	if (pAC->BoardLevel != 2) {
+		/* level 2 init modules here */
+		SkGeInit	(pAC, pAC->IoBase, 2);
+		SkI2cInit	(pAC, pAC->IoBase, 2);
+		SkEventInit	(pAC, pAC->IoBase, 2);
+		SkPnmiInit	(pAC, pAC->IoBase, 2);
+		SkAddrInit	(pAC, pAC->IoBase, 2);
+		SkRlmtInit	(pAC, pAC->IoBase, 2);
+		SkTimerInit	(pAC, pAC->IoBase, 2);
+		pAC->BoardLevel = 2;
+	}
 	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-		// Enable transmit descriptor polling.
+		/* Enable transmit descriptor polling. */
 		SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
 		FillRxRing(pAC, &pAC->RxPort[i]);
 	}
 	SkGeYellowLED(pAC, pAC->IoBase, 1);
 
 #ifdef USE_INT_MOD
-// moderate only TX complete interrupts (these are not time critical)
+/* moderate only TX complete interrupts (these are not time critical) */
 #define IRQ_MOD_MASK (IRQ_EOF_AS_TX1 | IRQ_EOF_AS_TX2)
 	{
 		unsigned long ModBase;
@@ -1435,17 +1533,29 @@
 	SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
 
 	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-	SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
-	if (pAC->RlmtMode != 0) {
+
+	if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) {
+		EvPara.Para32[0] = pAC->RlmtNets;
+		EvPara.Para32[1] = -1;
+		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
+			EvPara);
 		EvPara.Para32[0] = pAC->RlmtMode;
+		EvPara.Para32[1] = 0;
 		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE,
 			EvPara);
 	}
+
+	EvPara.Para32[0] = pNet->NetNr;
+	EvPara.Para32[1] = -1;
+	SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
 	SkEventDispatcher(pAC, pAC->IoBase);
 	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-	
+
+	pAC->MaxPorts++;
+	pNet->Up = 1;
+
 	MOD_INC_USE_COUNT;
-	
+
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeOpen suceeded\n"));
 
@@ -1467,48 +1577,84 @@
 static int SkGeClose(
 struct net_device	*dev)
 {
+DEV_NET		*pNet;
 SK_AC		*pAC;
+
 unsigned int	Flags;		/* for spin lock */
-int		i;
-SK_EVPARA	EvPara;
+int				i;
+int				PortIdx;
+SK_EVPARA		EvPara;
 
 	netif_stop_queue(dev);
 
-	pAC = (SK_AC*) dev->priv;
-	
+	pNet = (DEV_NET*) dev->priv;
+	pAC = pNet->pAC;
+
+	if (pAC->RlmtNets == 1)
+		PortIdx = pAC->ActivePort;
+	else
+		PortIdx = pNet->NetNr;
+
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
 
 	/* 
 	 * Clear multicast table, promiscuous mode ....
 	 */
-	SkAddrMcClear(pAC, pAC->IoBase, pAC->ActivePort, 0);
-	SkAddrPromiscuousChange(pAC, pAC->IoBase, pAC->ActivePort,
+	 
+	SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
+	SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
 		SK_PROM_MODE_NONE);
 
+	if (pAC->MaxPorts == 1) {
+		spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+		/* disable interrupts */
+		SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+		EvPara.Para32[0] = pNet->NetNr;
+		EvPara.Para32[1] = -1;
+		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+		SkEventDispatcher(pAC, pAC->IoBase);
+		SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+		/* stop the hardware */
+		SkGeDeInit(pAC, pAC->IoBase);
+		pAC->BoardLevel = 0;
+		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+	} else {
 
-	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-	/* disable interrupts */
-	SK_OUT32(pAC->IoBase, B0_IMSK, 0);
-	SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-	SkEventDispatcher(pAC, pAC->IoBase);
-	SK_OUT32(pAC->IoBase, B0_IMSK, 0);
-	/* stop the hardware */
-	SkGeDeInit(pAC, pAC->IoBase);
-	pAC->BoardLevel = 0;
-	
-	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
-	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+		spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+		EvPara.Para32[0] = pNet->NetNr;
+		EvPara.Para32[1] = -1;
+		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+		SkEventDispatcher(pAC, pAC->IoBase);
+		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+		
+		/* Stop port */
+		spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]
+			[TX_PRIO_LOW].TxDesRingLock, Flags);
+		SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr, 
+			SK_STOP_ALL, SK_HARD_RST);
+		spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]
+			[TX_PRIO_LOW].TxDesRingLock, Flags);
+	}
+	if (pAC->RlmtNets == 1) {
 		/* clear all descriptor rings */
-		ReceiveIrq(pAC, &pAC->RxPort[i]);
-		ClearRxRing(pAC, &pAC->RxPort[i]);
-		ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
+		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+			ReceiveIrq(pAC, &pAC->RxPort[i]);
+			ClearRxRing(pAC, &pAC->RxPort[i]);
+			ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
+		}
+	} else {
+		/* clear port descriptor rings */
+		ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr]);
+		ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
+		ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
 	}
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeClose: done "));
 
+	pAC->MaxPorts--;
+	pNet->Up = 0;
 	MOD_DEC_USE_COUNT;
 	
 	return (0);
@@ -1531,12 +1677,17 @@
  */
 static int SkGeXmit(struct sk_buff *skb, struct net_device *dev)
 {
+DEV_NET		*pNet;
 SK_AC		*pAC;
-int		Rc;	/* return code of XmitFrame */
+int			Rc;	/* return code of XmitFrame */
 	
-	pAC = (SK_AC*) dev->priv;
+	pNet = (DEV_NET*) dev->priv;
+	pAC = pNet->pAC;
 
-	Rc = XmitFrame(pAC, &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW], skb);
+	if (pAC->RlmtNets == 2)
+		Rc = XmitFrame(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW], skb);
+	else
+		Rc = XmitFrame(pAC, &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW], skb);
 
 	/* Transmitter out of resources? */
 	if (Rc <= 0)
@@ -1551,7 +1702,7 @@
 	dev->trans_start = jiffies;
 	return (0);
 } /* SkGeXmit */
-	
+
 
 /*****************************************************************************
  *
@@ -1570,10 +1721,10 @@
  *	if necessary.
  *
  * Returns:
- *	> 0 - on succes: the number of bytes in the message
- *	= 0 - on resource shortage: this frame sent or dropped, now
+ *  > 0 - on succes: the number of bytes in the message
+ *  = 0 - on resource shortage: this frame sent or dropped, now
  *        the ring is full ( -> set tbusy)
- *	< 0 - on failure: other problems ( -> return failure to upper layers)
+ *  < 0 - on failure: other problems ( -> return failure to upper layers)
  */
 static int XmitFrame(
 SK_AC 		*pAC,		/* pointer to adapter context */
@@ -1595,7 +1746,7 @@
 		FreeTxDescriptors(pAC, pTxPort);
 		if (pTxPort->TxdRingFree == 0) {
 			spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
-			SK_PNMI_CNT_NO_TX_BUF(pAC);
+			SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 				SK_DBGCAT_DRV_TX_PROGRESS,
 				("XmitFrame failed\n"));
@@ -1699,13 +1850,13 @@
 			 * freed ( -> ring completely free now).
 			 */
 			pTxPort->pTxdRingTail = pTxd;
-			netif_start_queue(pAC->dev);
+			netif_start_queue(pAC->dev[pTxPort->PortIndex]);
 			return;
 		}
 		if (Control & TX_CTRL_OWN_BMU) {
 			pTxPort->pTxdRingTail = pTxd;
 			if (pTxPort->TxdRingFree > 0) {
-				netif_start_queue(pAC->dev);
+				netif_start_queue(pAC->dev[pTxPort->PortIndex]);
 			}
 			return;
 		}
@@ -1784,8 +1935,8 @@
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 			SK_DBGCAT_DRV_ENTRY,
 			("%s: Allocation of rx buffer failed !\n",
-			pAC->dev->name));
-		SK_PNMI_CNT_NO_RX_BUF(pAC);
+			pAC->dev[pRxPort->PortIndex]->name));
+		SK_PNMI_CNT_NO_RX_BUF(pAC, pRxPort->PortIndex);
 		return(SK_FALSE);
 	}
 	skb_reserve(pMsgBlock, 2); /* to align IP frames */
@@ -1877,64 +2028,110 @@
 int		Result;
 SK_U64		PhysAddr;
 
-
 rx_start:	
 	/* do forever; exit if RX_CTRL_OWN_BMU found */
-	while (pRxPort->RxdRingFree < pAC->RxDescrPerRing) {
-		pRxd = pRxPort->pRxdRingHead;
-		
+	for ( pRxd = pRxPort->pRxdRingHead ;
+		  pRxPort->RxdRingFree < pAC->RxDescrPerRing ;
+		  pRxd = pRxd->pNextRxd,
+		  pRxPort->pRxdRingHead = pRxd,
+		  pRxPort->RxdRingFree ++) {
+
+		/*
+		 * For a better understanding of this loop 
+		 * Go through every descriptor beginning at the head 
+		 * Please note: the ring might be completely received so the OWN bit
+		 * set is not a good crirteria to leave that loop.
+		 * Therefore the RingFree counter is used.
+		 * On entry of this loop pRxd is a pointer to the Rxd that needs
+		 * to be checked next.
+		 */
+
 		Control = pRxd->RBControl;
-		
+	
 		/* check if this descriptor is ready */
 		if ((Control & RX_CTRL_OWN_BMU) != 0) {
 			/* this descriptor is not yet ready */
+			/* This is the usual end of the loop */
+			/* We don't need to start the ring again */
 			FillRxRing(pAC, pRxPort);
 			return;
 		}
-		
+
 		/* get length of frame and check it */
 		FrameLength = Control & RX_CTRL_LEN_MASK;
-		if (FrameLength > pAC->RxBufSize)
+		if (FrameLength > pAC->RxBufSize) {
 			goto rx_failed;
+		}
 
 		/* check for STF and EOF */
 		if ((Control & (RX_CTRL_STF | RX_CTRL_EOF)) !=
-			(RX_CTRL_STF | RX_CTRL_EOF))
+			(RX_CTRL_STF | RX_CTRL_EOF)) {
 			goto rx_failed;
+		}
 		
 		/* here we have a complete frame in the ring */
 		pMsg = pRxd->pMBuf;
+
+		FrameStat = pRxd->FrameStat;
+		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
+			("Received frame of length %d on port %d\n",
+			FrameLength, PortIndex));
+		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
+			("Number of free rx descriptors: %d\n",
+			pRxPort->RxdRingFree));
+		/*DumpMsg(pMsg, "Rx");	*/	
 		
+		if ((Control & RX_CTRL_STAT_VALID) != RX_CTRL_STAT_VALID ||
+			(FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) {
+			/* there is a receive error in this frame */
+			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+				SK_DBGCAT_DRV_RX_PROGRESS,
+				("skge: Error in received frame, dropped!\n"
+				"Control: %x\nRxStat: %x\n",
+				Control, FrameStat));
+			PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+			PhysAddr |= (SK_U64) pRxd->VDataLow;
+			pci_dma_sync_single(&pAC->PciDev,
+						(dma_addr_t) PhysAddr,
+						FrameLength,
+						PCI_DMA_FROMDEVICE);
+			ReQueueRxBuffer(pAC, pRxPort, pMsg,
+				pRxd->VDataHigh, pRxd->VDataLow);
+
+			continue;
+		}
+
 		/*
 		 * if short frame then copy data to reduce memory waste
 		 */
-		pNewMsg = NULL;
-		if (FrameLength < SK_COPY_THRESHOLD) {
-			pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC);
-			if (pNewMsg != NULL) {
-				PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
-				PhysAddr |= (SK_U64) pRxd->VDataLow;
-
-				/* use new skb and copy data */
-				skb_reserve(pNewMsg, 2);
-				skb_put(pNewMsg, FrameLength);
-				pci_dma_sync_single(&pAC->PciDev,
-						    (dma_addr_t) PhysAddr,
-						    FrameLength,
-						    PCI_DMA_FROMDEVICE);
-				eth_copy_and_sum(pNewMsg, pMsg->data,
-					FrameLength, 0);
-				ReQueueRxBuffer(pAC, pRxPort, pMsg,
-					pRxd->VDataHigh, pRxd->VDataLow);
-				pMsg = pNewMsg;
-			}
+		if ((FrameLength < SK_COPY_THRESHOLD) &&
+			((pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC)) != NULL)) {
+			/*
+			 * Short frame detected and allocation successfull
+			 */
+			PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+			PhysAddr |= (SK_U64) pRxd->VDataLow;
+
+			/* use new skb and copy data */
+			skb_reserve(pNewMsg, 2);
+			skb_put(pNewMsg, FrameLength);
+			pci_dma_sync_single(&pAC->PciDev,
+						(dma_addr_t) PhysAddr,
+						FrameLength,
+						PCI_DMA_FROMDEVICE);
+			eth_copy_and_sum(pNewMsg, pMsg->data,
+				FrameLength, 0);
+			ReQueueRxBuffer(pAC, pRxPort, pMsg,
+				pRxd->VDataHigh, pRxd->VDataLow);
+			pMsg = pNewMsg;
+
 		}
+		else {
+			/*
+			 * if large frame, or SKB allocation failed, pass
+			 * the SKB directly to the networking
+			 */
 
-		/*
-		 * if large frame, or SKB allocation failed, pass
-		 * the SKB directly to the networking
-		 */
-		if (pNewMsg == NULL) {
 			PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
 			PhysAddr |= (SK_U64) pRxd->VDataLow;
 
@@ -1954,7 +2151,7 @@
 				if ((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) {
 					Result = SkCsGetReceiveInfo(pAC,
 						&pMsg->data[14], 
-						Csum1, Csum2);
+						Csum1, Csum2, pRxPort->PortIndex);
 					if (Result == 
 						SKCS_STATUS_IP_FRAGMENT ||
 						Result ==
@@ -1970,123 +2167,85 @@
 			} /* IP frame */
 		} /* frame > SK_COPY_TRESHOLD */
 		
-		FrameStat = pRxd->FrameStat;
-                if ((FrameStat & XMR_FS_LNG_ERR) != 0) {
-                        /* jumbo frame, count to correct statistic */
-                        SK_PNMI_CNT_RX_LONGFRAMES(pAC, pRxPort->PortIndex);
-                }
-		pRxd = pRxd->pNextRxd;
-		pRxPort->pRxdRingHead = pRxd;
-		pRxPort->RxdRingFree ++;
-		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
-			("Received frame of length %d on port %d\n",
-			FrameLength, PortIndex));
-		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
-			("Number of free rx descriptors: %d\n",
-			pRxPort->RxdRingFree));
-		
-		if ((Control & RX_CTRL_STAT_VALID) == RX_CTRL_STAT_VALID &&
-			(FrameStat & XMR_FS_ANY_ERR) == 0) {
-			// was the following, changed to allow VLAN support
-			// (XMR_FS_ANY_ERR | XMR_FS_1L_VLAN | XMR_FS_2L_VLAN)
-			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-				SK_DBGCAT_DRV_RX_PROGRESS,("V"));
-			ForRlmt = SK_RLMT_RX_PROTOCOL;
-			IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
-			SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
-				IsBc, &Offset, &NumBytes);
-			if (NumBytes != 0) {
-				IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
-				SK_RLMT_LOOKAHEAD(pAC, PortIndex, 
-					&pMsg->data[Offset],
-					IsBc, IsMc, &ForRlmt);
+		SK_DBG_MSG(NULL, SK_DBGMOD_DRV,	1,("V"));
+		ForRlmt = SK_RLMT_RX_PROTOCOL;
+		IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
+		SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
+			IsBc, &Offset, &NumBytes);
+		if (NumBytes != 0) {
+			IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
+			SK_RLMT_LOOKAHEAD(pAC, PortIndex, 
+				&pMsg->data[Offset],
+				IsBc, IsMc, &ForRlmt);
+		}
+		if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
+					SK_DBG_MSG(NULL, SK_DBGMOD_DRV,	1,("W"));
+			/* send up only frames from active port */
+			if ((PortIndex == pAC->ActivePort) ||
+				(pAC->RlmtNets == 2)) {
+				/* frame for upper layer */
+				SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U"));
+#ifdef xDEBUG
+				DumpMsg(pMsg, "Rx");
+#endif
+				SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
+					FrameLength, pRxPort->PortIndex);
+
+				pMsg->dev = pAC->dev[pRxPort->PortIndex];
+				pMsg->protocol = eth_type_trans(pMsg,
+					pAC->dev[pRxPort->PortIndex]);
+				netif_rx(pMsg);
+				pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
 			}
-			if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
-				/* send up only frames from active port */
-			    	if (PortIndex == pAC->ActivePort) {
-					/* frame for upper layer */
-					SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 
-						SK_DBGCAT_DRV_RX_PROGRESS,
-						("U"));
-#ifdef DUMP_RX
-					DumpMsg(pMsg, "Rx");
-#endif
-					pMsg->dev = pAC->dev;
-					pMsg->protocol = eth_type_trans(pMsg,
-						pAC->dev);
-					SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
-						FrameLength);
-					netif_rx(pMsg);
-					pAC->dev->last_rx = jiffies;
-				}
-				else {
-					/* drop frame */
-					SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 
-						SK_DBGCAT_DRV_RX_PROGRESS,
-						("D"));
-					DEV_KFREE_SKB_IRQ(pMsg);
-				}
-			} /* if not for rlmt */
 			else {
-				/* packet for rlmt */
+				/* drop frame */
 				SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 
-					SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
-				pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
-					pAC->IoBase, FrameLength);
-				if (pRlmtMbuf != NULL) {
-					pRlmtMbuf->pNext = NULL;
-					pRlmtMbuf->Length = FrameLength;
-					pRlmtMbuf->PortIdx = PortIndex;
-					EvPara.pParaPtr = pRlmtMbuf;
-					memcpy((char*)(pRlmtMbuf->pData),
-					       (char*)(pMsg->data),
-					       FrameLength);
-					SkEventQueue(pAC, SKGE_RLMT,
-						SK_RLMT_PACKET_RECEIVED,
-						EvPara);
-					pAC->CheckQueue = SK_TRUE;
-					SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 
-						SK_DBGCAT_DRV_RX_PROGRESS,
-						("Q"));
-				}
-				if ((pAC->dev->flags & 
-					(IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
-					(ForRlmt & SK_RLMT_RX_PROTOCOL) == 
-					SK_RLMT_RX_PROTOCOL) { 
-					pMsg->dev = pAC->dev;
-					pMsg->protocol = eth_type_trans(pMsg,
-						pAC->dev);
-					netif_rx(pMsg);
-					pAC->dev->last_rx = jiffies;
-				}
-				else {
-					DEV_KFREE_SKB_IRQ(pMsg);
-				}
-
-			} /* if packet for rlmt */
-		} /* if valid frame */
+					SK_DBGCAT_DRV_RX_PROGRESS,
+					("D"));
+				DEV_KFREE_SKB(pMsg);
+			}
+			
+		} /* if not for rlmt */
 		else {
-			/* there is a receive error in this frame */
-			if ((FrameStat & XMR_FS_1L_VLAN) != 0) {
-				printk("%s: Received frame"
-					" with VLAN Level 1 header, check"
-					" switch configuration\n",
-					pAC->dev->name);
+			/* packet for rlmt */
+			SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 
+				SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
+			pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
+				pAC->IoBase, FrameLength);
+			if (pRlmtMbuf != NULL) {
+				pRlmtMbuf->pNext = NULL;
+				pRlmtMbuf->Length = FrameLength;
+				pRlmtMbuf->PortIdx = PortIndex;
+				EvPara.pParaPtr = pRlmtMbuf;
+				memcpy((char*)(pRlmtMbuf->pData),
+					   (char*)(pMsg->data),
+					   FrameLength);
+				SkEventQueue(pAC, SKGE_RLMT,
+					SK_RLMT_PACKET_RECEIVED,
+					EvPara);
+				pAC->CheckQueue = SK_TRUE;
+				SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 
+					SK_DBGCAT_DRV_RX_PROGRESS,
+					("Q"));
 			}
-			if ((FrameStat & XMR_FS_2L_VLAN) != 0) {
-				printk("%s: Received frame"
-					" with VLAN Level 2 header, check"
-					" switch configuration\n",
-					pAC->dev->name);
+			if ((pAC->dev[pRxPort->PortIndex]->flags & 
+				(IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
+				(ForRlmt & SK_RLMT_RX_PROTOCOL) == 
+				SK_RLMT_RX_PROTOCOL) { 
+				pMsg->dev = pAC->dev[pRxPort->PortIndex];
+				pMsg->protocol = eth_type_trans(pMsg,
+					pAC->dev[pRxPort->PortIndex]);
+				netif_rx(pMsg);
+				pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
 			}
-			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-				SK_DBGCAT_DRV_RX_PROGRESS,
-				("skge: Error in received frame, dropped!\n"
-				"Control: %x\nRxStat: %x\n",
-				Control, FrameStat));
-			DEV_KFREE_SKB_IRQ(pMsg);
-		}
-	} /* while */
+			else {
+				DEV_KFREE_SKB(pMsg);
+			}
+
+		} /* if packet for rlmt */
+	} /* for ... scanning the RXD ring */
+
+	/* RXD ring is empty -> fill and restart */
 	FillRxRing(pAC, pRxPort);
 	/* do not start if called from Close */
 	if (pAC->BoardLevel > 0) {
@@ -2254,6 +2413,7 @@
 int	RxRam;		/* RAM used for the active port receive queue */
 int	i;		/* loop counter */
 
+if (pAC->RlmtNets == 1) {
 	StandbyRam = SK_RLMT_STANDBY_QRXSIZE + SK_RLMT_STANDBY_QXASIZE +
 		SK_RLMT_STANDBY_QXSSIZE;
 	RemainingRam = pAC->GIni.GIRamSize - 
@@ -2274,21 +2434,40 @@
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("queue sizes settings - rx:%d  txA:%d txS:%d\n",
 		pAC->RxQueueSize,pAC->TxAQueueSize, pAC->TxSQueueSize));
+} else {
+	RemainingRam = pAC->GIni.GIRamSize/pAC->GIni.GIMacsFound;
+	RxRam = (RemainingRam * 8 / 10) & ~7;
+	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+		pAC->GIni.GP[i].PRxQSize = RxRam;
+		pAC->GIni.GP[i].PXSQSize = 0;
+		pAC->GIni.GP[i].PXAQSize = (RemainingRam - RxRam) & ~7;
+	}
 	
+	pAC->RxQueueSize = RxRam;
+	pAC->TxSQueueSize = 0;
+	pAC->TxAQueueSize = (RemainingRam - RxRam) & ~7;
+}
 	for (i=0; i<SK_MAX_MACS; i++) {
 		pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing;
 	}
-	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-		pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 100;
+
+	if (pAC->RlmtNets == 2) {
+		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+			pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 100;
+		}
+	} else {
+		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+			pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 100;
+		}
+		/*
+		 * Do not set the Limit to 0, because this could cause
+		 * wrap around with ReQueue'ed buffers (a buffer could
+		 * be requeued in the same position, made accessable to
+		 * the hardware, and the hardware could change its
+		 * contents!
+		 */
+		pAC->RxPort[pAC->ActivePort].RxFillLimit = 1;
 	}
-	/*
-	 * Do not set the Limit to 0, because this could cause
-	 * wrap around with ReQueue'ed buffers (a buffer could
-	 * be requeued in the same position, made accessable to
-	 * the hardware, and the hardware could change its
-	 * contents!
-	 */
-	pAC->RxPort[pAC->ActivePort].RxFillLimit = 1;
 
 #ifdef DEBUG
 	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
@@ -2316,7 +2495,10 @@
  */
 static int SkGeSetMacAddr(struct net_device *dev, void *p)
 {
-SK_AC		*pAC = (SK_AC*) dev->priv;
+
+DEV_NET *pNet = (DEV_NET*) dev->priv;
+SK_AC	*pAC = pNet->pAC;
+
 struct sockaddr	*addr = p;
 unsigned int	Flags;
 	
@@ -2328,8 +2510,15 @@
 	memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
 	
 	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-	SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
-		(SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
+
+	if (pAC->RlmtNets == 2)
+		SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr,
+			(SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
+	else
+		SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
+			(SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
+
+	
 	
 	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 	return 0;
@@ -2352,37 +2541,47 @@
  */
 static void SkGeSetRxMode(struct net_device *dev)
 {
-SK_AC			*pAC;
+
+DEV_NET		*pNet;
+SK_AC		*pAC;
+
 struct dev_mc_list	*pMcList;
 int			i;
+int			PortIdx;
 unsigned int		Flags;
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeSetRxMode starts now... "));
-	pAC = (SK_AC*) dev->priv;
-	
+
+	pNet = (DEV_NET*) dev->priv;
+	pAC = pNet->pAC;
+	if (pAC->RlmtNets == 1)
+		PortIdx = pAC->ActivePort;
+	else
+		PortIdx = pNet->NetNr;
+
 	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
 	if (dev->flags & IFF_PROMISC) {
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 			("PROMISCUOUS mode\n"));
-		SkAddrPromiscuousChange(pAC, pAC->IoBase, pAC->ActivePort,
+		SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
 			SK_PROM_MODE_LLC);
 	} else if (dev->flags & IFF_ALLMULTI) {
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 			("ALLMULTI mode\n"));
-		SkAddrPromiscuousChange(pAC, pAC->IoBase, pAC->ActivePort,
+		SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
 			SK_PROM_MODE_ALL_MC);
 	} else {
-		SkAddrPromiscuousChange(pAC, pAC->IoBase, pAC->ActivePort,
+		SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
 			SK_PROM_MODE_NONE);
-		SkAddrMcClear(pAC, pAC->IoBase, pAC->ActivePort, 0);
+		SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
 
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 			("Number of MC entries: %d ", dev->mc_count));
 		
 		pMcList = dev->mc_list;
 		for (i=0; i<dev->mc_count; i++, pMcList = pMcList->next) {
-			SkAddrMcAdd(pAC, pAC->IoBase, pAC->ActivePort,
+			SkAddrMcAdd(pAC, pAC->IoBase, PortIdx,
 				(SK_MAC_ADDR*)pMcList->dmi_addr, 0);
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MCA,
 				("%02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -2393,7 +2592,7 @@
 				pMcList->dmi_addr[4],
 				pMcList->dmi_addr[5]));
 		}
-		SkAddrMcUpdate(pAC, pAC->IoBase, pAC->ActivePort);					
+		SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx);
 	
 	}
 	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
@@ -2417,6 +2616,8 @@
  */
 static int SkGeChangeMtu(struct net_device *dev, int NewMtu)
 {
+DEV_NET		*pNet;
+DEV_NET		*pOtherNet;
 SK_AC		*pAC;
 unsigned int	Flags;
 int		i;
@@ -2424,30 +2625,58 @@
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeChangeMtu starts now...\n"));
- 
-	pAC = (SK_AC*) dev->priv;
+
+	pNet = (DEV_NET*) dev->priv;
+	pAC = pNet->pAC;
+
 	if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
 		return -EINVAL;
 	}
 
+	pNet->Mtu = NewMtu;
+	pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv;
+	if ((pOtherNet->Mtu > 1500) && (NewMtu <= 1500) && (pOtherNet->Up==1)) {
+		return(0);
+	}
+
+	EvPara.Para32[0] = pNet->NetNr;
+	EvPara.Para32[1] = -1;
+
 	pAC->RxBufSize = NewMtu + 32;
 	dev->mtu = NewMtu;
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("New MTU: %d\n", NewMtu));
 
+	if(pAC->BoardLevel != 2) {
+		return 0;
+	}
+
 	/* prevent reconfiguration while changing the MTU */
 
 	/* disable interrupts */
 	SK_OUT32(pAC->IoBase, B0_IMSK, 0);
 	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-	SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+
+	/* Found more than one port */
+	if ((pAC->GIni.GIMacsFound == 2 ) && 
+		(pAC->RlmtNets == 2)) {
+			/* Stop both ports */
+			EvPara.Para32[0] = 0;
+			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+			EvPara.Para32[0] = 1;
+			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+	} else {
+		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+	}
+
 	SkEventDispatcher(pAC, pAC->IoBase);
 
 	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-		spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
+		spin_lock_irqsave(
+			&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock, Flags);
+		netif_stop_queue(pAC->dev[i]);
 	}
-	netif_stop_queue(pAC->dev);
 
 	/* 
 	 * adjust number of rx buffers allocated
@@ -2455,23 +2684,35 @@
 	if (NewMtu > 1500) {
 		/* use less rx buffers */
 		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-			if (i == pAC->ActivePort)
-				pAC->RxPort[i].RxFillLimit =
-					pAC->RxDescrPerRing - 100;
-			else
-				pAC->RxPort[i].RxFillLimit =
-					pAC->RxDescrPerRing - 10;
-
+			/* Found more than one port */
+			if ((pAC->GIni.GIMacsFound == 2 ) && 
+				(pAC->RlmtNets == 2)) {
+					pAC->RxPort[i].RxFillLimit = 
+						pAC->RxDescrPerRing - 100;
+			} else {
+				if (i == pAC->ActivePort)
+					pAC->RxPort[i].RxFillLimit =
+						pAC->RxDescrPerRing - 100;
+				else
+					pAC->RxPort[i].RxFillLimit =
+						pAC->RxDescrPerRing - 10;
+			}
 		}
 	}
 	else {
 		/* use normal anoumt of rx buffers */
 		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-			if (i == pAC->ActivePort)
-				pAC->RxPort[i].RxFillLimit = 1;
-			else
-				pAC->RxPort[i].RxFillLimit =
-					pAC->RxDescrPerRing - 100;
+			/* Found more than one port */
+			if ((pAC->GIni.GIMacsFound == 2 ) && 
+				(pAC->RlmtNets == 2)) {
+					pAC->RxPort[i].RxFillLimit = 1;
+			} else {
+				if (i == pAC->ActivePort)
+					pAC->RxPort[i].RxFillLimit = 1;
+				else
+					pAC->RxPort[i].RxFillLimit =
+						pAC->RxDescrPerRing - 100;
+			}
 		}
 	}
 	 
@@ -2481,6 +2722,7 @@
 	 * enable/disable hardware support for long frames
 	 */
 	if (NewMtu > 1500) {
+//		pAC->JumboActivated = SK_TRUE; /* is never set back !!! */
 		pAC->GIni.GIPortUsage = SK_JUMBO_LINK;
 		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
 			pAC->GIni.GP[i].PRxCmd = 
@@ -2488,10 +2730,14 @@
 		}
 	}
 	else {
-		pAC->GIni.GIPortUsage = SK_RED_LINK;
+		if ((pAC->GIni.GIMacsFound == 2 ) && 
+			(pAC->RlmtNets == 2)) {
+			pAC->GIni.GIPortUsage = SK_MUL_LINK;
+		} else {
+			pAC->GIni.GIPortUsage = SK_RED_LINK;
+		}
 		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-			pAC->GIni.GP[i].PRxCmd =
-				XM_RX_STRIP_FCS | XM_RX_LENERR_OK;
+			pAC->GIni.GP[i].PRxCmd = XM_RX_STRIP_FCS;
 		}
 	}
 
@@ -2519,7 +2765,7 @@
 		ClearRxRing(pAC, &pAC->RxPort[i]);
 		FillRxRing(pAC, &pAC->RxPort[i]);
 
-		// Enable transmit descriptor polling.
+		/* Enable transmit descriptor polling. */
 		SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
 		FillRxRing(pAC, &pAC->RxPort[i]);
 	};
@@ -2536,7 +2782,7 @@
 	}
 #endif
 
-	netif_start_queue(pAC->dev);
+	netif_start_queue(pAC->dev[pNet->PortNr]);
 	for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) {
 		spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
 	}
@@ -2548,7 +2794,30 @@
 	SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
 	SkEventDispatcher(pAC, pAC->IoBase);
 
+	/* Found more than one port */
+	if ((pAC->GIni.GIMacsFound == 2 ) && 
+		(pAC->RlmtNets == 2)) {
+			/* Start both ports */
+			EvPara.Para32[0] = pAC->RlmtNets;
+			EvPara.Para32[1] = -1;
+			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
+				EvPara);
+			
+			
+			EvPara.Para32[1] = -1;
+			EvPara.Para32[0] = pNet->PortNr;
+			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+			
+			if (pOtherNet->Up) {
+				EvPara.Para32[0] = pOtherNet->PortNr;
+				SkEventQueue(pAC, SKGE_RLMT, 
+					SK_RLMT_START, EvPara);
+			}
+	} else {
+		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+	}
 
+	SkEventDispatcher(pAC, pAC->IoBase);
 	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 	
 	return 0;
@@ -2568,7 +2837,8 @@
  */
 static struct net_device_stats *SkGeStats(struct net_device *dev)
 {
-SK_AC	*pAC = (SK_AC*) dev->priv;
+DEV_NET *pNet = (DEV_NET*) dev->priv;
+SK_AC	*pAC = pNet->pAC;
 SK_PNMI_STRUCT_DATA *pPnmiStruct;       /* structure for all Pnmi-Data */
 SK_PNMI_STAT    *pPnmiStat;             /* pointer to virtual XMAC stat. data */SK_PNMI_CONF    *pPnmiConf;             /* pointer to virtual link config. */
 unsigned int    Size;                   /* size of pnmi struct */
@@ -2580,7 +2850,7 @@
         memset(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
         Size = SK_PNMI_STRUCT_SIZE;
-        SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size);
+		SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
         pPnmiStat = &pPnmiStruct->Stat[0];
         pPnmiConf = &pPnmiStruct->Conf[0];
@@ -2622,7 +2892,7 @@
  * Description:
  *	This function is called if an ioctl is issued on the device.
  *	There are three subfunction for reading, writing and test-writing
- *	the private MIB data structure (useful for SysKonnect-internal tools).
+ *	the private MIB data structure (usefull for SysKonnect-internal tools).
  *
  * Returns:
  *	0, if everything is ok
@@ -2630,14 +2900,18 @@
  */
 static int SkGeIoctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
+DEV_NET		*pNet;
 SK_AC		*pAC;
+
 SK_GE_IOCTL	Ioctl;
 unsigned int	Err = 0;
 int		Size;
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeIoctl starts now...\n"));
-	pAC = (SK_AC*) dev->priv;
+
+	pNet = (DEV_NET*) dev->priv;
+	pAC = pNet->pAC;
 	
 	if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
 		return -EFAULT;
@@ -2653,7 +2927,7 @@
 			Ioctl.Len : sizeof(pAC->PnmiStruct))) {
 			return -EFAULT;
 		}
-		Size = SkGeIocMib(pAC, Ioctl.Len, cmd);
+		Size = SkGeIocMib(pNet, Ioctl.Len, cmd);
 		if(copy_to_user(Ioctl.pData, &pAC->PnmiStruct,
 			Ioctl.Len<Size? Ioctl.Len : Size)) {
 			return -EFAULT;
@@ -2688,25 +2962,30 @@
  *	returned size from PNMI call
  */
 static int SkGeIocMib(
-SK_AC		*pAC,	/* pointer to the adapter context */
+DEV_NET		*pNet,	/* pointer to the adapter context */
 unsigned int	Size,	/* length of ioctl data */
 int		mode)	/* flag for set/preset */
 {
 unsigned int	Flags;	/* for spin lock */
-	
+SK_AC		*pAC;
+
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeIocMib starts now...\n"));
+	pAC = pNet->pAC;
 	/* access MIB */
 	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
 	switch(mode) {
 	case SK_IOCTL_GETMIB:
-		SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size);
+		SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
+			pNet->NetNr);
 		break;
 	case SK_IOCTL_PRESETMIB:
-		SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size);
+		SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
+			pNet->NetNr);
 		break;
 	case SK_IOCTL_SETMIB:
-		SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size);
+		SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
+			pNet->NetNr);
 		break;
 	default:
 		break;
@@ -2780,7 +3059,7 @@
 			AutoNeg = AN_SENS;
 		}
 		else printk("%s: Illegal value for AutoNeg_A\n",
-			pAC->dev->name);
+			pAC->dev[0]->name);
 	}
 
 	DuplexCap = DC_BOTH;
@@ -2801,18 +3080,18 @@
 			DuplexCap = DC_HALF;
 		}
 		else printk("%s: Illegal value for DupCap_A\n",
-			pAC->dev->name);
+			pAC->dev[0]->name);
 	}
 	
 	/* check for illegal combinations */
 	if (AutoSet && AutoNeg==AN_SENS && DupSet) {
 		printk("%s, Port A: DuplexCapabilities"
-			" ignored using Sense mode\n", pAC->dev->name);
+			" ignored using Sense mode\n", pAC->dev[0]->name);
 	}
 	if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
 		printk("%s, Port A: Illegal combination"
 			" of values AutoNeg. and DuplexCap.\n    Using "
-			"Full Duplex\n", pAC->dev->name);
+			"Full Duplex\n", pAC->dev[0]->name);
 
 		DuplexCap = DC_FULL;
 	}
@@ -2824,7 +3103,7 @@
 		printk("%s, Port A: Duplex setting not"
 			" possible in\n    default AutoNegotiation mode"
 			" (Sense).\n    Using AutoNegotiation On\n",
-			pAC->dev->name);
+			pAC->dev[0]->name);
 		AutoNeg = AN_ON;
 	}
 	
@@ -2859,7 +3138,7 @@
 		SK_FLOW_MODE_NONE) {
 		printk("%s, Port A: FlowControl"
 			" impossible without AutoNegotiation,"
-			" disabled\n", pAC->dev->name);
+			" disabled\n", pAC->dev[0]->name);
 		pAC->GIni.GP[0].PFlowCtrlMode = SK_FLOW_MODE_NONE;
 	}
 
@@ -2878,7 +3157,7 @@
 			MSMode = SK_MS_MODE_SLAVE;
 		}
 		else printk("%s: Illegal value for Role_A\n",
-			pAC->dev->name);
+			pAC->dev[0]->name);
 	}
 	pAC->GIni.GP[0].PMSMode = MSMode;
 	
@@ -2927,12 +3206,12 @@
 	/* check for illegal combinations */
 	if (AutoSet && AutoNeg==AN_SENS && DupSet) {
 		printk("%s, Port B: DuplexCapabilities"
-			" ignored using Sense mode\n", pAC->dev->name);
+			" ignored using Sense mode\n", pAC->dev[1]->name);
 	}
 	if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
 		printk("%s, Port B: Illegal combination"
 			" of values AutoNeg. and DuplexCap.\n    Using "
-			"Full Duplex\n", pAC->dev->name);
+			"Full Duplex\n", pAC->dev[1]->name);
 
 		DuplexCap = DC_FULL;
 	}
@@ -2944,14 +3223,14 @@
 		printk("%s, Port B: Duplex setting not"
 			" possible in\n    default AutoNegotiation mode"
 			" (Sense).\n    Using AutoNegotiation On\n",
-			pAC->dev->name);
+			pAC->dev[1]->name);
 		AutoNeg = AN_ON;
 	}
-	
+
 	/* set the desired mode */
 	pAC->GIni.GP[1].PLinkModeConf =
 		Capabilities[AutoNeg][DuplexCap];
-	
+
 	pAC->GIni.GP[1].PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
 	if (FlowCtrl_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
 		FlowCtrl_B[pAC->Index] != NULL) {
@@ -2979,7 +3258,7 @@
 		SK_FLOW_MODE_NONE) {
 		printk("%s, Port B: FlowControl"
 			" impossible without AutoNegotiation,"
-			" disabled\n", pAC->dev->name);
+			" disabled\n", pAC->dev[1]->name);
 		pAC->GIni.GP[1].PFlowCtrlMode = SK_FLOW_MODE_NONE;
 	}
 
@@ -2998,7 +3277,7 @@
 			MSMode = SK_MS_MODE_SLAVE;
 		}
 		else printk("%s: Illegal value for Role_B\n",
-			pAC->dev->name);
+			pAC->dev[1]->name);
 	}
 	pAC->GIni.GP[1].PMSMode = MSMode;
 	
@@ -3009,8 +3288,8 @@
 		PrefPort[pAC->Index] != NULL) {
 		if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */
 			pAC->ActivePort = 0;
-			pAC->Rlmt.MacPreferred = -1; /* auto */
-			pAC->Rlmt.PrefPort = 0;
+			pAC->Rlmt.Net[0].Preference = -1; /* auto */
+			pAC->Rlmt.Net[0].PrefPort = 0;
 		}
 		else if (strcmp(PrefPort[pAC->Index],"A") == 0) {
 			/*
@@ -3018,8 +3297,8 @@
 			 * switch is issued after net up.
 			 */
 			Port = 0;
-			pAC->Rlmt.MacPreferred = Port;
-			pAC->Rlmt.PrefPort = Port;
+			pAC->Rlmt.Net[0].Preference = Port;
+			pAC->Rlmt.Net[0].PrefPort = Port;
 		}
 		else if (strcmp(PrefPort[pAC->Index],"B") == 0) {
 			/*
@@ -3027,12 +3306,14 @@
 			 * switch is issued after net up.
 			 */
 			Port = 1;
-			pAC->Rlmt.MacPreferred = Port;
-			pAC->Rlmt.PrefPort = Port;
+			pAC->Rlmt.Net[0].Preference = Port;
+			pAC->Rlmt.Net[0].PrefPort = Port;
 		}
 		else printk("%s: Illegal value for PrefPort\n",
-			pAC->dev->name);
+			pAC->dev[0]->name);
 	}
+
+	pAC->RlmtNets = 1;
 	
 	if (RlmtMode != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
 		RlmtMode[pAC->Index] != NULL) {
@@ -3051,9 +3332,18 @@
 				SK_RLMT_CHECK_LOC_LINK | 
 				SK_RLMT_CHECK_SEG;
 		}
+		else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) &&
+			(pAC->GIni.GIMacsFound == 2)) {
+				pAC->RlmtMode = SK_RLMT_CHECK_LINK;
+				pAC->RlmtNets = 2;
+		}
 		else {
 			printk("%s: Illegal value for"
-				" RlmtMode, using default\n", pAC->dev->name);
+				" RlmtMode, using default\n", pAC->dev[0]->name);
+
+printk("MacFound = %d\nRlmtMode = %s", pAC->GIni.GIMacsFound, RlmtMode[pAC->Index]);
+	
+
 			pAC->RlmtMode = 0;
 		}
 	}
@@ -3355,7 +3645,7 @@
 	case SK_DRV_ADAP_FAIL:
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
 			("ADAPTER FAIL EVENT\n"));
-		printk("%s: Adapter failed.\n", pAC->dev->name);
+		printk("%s: Adapter failed.\n", pAC->dev[0]->name);
 		/* disable interrupts */
 		SK_OUT32(pAC->IoBase, B0_IMSK, 0);
 		/* cgoos */
@@ -3365,9 +3655,9 @@
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
 			("PORT FAIL EVENT, Port: %d\n", FromPort));
 		if (FromPort == 0) {
-			printk("%s: Port A failed.\n", pAC->dev->name);
+			printk("%s: Port A failed.\n", pAC->dev[0]->name);
 		} else {
-			printk("%s: Port B failed.\n", pAC->dev->name);
+			printk("%s: Port B failed.\n", pAC->dev[1]->name);
 		}
 		/* cgoos */
 		break;
@@ -3408,7 +3698,7 @@
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
 			("NET UP EVENT, Port: %d ", Param.Para32[0]));
 		printk("%s: network connection up using"
-			" port %c\n", pAC->dev->name, 'A'+Param.Para32[0]);
+			" port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
 		printk("    speed:           1000\n");
 		Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
 		if (Stat == SK_LMODE_STAT_AUTOHALF ||
@@ -3451,7 +3741,8 @@
 			}
 		}
 		
-		if (Param.Para32[0] != pAC->ActivePort) {
+		if ((Param.Para32[0] != pAC->ActivePort) && 
+			(pAC->RlmtNets == 1)) {
 			NewPara.Para32[0] = pAC->ActivePort;
 			NewPara.Para32[1] = Param.Para32[0];
 			SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
@@ -3462,21 +3753,21 @@
 		/* action list 7 */
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
 			("NET DOWN EVENT "));
-		printk("%s: network connection down\n", pAC->dev->name);
+		printk("%s: network connection down\n", pAC->dev[Param.Para32[1]]->name);
 		break;
 	case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
 			("PORT SWITCH HARD "));
 	case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
 	/* action list 6 */
-		printk("%s: switching to port %c\n", pAC->dev->name,
+		printk("%s: switching to port %c\n", pAC->dev[0]->name,
 			'A'+Param.Para32[1]);
 	case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
 		FromPort = Param.Para32[0];
 		ToPort = Param.Para32[1];
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
 			("PORT SWITCH EVENT, From: %d  To: %d (Pref %d) ",
-			FromPort, ToPort, pAC->Rlmt.PrefPort));
+			FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort));
 		NewPara.Para64 = FromPort;
 		SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
 		NewPara.Para64 = ToPort;
@@ -3591,7 +3882,7 @@
 		break;
 	}
 	printk(KERN_INFO "%s: -- ERROR --\n        Class:  %s\n"
-		"        Nr:  0x%x\n        Msg:  %s\n", pAC->dev->name,
+		"        Nr:  0x%x\n        Msg:  %s\n", pAC->dev[0]->name,
 		ClassStr, ErrNum, pErrorMsg);
 
 } /* SkErrorLog */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/skgehwt.c linux/drivers/net/sk98lin/skgehwt.c
--- v2.4.6/linux/drivers/net/sk98lin/skgehwt.c	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/skgehwt.c	Wed Jul  4 11:50:39 2001
@@ -1,23 +1,32 @@
 /******************************************************************************
  *
  * Name:	skgehwt.c
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.13 $
- * Date:	$Date: 1999/11/22 13:31:12 $
+ * Project:	PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 1.12 $
+ * Date:	$Date: 1998/10/15 15:11:34 $
  * Purpose:	Hardware Timer.
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
+ *	(C)Copyright 1989-1998 SysKonnect,
  *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	All Rights Reserved
  *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
+ *	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT
+ *	The copyright notice above does not evidence any
+ *	actual or intended publication of such source code.
+ *
+ *	This Module contains Proprietary Information of SysKonnect
+ *	and should be treated as Confidential.
+ *
+ *	The information in this file is provided for the exclusive use of
+ *	the licensees of SysKonnect.
+ *	Such users have the right to use, modify, and incorporate this code
+ *	into products for purposes authorized by the license agreement
+ *	provided they include this notice and the associated copyright notice
+ *	with any such product.
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -27,9 +36,6 @@
  * History:
  *
  *	$Log: skgehwt.c,v $
- *	Revision 1.13  1999/11/22 13:31:12  cgoos
- *	Changed license header to GPL.
- *	
  *	Revision 1.12  1998/10/15 15:11:34  gklug
  *	fix: ID_sccs to SysKonnectFileId
  *	
@@ -77,7 +83,7 @@
 	Event queue and dispatcher
 */
 static const char SysKonnectFileId[] =
-	"$Header: /usr56/projects/ge/schedule/skgehwt.c,v 1.13 1999/11/22 13:31:12 cgoos Exp $" ;
+	"$Header: /usr56/projects/ge/schedule/skgehwt.c,v 1.12 1998/10/15 15:11:34 gklug Exp $" ;
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
 #include "h/skdrv2nd.h"		/* Adapter Control- and Driver specific Def. */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/skgeinit.c linux/drivers/net/sk98lin/skgeinit.c
--- v2.4.6/linux/drivers/net/sk98lin/skgeinit.c	Tue Mar 20 12:04:59 2001
+++ linux/drivers/net/sk98lin/skgeinit.c	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	skgeinit.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.57 $
- * Date:	$Date: 2000/08/03 14:55:28 $
+ * Version:	$Revision: 1.63 $
+ * Date:	$Date: 2001/04/05 11:02:09 $
  * Purpose:	Contains functions to initialize the GE HW
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2000 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,6 +26,24 @@
  * History:
  *
  *	$Log: skgeinit.c,v $
+ *	Revision 1.63  2001/04/05 11:02:09  rassmann
+ *	Stop Port check of the STOP bit did not take 2/18 sec as wanted.
+ *	
+ *	Revision 1.62  2001/02/07 07:54:21  rassmann
+ *	Corrected copyright.
+ *	
+ *	Revision 1.61  2001/01/31 15:31:40  gklug
+ *	fix: problem with autosensing an SR8800 switch
+ *	
+ *	Revision 1.60  2000/10/18 12:22:21  cgoos
+ *	Added workaround for half duplex hangup.
+ *	
+ *	Revision 1.59  2000/10/10 11:22:06  gklug
+ *	add: in manual half duplex mode ignore carrier extension errors
+ *	
+ *	Revision 1.58  2000/10/02 14:10:27  rassmann
+ *	Reading BCOM PHY after releasing reset until it returns a valid value.
+ *	
  *	Revision 1.57  2000/08/03 14:55:28  rassmann
  *	Waiting for I2C to be ready before de-initializing adapter
  *	(prevents sensors from hanging up).
@@ -122,7 +139,7 @@
  *	chg: Default is autosensing with AUTOFULL mode
  *
  *	Revision 1.31  1998/11/25 15:36:16  gklug
- *	fix: do NOT stop LED Timer when port should be stopped
+ *	fix: do NOT stop LED Timer when port should be stoped
  *
  *	Revision 1.30  1998/11/24 13:15:28  gklug
  *	add: Init PCkeckPar struct member
@@ -283,7 +300,7 @@
 /* local variables ************************************************************/
 
 static const char SysKonnectFileId[] =
-	"@(#)$Id: skgeinit.c,v 1.57 2000/08/03 14:55:28 rassmann Exp $ (C) SK ";
+	"@(#)$Id: skgeinit.c,v 1.63 2001/04/05 11:02:09 rassmann Exp $ (C) SK ";
 
 struct s_QOffTab {
 	int	RxQOff;		/* Receive Queue Address Offset */
@@ -666,7 +683,11 @@
 	SK_OUT16(IoC, B3_PA_TOINI_TX1, SK_PKT_TO_MAX);
 	SK_OUT16(IoC, B3_PA_TOINI_TX2, SK_PKT_TO_MAX);
 
-	/* enable timeout timers if jumbo frames not used */
+	/*
+	 * enable timeout timers if jumbo frames not used
+	 * NOTE: the packet arbiter timeout interrupt is needed for
+	 * half duplex hangup workaround
+	 */
 	if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) {
 		if (pAC->GIni.GIMacsFound == 1) {
 			SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1);
@@ -1118,10 +1139,10 @@
  *
  *	Dir =	SK_STOP_TX 	Stops the transmit path only and resets
  *				the XMAC. The receive queue is still and
- *				the pending rx frames may still transferred
+ *				the pending rx frames may still transfered
  *				into the RxD.
  *		SK_STOP_RX	Stop the receive path. The tansmit path
- *				has to be stopped once before.
+ *				has to be stoped once before.
  *		SK_STOP_ALL	SK_STOP_TX + SK_STOP_RX
  *
  *	RstMode=SK_SOFT_RST	Resets the XMAC. The PHY is still alive.
@@ -1129,7 +1150,7 @@
  *
  * Example:
  *	1) A Link Down event was signaled for a port. Therefore the activity
- *	of this port should be stopped and a hardware reset should be issued
+ *	of this port should be stoped and a hardware reset should be issued
  *	to enable the workaround of XMAC errata #2. But the received frames
  *	should not be discarded.
  *		...
@@ -1198,10 +1219,10 @@
 	SK_U16	Word;
 	SK_U32	XsCsr;
 	SK_U32	XaCsr;
-	int	i;
+	int		i;
 	SK_BOOL	AllPortsDis;
 	SK_U64	ToutStart;
-	int	ToutCnt;
+	int		ToutCnt;
 
 	pPrt = &pAC->GIni.GP[Port];
 
@@ -1226,7 +1247,7 @@
 		do {
 			/*
 			 * Clear packet arbiter timeout to make sure
-			 * this loop will terminate
+			 * this loop will terminate.
 			 */
 			if (Port == MAC_1) {
 				Word = PA_CLR_TO_TX1;
@@ -1237,9 +1258,8 @@
 			SK_OUT16(IoC, B3_PA_CTRL, Word);
 
 			/*
-			 * If the transfer stucks at the XMAC the STOP command
-			 * will not terminate if we don't flush the XMACs
-			 * transmit FIFO !
+			 * If the transfer stucks at the XMAC the STOP command will not
+			 * terminate if we don't flush the XMAC's transmit FIFO!
 			 */
 			XM_IN32(IoC, Port, XM_MODE, &DWord);
 			DWord |= XM_MD_FTF;
@@ -1248,7 +1268,7 @@
 			XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
 			XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);
 
-			if (ToutStart + (SK_TICKS_PER_SEC / 18) >= SkOsGetTime(pAC)) {
+			if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) {
 				/*
 				 * Timeout of 1/18 second reached.
 				 * This needs to be checked at 1/18 sec only.
@@ -1257,9 +1277,8 @@
 				switch (ToutCnt) {
 				case 1:
 					/*
-					 * Cache Incoherency workaround:
-					 * Assume a start command has been 
-					 * lost while sending the frame. 
+					 * Cache Incoherency workaround: Assume a start command
+					 * has been lost while sending the frame. 
 					 */
 					ToutStart = SkOsGetTime(pAC);
 					if (XsCsr & CSR_STOP) {
@@ -1275,6 +1294,7 @@
 					 * calls StopPort again.
 					 * XXX.
 					 */
+
 					/* Fatal Error, Loop aborted */
 					/* Create an Error Log Entry */
 					SK_ERR_LOG(
@@ -1290,12 +1310,12 @@
 				}
 			}
 
-		/*
-		 * Because of the ASIC problem report entry from 21.08.1998 it is
-		 * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
-		 */
-		} while ((XsCsr & (CSR_STOP|CSR_SV_IDLE)) != CSR_SV_IDLE ||
-			 (XaCsr & (CSR_STOP|CSR_SV_IDLE)) != CSR_SV_IDLE);
+			/*
+			 * Because of the ASIC problem report entry from 21.08.1998 it is
+			 * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
+			 */
+		} while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE ||
+			 (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
 
 		/* reset the XMAC depending on the RstMode */
 		if (RstMode == SK_SOFT_RST) {
@@ -1362,13 +1382,13 @@
 				i--;
 			}
 
-		/* finish if CSR_STOP is done or CSR_SV_IDLE is true and i==0 */
-		/*
-		 * because of the ASIC problem report entry from 21.08.98
-		 * it is required to wait until CSR_STOP is reset and
-		 * CSR_SV_IDLE is set.
-		 */
-		} while ((DWord & (CSR_STOP|CSR_SV_IDLE)) != CSR_SV_IDLE &&
+			/* finish if CSR_STOP is done or CSR_SV_IDLE is true and i==0 */
+			/*
+			 * because of the ASIC problem report entry from 21.08.98
+			 * it is required to wait until CSR_STOP is reset and
+			 * CSR_SV_IDLE is set.
+			 */
+		} while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE &&
 			((DWord & CSR_SV_IDLE) == 0 || i != 0));
 
 		/* The path data transfer activity is fully stopped now. */
@@ -1433,6 +1453,7 @@
 		pPrt->PIsave = 0;
 		pPrt->PPrevShorts = 0;
 		pPrt->PLinkResCt = 0;
+		pPrt->PAutoNegTOCt = 0;
 		pPrt->PPrevRx = 0;
 		pPrt->PPrevFcs = 0;
 		pPrt->PRxLim = SK_DEF_RX_WA_LIM;
@@ -1717,6 +1738,17 @@
 		if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
 			pPrt->PRxCmd |= XM_RX_BIG_PK_OK;
 		}
+
+		if (pPrt->PLinkModeConf == SK_LMODE_HALF) {
+			/*
+			 * If in manual half duplex mode
+			 * the other side might be in full duplex mode
+			 * so ignore if a carrier extension is not seen on
+			 * frames received
+			 */
+			pPrt->PRxCmd |= XM_RX_DIS_CEXT;
+		}
+
 	}
 }	/* SkGeInit2 */
 
@@ -1891,7 +1923,7 @@
  *		for PRxQSize, PXSQSize, or PXAQSize are invalid for one
  *		or more queues. The specified port was NOT initialized.
  *		An error log entry was generated.
- *	2:	The port has to be stopped before it can be initilaized again.
+ *	2:	The port has to be stopped before it can be initialized again.
  */
 int SkGeInitPort(
 SK_AC	*pAC,		/* adapter context */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/skgepnmi.c linux/drivers/net/sk98lin/skgepnmi.c
--- v2.4.6/linux/drivers/net/sk98lin/skgepnmi.c	Tue Mar 20 12:04:59 2001
+++ linux/drivers/net/sk98lin/skgepnmi.c	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	skgepnmi.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.78 $
- * Date:	$Date: 2000/09/12 10:44:58 $
+ * Version:	$Revision: 1.87 $
+ * Date:	$Date: 2001/04/06 13:35:09 $
  * Purpose:	Private Network Management Interface
  *
  ****************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,6 +26,37 @@
  * History:
  *
  *	$Log: skgepnmi.c,v $
+ *	Revision 1.87  2001/04/06 13:35:09  mkunz
+ *	-Bugs fixed in handling of OID_SKGE_MTU and the VPD OID's
+ *	
+ *	Revision 1.86  2001/03/09 09:18:03  mkunz
+ *	Changes in SK_DBG_MSG
+ *	
+ *	Revision 1.85  2001/03/08 09:37:31  mkunz
+ *	Bugfix in ResetCounter for Pnmi.Port structure
+ *	
+ *	Revision 1.84  2001/03/06 09:04:55  mkunz
+ *	Made some changes in instance calculation
+ *	C	^VS:
+ *	
+ *	Revision 1.83  2001/02/15 09:15:32  mkunz
+ *	Necessary changes for dual net mode added
+ *	
+ *	Revision 1.82  2001/02/07 08:24:19  mkunz
+ *	-Made changes in handling of OID_SKGE_MTU
+ *	
+ *	Revision 1.81  2001/02/06 09:58:00  mkunz
+ *	-Vpd bug fixed
+ *	-OID_SKGE_MTU added
+ *	-pnmi support for dual net mode. Interface function and macros extended
+ *	
+ *	Revision 1.80  2001/01/22 13:41:35  rassmann
+ *	Supporting two nets on dual-port adapters.
+ *	
+ *	Revision 1.79  2000/12/05 14:57:40  cgoos
+ *	SetStruct failed before first Link Up (link mode of virtual
+ *	port "INDETERMINATED").
+ *	
  *	Revision 1.78  2000/09/12 10:44:58  cgoos
  *	Fixed SK_PNMI_STORE_U32 calls with typecasted argument.
  *	
@@ -72,7 +102,7 @@
  *	
  *	Revision 1.67  1999/09/22 09:53:20  rwahl
  *	- Read Broadcom register for updating fcs error counter (1000Base-T).
- *	
+ *
  *	Revision 1.66  1999/08/26 13:47:56  rwahl
  *	Added SK_DRIVER_SENDEVENT when queueing RLMT_CHANGE_THRES trap.
  *	
@@ -81,7 +111,7 @@
  *	
  *	Revision 1.64  1999/05/20 09:24:12  cgoos
  *	Changes for 1000Base-T (sensors, Master/Slave).
- *	
+ *
  *	Revision 1.63  1999/04/13 15:11:58  mhaveman
  *	Moved include of rlmt.h to header skgepnmi.h because some macros
  *	are needed there.
@@ -149,7 +179,7 @@
  *	Fixed: Couldnot delete VPD keys on UNIX.
  *	
  *	Revision 1.48  1998/12/09 14:11:10  mhaveman
- *	-Add: Debugmessage for XMAC_RESET suppressed to minimize output.
+ *	-Add: Debugmessage for XMAC_RESET supressed to minimize output.
  *	-Fixed: RlmtChangeThreshold will now be initialized.
  *	-Fixed: VPD_ENTRIES_LIST extended value with unnecessary space char.
  *	-Fixed: On VPD key creation an invalid key name could be created
@@ -185,7 +215,7 @@
  *	Revision 1.43  1998/12/03 14:18:10  mhaveman
  *	-Fixed problem in PnmiSetStruct. It was impossible to set any value.
  *	-Removed VPD key evaluation for VPD_FREE_BYTES and VPD_ACTION.
- *	
+ *
  *	Revision 1.42  1998/12/03 11:31:47  mhaveman
  *	Inserted cast to satisfy lint.
  *	
@@ -206,7 +236,7 @@
  *	-Fixed bug for RX counters. On an RX overflow interrupt the high
  *	 words of all RX counters were incremented.
  *	-SET operations on FLOWCTRL_MODE and LINK_MODE accept now the
- *	 value 0, which has no effect. It is useful for multiple instance
+ *	 value 0, which has no effect. It is usefull for multiple instance
  *	 SETs.
  *	
  *	Revision 1.37  1998/11/20 08:02:04  mhaveman
@@ -220,7 +250,7 @@
  *	
  *	Revision 1.35  1998/11/16 07:45:34  mhaveman
  *	SkAddrOverride now returns value and will be checked.
- *	
+ *
  *	Revision 1.34  1998/11/10 13:40:37  mhaveman
  *	Needed to change interface, because NT driver needs a return value
  *	of needed buffer space on TOO_SHORT errors. Therefore all
@@ -240,7 +270,7 @@
  *	Revision 1.30  1998/11/03 12:04:46  mhaveman
  *	Fixed problem in SENSOR_VALUE, which wrote beyond the buffer end
  *	Fixed alignment problem with CHIPSET.
- *	
+ *
  *	Revision 1.29  1998/11/02 11:23:54  mhaveman
  *	Corrected SK_ERROR_LOG to SK_ERR_LOG. Sorry.
  *	
@@ -270,14 +300,14 @@
  *	-Fixed sequence of error return code (INSTANCE -> ACCESS -> SHORT)
  *	-Changed type of parameter Instance back to SK_U32 because of VPD
  *	-Updated new VPD function calls
- *	
+ *
  *	Revision 1.23  1998/10/23 10:16:37  mhaveman
  *	Fixed bugs after buffer test simulation.
  *	
  *	Revision 1.22  1998/10/21 13:23:52  mhaveman
  *	-Call syntax of SkOsGetTime() changed to SkOsGetTime(pAc).
  *	-Changed calculation of hundrets of seconds.
- *	
+ *
  *	Revision 1.20  1998/10/20 07:30:45  mhaveman
  *	Made type changes to unsigned integer where possible.
  *	
@@ -291,12 +321,12 @@
  *	 to HWACCESS.
  *	-Provided all MEMCPY/MEMSET macros with (char *) pointers, because
  *	 Solaris throwed warnings when mapping to bcopy/bset.
- *	
+ *
  *	Revision 1.17  1998/10/13 07:42:01  mhaveman
  *	-Added OIDs OID_SKGE_TRAP_NUMBER and OID_SKGE_ALL_DATA
  *	-Removed old cvs history entries
  *	-Renamed MacNumber to PortNumber
- *	
+ *
  *	Revision 1.16  1998/10/07 10:52:49  mhaveman
  *	-Inserted handling of some OID_GEN_ Ids for windows
  *	-Fixed problem with 803.2 statistic.
@@ -332,7 +362,7 @@
 
 
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skgepnmi.c,v 1.78 2000/09/12 10:44:58 cgoos Exp $"
+	"@(#) $Id: skgepnmi.c,v 1.87 2001/04/06 13:35:09 mkunz Exp $"
 	" (C) SysKonnect.";
 
 #include "h/skdrv1st.h"
@@ -356,14 +386,17 @@
  */
 int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
 int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
-	unsigned int *pLen, SK_U32 Instance);
+	unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
 int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
-	unsigned int *pLen, SK_U32 Instance);
+	unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
 int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
-	unsigned int *pLen, SK_U32 Instance);
-int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, unsigned int *pLen);
-int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, unsigned int *pLen);
-int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, unsigned int *pLen);
+	unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
+int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
+	unsigned int *pLen, SK_U32 NetIndex);
+int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, 
+	unsigned int *pLen, SK_U32 NetIndex);
+int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, 
+	unsigned int *pLen, SK_U32 NetIndex);
 int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
 
 
@@ -372,7 +405,7 @@
  */
 static int Addr(SK_AC *pAC, SK_IOC IoC, int action,
 	SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
-	unsigned int TableIndex);
+	unsigned int TableIndex, SK_U32 NetIndex);
 static SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
 	PhysPortIndex);
 static SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
@@ -381,14 +414,14 @@
 static void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
 static int CsumStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
 	char *pBuf, unsigned int *pLen, SK_U32 Instance,
-	unsigned int TableIndex);
+	unsigned int TableIndex, SK_U32 NetIndex);
 static int General(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
 	char *pBuf, unsigned int *pLen, SK_U32 Instance,
-	unsigned int TableIndex);
+	unsigned int TableIndex, SK_U32 NetIndex);
 static SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
 	unsigned int PhysPortIndex, unsigned int StatIndex);
 static SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
-	unsigned int StatIndex);
+	unsigned int StatIndex, SK_U32 NetIndex);
 static char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
 static void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
 	unsigned int *pEntries);
@@ -397,50 +430,50 @@
 static int LookupId(SK_U32 Id);
 static int Mac8023Stat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
 	char *pBuf, unsigned int *pLen, SK_U32 Instance,
-	unsigned int TableIndex);
+	unsigned int TableIndex, SK_U32 NetIndex);
 static int MacPrivateConf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
 	char *pBuf, unsigned int *pLen, SK_U32 Instance,
-	unsigned int TableIndex);
+	unsigned int TableIndex, SK_U32 NetIndex);
 static int MacPrivateStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
 	char *pBuf, unsigned int *pLen, SK_U32 Instance,
-	unsigned int TableIndex);
+	unsigned int TableIndex, SK_U32 NetIndex);
 static int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
 	unsigned int LastMac);
 static int Monitor(SK_AC *pAC, SK_IOC IoC, int action,
 	SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
-	unsigned int TableIndex);
+	unsigned int TableIndex, SK_U32 NetIndex);
 static int OidStruct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
 	char *pBuf, unsigned int *pLen, SK_U32 Instance,
-	unsigned int TableIndex);
+	unsigned int TableIndex, SK_U32 NetIndex);
 static int Perform(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
 	char *pBuf, unsigned int* pLen, SK_U32 Instance,
-	unsigned int TableIndex);
+	unsigned int TableIndex, SK_U32 NetIndex);
 static int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
-	unsigned int *pLen);
+	unsigned int *pLen, SK_U32 NetIndex);
 static int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
-	char *pBuf, unsigned int *pLen, SK_U32 Instance);
+	char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
 static void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
 static void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
 	unsigned int PortIndex);
 static void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
 	unsigned int SensorIndex);
 static void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
-static void ResetCounter(SK_AC *pAC, SK_IOC IoC);
+static void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
 static int Rlmt(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
 	char *pBuf, unsigned int *pLen, SK_U32 Instance,
-	unsigned int TableIndex);
+	unsigned int TableIndex, SK_U32 NetIndex);
 static int RlmtStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
 	char *pBuf, unsigned int *pLen, SK_U32 Instance,
-	unsigned int TableIndex);
-static int RlmtUpdate(SK_AC *pAC, SK_IOC IoC);
+	unsigned int TableIndex, SK_U32 NetIndex);
+static int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
 static int SensorStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
 	char *pBuf, unsigned int *pLen, SK_U32 Instance,
-	unsigned int TableIndex);
+	unsigned int TableIndex, SK_U32 NetIndex);
 static int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
 static void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
 static int Vpd(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
 	char *pBuf, unsigned int *pLen, SK_U32 Instance,
-	unsigned int TableIndex);
+	unsigned int TableIndex, SK_U32 NetIndex);
 
 
 /******************************************************************************
@@ -1323,11 +1356,16 @@
 		sizeof(SK_PNMI_RLMT_MONITOR),
 		SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAdmin),
 		SK_PNMI_RW, Monitor, 0},
+	{OID_SKGE_MTU,
+		1,
+		0,
+		SK_PNMI_MAI_OFF(MtuSize),
+		SK_PNMI_RW, MacPrivateConf, 0},
 };
 
 /*
  * Table for hardware register saving on resets and port switches
-*/
+ */
 static const SK_PNMI_STATADDR StatAddress[SK_PNMI_MAX_IDX] = {
 	/*  0 */	{TRUE, XM_TXF_OK},
 	/*  1 */	{TRUE, 0},
@@ -1445,6 +1483,7 @@
 		for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
 
 			pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
+			pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
 		}
 		break;
 
@@ -1600,7 +1639,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
  *	                         the data.
  *	SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown
@@ -1615,14 +1654,15 @@
 SK_U32 Id,		/* Object ID that is to be processed */
 void *pBuf,		/* Buffer to which to mgmt data will be retrieved */
 unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
-SK_U32 Instance)	/* Instance (1..n) that is to be queried or -1 */
+SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-		("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d\n", Id,
-		*pLen));
+		("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
+			Id, *pLen, Instance, NetIndex));
 
 	return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
-		Instance));
+		Instance, NetIndex));
 }
 
 /*****************************************************************************
@@ -1632,13 +1672,13 @@
  * Description:
  *	Calls a general sub-function for all this stuff. The preset does
  *	the same as a set, but returns just before finally setting the
- *	new value. This is useful to check if a set might be successful.
+ *	new value. This is usefull to check if a set might be successfull.
  *	If as instance a -1 is passed, an array of values is supposed and
  *	all instance of the OID will be set.
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -1657,14 +1697,16 @@
 SK_U32 Id,		/* Object ID that is to be processed */
 void *pBuf,		/* Buffer which stores the mgmt data to be set */
 unsigned int *pLen,	/* Total length of mgmt data */
-SK_U32 Instance)	/* Instance (1..n) that is to be set or -1 */
+SK_U32 Instance,	/* Instance (1..n) that is to be set or -1 */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-		("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d\n",
-		Id, *pLen));
+		("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
+			Id, *pLen, Instance, NetIndex));
+
 
 	return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
-		Instance));
+		Instance, NetIndex));
 }
 
 /*****************************************************************************
@@ -1674,13 +1716,13 @@
  * Description:
  *	Calls a general sub-function for all this stuff. The preset does
  *	the same as a set, but returns just before finally setting the
- *	new value. This is useful to check if a set might be successful.
+ *	new value. This is usefull to check if a set might be successfull.
  *	If as instance a -1 is passed, an array of values is supposed and
  *	all instance of the OID will be set.
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -1699,14 +1741,15 @@
 SK_U32 Id,		/* Object ID that is to be processed */
 void *pBuf,		/* Buffer which stores the mgmt data to be set */
 unsigned int *pLen,	/* Total length of mgmt data */
-SK_U32 Instance)	/* Instance (1..n) that is to be set or -1 */
+SK_U32 Instance,	/* Instance (1..n) that is to be set or -1 */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-		("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d\n", Id,
-		*pLen));
+		("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
+			Id, *pLen, Instance, NetIndex));
 
 	return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
-		Instance));
+		Instance, NetIndex));
 }
 
 /*****************************************************************************
@@ -1723,16 +1766,18 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
  *	                         the data.
+ *	SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist 
  */
 
 int SkPnmiGetStruct(
 SK_AC *pAC,		/* Pointer to adapter context */
 SK_IOC IoC,		/* IO context handle */
 void *pBuf,		/* Buffer which will store the retrieved data */
-unsigned int *pLen)	/* Length of buffer */
+unsigned int *pLen,	/* Length of buffer */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	int		Ret;
 	unsigned int	TableIndex;
@@ -1741,11 +1786,12 @@
 	unsigned int	InstanceCnt;
 	SK_U32		Instance;
 	unsigned int	TmpLen;
-	char		KeyArr[SK_PNMI_VPD_ARR_SIZE][SK_PNMI_VPD_STR_SIZE];
+	char		KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
+
 
-	
 	SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-		("PNMI: SkPnmiGetStruct: Called, BufLen=%d\n", *pLen));
+		("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
+			*pLen, NetIndex));
 
 	if (*pLen < SK_PNMI_STRUCT_SIZE) {
 
@@ -1759,6 +1805,13 @@
 		return (SK_PNMI_ERR_TOO_SHORT);
 	}
 
+    /*
+     * Check NetIndex
+     */
+	if (NetIndex >= pAC->Rlmt.NumNets) {
+		return (SK_PNMI_ERR_UNKNOWN_NET);
+	}
+
 	/* Update statistic */
 	SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
 
@@ -1770,7 +1823,7 @@
 		return (Ret);
 	}
 
-	if ((Ret = RlmtUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
+	if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
 
 		SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
 		*pLen = SK_PNMI_MIN_STRUCT_SIZE;
@@ -1812,7 +1865,6 @@
 		TableIndex ++) {
 
 		InstanceNo = IdTable[TableIndex].InstanceNo;
-
 		for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
 			InstanceCnt ++) {
 
@@ -1830,8 +1882,7 @@
 				IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
 				IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
 
-				SK_PNMI_READ_U32(KeyArr[InstanceCnt - 1],
-					Instance);
+				SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
 			}
 			else {
 				Instance = (SK_U32)InstanceCnt;
@@ -1840,7 +1891,7 @@
 			TmpLen = *pLen - DstOffset;
 			Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
 				IdTable[TableIndex].Id, (char *)pBuf +
-				DstOffset, &TmpLen, Instance, TableIndex);
+				DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
 
 			/*
 			 * An unknown instance error means that we reached
@@ -1850,7 +1901,7 @@
 			 */
 			if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
 
-				break;
+                break;
 			}
 
 			if (Ret != SK_PNMI_ERR_OK) {
@@ -1884,7 +1935,7 @@
  * Description:
  *	Calls a general sub-function for all this set stuff. The preset does
  *	the same as a set, but returns just before finally setting the
- *	new value. This is useful to check if a set might be successful.
+ *	new value. This is usefull to check if a set might be successfull.
  *	The sub-function runs through the IdTable, checks which OIDs are able
  *	to set, and calls the handler function of the OID to perform the
  *	preset. The return value of the function will also be stored in
@@ -1893,7 +1944,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -1905,12 +1956,15 @@
 SK_AC *pAC,		/* Pointer to adapter context */
 SK_IOC IoC,		/* IO context handle */
 void *pBuf,		/* Buffer which contains the data to be set */
-unsigned int *pLen)	/* Length of buffer */
+unsigned int *pLen,	/* Length of buffer */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-		("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d\n", *pLen));
+		("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
+			*pLen, NetIndex));
 
-	return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf, pLen));
+	return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf, 
+    					pLen, NetIndex));
 }
 
 /*****************************************************************************
@@ -1929,7 +1983,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -1941,12 +1995,15 @@
 SK_AC *pAC,		/* Pointer to adapter context */
 SK_IOC IoC,		/* IO context handle */
 void *pBuf,		/* Buffer which contains the data to be set */
-unsigned int *pLen)	/* Length of buffer */
+unsigned int *pLen,	/* Length of buffer */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-		("PNMI: SkPnmiSetStruct: Called, BufLen=%d\n", *pLen));
+		("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
+			*pLen, NetIndex));
 
-	return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf, pLen));
+	return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf, 
+    					pLen, NetIndex));
 }
 
 /*****************************************************************************
@@ -1981,11 +2038,6 @@
  *	SK_PNMI_EVT_RLMT_PORT_DOWN    Generated by RLMT to notify that a port
  *	                              went logically down. A trap message will
  *	                              be stored to the trap buffer.
- *	SK_PNMI_EVT_RLMT_PORT_SWITCH  Generated by RLMT to notify that the
- *	                              active port switched. PNMI will split
- *	                              this into two message ACTIVE_DOWN and
- *	                              ACTIVE_UP to be future compatible with
- *	                              load balancing and card fail over.
  *	SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
  *	                              spanning tree root bridges were
  *	                              detected. A trap message will be stored
@@ -1997,6 +2049,9 @@
  *	                              is now an active port. PNMI will now
  *	                              add the statistic data of this port to
  *	                              the virtual port.
+ *	SK_PNMI_EVT_RLMT_SET_NETS     Notifies PNMI about the net mode. The first Parameter
+ *	                              contains the number of nets. 1 means single net, 2 means
+ *	                              dual net. The second Parameter is -1
  *
  * Returns:
  *	Always 0
@@ -2009,6 +2064,7 @@
 SK_EVPARA Param)	/* Event dependent parameter */
 {
 	unsigned int	PhysPortIndex;
+    unsigned int	MaxNetNumber;
 	int		CounterIndex;
 	int		Ret;
 	SK_U16		MacStatus;
@@ -2022,6 +2078,7 @@
 	SK_U64		OldestValue;
 	SK_U64		Delta;
 	SK_PNMI_ESTIMATE *pEst;
+	SK_U32		NetIndex;
 
 
 #ifdef DEBUG
@@ -2284,9 +2341,27 @@
 
 	case SK_PNMI_EVT_CLEAR_COUNTER:
 		/*
+		 *  Param.Para32[0] contains the NetIndex (0 ..1).
+		 *  Param.Para32[1] is reserved, contains -1.
+		 */
+		NetIndex = (SK_U32)Param.Para32[0];
+
+#ifdef DEBUG
+		if (NetIndex >= pAC->Rlmt.NumNets) {
+
+			SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+				("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
+				NetIndex));
+
+			return (0);
+		}
+#endif
+
+		/*
 		 * Set all counters and timestamps to zero
 		 */
-		ResetCounter(pAC, IoC);
+		ResetCounter(pAC, IoC, NetIndex); /* the according NetIndex is required
+												as a Parameter of the Event */ 
 		break;
 
 	case SK_PNMI_EVT_XMAC_RESET:
@@ -2351,9 +2426,8 @@
 		}
 #endif
 		/*
-		 * Store a trap message in the trap buffer and generate
-		 * an event for user space applications with the
-		 * SK_DRIVER_SENDEVENT macro.
+		 * Store a trap message in the trap buffer and generate an event for
+		 * user space applications with the SK_DRIVER_SENDEVENT macro.
 		 */
 		QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP,
 			(unsigned int)Param.Para32[0]);
@@ -2372,9 +2446,8 @@
 		}
 #endif
 		/*
-		 * Store a trap message in the trap buffer and generate
-		 * an event for user space applications with the
-		 * SK_DRIVER_SENDEVENT macro.
+		 * Store a trap message in the trap buffer and generate an event for
+		 * user space applications with the SK_DRIVER_SENDEVENT macro.
 		 */
 		QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN,
 			(unsigned int)Param.Para32[0]);
@@ -2383,6 +2456,7 @@
 
 	case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
 		PhysPortIndex = (unsigned int)Param.Para32[0];
+		NetIndex = (SK_U32)Param.Para32[1];
 #ifdef DEBUG
 		if (PhysPortIndex >= SK_MAX_MACS) {
 
@@ -2390,8 +2464,23 @@
 				("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
 				PhysPortIndex));
 		}
+
+		if (NetIndex >= pAC->Rlmt.NumNets) {
+
+			SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+				("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
+				NetIndex));
+		}
 #endif
 		/*
+		 * For now, ignore event if NetIndex != 0.
+		 */
+		if (Param.Para32[1] != 0) {
+
+			return (0);
+		}
+
+		/*
 		 * Nothing to do if port is already inactive
 		 */
 		if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
@@ -2400,9 +2489,9 @@
 		}
 
 		/*
-		 * Update statistic counters to calculate new offset
-		 * for the virtual port and increment semaphore to
-		 * indicate that an update was already done.
+		 * Update statistic counters to calculate new offset for the virtual
+		 * port and increment semaphore to indicate that an update was already
+		 * done.
 		 */
 		if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
 			SK_PNMI_ERR_OK) {
@@ -2413,13 +2502,12 @@
 		pAC->Pnmi.MacUpdatedFlag ++;
 
 		/*
-		 * Calculate new counter offset for virtual port to
-		 * grant continous counting on port switches. The virtual
-		 * port consists of all currently active ports. The port
-		 * down event indicates that a port is removed fromt the
-		 * virtual port. Therefore add the counter value of the
-		 * removed port to the CounterOffset for the virtual port
-		 * to grant the same counter value.
+		 * Calculate new counter offset for virtual port to grant continous
+		 * counting on port switches. The virtual port consists of all currently
+		 * active ports. The port down event indicates that a port is removed
+		 * from the virtual port. Therefore add the counter value of the removed
+		 * port to the CounterOffset for the virtual port to grant the same
+		 * counter value.
 		 */
 		for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
 			CounterIndex ++) {
@@ -2429,8 +2517,7 @@
 				continue;
 			}
 
-			Value = GetPhysStatVal(pAC, IoC, PhysPortIndex,
-				CounterIndex);
+			Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
 
 			pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
 		}
@@ -2445,6 +2532,7 @@
 
 	case SK_PNMI_EVT_RLMT_ACTIVE_UP:
 		PhysPortIndex = (unsigned int)Param.Para32[0];
+		NetIndex = (SK_U32)Param.Para32[1];
 #ifdef DEBUG
 		if (PhysPortIndex >= SK_MAX_MACS) {
 
@@ -2452,8 +2540,23 @@
 				("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
 				PhysPortIndex));
 		}
+
+		if (NetIndex >= pAC->Rlmt.NumNets) {
+
+			SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+				("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
+				NetIndex));
+		}
 #endif
 		/*
+		 * For now, ignore event if NetIndex != 0.
+		 */
+		if (Param.Para32[1] != 0) {
+
+			return (0);
+		}
+
+		/*
 		 * Nothing to do if port is already active
 		 */
 		if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
@@ -2462,24 +2565,22 @@
 		}
 
 		/*
-		 * Statistic maintanence
+		 * Statistic maintenance
 		 */
 		pAC->Pnmi.RlmtChangeCts ++;
-		pAC->Pnmi.RlmtChangeTime =
-			SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
+		pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
 
 		/*
-		 * Store a trap message in the trap buffer and generate
-		 * an event for user space applications with the
-		 * SK_DRIVER_SENDEVENT macro.
+		 * Store a trap message in the trap buffer and generate an event for
+		 * user space applications with the SK_DRIVER_SENDEVENT macro.
 		 */
 		QueueRlmtNewMacTrap(pAC, PhysPortIndex);
 		(void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
 		/*
-		 * Update statistic counters to calculate new offset
-		 * for the virtual port and increment semaphore to indicate
-		 * that an update was already done.
+		 * Update statistic counters to calculate new offset for the virtual
+		 * port and increment semaphore to indicate that an update was
+		 * already done.
 		 */
 		if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
 			SK_PNMI_ERR_OK) {
@@ -2490,11 +2591,10 @@
 		pAC->Pnmi.MacUpdatedFlag ++;
 
 		/*
-		 * Calculate new counter offset for virtual port to
-		 * grant continous counting on port switches. A new port
-		 * is added to the virtual port. Therefore substract the
-		 * counter value of the new port from the CounterOffset
-		 * for the virtual port to grant the same value.
+		 * Calculate new counter offset for virtual port to grant continous
+		 * counting on port switches. A new port is added to the virtual port.
+		 * Therefore substract the counter value of the new port from the
+		 * CounterOffset for the virtual port to grant the same value.
 		 */
 		for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
 			CounterIndex ++) {
@@ -2504,8 +2604,7 @@
 				continue;
 			}
 
-			Value = GetPhysStatVal(pAC, IoC, PhysPortIndex,
-				CounterIndex);
+			Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
 
 			pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
 		}
@@ -2518,40 +2617,41 @@
 		pAC->Pnmi.MacUpdatedFlag --;
 		break;
 
-	case SK_PNMI_EVT_RLMT_PORT_SWITCH:
+	case SK_PNMI_EVT_RLMT_SEGMENTATION:
 		/*
-		 * This event becomes obsolete if RLMT generates directly
-		 * the events SK_PNMI_EVT_RLMT_ACTIVE_DOWN and
-		 * SK_PNMI_EVT_RLMT_ACTIVE_UP. The events are here emulated.
-		 * PNMI handles that multiple ports may become active. 
-		 * Increment semaphore to indicate that an update was
-		 * already done.
+		 * Para.Para32[0] contains the NetIndex.
 		 */
-		if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
-			SK_PNMI_ERR_OK) {
-
-			SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
-			return (0);
-		}
-		pAC->Pnmi.MacUpdatedFlag ++;
-
-		SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Param);
-		Param.Para32[0] = Param.Para32[1];
-		SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_RLMT_ACTIVE_UP, Param);
-
-		pAC->Pnmi.MacUpdatedFlag --;
-		break;
 
-	case SK_PNMI_EVT_RLMT_SEGMENTATION:
 		/*
-		 * Store a trap message in the trap buffer and generate
-		 * an event for user space applications with the
-		 * SK_DRIVER_SENDEVENT macro.
+		 * Store a trap message in the trap buffer and generate an event for
+		 * user space applications with the SK_DRIVER_SENDEVENT macro.
 		 */
 		QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
 		(void)SK_DRIVER_SENDEVENT(pAC, IoC);
 		break;
 
+    case SK_PNMI_EVT_RLMT_SET_NETS:
+		/*
+		 *  Param.Para32[0] contains the number of Nets.
+		 *  Param.Para32[1] is reserved, contains -1.
+		 */
+	    /*
+    	 * Check number of nets
+		 */
+		MaxNetNumber = pAC->GIni.GIMacsFound;
+		if (((unsigned int)Param.Para32[0] < 1)
+			|| ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
+			return (SK_PNMI_ERR_UNKNOWN_NET);
+		}
+
+        if((unsigned int)Param.Para32[0] == 1){ /* single net mode */
+        	pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
+        }
+        else { /* dual net mode */
+        	pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
+        }
+        break;
+
 	default:
 		break;
 	}
@@ -2580,6 +2680,7 @@
  * Returns:
  *	SK_PNMI_ERR_XXX. For details have a look to the description of the
  *	calling functions.
+ *	SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist 
  */
 
 static int PnmiVar(
@@ -2589,7 +2690,8 @@
 SK_U32 Id,		/* Object ID that is to be processed */
 char *pBuf,		/* Buffer which stores the mgmt data to be set */
 unsigned int *pLen,	/* Total length of mgmt data */
-SK_U32 Instance)	/* Instance (1..n) that is to be set or -1 */
+SK_U32 Instance,	/* Instance (1..n) that is to be set or -1 */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	unsigned int	TableIndex;
 	int		Ret;
@@ -2600,11 +2702,18 @@
 		*pLen = 0;
 		return (SK_PNMI_ERR_UNKNOWN_OID);
 	}
+	
+    /* 
+     * Check NetIndex 
+     */
+	if (NetIndex >= pAC->Rlmt.NumNets) {
+		return (SK_PNMI_ERR_UNKNOWN_NET);
+	}
 
 	SK_PNMI_CHECKFLAGS("PnmiVar: On call");
 
 	Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
-		Instance, TableIndex);
+		Instance, TableIndex, NetIndex);
 
 	SK_PNMI_CHECKFLAGS("PnmiVar: On return");
 
@@ -2627,6 +2736,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_XXX. The codes are described in the calling functions.
+ *	SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist 
  */
 
 static int PnmiStruct(
@@ -2634,7 +2744,8 @@
 SK_IOC IoC,		/* IO context handle */
 int  Action,		/* Set action to be performed */
 char *pBuf,		/* Buffer which contains the data to be set */
-unsigned int *pLen)	/* Length of buffer */
+unsigned int *pLen,	/* Length of buffer */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	int		Ret;
 	unsigned int	TableIndex;
@@ -2660,13 +2771,20 @@
 		return (SK_PNMI_ERR_TOO_SHORT);
 	}
 	
+    /* 
+     * Check NetIndex 
+     */
+	if (NetIndex >= pAC->Rlmt.NumNets) {
+		return (SK_PNMI_ERR_UNKNOWN_NET);
+	}
+	
 	SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
 
 	/*
 	 * Update the values of RLMT and SIRQ and increment semaphores to
 	 * indicate that an update was already done.
 	 */
-	if ((Ret = RlmtUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
+	if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
 
 		SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
 		*pLen = SK_PNMI_MIN_STRUCT_SIZE;
@@ -2716,7 +2834,7 @@
 			Len = 0;
 			Ret = IdTable[TableIndex].Func(pAC, IoC,
 				SK_PNMI_GET, IdTable[TableIndex].Id,
-				NULL, &Len, Instance, TableIndex);
+				NULL, &Len, Instance, TableIndex, NetIndex);
 
 			if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
 
@@ -2754,7 +2872,7 @@
 			/* Call the OID handler function */
 			Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
 				IdTable[TableIndex].Id, pBuf + DstOffset,
-				&Len, Instance, TableIndex);
+				&Len, Instance, TableIndex, NetIndex);
 
 			if (Ret != SK_PNMI_ERR_OK) {
 
@@ -2816,7 +2934,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -2836,7 +2954,8 @@
 char *pBuf,		/* Buffer to which to mgmt data will be retrieved */
 unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
 SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex) /* Index to the Id table */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	if (Id != OID_SKGE_ALL_DATA) {
 
@@ -2859,13 +2978,13 @@
 	switch (Action) {
 
 	case SK_PNMI_GET:
-		return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen));
+		return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
 
 	case SK_PNMI_PRESET:
-		return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen));
+		return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
 
 	case SK_PNMI_SET:
-		return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen));
+		return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
 	}
 
 	SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
@@ -2883,7 +3002,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -2903,7 +3022,8 @@
 char *pBuf,		/* Buffer to which to mgmt data will be retrieved */
 unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
 SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex) /* Index to the Id table */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	int	Ret;
 	SK_U32	ActionOp;
@@ -2992,7 +3112,7 @@
 
 	case SK_PNMI_ACT_RESETCNT:
 		/* Set all counters and timestamps to zero */
-		ResetCounter(pAC, IoC);
+		ResetCounter(pAC, IoC, NetIndex);
 		break;
 
 	default:
@@ -3017,7 +3137,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -3034,7 +3154,8 @@
 char *pBuf,		/* Buffer to which to mgmt data will be retrieved */
 unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
 SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex) /* Index to the Id table */
+unsigned int TableIndex,	/* Index to the Id table */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	int    Ret;
 	SK_U64 StatVal;
@@ -3080,7 +3201,7 @@
 		}
 
 #else /* SK_NDIS_64BIT_CTR */
-		
+
 		/*
 		 * for compatibility, at least 32bit are required for oid
 		 */
@@ -3092,7 +3213,7 @@
 			*pLen = sizeof(SK_U64);
 			return (SK_PNMI_ERR_TOO_SHORT);
 		}
-		
+
 		Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
 #endif /* SK_NDIS_64BIT_CTR */
 		break;
@@ -3117,17 +3238,17 @@
 	switch (Id) {
 
 	case OID_802_3_PERMANENT_ADDRESS:
-		CopyMac(pBuf, &pAC->Addr.PermanentMacAddress);
+		CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
 		*pLen = sizeof(SK_MAC_ADDR);
 		break;
 
 	case OID_802_3_CURRENT_ADDRESS:
-		CopyMac(pBuf, &pAC->Addr.CurrentMacAddress);
+		CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
 		*pLen = sizeof(SK_MAC_ADDR);
 		break;
 
 	default:
-		StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param);
+		StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
 
 		/*
 		 * by default 32bit values are evaluated
@@ -3159,7 +3280,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -3176,7 +3297,8 @@
 char *pBuf,		/* Buffer to which to mgmt data will be retrieved */
 unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
 SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex) /* Index to the Id table */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	unsigned int	LogPortMax;
 	unsigned int	LogPortIndex;
@@ -3194,22 +3316,28 @@
 	PhysPortMax = pAC->GIni.GIMacsFound;
 	LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 
-	if ((Instance != (SK_U32)(-1))) {
+	if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ /* Dual net mode */
+		LogPortMax--;
+	}
 
+	if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
+		/* Check instance range */
 		if ((Instance < 1) || (Instance > LogPortMax)) {
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_UNKNOWN_INST);
 		}
-
 		LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
 		Limit = LogPortIndex + 1;
 	}
-	else {
+
+	else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
+
 		LogPortIndex = 0;
 		Limit = LogPortMax;
 	}
 
+
 	/*
 	 * Check action
 	 */
@@ -3232,7 +3360,7 @@
 	 * Update XMAC statistic and increment semaphore to indicate that
 	 * an update was already done.
 	 */
-	Ret = MacUpdate(pAC, IoC, 0, PhysPortMax - 1);
+	Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
 	if (Ret != SK_PNMI_ERR_OK) {
 
 		*pLen = 0;
@@ -3264,15 +3392,15 @@
 		 */
 		case OID_SKGE_STAT_RX_TOO_LONG:
 			StatVal = GetStatVal(pAC, IoC, LogPortIndex,
-					     IdTable[TableIndex].Param) -
+					     IdTable[TableIndex].Param, NetIndex) -
 				GetStatVal(pAC, IoC, LogPortIndex,
-					   SK_PNMI_HRX_LONGFRAMES);
+					   SK_PNMI_HRX_LONGFRAMES, NetIndex);
 			SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
 			break;
 
 		default:
 			StatVal = GetStatVal(pAC, IoC, LogPortIndex,
-				IdTable[TableIndex].Param);
+				IdTable[TableIndex].Param, NetIndex);
 			SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
 			break;
 		}
@@ -3299,7 +3427,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -3319,7 +3447,8 @@
 char *pBuf,		/* Buffer to which to mgmt data will be retrieved */
 unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
 SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex) /* Index to the Id table */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	int		Ret;
 	unsigned int	LogPortMax;
@@ -3330,24 +3459,31 @@
 	unsigned int	Offset = 0;
 
 
+
 	/*
-	 * Calculate instance if wished
+	 * Calculate instance if wished. MAC index 0 is the virtual
+	 * MAC.
 	 */
 	PhysPortMax = pAC->GIni.GIMacsFound;
 	LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 
-	if ((Instance != (SK_U32)(-1))) {
-		
+	if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ /* Dual net mode */
+		LogPortMax--;
+	}
+
+	if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
+		/* Check instance range */
 		if ((Instance < 1) || (Instance > LogPortMax)) {
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_UNKNOWN_INST);
 		}
-
 		LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
 		Limit = LogPortIndex + 1;
 	}
-	else {
+
+	else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
+
 		LogPortIndex = 0;
 		Limit = LogPortMax;
 	}
@@ -3375,34 +3511,28 @@
 
 			case OID_SKGE_PHYS_CUR_ADDR:
 				if (LogPortIndex == 0) {
-
-					CopyMac(pBuf + Offset, &pAC->Addr.
-						CurrentMacAddress);
+					CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
 				}
 				else {
-					PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-						pAC, LogPortIndex);
+					PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
 
-					CopyMac(pBuf + Offset, &pAC->Addr.
-						Port[PhysPortIndex].
-						CurrentMacAddress);
+					CopyMac(pBuf + Offset,
+						&pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
 				}
 				Offset += 6;
 				break;
 
 			case OID_SKGE_PHYS_FAC_ADDR:
 				if (LogPortIndex == 0) {
-
-					CopyMac(pBuf + Offset, &pAC->Addr.
-						PermanentMacAddress);
+					CopyMac(pBuf + Offset,
+						&pAC->Addr.Net[NetIndex].PermanentMacAddress);
 				}
 				else {
 					PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 						pAC, LogPortIndex);
 
-					CopyMac(pBuf + Offset, &pAC->Addr.
-						Port[PhysPortIndex].
-						PermanentMacAddress);
+					CopyMac(pBuf + Offset,
+						&pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
 				}
 				Offset += 6;
 				break;
@@ -3509,7 +3639,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -3526,7 +3656,8 @@
 char *pBuf,		/* Buffer to which to mgmt data will be retrieved */
 unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
 SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex) /* Index to the Id table */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	unsigned int	Index;
 	unsigned int	Limit;
@@ -3538,15 +3669,14 @@
 	 * Calculate instance if wished
 	 */
 	if (Instance != (SK_U32)(-1)) {
-		
+
 		if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_UNKNOWN_INST);
 		}
-
 		Index = (unsigned int)Instance - 1;
-		Limit = (unsigned int)Instance;
+		Limit = Index + 1;
 	}
 	else {
 		Index = 0;
@@ -3579,23 +3709,23 @@
 		switch (Id) {
 
 		case OID_SKGE_CHKSM_RX_OK_CTS:
-			StatVal = pAC->Csum.ProtoStats[Index].RxOkCts;
+			StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
 			break;
 
 		case OID_SKGE_CHKSM_RX_UNABLE_CTS:
-			StatVal = pAC->Csum.ProtoStats[Index].RxUnableCts;
+			StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
 			break;
 
 		case OID_SKGE_CHKSM_RX_ERR_CTS:
-			StatVal = pAC->Csum.ProtoStats[Index].RxErrCts;
+			StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
 			break;
 
 		case OID_SKGE_CHKSM_TX_OK_CTS:
-			StatVal = pAC->Csum.ProtoStats[Index].TxOkCts;
+			StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
 			break;
 
 		case OID_SKGE_CHKSM_TX_UNABLE_CTS:
-			StatVal = pAC->Csum.ProtoStats[Index].TxUnableCts;
+			StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
 			break;
 
 		default:
@@ -3628,7 +3758,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -3645,7 +3775,8 @@
 char *pBuf,		/* Buffer to which to mgmt data will be retrieved */
 unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
 SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex) /* Index to the Id table */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	unsigned int	i;
 	unsigned int	Index;
@@ -3872,7 +4003,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -3892,13 +4023,14 @@
 char *pBuf,		/* Buffer to which to mgmt data will be retrieved */
 unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
 SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex) /* Index to the Id table */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	SK_VPD_STATUS	*pVpdStatus;
 	unsigned int	BufLen;
 	char		Buf[256];
-	char		KeyArr[SK_PNMI_VPD_ARR_SIZE][SK_PNMI_VPD_STR_SIZE];
-	char		KeyStr[SK_PNMI_VPD_STR_SIZE];
+	char		KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
+	char		KeyStr[SK_PNMI_VPD_KEY_SIZE];
 	unsigned int	KeyNo;
 	unsigned int	Offset;
 	unsigned int	Index;
@@ -3914,7 +4046,6 @@
 	Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr),
 		&KeyNo);
 	if (Ret != SK_PNMI_ERR_OK) {
-
 		*pLen = 0;
 		return (Ret);
 	}
@@ -3939,7 +4070,6 @@
 			for (Index = 0; Index < KeyNo; Index ++) {
 
 				if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
-
 					FirstIndex = Index;
 					LastIndex = Index+1;
 					break;
@@ -4352,7 +4482,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -4369,7 +4499,8 @@
 char *pBuf,		/* Buffer to which to mgmt data will be retrieved */
 unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
 SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex) /* Index to the Id table */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	int		Ret;
 	unsigned int	Index;
@@ -4419,7 +4550,7 @@
 		}
 
 #else /* SK_NDIS_64BIT_CTR */
-		
+
 		/*
 		 * for compatibility, at least 32bit are required for oid
 		 */
@@ -4431,7 +4562,7 @@
 			*pLen = sizeof(SK_U64);
 			return (SK_PNMI_ERR_TOO_SHORT);
 		}
-		
+
 		Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
 #endif /* SK_NDIS_64BIT_CTR */
 		break;
@@ -4529,32 +4660,30 @@
 		case OID_SKGE_IN_ERRORS_CTS:
 		case OID_GEN_RCV_ERROR:
 			Val64RxHwErrs =
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED) +
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING) +
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW)+
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER) +
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER) +
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH)+
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL) +
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS) +
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT) +
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG)-
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_LONGFRAMES)+
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS) +
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT);
-			break;
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex)+
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex)+
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex)-
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_LONGFRAMES, NetIndex)+
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
+	        break;
 
 		case OID_SKGE_TX_HW_ERROR_CTS:
 		case OID_SKGE_OUT_ERROR_CTS:
 		case OID_GEN_XMIT_ERROR:
 			Val64TxHwErrs =
-				GetStatVal(pAC, IoC, 0,
-				SK_PNMI_HTX_EXCESS_COL) +
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL)+
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN)+
-				GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER)+
-				GetStatVal(pAC, IoC, 0,
-				SK_PNMI_HTX_EXCESS_COL);
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex)+
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex)+
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex)+
+				GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex);
 			break;
 		}
 	}
@@ -4766,61 +4895,142 @@
 		break;
 
 	case OID_SKGE_TX_SW_QUEUE_LEN:
-		Val64 = pAC->Pnmi.TxSwQueueLen;
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
+		}
+		/* Single net mode */
+		else {
+			Val64 =  pAC->Pnmi.Port[0].TxSwQueueLen +
+				pAC->Pnmi.Port[1].TxSwQueueLen;
+		}			
 		SK_PNMI_STORE_U64(pBuf, Val64);
 		*pLen = sizeof(SK_U64);
 		break;
 
+
 	case OID_SKGE_TX_SW_QUEUE_MAX:
-		Val64 = pAC->Pnmi.TxSwQueueMax;
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
+		}
+		/* Single net mode */
+		else {
+			Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
+				pAC->Pnmi.Port[1].TxSwQueueMax;
+		}
 		SK_PNMI_STORE_U64(pBuf, Val64);
 		*pLen = sizeof(SK_U64);
 		break;
 
 	case OID_SKGE_TX_RETRY:
-		Val64 = pAC->Pnmi.TxRetryCts;
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
+		}
+		/* Single net mode */
+		else {
+			Val64 = pAC->Pnmi.Port[0].TxRetryCts +
+				pAC->Pnmi.Port[1].TxRetryCts;
+		}
 		SK_PNMI_STORE_U64(pBuf, Val64);
 		*pLen = sizeof(SK_U64);
 		break;
 
 	case OID_SKGE_RX_INTR_CTS:
-		Val64 = pAC->Pnmi.RxIntrCts;
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
+		}
+		/* Single net mode */
+		else {
+			Val64 = pAC->Pnmi.Port[0].RxIntrCts +
+				pAC->Pnmi.Port[1].RxIntrCts;
+		}
 		SK_PNMI_STORE_U64(pBuf, Val64);
 		*pLen = sizeof(SK_U64);
 		break;
 
 	case OID_SKGE_TX_INTR_CTS:
-		Val64 = pAC->Pnmi.TxIntrCts;
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
+		}
+		/* Single net mode */
+		else {
+			Val64 = pAC->Pnmi.Port[0].TxIntrCts +
+				pAC->Pnmi.Port[1].TxIntrCts;
+		}
 		SK_PNMI_STORE_U64(pBuf, Val64);
 		*pLen = sizeof(SK_U64);
 		break;
 
 	case OID_SKGE_RX_NO_BUF_CTS:
-		Val64 = pAC->Pnmi.RxNoBufCts;
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
+		}
+		/* Single net mode */
+		else {
+			Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
+				pAC->Pnmi.Port[1].RxNoBufCts;
+		}
 		SK_PNMI_STORE_U64(pBuf, Val64);
 		*pLen = sizeof(SK_U64);
 		break;
 
 	case OID_SKGE_TX_NO_BUF_CTS:
-		Val64 = pAC->Pnmi.TxNoBufCts;
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
+		}
+		/* Single net mode */
+		else {
+			Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
+				pAC->Pnmi.Port[1].TxNoBufCts;
+		}
 		SK_PNMI_STORE_U64(pBuf, Val64);
 		*pLen = sizeof(SK_U64);
 		break;
 
 	case OID_SKGE_TX_USED_DESCR_NO:
-		Val64 = pAC->Pnmi.TxUsedDescrNo;
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
+		}
+		/* Single net mode */
+		else {
+			Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
+				pAC->Pnmi.Port[1].TxUsedDescrNo;
+		}
 		SK_PNMI_STORE_U64(pBuf, Val64);
 		*pLen = sizeof(SK_U64);
 		break;
 
 	case OID_SKGE_RX_DELIVERED_CTS:
-		Val64 = pAC->Pnmi.RxDeliveredCts;
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
+		}
+		/* Single net mode */
+		else {
+			Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
+				pAC->Pnmi.Port[1].RxDeliveredCts;
+		}
 		SK_PNMI_STORE_U64(pBuf, Val64);
 		*pLen = sizeof(SK_U64);
 		break;
 
 	case OID_SKGE_RX_OCTETS_DELIV_CTS:
-		Val64 = pAC->Pnmi.RxOctetsDeliveredCts;
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
+		}
+		/* Single net mode */
+		else {
+			Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
+				pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
+		}
 		SK_PNMI_STORE_U64(pBuf, Val64);
 		*pLen = sizeof(SK_U64);
 		break;
@@ -4836,19 +5046,45 @@
 		break;
 
 	case OID_SKGE_IN_ERRORS_CTS:
-		Val64 = Val64RxHwErrs + pAC->Pnmi.RxNoBufCts;
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
+		}
+		/* Single net mode */
+		else {
+			Val64 = Val64RxHwErrs + 
+				pAC->Pnmi.Port[0].RxNoBufCts +
+				pAC->Pnmi.Port[1].RxNoBufCts;
+		}
 		SK_PNMI_STORE_U64(pBuf, Val64);
 		*pLen = sizeof(SK_U64);
 		break;
 
 	case OID_SKGE_OUT_ERROR_CTS:
-		Val64 = Val64TxHwErrs + pAC->Pnmi.TxNoBufCts;
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
+		}
+		/* Single net mode */
+		else {
+			Val64 = Val64TxHwErrs + 
+				pAC->Pnmi.Port[0].TxNoBufCts +
+				pAC->Pnmi.Port[1].TxNoBufCts;
+		}
 		SK_PNMI_STORE_U64(pBuf, Val64);
 		*pLen = sizeof(SK_U64);
 		break;
 
 	case OID_SKGE_ERR_RECOVERY_CTS:
-		Val64 = pAC->Pnmi.ErrRecoveryCts;
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
+		}
+		/* Single net mode */
+		else {
+			Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
+				pAC->Pnmi.Port[1].ErrRecoveryCts;
+		}
 		SK_PNMI_STORE_U64(pBuf, Val64);
 		*pLen = sizeof(SK_U64);
 		break;
@@ -4867,13 +5103,12 @@
 		break;
 
 	case OID_GEN_RCV_ERROR:
-		Val64 = Val64RxHwErrs + pAC->Pnmi.RxNoBufCts;
+		Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
 
 		/*
 		 * by default 32bit values are evaluated
 		 */
 		if (!Is64BitReq) {
-			SK_U32	Val32;
 			Val32 = (SK_U32)Val64;
 			SK_PNMI_STORE_U32(pBuf, Val32);
 			*pLen = sizeof(SK_U32);
@@ -4885,13 +5120,12 @@
 		break;
 
 	case OID_GEN_XMIT_ERROR:
-		Val64 = Val64TxHwErrs + pAC->Pnmi.TxNoBufCts;
+		Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
 
 		/*
 		 * by default 32bit values are evaluated
 		 */
 		if (!Is64BitReq) {
-			SK_U32	Val32;
 			Val32 = (SK_U32)Val64;
 			SK_PNMI_STORE_U32(pBuf, Val32);
 			*pLen = sizeof(SK_U32);
@@ -4903,13 +5137,12 @@
 		break;
 
 	case OID_GEN_RCV_NO_BUFFER:
-		Val64 = pAC->Pnmi.RxNoBufCts;
+		Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
 
 		/*
 		 * by default 32bit values are evaluated
 		 */
 		if (!Is64BitReq) {
-			SK_U32	Val32;
 			Val32 = (SK_U32)Val64;
 			SK_PNMI_STORE_U32(pBuf, Val32);
 			*pLen = sizeof(SK_U32);
@@ -4921,7 +5154,7 @@
 		break;
 
 	case OID_GEN_TRANSMIT_QUEUE_LENGTH:
-		Val32 = (SK_U32)pAC->Pnmi.TxSwQueueLen;
+		Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
 		SK_PNMI_STORE_U32(pBuf, Val32);
 		*pLen = sizeof(SK_U32);
 		break;
@@ -4956,7 +5189,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -4976,7 +5209,8 @@
 char *pBuf,		/* Buffer to which to mgmt data will be retrieved */
 unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
 SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex) /* Index to the Id table */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	int		Ret;
 	unsigned int	PhysPortIndex;
@@ -5049,7 +5283,7 @@
 		 * statistic always up to date some time. Then we can
 		 * remove this type of call.
 		 */
-		if ((Ret = RlmtUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
+		if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
 
 			*pLen = 0;
 			return (Ret);
@@ -5062,7 +5296,7 @@
 		switch (Id) {
 
 		case OID_SKGE_RLMT_MODE:
-			*pBuf = (char)pAC->Rlmt.RlmtMode;
+			*pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
 			*pLen = sizeof(char);
 			break;
 
@@ -5088,8 +5322,7 @@
 
 				if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
-					*pBuf = (char)SK_PNMI_PORT_PHYS2LOG(
-						PhysPortIndex);
+					*pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
 					break;
 				}
 			}
@@ -5097,8 +5330,7 @@
 			break;
 
 		case OID_SKGE_RLMT_PORT_PREFERRED:
-			*pBuf = (char)SK_PNMI_PORT_PHYS2LOG(
-				pAC->Rlmt.MacPreferred);
+			*pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
 			*pLen = sizeof(char);
 			break;
 
@@ -5165,6 +5397,7 @@
 			/* Send an event to RLMT to change the mode */
 			SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 			EventParam.Para32[0] |= (SK_U32)(*pBuf);
+			EventParam.Para32[1] = 0;
 			if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
 				EventParam) > 0) {
 
@@ -5204,6 +5437,7 @@
 			 */
 			SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 			EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
+			EventParam.Para32[1] = NetIndex;
 			if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
 				EventParam) > 0) {
 
@@ -5264,7 +5498,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -5281,7 +5515,8 @@
 char *pBuf,		/* Buffer to which to mgmt data will be retrieved */
 unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
 SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex) /* Index to the Id table */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	unsigned int	PhysPortMax;
 	unsigned int	PhysPortIndex;
@@ -5291,26 +5526,40 @@
 	SK_U32		Val32;
 	SK_U64		Val64;
 
-
 	/*
 	 * Calculate the port indexes from the instance
 	 */
 	PhysPortMax = pAC->GIni.GIMacsFound;
 
 	if ((Instance != (SK_U32)(-1))) {
-
+		/* Check instance range */
 		if ((Instance < 1) || (Instance > PhysPortMax)) {
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_UNKNOWN_INST);
 		}
 
+		/* Single net mode */
 		PhysPortIndex = Instance - 1;
+
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			PhysPortIndex = NetIndex;
+		}
+
+		/* Both net modes */
 		Limit = PhysPortIndex + 1;
 	}
 	else {
+		/* Single net mode */
 		PhysPortIndex = 0;
 		Limit = PhysPortMax;
+
+		/* Dual net mode */
+		if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){
+			PhysPortIndex = NetIndex;
+			Limit = PhysPortIndex + 1;
+		}
 	}
 
 	/*
@@ -5360,7 +5609,7 @@
 	 * Update statistic and increment semaphores to indicate that
 	 * an update was already done.
 	 */
-	if ((Ret = RlmtUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
+	if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
 
 		*pLen = 0;
 		return (Ret);
@@ -5449,7 +5698,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -5469,7 +5718,8 @@
 char *pBuf,		/* Buffer to which to mgmt data will be retrieved */
 unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
 SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex) /* Index to the Id table */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	unsigned int	PhysPortMax;
 	unsigned int	PhysPortIndex;
@@ -5480,6 +5730,7 @@
 	char		Val8;
 	int		Ret;
 	SK_EVPARA	EventParam;
+	SK_U32		Val32;
 
 
 	/*
@@ -5489,18 +5740,23 @@
 	PhysPortMax = pAC->GIni.GIMacsFound;
 	LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 
-	if ((Instance != (SK_U32)(-1))) {
+	if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){ /* Dual net mode */
+		LogPortMax--;
+	}
 
+	if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
+		/* Check instance range */
 		if ((Instance < 1) || (Instance > LogPortMax)) {
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_UNKNOWN_INST);
 		}
-
 		LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
 		Limit = LogPortIndex + 1;
 	}
-	else {
+
+	else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
+
 		LogPortIndex = 0;
 		Limit = LogPortMax;
 	}
@@ -5535,10 +5791,17 @@
 			}
 			break;
 
+        case OID_SKGE_MTU:
+			if (*pLen < sizeof(SK_U32)) {
+
+				*pLen = sizeof(SK_U32);
+				return (SK_PNMI_ERR_TOO_SHORT);
+			}
+			break;
+
 		default:
 			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
 				SK_PNMI_ERR041MSG);
-
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
 		}
@@ -5755,6 +6018,12 @@
 				Offset += sizeof(char);
 				break;
 
+			case OID_SKGE_MTU:
+				Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
+				SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+				Offset += sizeof(SK_U32);
+				break;
+
 			default:
 				SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR042,
 					SK_PNMI_ERR042MSG);
@@ -5790,7 +6059,20 @@
 		}
 		break;
 
-	default:
+	case OID_SKGE_MTU:
+		if (*pLen < sizeof(SK_U32)) {
+
+			*pLen = sizeof(SK_U32);
+			return (SK_PNMI_ERR_TOO_SHORT);
+		}
+		if (*pLen != sizeof(SK_U32)) {
+
+			*pLen = 0;
+			return (SK_PNMI_ERR_BAD_VALUE);
+		}
+		break;
+
+    default:
 		*pLen = 0;
 		return (SK_PNMI_ERR_READ_ONLY);
 	}
@@ -5812,7 +6094,8 @@
 				break;
 			}
 			if (Val8 < SK_LMODE_HALF ||
-				Val8 > SK_LMODE_AUTOSENSE) {
+				(LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
+				(LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
 
 				*pLen = 0;
 				return (SK_PNMI_ERR_BAD_VALUE);
@@ -5887,7 +6170,8 @@
 				break;
 			}
 			if (Val8 < SK_FLOW_MODE_NONE ||
-				Val8 > SK_FLOW_MODE_SYM_OR_REM) {
+				(LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
+				(LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
 
 				*pLen = 0;
 				return (SK_PNMI_ERR_BAD_VALUE);
@@ -5963,7 +6247,8 @@
 				break;
 			}
 			if (Val8 < SK_MS_MODE_AUTO ||
-				Val8 > SK_MS_MODE_SLAVE) {
+				(LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
+				(LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
 
 				*pLen = 0;
 				return (SK_PNMI_ERR_BAD_VALUE);
@@ -6026,10 +6311,35 @@
 					return (SK_PNMI_ERR_GENERAL);
 				}
 			}
-			
+
 			Offset += sizeof(char);
 			break;
 
+		case OID_SKGE_MTU :
+			/* Check the value range */
+			Val32 = *(SK_U32*)(pBuf + Offset);
+			if (Val32 == 0) {
+				/* mtu of this port remains unchanged */
+				Offset += sizeof(SK_U32);
+				break;
+			}
+			if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
+				*pLen = 0;
+				return (SK_PNMI_ERR_BAD_VALUE);
+			}
+
+			/* The preset ends here */
+			if (Action == SK_PNMI_PRESET) {
+				return (SK_PNMI_ERR_OK);
+			}
+
+			if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
+				return (SK_PNMI_ERR_GENERAL);
+			}
+
+			Offset += sizeof(SK_U32);
+			break;
+
 		default:
 			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR045,
 				SK_PNMI_ERR045MSG);
@@ -6052,7 +6362,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -6072,7 +6382,8 @@
 char *pBuf,		/* Buffer to which to mgmt data will be retrieved */
 unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
 SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex) /* Index to the Id table */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	unsigned int	Index;
 	unsigned int	Limit;
@@ -6502,7 +6813,7 @@
  *
  * Description:
  *	The COMMON module only tells us if the mode is half or full duplex.
- *	But in the decade of auto sensing it is useful for the user to
+ *	But in the decade of auto sensing it is usefull for the user to
  *	know if the mode was negotiated or forced. Therefore we have a
  *	look to the mode, which was last used by the negotiation process.
  *
@@ -6566,8 +6877,8 @@
 unsigned int KeyArrLen,	/* Length of array in bytes */
 unsigned int *pKeyNo)	/* Number of keys */
 {
-	unsigned int		BufKeysLen = 128;
-	char			BufKeys[128];
+	unsigned int		BufKeysLen = SK_PNMI_VPD_BUFSIZE;
+	char			BufKeys[SK_PNMI_VPD_BUFSIZE];
 	unsigned int		StartOffset;
 	unsigned int		Offset;
 	int			Index;
@@ -6598,12 +6909,12 @@
 	 * errorlog notification. This case should not happen because
 	 * the maximum number of keys is limited due to RAM limitations
 	 */
-	if (*pKeyNo > SK_PNMI_VPD_ARR_SIZE) {
+	if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
 
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
 			SK_PNMI_ERR015MSG);
 
-		*pKeyNo = SK_PNMI_VPD_ARR_SIZE;
+		*pKeyNo = SK_PNMI_VPD_ENTRIES;
 	}
 
 	/*
@@ -6618,15 +6929,15 @@
 			continue;
 		}
 
-		if (Offset - StartOffset > SK_PNMI_VPD_STR_SIZE) {
+		if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
 
 			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
 				SK_PNMI_ERR016MSG);
 			return (SK_PNMI_ERR_GENERAL);
 		}
 
-		SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_STR_SIZE,
-			&BufKeys[StartOffset], SK_PNMI_VPD_STR_SIZE);
+		SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
+			&BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
 
 		Index ++;
 		StartOffset = Offset + 1;
@@ -6635,8 +6946,8 @@
 	/* Last key not zero terminated? Get it anyway */
 	if (StartOffset < Offset) {
 
-		SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_STR_SIZE,
-			&BufKeys[StartOffset], SK_PNMI_VPD_STR_SIZE);
+		SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
+			&BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
 	}
 
 	return (SK_PNMI_ERR_OK);
@@ -6698,7 +7009,8 @@
 
 static int RlmtUpdate(
 SK_AC *pAC,	/* Pointer to adapter context */
-SK_IOC IoC)	/* IO context handle */
+SK_IOC IoC,	/* IO context handle */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	SK_EVPARA	EventParam;
 
@@ -6711,6 +7023,8 @@
 
 	/* Send an synchronuous update event to the module */
 	SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
+	EventParam.Para32[0] = NetIndex;
+	EventParam.Para32[1] = (SK_U32)-1;
 	if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
 
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
@@ -6764,7 +7078,7 @@
 
 		/*
 		 * It is an auto-clearing register. If the command bits
-		 * went to zero again, the statistics are transferred.
+		 * went to zero again, the statistics are transfered.
 		 * Normally the command should be executed immediately.
 		 * But just to be sure we execute a loop.
 		 */
@@ -6807,40 +7121,49 @@
  */
 
 static SK_U64 GetStatVal(
-SK_AC *pAC,			/* Pointer to adapter context */
-SK_IOC IoC,			/* IO context handle */
+SK_AC *pAC,					/* Pointer to adapter context */
+SK_IOC IoC,					/* IO context handle */
 unsigned int LogPortIndex,	/* Index of the logical Port to be processed */
-unsigned int StatIndex)		/* Index to statistic value */
+unsigned int StatIndex,		/* Index to statistic value */
+SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
 {
 	unsigned int	PhysPortIndex;
 	unsigned int	PhysPortMax;
 	SK_U64		Val = 0;
 
 
-	if (LogPortIndex == 0) {
+	if(pAC->Pnmi.DualNetActiveFlag == SK_TRUE){	/* Dual net mode */
 
-		PhysPortMax = pAC->GIni.GIMacsFound;
+		PhysPortIndex = NetIndex;
+		Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
+    }	/* end of dual net mode */
 
-		/* Add counter of all active ports */
-		for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
-			PhysPortIndex ++) {
+	else { /* single net mode */
 
-			if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+		if (LogPortIndex == 0) {
 
-				Val += GetPhysStatVal(pAC, IoC, PhysPortIndex,
-					StatIndex);
-			}
-		}
+			PhysPortMax = pAC->GIni.GIMacsFound;
 
-		/* Correct value because of port switches */
-		Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
-	}
-	else {
-		/* Get counter value of physical port */
-		PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
-		Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
-	}
+			/* Add counter of all active ports */
+			for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
+				PhysPortIndex ++) {
+
+				if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+
+					Val += GetPhysStatVal(pAC, IoC, PhysPortIndex,
+						StatIndex);
+				}
+			}
 
+			/* Correct value because of port switches */
+			Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
+		}
+		else {
+			/* Get counter value of physical port */
+			PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
+			Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
+		}
+	} /* end of single net mode */
 	return (Val);
 }
 
@@ -6862,8 +7185,8 @@
  */
 
 static SK_U64 GetPhysStatVal(
-SK_AC *pAC,			/* Pointer to adapter context */
-SK_IOC IoC,			/* IO context handle */
+SK_AC *pAC,					/* Pointer to adapter context */
+SK_IOC IoC,					/* IO context handle */
 unsigned int PhysPortIndex,	/* Index of the logical Port to be processed */
 unsigned int StatIndex)		/* Index to statistic value */
 {
@@ -6959,7 +7282,8 @@
 
 static void ResetCounter(
 SK_AC *pAC,		/* Pointer to adapter context */
-SK_IOC IoC)		/* IO context handle */
+SK_IOC IoC,		/* IO context handle */
+SK_U32 NetIndex)
 {
 	unsigned int	PhysPortIndex;
 	SK_EVPARA	EventParam;
@@ -6971,7 +7295,10 @@
 	SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
 
 	/* Notify RLMT module */
+	EventParam.Para32[0] = NetIndex;
+	EventParam.Para32[1] = (SK_U32)-1;
 	SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
+	EventParam.Para32[1] = 0;
 
 	/* Notify SIRQ module */
 	SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
@@ -7019,16 +7346,16 @@
 		sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
 	pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
 	pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
-	pAC->Pnmi.TxSwQueueMax = 0;
-	pAC->Pnmi.TxRetryCts = 0;
-	pAC->Pnmi.RxIntrCts = 0;
-	pAC->Pnmi.TxIntrCts = 0;
-	pAC->Pnmi.RxNoBufCts = 0;
-	pAC->Pnmi.TxNoBufCts = 0;
-	pAC->Pnmi.TxUsedDescrNo = 0;
-	pAC->Pnmi.RxDeliveredCts = 0;
-	pAC->Pnmi.RxOctetsDeliveredCts = 0;
-	pAC->Pnmi.ErrRecoveryCts = 0;
+	pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
+	pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
+	pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
+	pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
+	pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
+	pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
+	pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
+	pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
+	pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
+	pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
 }
 
 /*****************************************************************************
@@ -7037,7 +7364,7 @@
  *
  * Description:
  *	The trap buffer stores various events. A user application somehow
- *	gets notified that an event occurred and retrieves the trap buffer
+ *	gets notified that an event occured and retrieves the trap buffer
  *	contens (or simply polls the buffer). The buffer is organized as
  *	a ring which stores the newest traps at the beginning. The oldest
  *	traps are overwritten by the newest ones. Each trap entry has a
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/skgesirq.c linux/drivers/net/sk98lin/skgesirq.c
--- v2.4.6/linux/drivers/net/sk98lin/skgesirq.c	Tue Mar 20 12:04:59 2001
+++ linux/drivers/net/sk98lin/skgesirq.c	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	skgesirq.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.55 $
- * Date:	$Date: 2000/06/19 08:36:25 $
+ * Version:	$Revision: 1.65 $
+ * Date:	$Date: 2001/02/23 13:41:51 $
  * Purpose:	Special IRQ module
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2000 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,6 +26,37 @@
  * History:
  *
  *	$Log: skgesirq.c,v $
+ *	Revision 1.65  2001/02/23 13:41:51  gklug
+ *	fix: PHYS2INST should be used correctly for Dual Net operation
+ *	chg: do no longer work with older PNMI
+ *	
+ *	Revision 1.64  2001/02/15 11:27:04  rassmann
+ *	Working with RLMT v1 if SK_MAX_NETS undefined.
+ *	
+ *	Revision 1.63  2001/02/06 10:44:23  mkunz
+ *	- NetIndex added to interface functions of pnmi V4 with dual net support
+ *	
+ *	Revision 1.62  2001/01/31 15:31:41  gklug
+ *	fix: problem with autosensing an SR8800 switch
+ *	
+ *	Revision 1.61  2000/11/09 11:30:09  rassmann
+ *	WA: Waiting after releasing reset until BCom chip is accessible.
+ *
+ *	Revision 1.60  2000/10/18 12:37:48  cgoos
+ *	Reinserted the comment for version 1.56.
+ *	
+ *	Revision 1.59  2000/10/18 12:22:20  cgoos
+ *	Added workaround for half duplex hangup.
+ *	
+ *	Revision 1.58  2000/09/28 13:06:04  gklug
+ *	fix: BCOM may NOT be touched if XMAC is in RESET state
+ *	
+ *	Revision 1.57  2000/09/08 12:38:39  cgoos
+ *	Added forgotten variable declaration.
+ *	
+ *	Revision 1.56  2000/09/08 08:12:13  cgoos
+ *	Changed handling of parity errors in SkGeHwErr (correct reset of error).
+ *
  *	Revision 1.55  2000/06/19 08:36:25  cgoos
  *	Changed comment.
  *	
@@ -216,39 +246,38 @@
  *
  ******************************************************************************/
 
-
 /*
-	Special Interrupt handler
-
-	The following abstract should show how this module is included
-	in the driver path:
-
-	In the ISR of the driver the bits for frame transmission complete and
-	for receive complete are checked and handled by the driver itself.
-	The bits of the slow path mask are checked after this and then the
-	entry into the so-called "slow path" is prepared. It is an implemetors
-	decision whether this is executed directly or just scheduled by
-	disabling the mask. In the interrupt service routine events may be
-	generated, so it would be a good idea to call the EventDispatcher
-	right after this ISR.
-
-	The Interrupt service register of the adapter is NOT read by this
-	module. SO if the drivers implemetor needs a while loop around the
-	slow data paths Interrupt bits, he needs to call the SkGeIsr() for
-	each loop entered.
-
-	However, the XMAC Interrupt status registers are read in a while loop.
-
-*/
+ *	Special Interrupt handler
+ *
+ *	The following abstract should show how this module is included
+ *	in the driver path:
+ *
+ *	In the ISR of the driver the bits for frame transmission complete and
+ *	for receive complete are checked and handled by the driver itself.
+ *	The bits of the slow path mask are checked after this and then the
+ *	entry into the so-called "slow path" is prepared. It is an implemetors
+ *	decision whether this is executed directly or just scheduled by
+ *	disabling the mask. In the interrupt service routine events may be
+ *	generated, so it would be a good idea to call the EventDispatcher
+ *	right after this ISR.
+ *
+ *	The Interrupt service register of the adapter is NOT read by this
+ *	module. SO if the drivers implemetor needs a while loop around the
+ *	slow data paths Interrupt bits, he needs to call the SkGeIsr() for
+ *	each loop entered.
+ *
+ *	However, the XMAC Interrupt status registers are read in a while loop.
+ *
+ */
+ 
 static const char SysKonnectFileId[] =
-	"$Id: skgesirq.c,v 1.55 2000/06/19 08:36:25 cgoos Exp $" ;
+	"$Id: skgesirq.c,v 1.65 2001/02/23 13:41:51 gklug Exp $" ;
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
 #include "h/skgepnmi.h"		/* PNMI Definitions */
 #include "h/skrlmt.h"		/* RLMT Definitions */
 #include "h/skdrv2nd.h"		/* Adapter Control- and Driver specific Def. */
 
-
 /* local function prototypes */
 static int	SkGePortCheckUpXmac(SK_AC*, SK_IOC, int);
 static int	SkGePortCheckUpBcom(SK_AC*, SK_IOC, int);
@@ -257,21 +286,31 @@
 static void	SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16);
 static void	SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16);
 
+/*
+ * Define an array of RX counter which are checked
+ * in AutoSense mode to check whether a link is not able to autonegotiate.
+ */
+static const SK_U32 SkGeRxOids[]= {
+	OID_SKGE_STAT_RX_64,
+	OID_SKGE_STAT_RX_127,
+	OID_SKGE_STAT_RX_255,
+	OID_SKGE_STAT_RX_511,
+	OID_SKGE_STAT_RX_1023,
+	OID_SKGE_STAT_RX_MAX,
+} ;
 
 #ifdef __C2MAN__
 /*
-	Special IRQ function
-
-	General Description:
-
+ *	Special IRQ function
+ *
+ *	General Description:
+ *
  */
 intro()
 {}
 #endif
 
-/*
- * Define return codes of SkGePortCheckUp and CheckShort
- */
+/* Define return codes of SkGePortCheckUp and CheckShort. */
 #define	SK_HW_PS_NONE		0	/* No action needed */
 #define	SK_HW_PS_RESTART	1	/* Restart needed */
 #define	SK_HW_PS_LINK		2	/* Link Up actions needed */
@@ -287,13 +326,13 @@
  *
  */
 void	SkHWInitDefSense(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,	/* adapter context */
+SK_IOC	IoC,	/* IO context */
 int	Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
 
-	pPrt = &pAC->GIni.GP[Port] ;
+	pPrt = &pAC->GIni.GP[Port];
 
 	pPrt->PAutoNegTimeOut = 0;
 
@@ -302,15 +341,16 @@
 		return;
 	}
 
-	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ,
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
 		("AutoSensing: First mode %d on Port %d\n",
-		(int) SK_LMODE_AUTOFULL,
+		(int)SK_LMODE_AUTOFULL,
 		 Port));
 
 	pPrt->PLinkMode = SK_LMODE_AUTOFULL;
 
 	return;
-}
+}	/* SkHWInitDefSense */
+
 
 /******************************************************************************
  *
@@ -323,29 +363,30 @@
  *
  */
 SK_U8	SkHWSenseGetNext(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,	/* adapter context */
+SK_IOC	IoC,	/* IO context */
 int	Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
 
-	pPrt = &pAC->GIni.GP[Port] ;
+	pPrt = &pAC->GIni.GP[Port];
 
 	pPrt->PAutoNegTimeOut = 0;
 
 	if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
 		/* Leave all as configured */
-		return(pPrt->PLinkModeConf);
+		return (pPrt->PLinkModeConf);
 	}
 
 	if (pPrt->PLinkMode == SK_LMODE_AUTOFULL) {
 		/* Return next mode AUTOBOTH */
-		return(SK_LMODE_AUTOBOTH);
+		return (SK_LMODE_AUTOBOTH);
 	}
 
 	/* Return default autofull */
-	return(SK_LMODE_AUTOFULL);
-}
+	return (SK_LMODE_AUTOFULL);
+}	/* SkHWSenseGetNext */
+
 
 /******************************************************************************
  *
@@ -360,12 +401,12 @@
 void	SkHWSenseSetNext(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port,		/* Port Index (MAC_1 + n) */
+int	Port,			/* Port Index (MAC_1 + n) */
 SK_U8	NewMode)	/* New Mode to be written in sense mode */
 {
 	SK_GEPORT	*pPrt;
 
-	pPrt = &pAC->GIni.GP[Port] ;
+	pPrt = &pAC->GIni.GP[Port];
 
 	pPrt->PAutoNegTimeOut = 0;
 
@@ -373,13 +414,13 @@
 		return;
 	}
 
-	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ,
-		("AutoSensing: next mode %d on Port %d\n", (int) NewMode,
-		 Port));
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+		("AutoSensing: next mode %d on Port %d\n", (int)NewMode, Port));
 	pPrt->PLinkMode = NewMode;
 
 	return;
-}
+}	/* SkHWSenseSetNext */
+
 
 /******************************************************************************
  *
@@ -394,47 +435,44 @@
 void	SkHWLinkDown(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port)		/* Port Index (MAC_1 + n) */
+int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
 	SK_U16		Word;
 
-	pPrt = &pAC->GIni.GP[Port] ;
+	pPrt = &pAC->GIni.GP[Port];
 
-	/* Disable all XMAC interrupts */
+	/* Disable all XMAC interrupts. */
 	XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
 
-	/* Disable Receive and Transmitter */
+	/* Disable Receiver and Transmitter. */
 	XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
-	XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX|XM_MMU_ENA_TX));
+	XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
 	
-	/* disable all PHY interrupts */
-	switch (pAC->GIni.GP[Port].PhyType) {
+	/* Disable all PHY interrupts. */
+	switch (pPrt->PhyType) {
 		case SK_PHY_BCOM:
-			/* make sure that PHY is initialized */
+			/* Make sure that PHY is initialized. */
 			if (pAC->GIni.GP[Port].PState) {
-				/* Workaround BCOM Errata (#10523) all BCom */
-				/* Disable Power Management if link is down */
-				PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL,
-					&Word);
-				PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL,	
+				/* NOT allowed if BCOM is in RESET state */
+				/* Workaround BCOM Errata (#10523) all BCom. */
+				/* Disable Power Management if link is down. */
+				PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &Word);
+				PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL,
 					Word | PHY_B_AC_DIS_PM);
+				PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK, 0xffff);
 			}
-			PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK, 
-				0xffff);
 			break;
 		case SK_PHY_LONE:
-			PHY_WRITE(IoC, pPrt, Port, PHY_LONE_INT_ENAB, 
-				0x0);
+			PHY_WRITE(IoC, pPrt, Port, PHY_LONE_INT_ENAB, 0x0);
 			break;
 		case SK_PHY_NAT:
 			/* todo: National
-			PHY_WRITE(IoC, pPrt, Port, PHY_NAT_INT_MASK, 
-				0xffff); */
+			PHY_WRITE(IoC, pPrt, Port, PHY_NAT_INT_MASK, 0xffff); */
 			break;
 	}
 
-	/* Init default sense mode */
+	/* Init default sense mode. */
 	SkHWInitDefSense(pAC, IoC, Port);
 
 	if (!pPrt->PHWLinkUp) {
@@ -444,27 +482,25 @@
 	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ,
 		("Link down Port %d\n", Port));
 
-	/* Set Link to DOWN */
+	/* Set Link to DOWN. */
 	pPrt->PHWLinkUp = SK_FALSE;
 
 	/* Reset Port stati */
 	pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
-	pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE ;
+	pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
 
 	/*
-	 * Reinit Phy especially when the AutoSense default is set now
+	 * Reinit Phy especially when the AutoSense default is set now.
 	 */
 	SkXmInitPhy(pAC, IoC, Port, SK_FALSE);
 
-	/*
-	 * GP0: used for workaround of Rev. C
-	 * Errata 2
-	 */
+	/* GP0: used for workaround of Rev. C Errata 2. */
+
+	/* Do NOT signal to RLMT. */
 
-	/* Do NOT signal to RLMT */
+	/* Do NOT start the timer here. */
+}	/* SkHWLinkDown */
 
-	/* Do NOT start the timer here */
-}
 
 /******************************************************************************
  *
@@ -477,21 +513,21 @@
  *
  */
 void	SkHWLinkUp(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,	/* adapter context */
+SK_IOC	IoC,	/* IO context */
 int	Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
 
-	pPrt = &pAC->GIni.GP[Port] ;
+	pPrt = &pAC->GIni.GP[Port];
 
 	if (pPrt->PHWLinkUp) {
 		/* We do NOT need to proceed on active link */
 		return;
 	} 
 
-	pPrt->PHWLinkUp = SK_TRUE ;
-	pPrt->PAutoNegFail = SK_FALSE ;
+	pPrt->PHWLinkUp = SK_TRUE;
+	pPrt->PAutoNegFail = SK_FALSE;
 	pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
 
 	if (pPrt->PLinkMode != SK_LMODE_AUTOHALF &&
@@ -504,17 +540,19 @@
 		/* Set Link Mode */
 		if (pPrt->PLinkMode == SK_LMODE_FULL) {
 			pPrt->PLinkModeStatus = SK_LMODE_STAT_FULL;
-		} else {
+		}
+		else {
 			pPrt->PLinkModeStatus = SK_LMODE_STAT_HALF;
 		}
 
 		/* No flow control without autonegotiation */
-		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE ;
+		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
 
 		/* RX/TX enable */
 		SkXmRxTxEnable(pAC, IoC, Port);
 	}
-}
+}	/* SkHWLinkUp */
+
 
 /******************************************************************************
  *
@@ -522,27 +560,28 @@
  *
  */
 static	void	SkMacParity(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,	/* adapter context */
+SK_IOC	IoC,	/* IO context */
 int	Port)		/* Port Index of the port failed */
 {
 	SK_EVPARA	Para;
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
 	SK_U64		TxMax;		/* TxMax Counter */
-	unsigned int	Len;
+	unsigned	Len;
 
 	pPrt = &pAC->GIni.GP[Port];
 
 	/* Clear IRQ */
-	SK_OUT16(IoC, MR_ADDR(Port,TX_MFF_CTRL1), MFF_CLR_PERR) ;
+	SK_OUT16(IoC, MR_ADDR(Port,TX_MFF_CTRL1), MFF_CLR_PERR);
 
 	if (pPrt->PCheckPar) {
 		if (Port == MAC_1) {
 			SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E016,
-				SKERR_SIRQ_E016MSG) ;
-		} else {
+				SKERR_SIRQ_E016MSG);
+		}
+		else {
 			SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E017,
-				SKERR_SIRQ_E017MSG) ;
+				SKERR_SIRQ_E017MSG);
 		}
 		Para.Para64 = Port;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
@@ -552,17 +591,18 @@
 		return;
 	}
 
-
 	/* Check whether frames with a size of 1k were sent */
 	Len = sizeof(SK_U64);
-	SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_MAX, (char *) &TxMax,
-		&Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(Port));
+	SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_MAX, (char *)&TxMax,
+		&Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),
+		pAC->Rlmt.Port[Port].Net->NetNumber);
 
 	if (TxMax > 0) {
 		/* From now on check the parity */
 		pPrt->PCheckPar = SK_TRUE;
 	}
-}
+}	/* SkMacParity */
+
 
 /******************************************************************************
  *
@@ -578,17 +618,22 @@
 SK_U32	HwStatus)	/* Interrupt status word */
 {
 	SK_EVPARA	Para;
+	SK_U16		Word;
 
-	if (HwStatus & IS_IRQ_STAT) {
-		SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E013,
-			SKERR_SIRQ_E013MSG) ;
-		Para.Para64 = 0;
-		SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
-	}
+	if ((HwStatus & IS_IRQ_MST_ERR) || (HwStatus & IS_IRQ_STAT)) {
+		if (HwStatus & IS_IRQ_STAT) {
+			SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG);
+		}
+		else {
+			SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG);
+		}
+
+		/* Reset all bits in the PCI STATUS register */
+		SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+		SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
+		SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS);
+		SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 
-	if (HwStatus & IS_IRQ_MST_ERR) {
-		SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E012,
-			SKERR_SIRQ_E012MSG) ;
 		Para.Para64 = 0;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
 	}
@@ -596,57 +641,54 @@
 	if (HwStatus & IS_NO_STAT_M1) {
 		/* Ignore it */
 		/* This situation is also indicated in the descriptor */
-		SK_OUT16(IoC, MR_ADDR(MAC_1,RX_MFF_CTRL1), MFF_CLR_INSTAT) ;
+		SK_OUT16(IoC, MR_ADDR(MAC_1,RX_MFF_CTRL1), MFF_CLR_INSTAT);
 	}
 
 	if (HwStatus & IS_NO_STAT_M2) {
 		/* Ignore it */
 		/* This situation is also indicated in the descriptor */
-		SK_OUT16(IoC, MR_ADDR(MAC_2,RX_MFF_CTRL1), MFF_CLR_INSTAT) ;
+		SK_OUT16(IoC, MR_ADDR(MAC_2,RX_MFF_CTRL1), MFF_CLR_INSTAT);
 	}
 
 	if (HwStatus & IS_NO_TIST_M1) {
 		/* Ignore it */
 		/* This situation is also indicated in the descriptor */
-		SK_OUT16(IoC, MR_ADDR(MAC_1,RX_MFF_CTRL1), MFF_CLR_INTIST) ;
+		SK_OUT16(IoC, MR_ADDR(MAC_1,RX_MFF_CTRL1), MFF_CLR_INTIST);
 	}
 
 	if (HwStatus & IS_NO_TIST_M2) {
 		/* Ignore it */
 		/* This situation is also indicated in the descriptor */
-		SK_OUT16(IoC, MR_ADDR(MAC_2,RX_MFF_CTRL1), MFF_CLR_INTIST) ;
+		SK_OUT16(IoC, MR_ADDR(MAC_2,RX_MFF_CTRL1), MFF_CLR_INTIST);
 	}
 
 	if (HwStatus & IS_RAM_RD_PAR) {
-		SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR) ;
-		SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E014,
-			SKERR_SIRQ_E014MSG) ;
+		SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR);
+		SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG);
 		Para.Para64 = 0;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
 	}
 
 	if (HwStatus & IS_RAM_WR_PAR) {
-		SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR) ;
-		SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E015,
-			SKERR_SIRQ_E015MSG) ;
+		SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR);
+		SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG);
 		Para.Para64 = 0;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
 	}
 
 	if (HwStatus & IS_M1_PAR_ERR) {
-		SkMacParity(pAC, IoC, MAC_1) ;
+		SkMacParity(pAC, IoC, MAC_1);
 	}
 
 	if (HwStatus & IS_M2_PAR_ERR) {
-		SkMacParity(pAC, IoC, MAC_2) ;
+		SkMacParity(pAC, IoC, MAC_2);
 	}
 
 	if (HwStatus & IS_R1_PAR_ERR) {
 		/* Clear IRQ */
-		SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P) ;
+		SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P);
 
-		SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E018,
-			SKERR_SIRQ_E018MSG) ;
+		SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
 		Para.Para64 = MAC_1;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
 		Para.Para32[0] = MAC_1;
@@ -655,17 +697,16 @@
 
 	if (HwStatus & IS_R2_PAR_ERR) {
 		/* Clear IRQ */
-		SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P) ;
+		SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P);
 
-		SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E019,
-			SKERR_SIRQ_E019MSG) ;
+		SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
 		Para.Para64 = MAC_2;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
 		Para.Para32[0] = MAC_2;
 		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
 	}
+}	/* SkGeHwErr */
 
-}
 
 /******************************************************************************
  *
@@ -680,13 +721,13 @@
 SK_IOC	IoC,		/* IO context */
 SK_U32	Istatus)	/* Interrupt status word */
 {
-	SK_U32		RegVal32;	/* Read register Value */
 	SK_EVPARA	Para;
+	SK_U32		RegVal32;	/* Read register Value */
 	SK_U16		XmIsr;
 
 	if (Istatus & IS_HW_ERR) {
-		SK_IN32(IoC, B0_HWE_ISRC, &RegVal32) ;
-		SkGeHwErr(pAC, IoC, RegVal32) ;
+		SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
+		SkGeHwErr(pAC, IoC, RegVal32);
 	}
 
 	/*
@@ -694,41 +735,101 @@
 	 */
 	/* Check whether XMACs are correctly initialized */
 	if ((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) &&
-	    !pAC->GIni.GP[MAC_1].PState) {
-		/* XMAC was not initialized but Packet timeout occurred */
+		!pAC->GIni.GP[MAC_1].PState) {
+		/* XMAC was not initialized but Packet timeout occured */
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004,
-			SKERR_SIRQ_E004MSG) ;
+			SKERR_SIRQ_E004MSG);
 	}
 
 	if ((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) &&
 	    !pAC->GIni.GP[MAC_2].PState) {
-		/* XMAC was not initialized but Packet timeout occurred */
+		/* XMAC was not initialized but Packet timeout occured */
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,
-			SKERR_SIRQ_E005MSG) ;
+			SKERR_SIRQ_E005MSG);
 	}
 
 	if (Istatus & IS_PA_TO_RX1) {
 		/* Means network is filling us up */
 		SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E002,
-			SKERR_SIRQ_E002MSG) ;
-		SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1) ;
+			SKERR_SIRQ_E002MSG);
+		SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1);
 	}
 
 	if (Istatus & IS_PA_TO_RX2) {
 		/* Means network is filling us up */
 		SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E003,
-			SKERR_SIRQ_E003MSG) ;
-		SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2) ;
+			SKERR_SIRQ_E003MSG);
+		SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2);
 	}
 
 	if (Istatus & IS_PA_TO_TX1) {
+		unsigned int	Len;
+		SK_U64		Octets;
+		SK_GEPORT	*pPrt = &pAC->GIni.GP[0];
+
 		/* May be a normal situation in a server with a slow network */
-		SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1) ;
+		SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1);
+
+		/*
+		 * workaround: if in half duplex mode, check for tx hangup.
+		 * Read number of TX'ed bytes, wait for 10 ms, then compare
+		 * the number with current value. If nothing changed, we
+		 * assume that tx is hanging and do a FIFO flush (see event
+		 * routine).
+		 */
+		if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || 
+		    pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
+		    !pPrt->HalfDupTimerActive) {
+			/* 
+			 * many more pack. arb. timeouts may come in between,
+			 * we ignore those
+			 */
+			pPrt->HalfDupTimerActive = SK_TRUE;
+
+			Len = sizeof(SK_U64);
+			SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *) &Octets,
+				&Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 0),
+				pAC->Rlmt.Port[0].Net->NetNumber);
+			pPrt->LastOctets = Octets;
+			Para.Para32[0] = 0;
+			SkTimerStart(pAC, IoC,
+				&pPrt->HalfDupChkTimer,
+				SK_HALFDUP_CHK_TIME,
+				SKGE_HWAC,
+				SK_HWEV_HALFDUP_CHK,
+				Para);
+		}
 	}
 
 	if (Istatus & IS_PA_TO_TX2) {
+		unsigned int	Len;
+		SK_U64		Octets;
+		SK_GEPORT	*pPrt = &pAC->GIni.GP[1];
+
 		/* May be a normal situation in a server with a slow network */
-		SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2) ;
+		SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2);
+
+		/*
+		 * workaround: see above
+		 */
+		if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || 
+		    pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
+		    !pPrt->HalfDupTimerActive) {
+			pPrt->HalfDupTimerActive = SK_TRUE;
+
+			Len = sizeof(SK_U64);
+			SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *) &Octets,
+				&Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 1),
+				pAC->Rlmt.Port[1].Net->NetNumber);
+			pPrt->LastOctets = Octets;
+			Para.Para32[0] = 1;
+			SkTimerStart(pAC, IoC,
+				&pPrt->HalfDupChkTimer,
+				SK_HALFDUP_CHK_TIME,
+				SKGE_HWAC,
+				SK_HWEV_HALFDUP_CHK,
+				Para);
+		}
 	}
 
 	/*
@@ -736,9 +837,9 @@
 	 */
 	if (Istatus & IS_R1_C) {
 		/* Clear IRQ */
-		SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C) ;
+		SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,
-			SKERR_SIRQ_E006MSG) ;
+			SKERR_SIRQ_E006MSG);
 		Para.Para64 = MAC_1;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
 		Para.Para32[0] = MAC_1;
@@ -747,9 +848,9 @@
 
 	if (Istatus & IS_R2_C) {
 		/* Clear IRQ */
-		SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C) ;
+		SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,
-			SKERR_SIRQ_E007MSG) ;
+			SKERR_SIRQ_E007MSG);
 		Para.Para64 = MAC_2;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
 		Para.Para32[0] = MAC_2;
@@ -758,9 +859,9 @@
 
 	if (Istatus & IS_XS1_C) {
 		/* Clear IRQ */
-		SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C) ;
+		SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,
-			SKERR_SIRQ_E008MSG) ;
+			SKERR_SIRQ_E008MSG);
 		Para.Para64 = MAC_1;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
 		Para.Para32[0] = MAC_1;
@@ -769,9 +870,9 @@
 
 	if (Istatus & IS_XA1_C) {
 		/* Clear IRQ */
-		SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C) ;
+		SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,
-			SKERR_SIRQ_E009MSG) ;
+			SKERR_SIRQ_E009MSG);
 		Para.Para64 = MAC_1;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
 		Para.Para32[0] = MAC_1;
@@ -780,9 +881,9 @@
 
 	if (Istatus & IS_XS2_C) {
 		/* Clear IRQ */
-		SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C) ;
+		SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,
-			SKERR_SIRQ_E010MSG) ;
+			SKERR_SIRQ_E010MSG);
 		Para.Para64 = MAC_2;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
 		Para.Para32[0] = MAC_2;
@@ -791,9 +892,9 @@
 
 	if (Istatus & IS_XA2_C) {
 		/* Clear IRQ */
-		SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C) ;
+		SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,
-			SKERR_SIRQ_E011MSG) ;
+			SKERR_SIRQ_E011MSG);
 		Para.Para64 = MAC_2;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
 		Para.Para32[0] = MAC_2;
@@ -801,52 +902,59 @@
 	}
 
 	/*
-	 * external reg interrupt
+	 * External reg interrupt.
 	 */
 	if (Istatus & IS_EXT_REG) {
 		SK_U16 	PhyInt;
 		SK_U16 	PhyIMsk;
-		int	i;
-		/* test IRQs from PHY */
-		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-			switch (pAC->GIni.GP[i].PhyType) {
+		int		i;
+		SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
+
+		/* Test IRQs from PHY. */
+		for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+			pPrt = &pAC->GIni.GP[i];
+			switch (pPrt->PhyType) {
 			case SK_PHY_XMAC:
 				break;
 			case SK_PHY_BCOM:
-	    			if(pAC->GIni.GP[i].PState) {
-					PHY_READ(IoC, &pAC->GIni.GP[i], i,
-						PHY_BCOM_INT_STAT, &PhyInt);
-					PHY_READ(IoC, &pAC->GIni.GP[i], i,
-						PHY_BCOM_INT_MASK, &PhyIMsk);
+				if (pPrt->PState) {
+					PHY_READ(IoC, pPrt, i, PHY_BCOM_INT_STAT, &PhyInt);
+					PHY_READ(IoC, pPrt, i, PHY_BCOM_INT_MASK, &PhyIMsk);
+
+#ifdef xDEBUG
+					if (PhyInt & PhyIMsk) {
+						CMSMPrintString(
+							pAC->pConfigTable,
+							MSG_TYPE_RUNTIME_INFO,
+							"SirqIsr - Stat: %x",
+							(void *)PhyInt,
+							(void *)NULL);
+					}
+#endif	/* DEBUG */
 					
-					if (PhyInt & (~PhyIMsk)) {
-						SK_DBG_MSG(pAC,SK_DBGMOD_HWM,
+					if (PhyInt & ~PhyIMsk) {
+						SK_DBG_MSG(
+							pAC,
+							SK_DBGMOD_HWM,
 							SK_DBGCAT_IRQ,
-							("Port %d Bcom Int: %x "
-							" Mask: %x\n",
-							i, PhyInt, PhyIMsk));
-						SkPhyIsrBcom(pAC, IoC, i,
-							(SK_U16) 
-							(PhyInt & (~PhyIMsk)));
+							("Port %d Bcom Int: %x Mask: %x\n",
+								i, PhyInt, PhyIMsk));
+						SkPhyIsrBcom(pAC, IoC, i, PhyInt);
 					}
 				}
-				else {
-				}
 				break;
 			case SK_PHY_LONE:
-				PHY_READ(IoC, &pAC->GIni.GP[i], i,
-					PHY_LONE_INT_STAT, &PhyInt);
-				PHY_READ(IoC, &pAC->GIni.GP[i], i,
-					PHY_LONE_INT_ENAB, &PhyIMsk);
+				PHY_READ(IoC, pPrt, i, PHY_LONE_INT_STAT, &PhyInt);
+				PHY_READ(IoC, pPrt, i, PHY_LONE_INT_ENAB, &PhyIMsk);
 				
 				if (PhyInt & PhyIMsk) {
-					SK_DBG_MSG(pAC,SK_DBGMOD_HWM,
+					SK_DBG_MSG(
+						pAC,
+						SK_DBGMOD_HWM,
 						SK_DBGCAT_IRQ,
-						("Port %d  Lone Int: %x "
-						" Mask: %x\n",
+						("Port %d  Lone Int: %x Mask: %x\n",
 						i, PhyInt, PhyIMsk));
-					SkPhyIsrLone(pAC, IoC, i,
-						(SK_U16) (PhyInt & PhyIMsk));
+					SkPhyIsrLone(pAC, IoC, i, PhyInt);
 				}
 				break;
 			case SK_PHY_NAT:
@@ -869,12 +977,12 @@
 		 * us only a link going down.
 		 */
 		/* clear interrupt */
-		SK_OUT8(IoC, MR_ADDR(MAC_1,LNK_SYNC_CTRL), LED_CLR_IRQ);
+		SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);
 	}
 
 	/* Check MAC after link sync counter */
 	if (Istatus & IS_MAC1) {
-		XM_IN16(IoC, MAC_1, XM_ISRC, &XmIsr) ;
+		XM_IN16(IoC, MAC_1, XM_ISRC, &XmIsr);
 		SkXmIrq(pAC, IoC, MAC_1, XmIsr);
 	}
 
@@ -889,7 +997,7 @@
 
 	/* Check MAC after link sync counter */
 	if (Istatus & IS_MAC2) {
-		XM_IN16(IoC, MAC_2, XM_ISRC, &XmIsr) ;
+		XM_IN16(IoC, MAC_2, XM_ISRC, &XmIsr);
 		SkXmIrq(pAC, IoC, MAC_2, XmIsr);
 	}
 
@@ -900,20 +1008,9 @@
 	if (Istatus & IS_TIMINT) {
 		SkHwtIsr(pAC, IoC);
 	}
-}
+}	/* SkGeSirqIsr */
+
 
-/*
- * Define an array of RX counter which are checked
- * in AutoSense mode to check whether a link is not able to autonegotiate.
- */
-static const SK_U32 SkGeRxOids[]= {
-	OID_SKGE_STAT_RX_64,
-	OID_SKGE_STAT_RX_127,
-	OID_SKGE_STAT_RX_255,
-	OID_SKGE_STAT_RX_511,
-	OID_SKGE_STAT_RX_1023,
-	OID_SKGE_STAT_RX_MAX,
-} ;
 /******************************************************************************
  *
  * SkGePortCheckShorts - Implementing of the Workaround Errata # 2
@@ -923,19 +1020,19 @@
  *	1	Restart needed on this port
  */
 int	SkGePortCheckShorts(
-SK_AC	*pAC,		/* Adapters context */
+SK_AC	*pAC,		/* Adapter Context */
 SK_IOC	IoC,		/* IO Context */
-int	Port)		/* Which port should be checked */
+int		Port)		/* Which port should be checked */
 {
-	SK_U64		Shorts;		/* Short Event Counter */
+	SK_U64		Shorts;			/* Short Event Counter */
 	SK_U64		CheckShorts;	/* Check value for Short Event Counter */
-	SK_U64		RxCts;		/* RX Counter (packets on network) */
-	SK_U64		RxTmp;		/* RX temp. Counter */
-	SK_U64		FcsErrCts;	/* FCS Error Counter */
-	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
-	unsigned int	Len;
-	int		Rtv;		/* Return value */
-	int		i;
+	SK_U64		RxCts;			/* RX Counter (packets on network) */
+	SK_U64		RxTmp;			/* RX temp. Counter */
+	SK_U64		FcsErrCts;		/* FCS Error Counter */
+	SK_GEPORT	*pPrt;			/* GIni Port struct pointer */
+	unsigned 	Len;
+	int			Rtv;			/* Return value */
+	int			i;
 
 	pPrt = &pAC->GIni.GP[Port];
 
@@ -946,8 +1043,9 @@
 	 * Extra precaution: check for short Event counter
 	 */
 	Len = sizeof(SK_U64);
-	SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_RX_SHORTS, (char *) &Shorts,
-		&Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(Port));
+	SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_RX_SHORTS, (char *)&Shorts,
+		&Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),
+		pAC->Rlmt.Port[Port].Net->NetNumber);
 
 	/*
 	 * Read RX counter (packets seen on the network and not neccesarily
@@ -956,9 +1054,10 @@
 	Len = sizeof(SK_U64);
 	RxCts = 0;
 
-	for (i = 0; i < sizeof(SkGeRxOids)/sizeof(SK_U32) ; i++) {
-		SkPnmiGetVar(pAC, IoC, SkGeRxOids[i], (char *) &RxTmp,
-			&Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(Port));
+	for (i = 0; i < sizeof(SkGeRxOids)/sizeof(SK_U32); i++) {
+		SkPnmiGetVar(pAC, IoC, SkGeRxOids[i], (char *)&RxTmp,
+			&Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),
+			pAC->Rlmt.Port[Port].Net->NetNumber);
 		RxCts += RxTmp;
 	}
 
@@ -973,19 +1072,20 @@
 		 * Reset Link Restart counter
 		 */
 		pPrt->PLinkResCt = 0;
+		pPrt->PAutoNegTOCt = 0;
 
 		/* If link is up check for 2 */
 		CheckShorts = 2;
 
 		Len = sizeof(SK_U64);
 		SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_RX_FCS,
-			(char *) &FcsErrCts, &Len,
-			(SK_U32) SK_PNMI_PORT_PHYS2INST(Port));
+			(char *)&FcsErrCts, &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),
+			pAC->Rlmt.Port[Port].Net->NetNumber);
 		
 		if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
 		    pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
 		    (pPrt->PLinkMode == SK_LMODE_HALF ||
-		     pPrt->PLinkMode == SK_LMODE_FULL)) {
+			 pPrt->PLinkMode == SK_LMODE_FULL)) {
 			/*
 			 * This is autosensing and we are in the fallback
 			 * manual full/half duplex mode.
@@ -997,8 +1097,9 @@
 				 */
 				pPrt->PPrevFcs = FcsErrCts;
 				pPrt->PPrevShorts = Shorts;
-				return(SK_HW_PS_RESTART);
-			} else {
+				return (SK_HW_PS_RESTART);
+			}
+			else {
 				pPrt->PLipaAutoNeg = SK_LIPA_MANUAL;
 			}
 		}
@@ -1006,20 +1107,18 @@
 		if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||
 		    (!(FcsErrCts - pPrt->PPrevFcs))) {
 			/*
-			 * Note: The compare with zero above has to be done
-			 * the way shown, otherwise the Linux driver will
-			 * have a problem.
+			 * Note: The compare with zero above has to be done the way shown,
+			 * otherwise the Linux driver will have a problem.
 			 */
 			/*
-			 * we received a bunch of frames or no
-			 * CRC error occurred on the network ->
-			 * ok.
+			 * We received a bunch of frames or no CRC error occured on the
+			 * network -> ok.
 			 */
 			pPrt->PPrevRx = RxCts;
 			pPrt->PPrevFcs = FcsErrCts;
 			pPrt->PPrevShorts = Shorts;
 
-			return(SK_HW_PS_NONE) ;
+			return (SK_HW_PS_NONE);
 		}
 
 		pPrt->PPrevFcs = FcsErrCts;
@@ -1027,7 +1126,7 @@
 
 
 	if ((Shorts - pPrt->PPrevShorts) > CheckShorts) {
-		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ,
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
 			("Short Event Count Restart Port %d \n", Port));
 		Rtv = SK_HW_PS_RESTART;
 	}
@@ -1035,13 +1134,13 @@
 	pPrt->PPrevShorts = Shorts;
 	pPrt->PPrevRx = RxCts;
 
-	return(Rtv);
-}
+	return (Rtv);
+}	/* SkGePortCheckShorts*/
 
 
 /******************************************************************************
  *
- * SkGePortCheckUp - Implementing of the Workaround Errata # 2
+ * SkGePortCheckUp - Implementation of the Workaround for Errata #2
  *
  * return:
  *	0	o.k. nothing needed
@@ -1049,15 +1148,11 @@
  *	2	Link came up
  */
 int	SkGePortCheckUp(
-SK_AC	*pAC,		/* Adapters context */
+SK_AC	*pAC,		/* Adapter Context */
 SK_IOC	IoC,		/* IO Context */
-int	Port)		/* Which port should be checked */
+int		Port)		/* Which port should be checked */
 {
-	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
-
-	pPrt = &pAC->GIni.GP[Port];
-
-	switch (pPrt->PhyType) {
+	switch (pAC->GIni.GP[Port].PhyType) {
 	case SK_PHY_XMAC:
 		return (SkGePortCheckUpXmac(pAC, IoC, Port));
 	case SK_PHY_BCOM:
@@ -1067,9 +1162,8 @@
 	case SK_PHY_NAT:
 		return (SkGePortCheckUpNat(pAC, IoC, Port));
 	}
-	
-	return(SK_HW_PS_NONE) ;
-}
+	return (SK_HW_PS_NONE);
+}	/* SkGePortCheckUp */
 
 
 /******************************************************************************
@@ -1082,75 +1176,69 @@
  *	2	Link came up
  */
 static int	SkGePortCheckUpXmac(
-SK_AC	*pAC,		/* Adapters context */
+SK_AC	*pAC,		/* Adapter Context */
 SK_IOC	IoC,		/* IO Context */
-int	Port)		/* Which port should be checked */
+int		Port)		/* Which port should be checked */
 {
+	SK_U64		Shorts;		/* Short Event Counter */
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
-	SK_BOOL		AutoNeg;	/* Is Autonegotiation used ? */
-	SK_U16		Isrc;		/* Interrupt source register */
+	unsigned	Len;
+	int			Done;
 	SK_U32		GpReg;		/* General Purpose register value */
+	SK_U16		Isrc;		/* Interrupt source register */
 	SK_U16		IsrcSum;	/* Interrupt source register sum */
 	SK_U16		LpAb;		/* Link Partner Ability */
 	SK_U16		ResAb;		/* Resolved Ability */
-	SK_U64		Shorts;		/* Short Event Counter */
-	unsigned int	Len;
-	SK_U8		NextMode;	/* Next AutoSensing Mode */
 	SK_U16		ExtStat;	/* Extended Status Register */
-	int		Done;
+	SK_BOOL		AutoNeg;	/* Is Autonegotiation used ? */
+	SK_U8		NextMode;	/* Next AutoSensing Mode */
 
 	pPrt = &pAC->GIni.GP[Port];
 
 	if (pPrt->PHWLinkUp) {
 		if (pPrt->PhyType != SK_PHY_XMAC) {
-			return(SK_HW_PS_NONE) ;
+			return (SK_HW_PS_NONE);
 		}
 		else {
-			return(SkGePortCheckShorts(pAC, IoC, Port)) ;
+			return (SkGePortCheckShorts(pAC, IoC, Port));
 		}
 	}
 
 	IsrcSum = pPrt->PIsave;
 	pPrt->PIsave = 0;
 
-	/* Now wait for each ports link */
+	/* Now wait for each port's link. */
 	if (pPrt->PLinkMode == SK_LMODE_HALF ||
 	    pPrt->PLinkMode == SK_LMODE_FULL) {
 		AutoNeg = SK_FALSE;
-	} else {
+	}
+	else {
 		AutoNeg = SK_TRUE;
 	}
 
 	if (pPrt->PLinkBroken) {
 		/* Link was broken */
-		XM_IN32(IoC,Port,XM_GP_PORT, &GpReg) ;
+		XM_IN32(IoC,Port,XM_GP_PORT, &GpReg);
 
 		if ((GpReg & XM_GP_INP_ASS) == 0) {
 			/* The Link is in sync */
-			XM_IN16(IoC,Port,XM_ISRC, &Isrc) ;
+			XM_IN16(IoC,Port,XM_ISRC, &Isrc);
 			IsrcSum |= Isrc;
 			SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
 			if ((Isrc & XM_IS_INP_ASS) == 0) {
 				/* It has been in sync since last Time */
 				/* Restart the PORT */
-	
-				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ,
-					("Link in sync Restart Port %d\n",
-					 Port));
+				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+					("Link in sync Restart Port %d\n", Port));
 
-				/*
-				 * We now need to reinitialize the PrevSHorts
-				 * counter.
-				 */
+				/* We now need to reinitialize the PrevShorts counter. */
 				Len = sizeof(SK_U64);
-				SkPnmiGetVar(pAC, IoC,
-					OID_SKGE_STAT_RX_SHORTS,
-					(char *) &Shorts,
-					&Len,
-					(SK_U32) SK_PNMI_PORT_PHYS2INST(Port));
+				SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_RX_SHORTS, (char *)&Shorts,
+					&Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),
+					pAC->Rlmt.Port[Port].Net->NetNumber);
 				pPrt->PPrevShorts = Shorts;
 
-				pAC->GIni.GP[Port].PLinkBroken = SK_FALSE ;
+				pAC->GIni.GP[Port].PLinkBroken = SK_FALSE;
 
 				/*
 				 * Link Restart Workaround:
@@ -1165,61 +1253,60 @@
 				pAC->GIni.GP[Port].PLinkResCt ++;
 				pPrt->PAutoNegTimeOut = 0;
 
-				if (pAC->GIni.GP[Port].PLinkResCt <
-					SK_MAX_LRESTART) {
-					return(SK_HW_PS_RESTART) ;
+				if (pAC->GIni.GP[Port].PLinkResCt < SK_MAX_LRESTART) {
+					return (SK_HW_PS_RESTART);
 				}
 
 				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
-					("Do NOT restart on Port %d %x %x\n",
-					Port, Isrc, IsrcSum));
+					("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));
 				pAC->GIni.GP[Port].PLinkResCt = 0;
-			} else {
-				pPrt->PIsave = (SK_U16) (IsrcSum & (XM_IS_AND));
+			}
+			else {
+				pPrt->PIsave = (SK_U16)(IsrcSum & (XM_IS_AND));
 				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
-					("Save Sync/nosync Port %d %x %x\n",
-					Port, Isrc, IsrcSum));
+					("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));
+
 				/* Do nothing more if link is broken */
-				return(SK_HW_PS_NONE) ;
+				return (SK_HW_PS_NONE);
 			}
-		} else {
+		}
+		else {
 			/* Do nothing more if link is broken */
-			return(SK_HW_PS_NONE) ;
+			return (SK_HW_PS_NONE);
 		}
 
-	} else {
+	}
+	else {
 		/* Link was not broken, check if it is */
-		XM_IN16(IoC,Port,XM_ISRC, &Isrc) ;
+		XM_IN16(IoC, Port, XM_ISRC, &Isrc);
 		IsrcSum |= Isrc;
 		if ((Isrc & XM_IS_INP_ASS) == XM_IS_INP_ASS) {
-			XM_IN16(IoC,Port,XM_ISRC, &Isrc) ;
+			XM_IN16(IoC, Port, XM_ISRC, &Isrc);
 			IsrcSum |= Isrc;
 			if ((Isrc & XM_IS_INP_ASS) == XM_IS_INP_ASS) {
-				XM_IN16(IoC,Port,XM_ISRC, &Isrc) ;
+				XM_IN16(IoC, Port, XM_ISRC, &Isrc);
 				IsrcSum |= Isrc;
 				if ((Isrc & XM_IS_INP_ASS) == XM_IS_INP_ASS) {
-					pPrt->PLinkBroken = SK_TRUE ;
+					pPrt->PLinkBroken = SK_TRUE;
 					/*
 					 * Re-Init Link partner Autoneg flag
 					 */
 					pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
-					SK_DBG_MSG(pAC,SK_DBGMOD_HWM,
-					   SK_DBGCAT_IRQ,
-					   ("Link broken Port %d\n",
-						 Port));
+					SK_DBG_MSG(pAC,SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+						("Link broken Port %d\n", Port));
 
-					/* cable removed-> reinit Sensemode */
-					/* Init default sense mode */
+					/* Cable removed-> reinit sense mode. */
+					/* Init default sense mode. */
 					SkHWInitDefSense(pAC, IoC, Port);
 
-					return(SK_HW_PS_RESTART) ;
+					return (SK_HW_PS_RESTART);
 				}
 			}
-		} else {
+		}
+		else {
 			SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);
-			if (SkGePortCheckShorts(pAC, IoC, Port) ==
-				SK_HW_PS_RESTART) {
-				return(SK_HW_PS_RESTART) ;
+			if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) {
+				return (SK_HW_PS_RESTART);
 			}
 		}
 	}
@@ -1228,18 +1315,15 @@
 	 * here we usually can check whether the link is in sync and
 	 * autonegotiation is done.
 	 */
-	XM_IN32(IoC,Port,XM_GP_PORT, &GpReg) ;
-	XM_IN16(IoC,Port,XM_ISRC, &Isrc) ;
+	XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
+	XM_IN16(IoC, Port, XM_ISRC, &Isrc);
 	IsrcSum |= Isrc;
 
 	SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
 	if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) {
 		if ((GpReg & XM_GP_INP_ASS) == 0) {
-			/*
-			 * Save Autonegotiation Done interrupt only if link 
-			 * is in sync
-			 */
-			pPrt->PIsave = (SK_U16) (IsrcSum & (XM_IS_AND));
+			/* Save Autonegotiation Done interrupt only if link is in sync. */
+			pPrt->PIsave = (SK_U16)(IsrcSum & (XM_IS_AND));
 		}
 #ifdef	DEBUG
 		if (pPrt->PIsave & (XM_IS_AND)) {
@@ -1247,44 +1331,40 @@
 				("AutoNeg done rescheduled Port %d\n", Port));
 		}
 #endif
-		return(SK_HW_PS_NONE) ;
+		return (SK_HW_PS_NONE);
 	}
 
 	if (AutoNeg) {
 		if (IsrcSum & XM_IS_AND) {
-			SkHWLinkUp(pAC, IoC, Port) ;
+			SkHWLinkUp(pAC, IoC, Port);
 			Done = SkXmAutoNegDone(pAC,IoC,Port);
 			if (Done != SK_AND_OK) {
-				/* Get PHY parameters, for debugging only */
-				PHY_READ(IoC, pPrt, Port, PHY_XMAC_AUNE_LP,
-					&LpAb);
-				PHY_READ(IoC, pPrt, Port, PHY_XMAC_RES_ABI,
-					&ResAb);
+				/* Get PHY parameters, for debuging only */
+				PHY_READ(IoC, pPrt, Port, PHY_XMAC_AUNE_LP, &LpAb);
+				PHY_READ(IoC, pPrt, Port, PHY_XMAC_RES_ABI, &ResAb);
 				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
 					("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n",
 					 Port, LpAb, ResAb));
 					
 				/* Try next possible mode */
 				NextMode = SkHWSenseGetNext(pAC, IoC, Port);
-				SkHWLinkDown(pAC, IoC, Port) ;
+				SkHWLinkDown(pAC, IoC, Port);
 				if (Done == SK_AND_DUP_CAP) {
 					/* GoTo next mode */
-					SkHWSenseSetNext(pAC, IoC, Port,
-						NextMode);
+					SkHWSenseSetNext(pAC, IoC, Port, NextMode);
 				}
 
-				return(SK_HW_PS_RESTART) ;
-
-			} else {
+				return (SK_HW_PS_RESTART);
+			}
+			else {
 				/*
-				 * Dummy Read extended status to prevent
-				 * extra link down/ups
+				 * Dummy Read extended status to prevent extra link down/ups
 				 * (clear Page Received bit if set)
 				 */
 				PHY_READ(IoC, pPrt, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
 				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
 					("AutoNeg done Port %d\n", Port));
-				return(SK_HW_PS_LINK) ;
+				return (SK_HW_PS_LINK);
 			}
 		} 
 		
@@ -1294,7 +1374,12 @@
 		pPrt->PAutoNegTimeOut ++;
 		if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
 			/*
-			 * Timeout occurred.
+			 * Increase the Timeout counter.
+			 */
+			pPrt->PAutoNegTOCt ++;
+
+			/*
+			 * Timeout occured.
 			 * What do we need now?
 			 */
 			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,
@@ -1304,42 +1389,57 @@
 			if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
 				pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
 				/*
-				 * Timeout occurred
+				 * Timeout occured
 				 * Set Link manually up.
 				 */
-				SkHWSenseSetNext(pAC, IoC, Port,
-					SK_LMODE_FULL);
-				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,
-					SK_DBGCAT_IRQ,
-					("Set manual full duplex Port %d\n",
-					 Port));
+				SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
+				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+					("Set manual full duplex Port %d\n", Port));
+			}
+
+			if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
+				pPrt->PLipaAutoNeg == SK_LIPA_AUTO &&
+				pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) {
+				/*
+				 * This is rather complicated.
+				 * we need to check here whether the LIPA_AUTO
+				 * we saw before is false alert. We saw at one 
+				 * switch ( SR8800) that on boot time it sends
+				 * just one autoneg packet and does no further
+				 * autonegotiation.
+				 * Solution: we restart the autosensing after
+				 * a few timeouts.
+				 */
+				pPrt->PAutoNegTOCt = 0;
+				pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
+				SkHWInitDefSense(pAC, IoC, Port);
 			}
 
 			/*
 			 * Do the restart
 			 */
-			return(SK_HW_PS_RESTART) ;
+			return (SK_HW_PS_RESTART);
 		}
-	} else {
+	}
+	else {
 		/*
 		 * Link is up and we don't need more.
 		 */
 #ifdef	DEBUG
 		if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
-				("ERROR: Lipa auto detected on port %d\n",
-				Port));
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+				("ERROR: Lipa auto detected on port %d\n", Port));
 		}
 #endif
 
 		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ,
 			("Link sync(GP), Port %d\n", Port));
-		SkHWLinkUp(pAC, IoC, Port) ;
-		return(SK_HW_PS_LINK) ;
+		SkHWLinkUp(pAC, IoC, Port);
+		return (SK_HW_PS_LINK);
 	}
 
-	return(SK_HW_PS_NONE) ;
-}
+	return (SK_HW_PS_NONE);
+}	/* SkGePortCheckUpXmac */
 
 
 /******************************************************************************
@@ -1352,59 +1452,216 @@
  *	2	Link came up
  */
 static int	SkGePortCheckUpBcom(
-SK_AC	*pAC,		/* Adapters context */
-SK_IOC	IoC,		/* IO Context */
-int	Port)		/* Which port should be checked */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* IO Context */
+int		Port)	/* Which port should be checked */
 {
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
-	SK_BOOL		AutoNeg;	/* Is Autonegotiation used ? */
+	int			Done;
 	SK_U16		Isrc;		/* Interrupt source register */
-	SK_U16		LpAb;		/* Link Partner Ability */
-	SK_U16		ExtStat;	/* Extended Status Register */
 	SK_U16		PhyStat;	/* Phy Status Register */
-	int		Done;
-	SK_U16		ResAb;
-	SK_U16		SWord;
+	SK_U16		ResAb;		/* Master/Slave resolution */
+	SK_U16		Ctrl;		/* Broadcom control flags */
+#ifdef DEBUG
+	SK_U16		LpAb;
+	SK_U16		ExtStat;
+#endif	/* DEBUG */
+	SK_BOOL		AutoNeg;	/* Is Autonegotiation used ? */
 
 	pPrt = &pAC->GIni.GP[Port];
 
 	/* Check for No HCD Link events (#10523) */
 	PHY_READ(IoC, pPrt, Port, PHY_BCOM_INT_STAT, &Isrc);
-	if ((Isrc & PHY_B_IS_NO_HDCL) == PHY_B_IS_NO_HDCL) {
 
-		/* Workaround BCOM Errata */
-		/* enable and disable Loopback mode if NO HCD occurs */
-		PHY_READ(IoC, pPrt, Port, PHY_BCOM_CTRL, &SWord);
-		PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, SWord | PHY_CT_LOOP);
-		PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, SWord & ~PHY_CT_LOOP);
+#ifdef xDEBUG
+	if ((Isrc & ~0x1800) == 0x70) {
+		SK_U32	Stat1, Stat2, Stat3;
+
+		Stat1 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_INT_MASK, &Stat1);
+		CMSMPrintString(
+			pAC->pConfigTable,
+			MSG_TYPE_RUNTIME_INFO,
+			"CheckUp1 - Stat: %x, Mask: %x",
+			(void *)Isrc,
+			(void *)Stat1);
+
+		Stat1 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_CTRL, &Stat1);
+		Stat2 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_STAT, &Stat2);
+		Stat1 = Stat1 << 16 | Stat2;
+		Stat2 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUNE_ADV, &Stat2);
+		Stat3 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUNE_LP, &Stat3);
+		Stat2 = Stat2 << 16 | Stat3;
+		CMSMPrintString(
+			pAC->pConfigTable,
+			MSG_TYPE_RUNTIME_INFO,
+			"Ctrl/Stat: %x, AN Adv/LP: %x",
+			(void *)Stat1,
+			(void *)Stat2);
+
+		Stat1 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUNE_EXP, &Stat1);
+		Stat2 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_EXT_STAT, &Stat2);
+		Stat1 = Stat1 << 16 | Stat2;
+		Stat2 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_1000T_CTRL, &Stat2);
+		Stat3 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_1000T_STAT, &Stat3);
+		Stat2 = Stat2 << 16 | Stat3;
+		CMSMPrintString(
+			pAC->pConfigTable,
+			MSG_TYPE_RUNTIME_INFO,
+			"AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
+			(void *)Stat1,
+			(void *)Stat2);
+
+		Stat1 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
+		Stat2 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
+		Stat1 = Stat1 << 16 | Stat2;
+		Stat2 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUX_CTRL, &Stat2);
+		Stat3 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUX_STAT, &Stat3);
+		Stat2 = Stat2 << 16 | Stat3;
+		CMSMPrintString(
+			pAC->pConfigTable,
+			MSG_TYPE_RUNTIME_INFO,
+			"PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
+			(void *)Stat1,
+			(void *)Stat2);
+	}
+#endif	/* DEBUG */
+
+	if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) {
+		/*
+		 * Workaround BCOM Errata:
+		 *	enable and disable loopback mode if "NO HCD" occurs.
+		 */
+		PHY_READ(IoC, pPrt, Port, PHY_BCOM_CTRL, &Ctrl);
+		PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, Ctrl | PHY_CT_LOOP);
+		PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, Ctrl & ~PHY_CT_LOOP);
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 			("No HCD Link event, Port %d\n", Port));
+#ifdef xDEBUG
+		CMSMPrintString(
+			pAC->pConfigTable,
+			MSG_TYPE_RUNTIME_INFO,
+			"No HCD link event, port %d.",
+			(void *)Port,
+			(void *)NULL);
+#endif	/* DEBUG */
 	}
 
+	/* Not obsolete: link status bit is latched to 0 and autoclearing! */
 	PHY_READ(IoC, pPrt, Port, PHY_BCOM_STAT, &PhyStat);
 
 	if (pPrt->PHWLinkUp) {
-		return(SK_HW_PS_NONE) ;
+		return (SK_HW_PS_NONE);
 	}
 
-	pPrt->PIsave = 0;
+#ifdef xDEBUG
+	{
+		SK_U32	Stat1, Stat2, Stat3;
+
+		Stat1 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_INT_MASK, &Stat1);
+		CMSMPrintString(
+			pAC->pConfigTable,
+			MSG_TYPE_RUNTIME_INFO,
+			"CheckUp1a - Stat: %x, Mask: %x",
+			(void *)Isrc,
+			(void *)Stat1);
+
+		Stat1 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_CTRL, &Stat1);
+		Stat2 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_STAT, &PhyStat);
+		Stat1 = Stat1 << 16 | PhyStat;
+		Stat2 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUNE_ADV, &Stat2);
+		Stat3 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUNE_LP, &Stat3);
+		Stat2 = Stat2 << 16 | Stat3;
+		CMSMPrintString(
+			pAC->pConfigTable,
+			MSG_TYPE_RUNTIME_INFO,
+			"Ctrl/Stat: %x, AN Adv/LP: %x",
+			(void *)Stat1,
+			(void *)Stat2);
+
+		Stat1 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUNE_EXP, &Stat1);
+		Stat2 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_EXT_STAT, &Stat2);
+		Stat1 = Stat1 << 16 | Stat2;
+		Stat2 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_1000T_CTRL, &Stat2);
+		Stat3 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb);
+		Stat2 = Stat2 << 16 | ResAb;
+		CMSMPrintString(
+			pAC->pConfigTable,
+			MSG_TYPE_RUNTIME_INFO,
+			"AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
+			(void *)Stat1,
+			(void *)Stat2);
+
+		Stat1 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
+		Stat2 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
+		Stat1 = Stat1 << 16 | Stat2;
+		Stat2 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUX_CTRL, &Stat2);
+		Stat3 = 0;
+		PHY_READ(pAC, pPrt, Port, PHY_BCOM_AUX_STAT, &Stat3);
+		Stat2 = Stat2 << 16 | Stat3;
+		CMSMPrintString(
+			pAC->pConfigTable,
+			MSG_TYPE_RUNTIME_INFO,
+			"PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
+			(void *)Stat1,
+			(void *)Stat2);
+	}
+#endif	/* DEBUG */
 
-	/* Now wait for each port's link */
-	if (pPrt->PLinkMode == SK_LMODE_HALF ||
-	    pPrt->PLinkMode == SK_LMODE_FULL) {
+	/* Now wait for each port's link. */
+	if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
 		AutoNeg = SK_FALSE;
-	} else {
+	}
+	else {
 		AutoNeg = SK_TRUE;
 	}
 
 	/*
-	 * here we usually can check whether the link is in sync and
+	 * Here we usually can check whether the link is in sync and
 	 * autonegotiation is done.
 	 */
-	XM_IN16(IoC, Port, XM_ISRC, &Isrc) ;
+#if 0
+/* RA;:;: obsolete */
+	XM_IN16(IoC, Port, XM_ISRC, &Isrc);
+#endif	/* 0 */
 
 	PHY_READ(IoC, pPrt, Port, PHY_BCOM_STAT, &PhyStat);
 
+#ifdef xDEBUG
+	if ((PhyStat & PHY_ST_LSYNC) >> 2 != (ExtStat & PHY_B_PES_LS) >> 8) {
+		CMSMPrintString(
+			pAC->pConfigTable,
+			MSG_TYPE_RUNTIME_INFO,
+			"PhyStat != ExtStat: %x %x",
+			(void *)PhyStat,
+			(void *)ExtStat);
+	}
+#endif	/* DEBUG */
+
 	SkXmAutoNegLipaBcom(pAC, IoC, Port, PhyStat);
 	
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
@@ -1412,28 +1669,22 @@
 
 	PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb);
 
-	if ((PhyStat & PHY_ST_LSYNC) == 0) {
-		if (ResAb & (PHY_B_1000S_MSF)) {
-			/* Error */
-			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
-				("Master/Slave Fault port %d\n", Port));
-			pPrt->PAutoNegFail = SK_TRUE;
-			pPrt->PMSStatus = SK_MS_STAT_FAULT;
-			return (SK_AND_OTHER);
-		}
-		return (SK_HW_PS_NONE);
-	}
-	
-	if (ResAb & (PHY_B_1000S_MSF)) {
+	if (ResAb & PHY_B_1000S_MSF) {
 		/* Error */
-		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 			("Master/Slave Fault port %d\n", Port));
 		pPrt->PAutoNegFail = SK_TRUE;
 		pPrt->PMSStatus = SK_MS_STAT_FAULT;
-		return (SK_AND_OTHER);
-	} else if (ResAb & PHY_B_1000S_MSR) {
+		return (SK_HW_PS_RESTART);
+	}
+
+	if ((PhyStat & PHY_ST_LSYNC) == 0) {
+		return (SK_HW_PS_NONE);
+	}
+	else if (ResAb & PHY_B_1000S_MSR) {
 		pPrt->PMSStatus = SK_MS_STAT_MASTER;
-	} else {
+	}
+	else {
 		pPrt->PMSStatus = SK_MS_STAT_SLAVE;
 	}
 	
@@ -1443,76 +1694,73 @@
 	if (AutoNeg) {
 		if (PhyStat & PHY_ST_AN_OVER) {
 			SkHWLinkUp(pAC, IoC, Port);
-			Done = SkXmAutoNegDone(pAC,IoC,Port);
+			Done = SkXmAutoNegDone(pAC, IoC, Port);
 			if (Done != SK_AND_OK) {
-				/* Get PHY parameters, for debugging only */
-				PHY_READ(IoC, pPrt, Port,
-					PHY_BCOM_AUNE_LP,
-					&LpAb);
-				PHY_READ(IoC, pPrt, Port,
-					PHY_BCOM_1000T_STAT,
-					&ExtStat);
-				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
-					("AutoNeg FAIL Port %d (LpAb %x, "
-					"1000TStat %x)\n",
-					 Port, LpAb, ExtStat));
-				return(SK_HW_PS_RESTART) ;
-
-			} else {
-				/*
-				 * Dummy Read interrupt status to prevent
-				 * extra link down/ups
-				 */
-				PHY_READ(IoC, pPrt, Port, PHY_BCOM_INT_STAT,
-					&ExtStat);
-				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
+#ifdef DEBUG
+				/* Get PHY parameters, for debugging only. */
+				PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUNE_LP, &LpAb);
+				PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ExtStat);
+				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+					("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
+					Port, LpAb, ExtStat));
+#endif	/* DEBUG */
+				return (SK_HW_PS_RESTART);
+			}
+			else {
+#ifdef xDEBUG
+				/* Dummy read ISR to prevent extra link downs/ups. */
+				PHY_READ(IoC, pPrt, Port, PHY_BCOM_INT_STAT, &ExtStat);
+
+				if ((ExtStat & ~0x1800) != 0) {
+					CMSMPrintString(
+						pAC->pConfigTable,
+						MSG_TYPE_RUNTIME_INFO,
+						"CheckUp2 - Stat: %x",
+						(void *)ExtStat,
+						(void *)NULL);
+				}
+#endif	/* DEBUG */
+				
+				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 					("AutoNeg done Port %d\n", Port));
-				return(SK_HW_PS_LINK) ;
+				return (SK_HW_PS_LINK);
 			}
 		} 
-	} else {
+	}
+	else {	/* !AutoNeg */
 		/*
 		 * Link is up and we don't need more.
 		 */
 #ifdef	DEBUG
 		if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
-				("ERROR: Lipa auto detected on port %d\n",
-				Port));
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+				("ERROR: Lipa auto detected on port %d\n", Port));
 		}
 #endif
 
-#if 0
-		PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb);
-		if (ResAb & (PHY_B_1000S_MSF)) {
-			/* Error */
-			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
-				("Master/Slave Fault port %d\n", Port));
-			pPrt->PAutoNegFail = SK_TRUE;
-			pPrt->PMSStatus = SK_MS_STAT_FAULT;
-			return (SK_AND_OTHER);
-		} else if (ResAb & PHY_B_1000S_MSR) {
-			pPrt->PMSStatus = SK_MS_STAT_MASTER ;
-		} else {
-			pPrt->PMSStatus = SK_MS_STAT_SLAVE ;
-		}
-#endif	/* 0 */
-
-
-		/*
-		 * Dummy Read interrupt status to prevent
-		 * extra link down/ups
-		 */
+#ifdef xDEBUG
+		/* Dummy read ISR to prevent extra link downs/ups. */
 		PHY_READ(IoC, pPrt, Port, PHY_BCOM_INT_STAT, &ExtStat);
+
+		if ((ExtStat & ~0x1800) != 0) {
+			CMSMPrintString(
+				pAC->pConfigTable,
+				MSG_TYPE_RUNTIME_INFO,
+				"CheckUp3 - Stat: %x",
+				(void *)ExtStat,
+				(void *)NULL);
+		}
+#endif	/* DEBUG */
 		
-		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ,
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
 			("Link sync(GP), Port %d\n", Port));
-		SkHWLinkUp(pAC, IoC, Port) ;
-		return(SK_HW_PS_LINK) ;
+		SkHWLinkUp(pAC, IoC, Port);
+		return (SK_HW_PS_LINK);
 	}
 
-	return(SK_HW_PS_NONE) ;
-}
+	return (SK_HW_PS_NONE);
+}	/* SkGePortCheckUpBcom */
+
 
 /******************************************************************************
  *
@@ -1524,24 +1772,24 @@
  *	2	Link came up
  */
 static int	SkGePortCheckUpLone(
-SK_AC	*pAC,		/* Adapters context */
+SK_AC	*pAC,		/* Adapter Context */
 SK_IOC	IoC,		/* IO Context */
-int	Port)		/* Which port should be checked */
+int		Port)		/* Which port should be checked */
 {
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
-	SK_BOOL		AutoNeg;	/* Is Autonegotiation used ? */
+	int		Done;
 	SK_U16		Isrc;		/* Interrupt source register */
 	SK_U16		LpAb;		/* Link Partner Ability */
-	SK_U8		NextMode;	/* Next AutoSensing Mode */
 	SK_U16		ExtStat;	/* Extended Status Register */
 	SK_U16		PhyStat;	/* Phy Status Register */
 	SK_U16		StatSum;
-	int		Done;
+	SK_BOOL		AutoNeg;	/* Is Autonegotiation used ? */
+	SK_U8		NextMode;	/* Next AutoSensing Mode */
 
 	pPrt = &pAC->GIni.GP[Port];
 
 	if (pPrt->PHWLinkUp) {
-		return(SK_HW_PS_NONE) ;
+		return (SK_HW_PS_NONE);
 	}
 
 	StatSum = pPrt->PIsave;
@@ -1551,7 +1799,8 @@
 	if (pPrt->PLinkMode == SK_LMODE_HALF ||
 	    pPrt->PLinkMode == SK_LMODE_FULL) {
 		AutoNeg = SK_FALSE;
-	} else {
+	}
+	else {
 		AutoNeg = SK_TRUE;
 	}
 
@@ -1559,7 +1808,7 @@
 	 * here we usually can check whether the link is in sync and
 	 * autonegotiation is done.
 	 */
-	XM_IN16(IoC, Port, XM_ISRC, &Isrc) ;
+	XM_IN16(IoC, Port, XM_ISRC, &Isrc);
 	PHY_READ(IoC, pPrt, Port, PHY_LONE_STAT, &PhyStat);
 	StatSum |= PhyStat;
 
@@ -1568,53 +1817,52 @@
 		/*
 		 * Save Autonegotiation Done bit
 		 */
-		pPrt->PIsave = (SK_U16) (StatSum & PHY_ST_AN_OVER);
+		pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER);
 #ifdef DEBUG
 		if (pPrt->PIsave & PHY_ST_AN_OVER) {
 			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
 				("AutoNeg done rescheduled Port %d\n", Port));
 		}
 #endif
-		return(SK_HW_PS_NONE) ;
+		return (SK_HW_PS_NONE);
 	}
 
 	if (AutoNeg) {
 		if (StatSum & PHY_ST_AN_OVER) {
-			SkHWLinkUp(pAC, IoC, Port) ;
+			SkHWLinkUp(pAC, IoC, Port);
 			Done = SkXmAutoNegDone(pAC,IoC,Port);
 			if (Done != SK_AND_OK) {
-				/* Get PHY parameters, for debugging only */
+				/* Get PHY parameters, for debuging only */
 				PHY_READ(IoC, pPrt, Port,
 					PHY_LONE_AUNE_LP,
 					&LpAb);
 				PHY_READ(IoC, pPrt, Port,
 					PHY_LONE_1000T_STAT,
 					&ExtStat);
-				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
+				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 					("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
 					 Port, LpAb, ExtStat));
 					
 				/* Try next possible mode */
 				NextMode = SkHWSenseGetNext(pAC, IoC, Port);
-				SkHWLinkDown(pAC, IoC, Port) ;
+				SkHWLinkDown(pAC, IoC, Port);
 				if (Done == SK_AND_DUP_CAP) {
 					/* GoTo next mode */
-					SkHWSenseSetNext(pAC, IoC, Port,
-						NextMode);
+					SkHWSenseSetNext(pAC, IoC, Port, NextMode);
 				}
 
-				return(SK_HW_PS_RESTART) ;
+				return (SK_HW_PS_RESTART);
 
-			} else {
+			}
+			else {
 				/*
 				 * Dummy Read interrupt status to prevent
 				 * extra link down/ups
 				 */
-				PHY_READ(IoC, pPrt, Port, PHY_LONE_INT_STAT,
-					&ExtStat);
-				SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
+				PHY_READ(IoC, pPrt, Port, PHY_LONE_INT_STAT, &ExtStat);
+				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 					("AutoNeg done Port %d\n", Port));
-				return(SK_HW_PS_LINK) ;
+				return (SK_HW_PS_LINK);
 			}
 		} 
 		
@@ -1624,7 +1872,7 @@
 		pPrt->PAutoNegTimeOut ++;
 		if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
 			/*
-			 * Timeout occurred.
+			 * Timeout occured.
 			 * What do we need now?
 			 */
 			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,
@@ -1634,7 +1882,7 @@
 			if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
 				pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
 				/*
-				 * Timeout occurred
+				 * Timeout occured
 				 * Set Link manually up.
 				 */
 				SkHWSenseSetNext(pAC, IoC, Port,
@@ -1648,17 +1896,17 @@
 			/*
 			 * Do the restart
 			 */
-			return(SK_HW_PS_RESTART) ;
+			return (SK_HW_PS_RESTART);
 		}
-	} else {
+	}
+	else {
 		/*
 		 * Link is up and we don't need more.
 		 */
 #ifdef	DEBUG
 		if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
-				("ERROR: Lipa auto detected on port %d\n",
-				Port));
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+				("ERROR: Lipa auto detected on port %d\n", Port));
 		}
 #endif
 
@@ -1668,14 +1916,14 @@
 		 */
 		PHY_READ(IoC, pPrt, Port, PHY_LONE_INT_STAT, &ExtStat);
 		
-		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ,
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
 			("Link sync(GP), Port %d\n", Port));
-		SkHWLinkUp(pAC, IoC, Port) ;
-		return(SK_HW_PS_LINK) ;
+		SkHWLinkUp(pAC, IoC, Port);
+		return (SK_HW_PS_LINK);
 	}
 
-	return(SK_HW_PS_NONE) ;
-}
+	return (SK_HW_PS_NONE);
+}	/* SkGePortCheckUpLone*/
 
 
 /******************************************************************************
@@ -1688,13 +1936,13 @@
  *	2	Link came up
  */
 static int	SkGePortCheckUpNat(
-SK_AC	*pAC,		/* Adapters context */
+SK_AC	*pAC,		/* Adapter Context */
 SK_IOC	IoC,		/* IO Context */
-int	Port)		/* Which port should be checked */
+int		Port)		/* Which port should be checked */
 {
 	/* todo: National */
-	return(SK_HW_PS_NONE) ;
-}
+	return (SK_HW_PS_NONE);
+}	/* SkGePortCheckUpNat */
 
 
 /******************************************************************************
@@ -1706,17 +1954,21 @@
  * Notes:
  */
 int	SkGeSirqEvent(
-SK_AC		*pAC,		/* Adapters context */
+SK_AC		*pAC,		/* Adapter Context */
 SK_IOC		IoC,		/* Io Context */
 SK_U32		Event,		/* Module specific Event */
 SK_EVPARA	Para)		/* Event specific Parameter */
 {
-	SK_U32	Port;
-	SK_U32	Time;
-	SK_U8	Val8 ;
-	int	PortStat;
+	SK_U64		Octets;
+	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
+	SK_U32		Port;
+	SK_U32		Time;
+	unsigned	Len;
+	int			PortStat;
+	SK_U8		Val8;
 
 	Port = Para.Para32[0];
+	pPrt = & pAC->GIni.GP[Port];
 
 	switch (Event) {
 	case SK_HWEV_WATIM:
@@ -1725,7 +1977,7 @@
 
 		switch (PortStat) {
 		case SK_HW_PS_RESTART:
-			if (pAC->GIni.GP[Port].PHWLinkUp) {
+			if (pPrt->PHWLinkUp) {
 				/*
 				 * Set Link to down.
 				 */
@@ -1735,16 +1987,7 @@
 				 * Signal directly to RLMT to ensure correct
 				 * sequence of SWITCH and RESET event.
 				 */
-				Para.Para32[0] = (SK_U32) Port;
 				SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
-
-				/* Start workaround Errata #2 timer */
-				SkTimerStart(pAC, IoC,
-					&pAC->GIni.GP[Port].PWaTimer,
-					SK_WA_INA_TIME,
-					SKGE_HWAC,
-					SK_HWEV_WATIM,
-					Para);
 			}
 
 			/* Restart needed */
@@ -1757,39 +2000,38 @@
 			break;
 
 		}
-
+		
 		/* Start again the check Timer */
-		if (pAC->GIni.GP[Port].PHWLinkUp) {
+		if (pPrt->PHWLinkUp) {
 			Time = SK_WA_ACT_TIME;
-		} else {
+		}
+		else {
 			Time = SK_WA_INA_TIME;
 		}
 
-		/* todo: still needed for non-Xmac-PHYs ??? */
-		/* Start workaround Errata #2 timer */
-		SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer, Time,
-			SKGE_HWAC, SK_HWEV_WATIM, Para);
-
+		/* Todo: still needed for non-XMAC PHYs??? */
+		/* Start workaround Errata #2 timer. */
+		SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer,
+			Time, SKGE_HWAC, SK_HWEV_WATIM, Para);
 		break;
 
 	case SK_HWEV_PORT_START:
-		if (pAC->GIni.GP[Port].PHWLinkUp) {
+		if (pPrt->PHWLinkUp) {
 			/*
 			 * Signal directly to RLMT to ensure correct
 			 * sequence of SWITCH and RESET event.
 			 */
-			Para.Para32[0] = (SK_U32) Port;
 			SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
 		}
 
-		SkHWLinkDown(pAC, IoC, Port) ;
+		SkHWLinkDown(pAC, IoC, Port);
 
 		/* Schedule Port RESET */
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
 
 		/* Start workaround Errata #2 timer */
-		SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer,
-			SK_WA_INA_TIME,SKGE_HWAC,SK_HWEV_WATIM,Para);
+		SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
+			SKGE_HWAC, SK_HWEV_WATIM, Para);
 		break;
 
 	case SK_HWEV_PORT_STOP:
@@ -1798,13 +2040,13 @@
 			 * Signal directly to RLMT to ensure correct
 			 * sequence of SWITCH and RESET event.
 			 */
-			Para.Para32[0] = (SK_U32) Port;
 			SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
 		}
+
 		/* Stop Workaround Timer */
-		SkTimerStop(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer) ;
+		SkTimerStop(pAC, IoC, &pPrt->PWaTimer);
 
-		SkHWLinkDown(pAC, IoC, Port) ;
+		SkHWLinkDown(pAC, IoC, Port);
 		break;
 
 	case SK_HWEV_UPDATE_STAT:
@@ -1813,18 +2055,18 @@
 
 	case SK_HWEV_CLEAR_STAT:
 		/* We do NOT need to clear any statistics */
-		for (Port = 0; Port < (SK_U32) pAC->GIni.GIMacsFound; Port++) {
-			pAC->GIni.GP[Port].PPrevRx = 0;
-			pAC->GIni.GP[Port].PPrevFcs = 0;
-			pAC->GIni.GP[Port].PPrevShorts = 0;
+		for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) {
+			pPrt->PPrevRx = 0;
+			pPrt->PPrevFcs = 0;
+			pPrt->PPrevShorts = 0;
 		}
 		break;
 
 	case SK_HWEV_SET_LMODE:
-		Val8 = (SK_U8) Para.Para32[1];
-		if (pAC->GIni.GP[Port].PLinkModeConf != Val8) {
+		Val8 = (SK_U8)Para.Para32[1];
+		if (pPrt->PLinkModeConf != Val8) {
 			/* Set New link mode */
-			pAC->GIni.GP[Port].PLinkModeConf = Val8;
+			pPrt->PLinkModeConf = Val8;
 
 			/* Restart Port */
 			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
@@ -1833,10 +2075,10 @@
 		break;
 
 	case SK_HWEV_SET_FLOWMODE:
-		Val8 = (SK_U8) Para.Para32[1];
-		if (pAC->GIni.GP[Port].PFlowCtrlMode != Val8) {
+		Val8 = (SK_U8)Para.Para32[1];
+		if (pPrt->PFlowCtrlMode != Val8) {
 			/* Set New Flow Control mode */
-			pAC->GIni.GP[Port].PFlowCtrlMode = Val8;
+			pPrt->PFlowCtrlMode = Val8;
 
 			/* Restart Port */
 			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
@@ -1845,10 +2087,10 @@
 		break;
 
 	case SK_HWEV_SET_ROLE:
-		Val8 = (SK_U8) Para.Para32[1];
-		if (pAC->GIni.GP[Port].PMSMode != Val8) {
+		Val8 = (SK_U8)Para.Para32[1];
+		if (pPrt->PMSMode != Val8) {
 			/* Set New link mode */
-			pAC->GIni.GP[Port].PMSMode = Val8;
+			pPrt->PMSMode = Val8;
 
 			/* Restart Port */
 			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
@@ -1856,14 +2098,31 @@
 		}
 		break;
 
+	case SK_HWEV_HALFDUP_CHK:
+		/*
+		 * half duplex hangup workaround. See packet arbiter timeout
+		 * interrupt for description
+		 */
+		pPrt->HalfDupTimerActive = SK_FALSE;
+		if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || 
+		    pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) {
+			Len = sizeof(SK_U64);
+			SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
+				&Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),
+				pAC->Rlmt.Port[Port].Net->NetNumber);
+			if (pPrt->LastOctets == Octets) {
+				/* TX hanging, do a FIFO flush restarts it. */
+				SkXmFlushTxFifo(pAC, IoC, Port);
+			}
+		}
+		break;
 	default:
-		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001,
-			SKERR_SIRQ_E001MSG);
+		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG);
 		break;
 	}
 
-	return(0) ;
-}
+	return (0);
+}	/* SkGeSirqEvent */
 
 
 /******************************************************************************
@@ -1875,17 +2134,20 @@
  * Returns: N/A
  */
 static void SkPhyIsrBcom(
-SK_AC		*pAC,		/* Adapters context */
+SK_AC		*pAC,		/* Adapter Context */
 SK_IOC		IoC,		/* Io Context */
-int		Port,		/* Port Num = PHY Num */
-SK_U16		IStatus)	/* Interrupts masked with PHY-Mask */
+int			Port,		/* Port Num = PHY Num */
+SK_U16		IStatus)	/* Interrupt Status */
 {
+	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
 	SK_EVPARA	Para;
 
+	pPrt = &pAC->GIni.GP[Port];
+
 	if (IStatus & PHY_B_IS_PSE) {
-		/* incorrectable pair swap error */
+		/* Incorrectable pair swap error. */
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E022,
-			SKERR_SIRQ_E022MSG) ;
+			SKERR_SIRQ_E022MSG);
 	}
 	
 	if (IStatus & PHY_B_IS_MDXI_SC) {
@@ -1901,19 +2163,19 @@
 	}
 	
 	if (IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) {
+		Para.Para32[0] = (SK_U32)Port;
+
 		SkHWLinkDown(pAC, IoC, Port);
 
 		/* Signal to RLMT */
-		Para.Para32[0] = (SK_U32) Port;
 		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
 
 		/* Start workaround Errata #2 timer */
-		SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer,
-			SK_WA_INA_TIME,SKGE_HWAC,SK_HWEV_WATIM,Para);
+		SkTimerStart(pAC, IoC, &pPrt->PWaTimer,
+			SK_WA_INA_TIME, SKGE_HWAC, SK_HWEV_WATIM, Para);
 	}
 
 	if (IStatus & PHY_B_IS_NO_HDCL) {
-		/* not used */
 	}
 
 	if (IStatus & PHY_B_IS_NO_HDC) {
@@ -1947,8 +2209,7 @@
 	if (IStatus & PHY_B_IS_CRC_ER) {
 		/* not used */
 	}
-
-}
+}	/* SkPhyIsrBcom */
 
 
 /******************************************************************************
@@ -1960,10 +2221,10 @@
  * Returns: N/A
  */
 static void SkPhyIsrLone(
-SK_AC		*pAC,		/* Adapters context */
-SK_IOC		IoC,		/* Io Context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* Io Context */
 int		Port,		/* Port Num = PHY Num */
-SK_U16		IStatus)	/* Interrupts masked with PHY-Mask */
+SK_U16	IStatus)	/* Interrupt Status */
 {
 	SK_EVPARA	Para;
 
@@ -1999,19 +2260,17 @@
 		SkHWLinkDown(pAC, IoC, Port);
 
 		/* Signal to RLMT */
-		Para.Para32[0] = (SK_U32) Port;
+		Para.Para32[0] = (SK_U32)Port;
 		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
 
 		/* Start workaround Errata #2 timer */
 		SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer,
-			SK_WA_INA_TIME,SKGE_HWAC,SK_HWEV_WATIM,Para);
+			SK_WA_INA_TIME, SKGE_HWAC, SK_HWEV_WATIM, Para);
 	}
 
 	if (IStatus & PHY_L_IS_MDINT) {
 		/* not used */
 	}
-
-}
-
+}	/* SkPhyIsrLone */
 
 /* End of File */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/ski2c.c linux/drivers/net/sk98lin/ski2c.c
--- v2.4.6/linux/drivers/net/sk98lin/ski2c.c	Tue Mar 20 12:04:59 2001
+++ linux/drivers/net/sk98lin/ski2c.c	Wed Jul  4 11:50:39 2001
@@ -2,17 +2,16 @@
  *
  * Name:	ski2c.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.44 $
- * Date:	$Date: 2000/08/07 15:49:03 $
- * Purpose:	Funktions to access Voltage and Temperature Sensor
- *		(taken from Monalisa (taken from Concentrator))
+ * Version:	$Revision: 1.47 $
+ * Date:	$Date: 2001/04/05 11:38:09 $
+ * Purpose:	Functions to access Voltage and Temperature Sensor
+ *			(taken from Monalisa (taken from Concentrator))
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2000 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -28,12 +27,22 @@
  * History:
  *
  *	$Log: ski2c.c,v $
+ *	Revision 1.47  2001/04/05 11:38:09  rassmann
+ *	Set SenState to idle in SkI2cWaitIrq().
+ *	Changed error message in SkI2cWaitIrq().
+ *	
+ *	Revision 1.46  2001/04/02 14:03:35  rassmann
+ *	Changed pAC to IoC in SK_IN32().
+ *	
+ *	Revision 1.45  2001/03/21 12:12:49  rassmann
+ *	Resetting I2C_READY interrupt in SkI2cInit1().
+ *	
  *	Revision 1.44  2000/08/07 15:49:03  gklug
- *	fix: SK_INFAST only in NetWare driver
+ *	Fix: SK_INFAST only in NetWare driver.
  *	
  *	Revision 1.43  2000/08/03 14:28:17  rassmann
- *	- Added function to wait for I2C being ready before resetting the board.
- *	- Replaced one duplicate "out of range" message with correct one.
+ *	Added function to wait for I2C being ready before resetting the board.
+ *	Replaced one duplicate "out of range" message with correct one.
  *	
  *	Revision 1.42  1999/11/22 13:35:12  cgoos
  *	Changed license header to GPL.
@@ -180,10 +189,10 @@
 
 
 /*
-	I2C Protocol
-*/
+ *	I2C Protocol
+ */
 static const char SysKonnectFileId[] =
-	"$Id: ski2c.c,v 1.44 2000/08/07 15:49:03 gklug Exp $";
+	"$Id: ski2c.c,v 1.47 2001/04/05 11:38:09 rassmann Exp $";
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
 #include "h/lm80.h"
@@ -191,7 +200,7 @@
 
 #ifdef __C2MAN__
 /*
-	I2C protocol implemetation.
+	I2C protocol implementation.
 
 	General Description:
 
@@ -486,7 +495,7 @@
 {
 	int	i;
 
-	for (i=0; i<8; i++) {
+	for (i = 0; i < 8; i++) {
 		if (Byte & (1<<(7-i))) {
 			SkI2cSndBit(IoC, 1);
 		} else {
@@ -510,7 +519,7 @@
 	int	i;
 	int	Byte = 0;
 
-	for (i=0; i<8; i++) {
+	for (i = 0; i < 8; i++) {
 		Byte <<= 1;
 		Byte |= SkI2cRcvBit(IoC);
 	}
@@ -601,13 +610,14 @@
 		if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
 			SK_I2C_STOP(IoC);
 #ifndef SK_DIAG
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
 #endif	/* !SK_DIAG */
 			return;
 		}
-		SK_IN32(pAC, B0_ISRC, &IrqSrc);
+		SK_IN32(IoC, B0_ISRC, &IrqSrc);
 	} while ((IrqSrc & IS_I2C_READY) == 0);
 
+	pSen->SenState = SK_SEN_IDLE;
 	return;
 }	/* SkI2cWaitIrq */
 
@@ -662,10 +672,11 @@
 /*
  * read a sensor's value
  *
- * This function read a sensors value from the I2C sensor chip. The sensor
+ * This function reads a sensor's value from the I2C sensor chip. The sensor
  * is defined by its index into the sensors database in the struct pAC points
  * to.
- * Returns	1 if the read is completed
+ * Returns
+ *		1 if the read is completed
  *		0 if the read must be continued (I2C Bus still allocated)
  */
 int	SkI2cReadSensor(
@@ -695,7 +706,7 @@
 	pAC->I2c.DummyReads = SK_MAX_SENSORS;
 #endif
 
-	for (i=0; i < SK_MAX_SENSORS; i ++) {
+	for (i = 0; i < SK_MAX_SENSORS; i ++) {
 		switch (i) {
 		case 0:
 			pAC->I2c.SenTable[i].SenDesc = "Temperature";
@@ -875,16 +886,19 @@
 	
 #ifndef	SK_DIAG
 	pAC->I2c.DummyReads = pAC->I2c.MaxSens;
+
+	/* Clear the interrupt source */
+	SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
 #endif	/* !SK_DIAG */
 	
-	/* Now we are IO initialized */
+	/* Now we are I/O initialized */
 	pAC->I2c.InitLevel = SK_INIT_IO;
 	return(0);
 }	/* SkI2cInit1 */
 
 
 /*
- * Init level 2: Start first sensors read
+ * Init level 2: Start first sensor read.
  */
 static	int	SkI2cInit2(
 SK_AC	*pAC,	/* Adapter Context */
@@ -923,12 +937,13 @@
  * Level 0:
  *	Initialize only the data structures. Do NOT access hardware.
  * Level 1:
- *	Initialize hardware through SK_IN?OUT commands. Do NOT use interrupts.
+ *	Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
  * Level 2:
  *	Everything is possible. Interrupts may be used from now on.
  *
- * return:	0 = success
- *		other = error.
+ * return:
+ *	0 = success
+ *	other = error.
  */
 int	SkI2cInit(
 SK_AC	*pAC,	/* Adapter Context */
@@ -986,7 +1001,7 @@
 	SK_EVPARA	ParaLocal;
 	SK_BOOL		TooHigh;	/* Is sensor too high? */
 	SK_BOOL		TooLow;		/* Is sensor too low? */
-	SK_U64		CurrTime;	/* current Time */
+	SK_U64		CurrTime;	/* Current Time */
 	SK_BOOL		DoTrapSend;	/* We need to send a trap */
 	SK_BOOL		DoErrLog;	/* We need to log the error */
 	SK_BOOL		IsError;	/* We need to log the error */
@@ -1000,13 +1015,10 @@
 	/* Get the current time */
 	CurrTime = SkOsGetTime(pAC);
 
-	/* Set para to the most useful setting:
-	 * The current sensor.
-	 */
+	/* Set para to the most useful setting: The current sensor. */
 	ParaLocal.Para64 = (SK_U64) pAC->I2c.CurrSens;
 
-	/* Check the Value against the thresholds */
-	/* First: Error Thresholds */
+	/* Check the Value against the thresholds. First: Error Thresholds */
 	TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
 	TooLow = (pSen->SenValue < pSen->SenThreErrLow);
 		
@@ -1192,11 +1204,11 @@
 SK_U32		Event,	/* Module specific Event */
 SK_EVPARA	Para)	/* Event specific Parameter */
 {
-	int		ReadComplete;
+	int			ReadComplete;
 	SK_SENSOR	*pSen;
 	SK_U32		Time;
 	SK_EVPARA	ParaLocal;
-	int		i;
+	int			i;
 
 	switch (Event) {
 	case SK_I2CEV_IRQ:
@@ -1224,16 +1236,16 @@
 		}
 		break;
 	case SK_I2CEV_CLEAR:
-		for (i=0; i < SK_MAX_SENSORS; i ++) {
+		for (i = 0; i < SK_MAX_SENSORS; i ++) {
 			pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
 			pAC->I2c.SenTable[i].SenErrCts = 0;
 			pAC->I2c.SenTable[i].SenWarnCts = 0;
 			pAC->I2c.SenTable[i].SenBegErrTS = 0;
 			pAC->I2c.SenTable[i].SenBegWarnTS = 0;
-			pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64) 0;
-			pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64) 0;
-			pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64) 0;
-			pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64) 0;
+			pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
+			pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
+			pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
+			pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
 		}
 		break;
 	default:
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/skproc.c linux/drivers/net/sk98lin/skproc.c
--- v2.4.6/linux/drivers/net/sk98lin/skproc.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/sk98lin/skproc.c	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,435 @@
+/******************************************************************************
+ *
+ * Name:    skproc.c
+ * Project:	GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 1.2.2.2 $
+ * Date:    $Date: 2001/03/15 12:50:13 $
+ * Purpose:	Funktions to display statictic data
+ *
+ ******************************************************************************/
+ 
+/******************************************************************************
+ *
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ *
+ *	Created 22-Nov-2000
+ *	Author: Mirko Lindner (mlindner@syskonnect.de)
+ *
+ *	The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ * History:
+ *
+ *	$Log: skproc.c,v $
+ *	Revision 1.2.2.2  2001/03/15 12:50:13  mlindner
+ *	fix: ProcFS owner protection
+ *	
+ *	Revision 1.2.2.1  2001/03/12 16:43:48  mlindner
+ *	chg: 2.4 requirements for procfs
+ *	
+ *	Revision 1.1  2001/01/22 14:15:31  mlindner
+ *	added ProcFs functionality
+ *	Dual Net functionality integrated
+ *	Rlmt networks added
+ *	
+ *
+ ******************************************************************************/
+
+#include <linux/proc_fs.h>
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+#define ZEROPAD	1		/* pad with zero */
+#define SIGN	2		/* unsigned/signed long */
+#define PLUS	4		/* show plus */
+#define SPACE	8		/* space if plus */
+#define LEFT	16		/* left justified */
+//#define SPECIAL	32		/* 0x */
+#define LARGE	64
+
+extern void proc_fill_inode(struct inode *inode, int fill);
+extern char * SkNumber(char * str, long long num, int base, int size, 
+				int precision ,int type);
+int proc_read(char *buffer,
+				char **buffer_location,
+				off_t offset,
+				int buffer_length,
+				int *eof,
+				void *data);
+
+static const char SK_Root_Dir_entry[] = "sk98lin";
+extern struct net_device *root_dev;
+
+
+struct proc_dir_entry pSkRootDir = { 
+	0,
+	sizeof(SK_Root_Dir_entry)-1,
+	(const char*)SK_Root_Dir_entry,
+	S_IFDIR | S_IRUGO,
+	2, 0, 0, 0, NULL,
+	NULL
+};
+
+
+/*****************************************************************************
+ *
+ * 	proc_read - print "summaries" entry 
+ *
+ * Description:
+ *  This function fills the proc entry with statistic data about 
+ *  the ethernet device.
+ *  
+ *
+ * Returns: buffer with statistic data
+ *	
+ */
+int proc_read(char *buffer,
+char **buffer_location,
+off_t offset,
+int buffer_length,
+int *eof,
+void *data)
+{
+	int len = 0;
+	int t;
+	int i;
+	DEV_NET				*pNet;
+	SK_AC				*pAC;
+	char 				test_buf[100];
+	unsigned int			Flags;		
+	unsigned int			Size;
+	struct net_device 		*next;
+	struct net_device 		*SkgeProcDev = root_dev;
+
+	SK_PNMI_STRUCT_DATA 	*pPnmiStruct;
+	SK_PNMI_STAT		*pPnmiStat;
+	struct proc_dir_entry *file = (struct proc_dir_entry*) data;
+
+	while (SkgeProcDev) {
+		pNet = (DEV_NET*) SkgeProcDev->priv;
+		pAC = pNet->pAC;
+		next = pAC->Next;
+		pPnmiStruct = &pAC->PnmiStruct;
+		/* NetIndex in GetStruct is now required, zero is only dummy */
+
+		for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
+			if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
+				t--;
+			
+			spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+			Size = SK_PNMI_STRUCT_SIZE;
+			SkPnmiGetStruct(pAC, pAC->IoBase, 
+				pPnmiStruct, &Size, t-1);
+			spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+	
+			if (strcmp(pAC->dev[t-1]->name, file->name) == 0) {
+				pPnmiStat = &pPnmiStruct->Stat[0];
+				len = sprintf(buffer, 
+					"\nDetailed statistic for device %s\n",
+					pAC->dev[t-1]->name);
+				len += sprintf(buffer + len,
+					"==================================\n");
+	
+				/* Board statistics */
+				len += sprintf(buffer + len, 
+					"\nBoard statistics\n\n");
+				len += sprintf(buffer + len,
+					"Active Port               %c\n",
+					'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
+					Net[t-1].PrefPort]->PortNumber);
+				len += sprintf(buffer + len,
+					"Preferred Port            %c\n",
+					'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
+					Net[t-1].PrefPort]->PortNumber);
+
+				len += sprintf(buffer + len,
+					"Bus speed (Mhz)           %d\n",
+					pPnmiStruct->BusSpeed);
+
+				len += sprintf(buffer + len,
+					"Bus width (Bit)           %d\n",
+					pPnmiStruct->BusWidth);
+
+				for (i=0; i < SK_MAX_SENSORS; i ++) {
+					if (strcmp(pAC->I2c.SenTable[i].SenDesc,
+							"Temperature") == 0 ) {
+						len += sprintf(buffer + len,
+							"Temperature (C)           %d.%d\n",
+							pAC->I2c.SenTable[i].SenValue / 10,
+							pAC->I2c.SenTable[i].SenValue % 10);
+						len += sprintf(buffer + len,
+							"Temperature (F)           %d.%d\n",
+							((((pAC->I2c.SenTable[i].SenValue)
+							*10)*9)/5 + 3200)/100,
+							((((pAC->I2c.SenTable[i].SenValue)
+							*10)*9)/5 + 3200) % 10);
+					} else if (strcmp(pAC->I2c.SenTable[i].SenDesc,
+							"Speed Fan") == 0 ) {
+						len += sprintf(buffer + len,
+							"Speed Fan                 %d\n",
+							pAC->I2c.SenTable[i].SenValue);
+					} else {
+						len += sprintf(buffer + len,
+							"%-20s      %d.%d\n",
+							pAC->I2c.SenTable[i].SenDesc,
+							pAC->I2c.SenTable[i].SenValue / 1000,
+							pAC->I2c.SenTable[i].SenValue % 1000);
+					}
+				}
+				
+				/*Receive statistics */
+				
+				len += sprintf(buffer + len, 
+				"\nReceive statistics\n\n");
+
+				len += sprintf(buffer + len,
+					"Received bytes            %s\n",
+					SkNumber(test_buf, pPnmiStat->StatRxOctetsOkCts,
+					10,0,-1,0));
+				len += sprintf(buffer + len,
+					"Received packets          %s\n",
+					SkNumber(test_buf, pPnmiStat->StatRxOkCts,
+					10,0,-1,0));
+				len += sprintf(buffer + len,
+					"Received errors           %s\n",
+					SkNumber(test_buf, pPnmiStat->StatRxFcsCts,
+					10,0,-1,0));
+				len += sprintf(buffer + len,
+					"Received dropped          %s\n",
+					SkNumber(test_buf, pPnmiStruct->RxNoBufCts,
+					10,0,-1,0));
+				len += sprintf(buffer + len,
+					"Received multicast        %s\n",
+					SkNumber(test_buf, pPnmiStat->StatRxMulticastOkCts,
+					10,0,-1,0));
+				len += sprintf(buffer + len,
+					"Received errors types\n");
+				len += sprintf(buffer + len,
+					"   length errors          %s\n",
+					SkNumber(test_buf, pPnmiStat->StatRxRuntCts,
+					10, 0, -1, 0));
+				len += sprintf(buffer + len,
+					"   over errors            %s\n",
+					SkNumber(test_buf, pPnmiStat->StatRxFifoOverflowCts,
+					10, 0, -1, 0));
+				len += sprintf(buffer + len,
+					"   crc errors             %s\n",
+					SkNumber(test_buf, pPnmiStat->StatRxFcsCts,
+					10, 0, -1, 0));
+				len += sprintf(buffer + len,
+					"   frame errors           %s\n",
+					SkNumber(test_buf, pPnmiStat->StatRxFramingCts,
+					10, 0, -1, 0));
+				len += sprintf(buffer + len,
+					"   fifo errors            %s\n",
+					SkNumber(test_buf, pPnmiStat->StatRxFifoOverflowCts,
+					10, 0, -1, 0));
+				len += sprintf(buffer + len,
+					"   missed errors          %s\n",
+					SkNumber(test_buf, pPnmiStat->StatRxMissedCts,
+					10, 0, -1, 0));
+				
+				/*Transmit statistics */
+				len += sprintf(buffer + len, 
+				"\nTransmit statistics\n\n");
+				
+				len += sprintf(buffer + len,
+					"Transmit bytes            %s\n",
+					SkNumber(test_buf, pPnmiStat->StatTxOctetsOkCts,
+					10,0,-1,0));
+				len += sprintf(buffer + len,
+					"Transmit packets          %s\n",
+					SkNumber(test_buf, pPnmiStat->StatTxOkCts,
+					10,0,-1,0));
+				len += sprintf(buffer + len,
+					"Transmit errors           %s\n",
+					SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts,
+					10,0,-1,0));
+				len += sprintf(buffer + len,
+					"Transmit dropped          %s\n",
+					SkNumber(test_buf, pPnmiStruct->TxNoBufCts,
+					10,0,-1,0));
+				len += sprintf(buffer + len,
+					"Transmit collisions       %s\n",
+					SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts,
+					10,0,-1,0));
+				len += sprintf(buffer + len,
+					"Transmited errors types\n");
+				len += sprintf(buffer + len,
+					"   aborted errors         %ld\n",
+					pAC->stats.tx_aborted_errors);
+				len += sprintf(buffer + len,
+					"   carrier errors         %s\n",
+					SkNumber(test_buf, pPnmiStat->StatTxCarrierCts,
+					10, 0, -1, 0));
+				len += sprintf(buffer + len,
+					"   fifo errors            %s\n",
+					SkNumber(test_buf, pPnmiStat->StatTxFifoUnderrunCts,
+					10, 0, -1, 0));
+				len += sprintf(buffer + len,
+					"   heartbeat errors       %s\n",
+					SkNumber(test_buf, pPnmiStat->StatTxCarrierCts,
+					10, 0, -1, 0));
+				len += sprintf(buffer + len,
+					"   window errors          %ld\n",
+					pAC->stats.tx_window_errors);
+			}
+		}
+		SkgeProcDev = next;
+	}
+	if (offset >= len) {
+		*eof = 1;
+		return 0;
+	}
+
+	*buffer_location = buffer + offset;
+	if (buffer_length >= len - offset) {
+		*eof = 1;
+	}
+	return (min(buffer_length, len - offset));
+}
+
+
+
+
+
+/*****************************************************************************
+ *
+ * SkDoDiv - convert 64bit number
+ *
+ * Description:
+ *	This function "converts" a long long number.
+ *
+ * Returns:
+ *	remainder of division
+ */
+static long SkDoDiv (long long Dividend, int Divisor, long long *pErg)
+{
+ long   	Rest;
+ long long 	Ergebnis;
+ long   	Akku;
+
+
+ Akku  = Dividend >> 32;
+
+ Ergebnis = ((long long) (Akku / Divisor)) << 32;
+ Rest = Akku % Divisor ;
+
+ Akku = Rest << 16;
+ Akku |= ((Dividend & 0xFFFF0000) >> 16);
+
+
+ Ergebnis += ((long long) (Akku / Divisor)) << 16;
+ Rest = Akku % Divisor ;
+
+ Akku = Rest << 16;
+ Akku |= (Dividend & 0xFFFF);
+
+ Ergebnis += (Akku / Divisor);
+ Rest = Akku % Divisor ;
+
+ *pErg = Ergebnis;
+ return (Rest);
+}
+
+
+#if 0
+#define do_div(n,base) ({ \
+long long __res; \
+__res = ((unsigned long long) n) % (unsigned) base; \
+n = ((unsigned long long) n) / (unsigned) base; \
+__res; })
+
+#endif
+
+
+/*****************************************************************************
+ *
+ * SkNumber - Print results
+ *
+ * Description:
+ *	This function converts a long long number into a string.
+ *
+ * Returns:
+ *	number as string
+ */
+char * SkNumber(char * str, long long num, int base, int size, int precision
+	,int type)
+{
+	char c,sign,tmp[66], *strorg = str;
+	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
+	int i;
+
+	if (type & LARGE)
+		digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+	if (type & LEFT)
+		type &= ~ZEROPAD;
+	if (base < 2 || base > 36)
+		return 0;
+	c = (type & ZEROPAD) ? '0' : ' ';
+	sign = 0;
+	if (type & SIGN) {
+		if (num < 0) {
+			sign = '-';
+			num = -num;
+			size--;
+		} else if (type & PLUS) {
+			sign = '+';
+			size--;
+		} else if (type & SPACE) {
+			sign = ' ';
+			size--;
+		}
+	}
+	if (type & SPECIAL) {
+		if (base == 16)
+			size -= 2;
+		else if (base == 8)
+			size--;
+	}
+	i = 0;
+	if (num == 0)
+		tmp[i++]='0';
+	else while (num != 0)
+		tmp[i++] = digits[SkDoDiv(num,base, &num)];
+
+	if (i > precision)
+		precision = i;
+	size -= precision;
+	if (!(type&(ZEROPAD+LEFT)))
+		while(size-->0)
+			*str++ = ' ';
+	if (sign)
+		*str++ = sign;
+	if (type & SPECIAL) {
+		if (base==8)
+			*str++ = '0';
+		else if (base==16) {
+			*str++ = '0';
+			*str++ = digits[33];
+		}
+	}
+	if (!(type & LEFT))
+		while (size-- > 0)
+			*str++ = c;
+	while (i < precision--)
+		*str++ = '0';
+	while (i-- > 0)
+		*str++ = tmp[i];
+	while (size-- > 0)
+		*str++ = ' ';
+	
+	str[0] = '\0';
+	
+	return strorg;
+}
+
+
+
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/skqueue.c linux/drivers/net/sk98lin/skqueue.c
--- v2.4.6/linux/drivers/net/sk98lin/skqueue.c	Tue Mar 20 12:04:59 2001
+++ linux/drivers/net/sk98lin/skqueue.c	Wed Jul  4 11:50:39 2001
@@ -1,23 +1,32 @@
 /******************************************************************************
  *
  * Name:	skqueue.c
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.15 $
- * Date:	$Date: 1999/11/22 13:36:29 $
+ * Project:	PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 1.14 $
+ * Date:	$Date: 1998/10/15 15:11:35 $
  * Purpose:	Management of an event queue.
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
+ *	(C)Copyright 1989-1998 SysKonnect,
  *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	All Rights Reserved
  *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
+ *	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT
+ *	The copyright notice above does not evidence any
+ *	actual or intended publication of such source code.
+ *
+ *	This Module contains Proprietary Information of SysKonnect
+ *	and should be treated as Confidential.
+ *
+ *	The information in this file is provided for the exclusive use of
+ *	the licensees of SysKonnect.
+ *	Such users have the right to use, modify, and incorporate this code
+ *	into products for purposes authorized by the license agreement
+ *	provided they include this notice and the associated copyright notice
+ *	with any such product.
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -27,9 +36,6 @@
  * History:
  *
  *	$Log: skqueue.c,v $
- *	Revision 1.15  1999/11/22 13:36:29  cgoos
- *	Changed license header to GPL.
- *	
  *	Revision 1.14  1998/10/15 15:11:35  gklug
  *	fix: ID_sccs to SysKonnectFileId
  *	
@@ -82,7 +88,7 @@
 	Event queue and dispatcher
 */
 static const char SysKonnectFileId[] =
-	"$Header: /usr56/projects/ge/schedule/skqueue.c,v 1.15 1999/11/22 13:36:29 cgoos Exp $" ;
+	"$Header: /usr56/projects/ge/schedule/skqueue.c,v 1.14 1998/10/15 15:11:35 gklug Exp $" ;
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
 #include "h/skqueue.h"		/* Queue Definitions */
@@ -147,7 +153,7 @@
  *		send command to state machine
  *	end
  *	return error reported by individual Event function
- *		0 if no error occurred.
+ *		0 if no error occured.
  */
 int	SkEventDispatcher(
 SK_AC	*pAC,	/* Adapters Context */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/skrlmt.c linux/drivers/net/sk98lin/skrlmt.c
--- v2.4.6/linux/drivers/net/sk98lin/skrlmt.c	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/skrlmt.c	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	skrlmt.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.49 $
- * Date:	$Date: 1999/11/22 13:38:02 $
+ * Version:	$Revision: 1.61 $
+ * Date:	$Date: 2001/03/14 12:52:08 $
  * Purpose:	Manage links on SK-NET Adapters, esp. redundant ones.
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,15 +26,53 @@
  * History:
  *
  *	$Log: skrlmt.c,v $
+ *	Revision 1.61  2001/03/14 12:52:08  rassmann
+ *	Fixed reporting of active port up/down to PNMI.
+ *	
+ *	Revision 1.60  2001/02/21 16:02:25  gklug
+ *	fix: when RLMT starts set Active Port for PNMI
+ *	
+ *	Revision 1.59  2001/02/16 14:38:19  rassmann
+ *	Initializing some pointers earlier in the init phase.
+ *	Rx Mbufs are freed if the net which they belong to is stopped.
+ *	
+ *	Revision 1.58  2001/02/14 14:06:31  rassmann
+ *	Editorial changes.
+ *	
+ *	Revision 1.57  2001/02/05 14:25:26  rassmann
+ *	Prepared RLMT for transparent operation.
+ *	
+ *	Revision 1.56  2001/01/30 10:29:09  rassmann
+ *	Not checking switching befor RlmtStart.
+ *	Editorial changes.
+ *	
+ *	Revision 1.55  2001/01/22 13:41:38  rassmann
+ *	Supporting two nets on dual-port adapters.
+ *	
+ *	Revision 1.54  2000/11/30 13:25:07  rassmann
+ *	Setting SK_TICK_INCR to 1 by default.
+ *	
+ *	Revision 1.53  2000/11/30 10:48:07  cgoos
+ *	Changed definition of SK_RLMT_BC_DELTA.
+ *	
+ *	Revision 1.52  2000/11/27 12:50:03  rassmann
+ *	Checking ports after receiving broadcasts.
+ *	
+ *	Revision 1.51  2000/11/17 08:58:00  rassmann
+ *	Moved CheckSwitch from SK_RLMT_PACKET_RECEIVED to SK_RLMT_TIM event.
+ *	
+ *	Revision 1.50  2000/11/09 12:24:34  rassmann
+ *	Indicating that segmentation check is not running anymore after
+ *	  SkRlmtCheckSeg().
+ *	Restarting segmentation timer after segmentation log.
+ *	Editorial changes.
+ *	
  *	Revision 1.49  1999/11/22 13:38:02  cgoos
  *	Changed license header to GPL.
  *	Added initialization to some variables to avoid compiler warnings.
  *	
  *	Revision 1.48  1999/10/04 14:01:17  rassmann
- *	Corrected reaction to reception of BPDU frames.
- *	Added parameter descriptions to "For Readme" section skrlmt.txt.
- *	Clarified usage of lookahead result *pForRlmt.
- *	Requested driver to present RLMT packets as soon as poosible.
+ *	Corrected reaction to reception of BPDU frames (#10441).
  *	
  *	Revision 1.47  1999/07/20 12:53:36  rassmann
  *	Fixed documentation errors for lookahead macros.
@@ -66,7 +103,7 @@
  *	
  *	Revision 1.40  1999/01/22 13:17:30  rassmann
  *	Informing PNMI of NET_UP.
- *	Clearing RLMT multicast addresses before first setting them.
+ *	Clearing RLMT multicast addresses before setting them for the first time.
  *	Reporting segmentation earlier, setting a "quiet time"
  *	 after a report.
  *	
@@ -218,13 +255,13 @@
 
 #ifndef	lint
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skrlmt.c,v 1.49 1999/11/22 13:38:02 cgoos Exp $ (C) SysKonnect.";
+	"@(#) $Id: skrlmt.c,v 1.61 2001/03/14 12:52:08 rassmann Exp $ (C) SysKonnect.";
 #endif	/* !defined(lint) */
 
 #define __SKRLMT_C
 
 #ifdef __cplusplus
-xxxx	/* not supported yet - force error */
+#error C++ is not yet supported.
 extern "C" {
 #endif	/* cplusplus */
 
@@ -245,11 +282,13 @@
 #ifndef SK_LITTLE_ENDIAN
 /* First 32 bits */
 #define OFFS_LO32	1
+
 /* Second 32 bits */
 #define OFFS_HI32	0
 #else	/* SK_LITTLE_ENDIAN */
 /* First 32 bits */
 #define OFFS_LO32	0
+
 /* Second 32 bits */
 #define OFFS_HI32	1
 #endif	/* SK_LITTLE_ENDIAN */
@@ -258,58 +297,60 @@
 
 /* ----- Private timeout values ----- */
 
-#define SK_RLMT_MIN_TO_VAL		   125000	/* 1/8 sec. */
-#define SK_RLMT_DEF_TO_VAL		  1000000	/* 1 sec. */
+#define SK_RLMT_MIN_TO_VAL			   125000	/* 1/8 sec. */
+#define SK_RLMT_DEF_TO_VAL			  1000000	/* 1 sec. */
 #define SK_RLMT_PORTDOWN_TIM_VAL	   900000	/* another 0.9 sec. */
 #define SK_RLMT_PORTSTART_TIM_VAL	   100000	/* 0.1 sec. */
 #define SK_RLMT_PORTUP_TIM_VAL		  2500000	/* 2.5 sec. */
-#define SK_RLMT_SEG_TO_VAL		900000000	/* 15 min. */
+#define SK_RLMT_SEG_TO_VAL			900000000	/* 15 min. */
+
+/* Assume tick counter increment is 1 - may be set OS-dependent. */
+#ifndef SK_TICK_INCR
+#define SK_TICK_INCR	SK_CONSTU64(1)
+#endif	/* !defined(SK_TICK_INCR) */
 
 /*
  * Amount that a time stamp must be later to be recognized as "substantially
- * later". This is about 1/128 sec.
+ * later". This is about 1/128 sec, but above 1 tick counter increment.
  */
-
-#define SK_RLMT_BC_DELTA	((SK_TICKS_PER_SEC >> 7) + 1)
+#define SK_RLMT_BC_DELTA		(1 + ((SK_TICKS_PER_SEC >> 7) > SK_TICK_INCR ? \
+									(SK_TICKS_PER_SEC >> 7) : SK_TICK_INCR))
 
 /* ----- Private RLMT defaults ----- */
 
-#define SK_RLMT_DEF_PREF_PORT	0			/* "Lower" port. */
-#define SK_RLMT_DEF_MODE 	SK_RLMT_CHECK_LINK	/* Default RLMT Mode. */
+#define SK_RLMT_DEF_PREF_PORT	0					/* "Lower" port. */
+#define SK_RLMT_DEF_MODE 		SK_RLMT_CHECK_LINK	/* Default RLMT Mode. */
 
 /* ----- Private RLMT checking states ----- */
 
-#define SK_RLMT_RCS_SEG		1	/* RLMT Check State: check seg. */
-#define SK_RLMT_RCS_START_SEG	2	/* RLMT Check State: start check seg. */
-#define SK_RLMT_RCS_SEND_SEG	4	/* RLMT Check State: send BPDU packet */
-#define SK_RLMT_RCS_REPORT_SEG	8	/* RLMT Check State: report seg. */
+#define SK_RLMT_RCS_SEG			1		/* RLMT Check State: check seg. */
+#define SK_RLMT_RCS_START_SEG	2		/* RLMT Check State: start check seg. */
+#define SK_RLMT_RCS_SEND_SEG	4		/* RLMT Check State: send BPDU packet */
+#define SK_RLMT_RCS_REPORT_SEG	8		/* RLMT Check State: report seg. */
 
 /* ----- Private PORT checking states ----- */
 
-#define SK_RLMT_PCS_TX		1	/* Port Check State: check tx. */
-#define SK_RLMT_PCS_RX		2	/* Port Check State: check rx. */
+#define SK_RLMT_PCS_TX			1		/* Port Check State: check tx. */
+#define SK_RLMT_PCS_RX			2		/* Port Check State: check rx. */
 
 /* ----- Private PORT events ----- */
 
 /* Note: Update simulation when changing these. */
-
 #define SK_RLMT_PORTSTART_TIM	1100	/* Port start timeout. */
-#define SK_RLMT_PORTUP_TIM	1101	/* Port can now go up. */
+#define SK_RLMT_PORTUP_TIM		1101	/* Port can now go up. */
 #define SK_RLMT_PORTDOWN_RX_TIM	1102	/* Port did not receive once ... */
-#define SK_RLMT_PORTDOWN	1103	/* Port went down. */
+#define SK_RLMT_PORTDOWN		1103	/* Port went down. */
 #define SK_RLMT_PORTDOWN_TX_TIM	1104	/* Partner did not receive ... */
 
 /* ----- Private RLMT events ----- */
 
 /* Note: Update simulation when changing these. */
-
-#define SK_RLMT_TIM		2100	/* RLMT timeout. */
-#define SK_RLMT_SEG_TIM		2101	/* RLMT segmentation check timeout. */
+#define SK_RLMT_TIM				2100	/* RLMT timeout. */
+#define SK_RLMT_SEG_TIM			2101	/* RLMT segmentation check timeout. */
 
 #define TO_SHORTEN(tim)	((tim) / 2)
 
 /* Error numbers and messages. */
-
 #define SKERR_RLMT_E001		(SK_ERRBASE_RLMT + 0)
 #define SKERR_RLMT_E001_MSG	"No Packet."
 #define SKERR_RLMT_E002		(SKERR_RLMT_E001 + 1)
@@ -333,78 +374,70 @@
 #define SKERR_RLMT_E010_MSG	"Ignored illegal Preferred Port."
 
 /* LLC field values. */
-
-#define LLC_COMMAND_RESPONSE_BIT	1
-#define LLC_TEST_COMMAND		0xE3
-#define LLC_UI				0x03
+#define LLC_COMMAND_RESPONSE_BIT		1
+#define LLC_TEST_COMMAND				0xE3
+#define LLC_UI							0x03
 
 /* RLMT Packet fields. */
-
-#define	SK_RLMT_DSAP			0
-#define	SK_RLMT_SSAP			0
-#define SK_RLMT_CTRL			(LLC_TEST_COMMAND)
-#define SK_RLMT_INDICATOR0		0x53	/* S */
-#define SK_RLMT_INDICATOR1		0x4B	/* K */
-#define SK_RLMT_INDICATOR2		0x2D	/* - */
-#define SK_RLMT_INDICATOR3		0x52	/* R */
-#define SK_RLMT_INDICATOR4		0x4C	/* L */
-#define SK_RLMT_INDICATOR5		0x4D	/* M */
-#define SK_RLMT_INDICATOR6		0x54	/* T */
-#define SK_RLMT_PACKET_VERSION	0
+#define	SK_RLMT_DSAP					0
+#define	SK_RLMT_SSAP					0
+#define SK_RLMT_CTRL					(LLC_TEST_COMMAND)
+#define SK_RLMT_INDICATOR0				0x53	/* S */
+#define SK_RLMT_INDICATOR1				0x4B	/* K */
+#define SK_RLMT_INDICATOR2				0x2D	/* - */
+#define SK_RLMT_INDICATOR3				0x52	/* R */
+#define SK_RLMT_INDICATOR4				0x4C	/* L */
+#define SK_RLMT_INDICATOR5				0x4D	/* M */
+#define SK_RLMT_INDICATOR6				0x54	/* T */
+#define SK_RLMT_PACKET_VERSION			0
 
 /* RLMT SPT Flag values. */
-
-#define	SK_RLMT_SPT_FLAG_CHANGE		0x01
-#define	SK_RLMT_SPT_FLAG_CHANGE_ACK	0x80
+#define	SK_RLMT_SPT_FLAG_CHANGE			0x01
+#define	SK_RLMT_SPT_FLAG_CHANGE_ACK		0x80
 
 /* RLMT SPT Packet fields. */
-
-#define	SK_RLMT_SPT_DSAP		0x42
-#define	SK_RLMT_SPT_SSAP		0x42
-#define SK_RLMT_SPT_CTRL		(LLC_UI)
-#define	SK_RLMT_SPT_PROTOCOL_ID0	0x00
-#define	SK_RLMT_SPT_PROTOCOL_ID1	0x00
+#define	SK_RLMT_SPT_DSAP				0x42
+#define	SK_RLMT_SPT_SSAP				0x42
+#define SK_RLMT_SPT_CTRL				(LLC_UI)
+#define	SK_RLMT_SPT_PROTOCOL_ID0		0x00
+#define	SK_RLMT_SPT_PROTOCOL_ID1		0x00
 #define	SK_RLMT_SPT_PROTOCOL_VERSION_ID	0x00
-#define	SK_RLMT_SPT_BPDU_TYPE		0x00
-#define	SK_RLMT_SPT_FLAGS		0x00	/* ?? */
-#define	SK_RLMT_SPT_ROOT_ID0		0xFF	/* Lowest possible priority. */
-#define	SK_RLMT_SPT_ROOT_ID1		0xFF	/* Lowest possible priority. */
+#define	SK_RLMT_SPT_BPDU_TYPE			0x00
+#define	SK_RLMT_SPT_FLAGS				0x00	/* ?? */
+#define	SK_RLMT_SPT_ROOT_ID0			0xFF	/* Lowest possible priority. */
+#define	SK_RLMT_SPT_ROOT_ID1			0xFF	/* Lowest possible priority. */
 
 /* Remaining 6 bytes will be the current port address. */
-
-#define	SK_RLMT_SPT_ROOT_PATH_COST0	0x00
-#define	SK_RLMT_SPT_ROOT_PATH_COST1	0x00
-#define	SK_RLMT_SPT_ROOT_PATH_COST2	0x00
-#define	SK_RLMT_SPT_ROOT_PATH_COST3	0x00
-#define	SK_RLMT_SPT_BRIDGE_ID0		0xFF	/* Lowest possible priority. */
-#define	SK_RLMT_SPT_BRIDGE_ID1		0xFF	/* Lowest possible priority. */
+#define	SK_RLMT_SPT_ROOT_PATH_COST0		0x00
+#define	SK_RLMT_SPT_ROOT_PATH_COST1		0x00
+#define	SK_RLMT_SPT_ROOT_PATH_COST2		0x00
+#define	SK_RLMT_SPT_ROOT_PATH_COST3		0x00
+#define	SK_RLMT_SPT_BRIDGE_ID0			0xFF	/* Lowest possible priority. */
+#define	SK_RLMT_SPT_BRIDGE_ID1			0xFF	/* Lowest possible priority. */
 
 /* Remaining 6 bytes will be the current port address. */
-
-#define	SK_RLMT_SPT_PORT_ID0		0xFF	/* Lowest possible priority. */
-#define	SK_RLMT_SPT_PORT_ID1		0xFF	/* Lowest possible priority. */
-#define	SK_RLMT_SPT_MSG_AGE0		0x00
-#define	SK_RLMT_SPT_MSG_AGE1		0x00
-#define	SK_RLMT_SPT_MAX_AGE0		0x00
-#define	SK_RLMT_SPT_MAX_AGE1		0xFF
-#define	SK_RLMT_SPT_HELLO_TIME0		0x00
-#define	SK_RLMT_SPT_HELLO_TIME1		0xFF
-#define	SK_RLMT_SPT_FWD_DELAY0		0x00
-#define	SK_RLMT_SPT_FWD_DELAY1		0x40
+#define	SK_RLMT_SPT_PORT_ID0			0xFF	/* Lowest possible priority. */
+#define	SK_RLMT_SPT_PORT_ID1			0xFF	/* Lowest possible priority. */
+#define	SK_RLMT_SPT_MSG_AGE0			0x00
+#define	SK_RLMT_SPT_MSG_AGE1			0x00
+#define	SK_RLMT_SPT_MAX_AGE0			0x00
+#define	SK_RLMT_SPT_MAX_AGE1			0xFF
+#define	SK_RLMT_SPT_HELLO_TIME0			0x00
+#define	SK_RLMT_SPT_HELLO_TIME1			0xFF
+#define	SK_RLMT_SPT_FWD_DELAY0			0x00
+#define	SK_RLMT_SPT_FWD_DELAY1			0x40
 
 /* Size defines. */
-
-#define SK_RLMT_MIN_PACKET_SIZE	34
-#define SK_RLMT_MAX_PACKET_SIZE	(SK_RLMT_MAX_TX_BUF_SIZE)
-#define SK_PACKET_DATA_LEN	(SK_RLMT_MAX_PACKET_SIZE - \
-				 SK_RLMT_MIN_PACKET_SIZE)
+#define SK_RLMT_MIN_PACKET_SIZE			34
+#define SK_RLMT_MAX_PACKET_SIZE			(SK_RLMT_MAX_TX_BUF_SIZE)
+#define SK_PACKET_DATA_LEN				(SK_RLMT_MAX_PACKET_SIZE - \
+										SK_RLMT_MIN_PACKET_SIZE)
 
 /* ----- RLMT packet types ----- */
-
-#define SK_PACKET_ANNOUNCE	1	/* Port announcement. */
-#define SK_PACKET_ALIVE		2	/* Alive packet to port. */
-#define SK_PACKET_ADDR_CHANGED	3	/* Port address changed. */
-#define SK_PACKET_CHECK_TX	4	/* Check your tx line. */
+#define SK_PACKET_ANNOUNCE				1	/* Port announcement. */
+#define SK_PACKET_ALIVE					2	/* Alive packet to port. */
+#define SK_PACKET_ADDR_CHANGED			3	/* Port address changed. */
+#define SK_PACKET_CHECK_TX				4	/* Check your tx line. */
 
 #ifdef SK_LITTLE_ENDIAN
 #define SK_U16_TO_NETWORK_ORDER(Val,Addr) { \
@@ -426,7 +459,6 @@
 /* typedefs *******************************************************************/
 
 /* RLMT packet.  Length: SK_RLMT_MAX_PACKET_SIZE (60) bytes. */
-
 typedef struct s_RlmtPacket {
 	SK_U8	DstAddr[SK_MAC_ADDR_LEN];
 	SK_U8	SrcAddr[SK_MAC_ADDR_LEN];
@@ -437,8 +469,8 @@
 	SK_U8	Indicator[7];
 	SK_U8	RlmtPacketType[2];
 	SK_U8	Align1[2];
-	SK_U8	Random[4];	/* Random value of requesting(!) station. */
-	SK_U8	RlmtPacketVersion[2];	/* RLMT Packet version */
+	SK_U8	Random[4];				/* Random value of requesting(!) station. */
+	SK_U8	RlmtPacketVersion[2];	/* RLMT Packet version. */
 	SK_U8	Data[SK_PACKET_DATA_LEN];
 } SK_RLMT_PACKET;
 
@@ -465,9 +497,9 @@
 
 /* global variables ***********************************************************/
 
-SK_MAC_ADDR	SkRlmtMcAddr = {{0x01,  0x00,  0x5A,  0x52,  0x4C,  0x4D}};
-SK_MAC_ADDR	BridgeMcAddr = {{0x01,  0x80,  0xC2,  0x00,  0x00,  0x00}};
-SK_MAC_ADDR	BcAddr = {{0xFF,  0xFF,  0xFF,  0xFF,  0xFF,  0xFF}};
+SK_MAC_ADDR	SkRlmtMcAddr =	{{0x01,  0x00,  0x5A,  0x52,  0x4C,  0x4D}};
+SK_MAC_ADDR	BridgeMcAddr =	{{0x01,  0x80,  0xC2,  0x00,  0x00,  0x00}};
+SK_MAC_ADDR	BcAddr = 		{{0xFF,  0xFF,  0xFF,  0xFF,  0xFF,  0xFF}};
 
 /* local variables ************************************************************/
 
@@ -477,10 +509,16 @@
 
 RLMT_STATIC void	SkRlmtCheckSwitch(
 	SK_AC	*pAC,
-	SK_IOC	IoC);
+	SK_IOC	IoC,
+	SK_U32	NetIdx);
 RLMT_STATIC void	SkRlmtCheckSeg(
 	SK_AC	*pAC,
-	SK_IOC	IoC);
+	SK_IOC	IoC,
+	SK_U32	NetIdx);
+RLMT_STATIC void	SkRlmtEvtSetNets(
+	SK_AC		*pAC,
+	SK_IOC		IoC,
+	SK_EVPARA	Para);
 
 /******************************************************************************
  *
@@ -506,7 +544,7 @@
  *	===========
  *
  *	Determine the adapter's random value.
- *	Set the hw registers, the "logical adapter address", the
+ *	Set the hw registers, the "logical MAC address", the
  *	RLMT multicast address, and eventually the BPDU multicast address.
  *
  * Context:
@@ -516,18 +554,15 @@
  *	Nothing.
  */
 void	SkRlmtInit(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* I/O context */
-int	Level)	/* initialization level */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
+int		Level)	/* Initialization Level */
 {
 	SK_U32		i, j;
 	SK_U64		Random;
 	SK_EVPARA	Para;
 
-	SK_DBG_MSG(
-		pAC,
-		SK_DBGMOD_RLMT,
-		SK_DBGCAT_INIT,
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
 		("RLMT Init level %d.\n", Level))
 
 	switch (Level) {
@@ -541,68 +576,70 @@
 			pAC->Rlmt.Port[i].PortStarted = SK_FALSE;
 			pAC->Rlmt.Port[i].PortNoRx = SK_FALSE;
 			pAC->Rlmt.Port[i].RootIdSet = SK_FALSE;
-		}
-
-		pAC->Rlmt.RlmtState = SK_RLMT_RS_INIT;
-		pAC->Rlmt.RootIdSet = SK_FALSE;
-		pAC->Rlmt.MacPreferred = 0xFFFFFFFF;	  /* Automatic. */
-		pAC->Rlmt.PrefPort = SK_RLMT_DEF_PREF_PORT;
-		pAC->Rlmt.MacActive = pAC->Rlmt.PrefPort; /* Just assuming. */
-		pAC->Rlmt.RlmtMode = SK_RLMT_DEF_MODE;
-		pAC->Rlmt.TimeoutValue = SK_RLMT_DEF_TO_VAL;
+			pAC->Rlmt.Port[i].PortNumber = i;
+			pAC->Rlmt.Port[i].Net = &pAC->Rlmt.Net[0];
+			pAC->Rlmt.Port[i].AddrPort = &pAC->Addr.Port[i];
+		}
+
+		pAC->Rlmt.NumNets = 1;
+		for (i = 0; i < SK_MAX_NETS; i++) {
+			pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
+			pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
+			pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;	  /* Automatic. */
+			pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
+			/* Just assuming. */
+			pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
+			pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
+			pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
+			pAC->Rlmt.Net[i].NetNumber = i;
+		}
+
+		pAC->Rlmt.Net[0].Port[0] = &pAC->Rlmt.Port[0];
+		pAC->Rlmt.Net[0].Port[1] = &pAC->Rlmt.Port[1];
+#if SK_MAX_NETS > 1
+		pAC->Rlmt.Net[1].Port[0] = &pAC->Rlmt.Port[1];
+#endif	/* SK_MAX_NETS > 1 */
 		break;
 
 	case SK_INIT_IO:	/* GIMacsFound first available here. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_INIT,
-			("RLMT: %d MACs were detected.\n",
-				pAC->GIni.GIMacsFound))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
+			("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound))
 
-		/* Initialize HW registers? */
+		pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
 
+		/* Initialize HW registers? */
 		if (pAC->GIni.GIMacsFound < 2) {
-			Para.Para32[0] = SK_RLMT_CHECK_LINK;
+			Para.Para32[0] = SK_RLMT_MODE_CLS;
+			Para.Para32[1] = 0;
 			(void)SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, Para);
 		}
 		break;
 
 	case SK_INIT_RUN:
+		/* Ensure RLMT is set to one net. */
+		if (pAC->Rlmt.NumNets > 1) {
+			Para.Para32[0] = 1;
+			Para.Para32[1] = -1;
+			SkRlmtEvtSetNets(pAC, IoC, Para);
+		}
+
 		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
 			Random = SkOsGetTime(pAC);
 			*(SK_U32*)&pAC->Rlmt.Port[i].Random = *(SK_U32*)&Random;
 
 			for (j = 0; j < 4; j++) {
-				pAC->Rlmt.Port[i].Random[j] ^= pAC->Addr.Port[i
-					].CurrentMacAddress.a[SK_MAC_ADDR_LEN -
-					1 - j];
+				pAC->Rlmt.Port[i].Random[j] ^= pAC->Rlmt.Port[i].AddrPort->
+					CurrentMacAddress.a[SK_MAC_ADDR_LEN - 1 - j];
 			}
 
-			(void)SkAddrMcClear(
-				pAC,
-				IoC,
-				i,
-				SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
+			(void)SkAddrMcClear(pAC, IoC, i, SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
 			
 			/* Add RLMT MC address. */
+			(void)SkAddrMcAdd(pAC, IoC, i, &SkRlmtMcAddr, SK_ADDR_PERMANENT);
 
-			(void)SkAddrMcAdd(
-				pAC,
-				IoC,
-				i,
-				&SkRlmtMcAddr,
-				SK_ADDR_PERMANENT);
-
-			if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_SEG) {
+			if (pAC->Rlmt.Net[0].RlmtMode & SK_RLMT_CHECK_SEG) {
 				/* Add BPDU MC address. */
-
-				(void)SkAddrMcAdd(
-					pAC,
-					IoC,
-					i,
-					&BridgeMcAddr,
-					SK_ADDR_PERMANENT);
+				(void)SkAddrMcAdd(pAC, IoC, i, &BridgeMcAddr, SK_ADDR_PERMANENT);
 			}
 
 			(void)SkAddrMcUpdate(pAC, IoC, i);
@@ -612,9 +649,7 @@
 	default:	/* error */
 		break;
 	}
-
 	return;
-
 }	/* SkRlmtInit */
 
 
@@ -639,32 +674,33 @@
  *	Nothing
  */
 RLMT_STATIC void	SkRlmtBuildCheckChain(
-SK_AC	*pAC)	/* adapter context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_U32	NetIdx)	/* Net Number */
 {
-	SK_U32	i;
-	SK_U32	NumMacsUp;
-	SK_U32	FirstMacUp=0;
-	SK_U32	PrevMacUp=0;
+	SK_U32			i;
+	SK_U32			NumMacsUp;
+	SK_RLMT_PORT *	FirstMacUp;
+	SK_RLMT_PORT *	PrevMacUp;
 
-	if (!(pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
-		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-			pAC->Rlmt.Port[i].PortsChecked = 0;
+	FirstMacUp	= NULL;
+	PrevMacUp	= NULL;
+	
+	if (!(pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
+		for (i = 0; i < pAC->Rlmt.Net[i].NumPorts; i++) {
+			pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
 		}
-		return;	/* Nothing to build. */
+		return;	/* Done. */
 	}
-
-	SK_DBG_MSG(
-		pAC,
-		SK_DBGMOD_RLMT,
-		SK_DBGCAT_CTRL,
+			
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
 		("SkRlmtBuildCheckChain.\n"))
 
 	NumMacsUp = 0;
 
-	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-		pAC->Rlmt.Port[i].PortsChecked = 0;
-		pAC->Rlmt.Port[i].PortsSuspect = 0;
-		pAC->Rlmt.Port[i].CheckingState &=
+	for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
+		pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
+		pAC->Rlmt.Net[NetIdx].Port[i]->PortsSuspect = 0;
+		pAC->Rlmt.Net[NetIdx].Port[i]->CheckingState &=
 			~(SK_RLMT_PCS_RX | SK_RLMT_PCS_TX);
 
 		/*
@@ -673,156 +709,43 @@
 		 * 1. the next port that is not LinkDown and
 		 * 2. the next port that is not PortDown.
 		 */
-
-		if (!pAC->Rlmt.Port[i].LinkDown) {
+		if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
 			if (NumMacsUp == 0) {
-				FirstMacUp = i;
+				FirstMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
 			}
 			else {
-				pAC->Rlmt.Port[PrevMacUp].PortCheck[
-					pAC->Rlmt.Port[
-					PrevMacUp].PortsChecked].CheckAddr =
-					pAC->Addr.Port[i].CurrentMacAddress;
-				pAC->Rlmt.Port[PrevMacUp].PortCheck[
-					pAC->Rlmt.Port[
-					PrevMacUp].PortsChecked].SuspectTx =
-					SK_FALSE;
-				pAC->Rlmt.Port[PrevMacUp].PortsChecked++;
+				pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[
+					pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked].CheckAddr =
+					pAC->Rlmt.Net[NetIdx].Port[i]->AddrPort->CurrentMacAddress;
+				PrevMacUp->PortCheck[
+					PrevMacUp->PortsChecked].SuspectTx = SK_FALSE;
+				PrevMacUp->PortsChecked++;
 			}
-			PrevMacUp = i;
+			PrevMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
 			NumMacsUp++;
 		}
 	}
 
 	if (NumMacsUp > 1) {
-		pAC->Rlmt.Port[PrevMacUp].PortCheck[pAC->Rlmt.Port[
-			PrevMacUp].PortsChecked].CheckAddr =
-			pAC->Addr.Port[FirstMacUp].CurrentMacAddress;
-		pAC->Rlmt.Port[PrevMacUp].PortCheck[pAC->Rlmt.Port[
-			PrevMacUp].PortsChecked].SuspectTx = SK_FALSE;
-		pAC->Rlmt.Port[PrevMacUp].PortsChecked++;
+		PrevMacUp->PortCheck[PrevMacUp->PortsChecked].CheckAddr =
+			FirstMacUp->AddrPort->CurrentMacAddress;
+		PrevMacUp->PortCheck[PrevMacUp->PortsChecked].SuspectTx =
+			SK_FALSE;
+		PrevMacUp->PortsChecked++;
 	}
 
 #ifdef DEBUG
-	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-                SK_DBG_MSG(
-                        pAC,
-                        SK_DBGMOD_RLMT,
-                        SK_DBGCAT_CTRL,
-                        ("Port %d checks %d other ports: %2X.\n",
-				i,
-				pAC->Rlmt.Port[i].PortsChecked,
-				pAC->Rlmt.Port[i].PortCheck[0].CheckAddr.a[5]))
+	for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Port %d checks %d other ports: %2X.\n", NetIdx,
+				pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked,
+				pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5]))
 	}
 #endif	/* DEBUG */
 
 	return;       
 }	/* SkRlmtBuildCheckChain */
 
-#ifdef SK_RLMT_SLOW_LOOKAHEAD
-
-/******************************************************************************
- *
- *	SkRlmtLookaheadPacket - examine received packet shortly, count s-th
- *
- * Description:
- *	This routine examines each received packet fast and short and
- *	increments some counters.
- *	The received packet has to be stored virtually contiguous.
- *	This function does the following:
- *	- Increment some counters.
- *	- Ensure length is sufficient.
- *	- Ensure that destination address is physical port address,
- *	  RLMT multicast, or BPDU multicast address.
- *
- * Notes:
- *	This function is fully reentrant while the fast path is not blocked.
- *
- * Context:
- *	isr/dpr, not pageable
- *
- * Returns:
- *	SK_FALSE packet for upper layers
- *	SK_TRUE  packet for RLMT
- */
-SK_BOOL	SkRlmtLookaheadPacket(
-SK_AC		*pAC,		/* adapter context */
-SK_U32		PortIdx,	/* receiving port */
-SK_U8		*pLaPacket,	/* received packet's data */
-unsigned	PacketLength,	/* received packet's length */ /* Necessary? */
-unsigned	LaLength)	/* lookahead length */
-{
-	int	i;
-	SK_BOOL	IsBc;		/* Broadcast address? */
-	int	RxDest;		/* Receive destination? */
-	int	Offset;		/* Offset of data to present to LOOKAHEAD. */
-	int	NumBytes;	/* #Bytes to present to LOOKAHEAD. */
-	SK_RLMT_PACKET	*pRPacket;
-	SK_ADDR_PORT	*pAPort;
-
-#ifdef DEBUG
-	PacketLength = PacketLength;
-#endif	/* DEBUG */
-
-	pRPacket = (SK_RLMT_PACKET*)pLaPacket;
-	pAPort = &pAC->Addr.Port[PortIdx];
-
-#ifdef DEBUG
-	if (pLaPacket == NULL) {
-
-		/* Create error log entry. */
-
-		SK_ERR_LOG(
-			pAC,
-			SK_ERRCL_SW,
-			SKERR_RLMT_E001,
-			SKERR_RLMT_E001_MSG);
-
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_RX,
-			("SkRlmtLookaheadPacket: NULL pointer.\n"))
-
-		return (SK_FALSE);
-	}
-#endif	/* DEBUG */
-
-	/* Drivers should get IsBc from the descriptor. */
-
-	IsBc = SK_TRUE;
-	for (i = 0; IsBc && i < SK_MAC_ADDR_LEN; i++) {
-		IsBc = IsBc && (pLaPacket[i] == 0xFF);
-	}
-
-	SK_RLMT_PRE_LOOKAHEAD(
-		pAC,
-		PortIdx,
-		PacketLength,
-		IsBc,
-		&Offset,
-		&NumBytes)
-
-	if (NumBytes == 0) {
-		return (SK_FALSE);
-	}
-
-	SK_RLMT_LOOKAHEAD(
-		pAC,
-		PortIdx,
-		&pLaPacket[Offset],
-		IsBc,
-		pLaPacket[0] & 1,	/* Drivers: Get info from descriptor. */
-		&RxDest)
-
-	if (RxDest & SK_RLMT_RX_RLMT) {
-		return (SK_TRUE);
-	}
-
-	return (SK_FALSE);
-}	/* SkRlmtLookaheadPacket */
-
-#endif	/* SK_RLMT_SLOW_LOOKAHEAD */
 
 /******************************************************************************
  *
@@ -838,20 +761,19 @@
  *	NULL or pointer to RLMT mbuf
  */
 RLMT_STATIC SK_MBUF	*SkRlmtBuildPacket(
-SK_AC		*pAC,		/* adapter context */
-SK_IOC		IoC,		/* I/O context */
-SK_U32		PortIdx,	/* sending port */
+SK_AC		*pAC,		/* Adapter Context */
+SK_IOC		IoC,		/* I/O Context */
+SK_U32		PortNumber,	/* Sending port */
 SK_U16		PacketType,	/* RLMT packet type */
-SK_MAC_ADDR	*SrcAddr,	/* source address */
-SK_MAC_ADDR	*DestAddr)	/* destination address */
+SK_MAC_ADDR	*SrcAddr,	/* Source address */
+SK_MAC_ADDR	*DestAddr)	/* Destination address */
 {
 	int		i;
 	SK_U16		Length;
 	SK_MBUF		*pMb;
 	SK_RLMT_PACKET	*pPacket;
 
-	if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) !=
-		NULL) {
+	if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) {
 		pPacket = (SK_RLMT_PACKET*)pMb->pData;
 		for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
 			pPacket->DstAddr[i] = DestAddr->a[i];
@@ -868,17 +790,14 @@
 		pPacket->Indicator[5] = SK_RLMT_INDICATOR5;
 		pPacket->Indicator[6] = SK_RLMT_INDICATOR6;
 
-		SK_U16_TO_NETWORK_ORDER(
-			PacketType,
-			&pPacket->RlmtPacketType[0]);
+		SK_U16_TO_NETWORK_ORDER(PacketType, &pPacket->RlmtPacketType[0]);
 
 		for (i = 0; i < 4; i++) {
-			pPacket->Random[i] = pAC->Rlmt.Port[PortIdx].Random[i];
+			pPacket->Random[i] = pAC->Rlmt.Port[PortNumber].Random[i];
 		}
 		
 		SK_U16_TO_NETWORK_ORDER(
-			SK_RLMT_PACKET_VERSION,
-			&pPacket->RlmtPacketVersion[0]);
+			SK_RLMT_PACKET_VERSION, &pPacket->RlmtPacketVersion[0]);
 
 		for (i = 0; i < SK_PACKET_DATA_LEN; i++) {
 			pPacket->Data[i] = 0x00;
@@ -886,12 +805,12 @@
 
 		Length = SK_RLMT_MAX_PACKET_SIZE;	/* Or smaller. */
 		pMb->Length = Length;
-		pMb->PortIdx = PortIdx;
+		pMb->PortIdx = PortNumber;
 		Length -= 14;
 		SK_U16_TO_NETWORK_ORDER(Length, &pPacket->TypeLen[0]);
 
 		if (PacketType == SK_PACKET_ALIVE) {
-			pAC->Rlmt.Port[PortIdx].TxHelloCts++;
+			pAC->Rlmt.Port[PortNumber].TxHelloCts++;
 		}
 	}
 
@@ -913,13 +832,13 @@
  *	NULL or pointer to RLMT mbuf
  */
 RLMT_STATIC SK_MBUF	*SkRlmtBuildSpanningTreePacket(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* I/O context */
-SK_U32	PortIdx)	/* sending port */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
+SK_U32	PortNumber)	/* Sending port */
 {
-	unsigned		i;
-	SK_U16			Length;
-	SK_MBUF			*pMb;
+	unsigned			i;
+	SK_U16				Length;
+	SK_MBUF				*pMb;
 	SK_SPTREE_PACKET	*pSPacket;
 
 	if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) !=
@@ -928,7 +847,7 @@
 		for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
 			pSPacket->DstAddr[i] = BridgeMcAddr.a[i];
 			pSPacket->SrcAddr[i] =
-				pAC->Addr.Port[PortIdx].CurrentMacAddress.a[i];
+				pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
 		}
 		pSPacket->DSap = SK_RLMT_SPT_DSAP;
 		pSPacket->SSap = SK_RLMT_SPT_SSAP;
@@ -949,13 +868,13 @@
 		pSPacket->BridgeId[1] = SK_RLMT_SPT_BRIDGE_ID1;
 
 		/*
-		 * Use virtual address as bridge ID and filter these packets
+		 * Use logical MAC address as bridge ID and filter these packets
 		 * on receive.
 		 */
-
 		for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
 			pSPacket->BridgeId[i + 2] = pSPacket->RootId[i + 2] =
-				pAC->Addr.CurrentMacAddress.a[i];
+				pAC->Addr.Net[pAC->Rlmt.Port[PortNumber].Net->NetNumber].
+					CurrentMacAddress.a[i];
 		}
 		pSPacket->PortId[0] = SK_RLMT_SPT_PORT_ID0;
 		pSPacket->PortId[1] = SK_RLMT_SPT_PORT_ID1;
@@ -970,11 +889,11 @@
 
 		Length = SK_RLMT_MAX_PACKET_SIZE;	/* Or smaller. */
 		pMb->Length = Length;
-		pMb->PortIdx = PortIdx;
+		pMb->PortIdx = PortNumber;
 		Length -= 14;
 		SK_U16_TO_NETWORK_ORDER(Length, &pSPacket->TypeLen[0]);
 
-		pAC->Rlmt.Port[PortIdx].TxSpHelloReqCts++;
+		pAC->Rlmt.Port[PortNumber].TxSpHelloReqCts++;
 	}
 
 	return (pMb);       
@@ -996,36 +915,22 @@
  *	Nothing.
  */
 RLMT_STATIC void	SkRlmtSend(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* I/O context */
-SK_U32	PortIdx)
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
+SK_U32	PortNumber)	/* Sending port */
 {
 	unsigned	j;
 	SK_EVPARA	Para;
 	SK_RLMT_PORT	*pRPort;
 
-	pRPort = &pAC->Rlmt.Port[PortIdx];
-	if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
-		if (pRPort->CheckingState &
-			(SK_RLMT_PCS_TX | SK_RLMT_PCS_RX)) {
-
-			/*
-			 * Port is suspicious. Send the RLMT packet to the
-			 * RLMT multicast address.
-			 */
-
-			if ((Para.pParaPtr = SkRlmtBuildPacket(
-				pAC,
-				IoC,
-				PortIdx,
-				SK_PACKET_ALIVE,
-				&pAC->Addr.Port[PortIdx].CurrentMacAddress,
+	pRPort = &pAC->Rlmt.Port[PortNumber];
+	if (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
+		if (pRPort->CheckingState & (SK_RLMT_PCS_TX | SK_RLMT_PCS_RX)) {
+			/* Port is suspicious. Send the RLMT packet to the RLMT mc addr. */
+			if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
+				SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
 				&SkRlmtMcAddr)) != NULL) {
-				SkEventQueue(
-					pAC,
-					SKGE_DRV,
-					SK_DRV_RLMT_SEND,
-					Para);
+				SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
 			}
 		}
 		else {
@@ -1033,61 +938,33 @@
 			 * Send a directed RLMT packet to all ports that are
 			 * checked by the indicated port.
 			 */
-
 			for (j = 0; j < pRPort->PortsChecked; j++) {
-				if ((Para.pParaPtr =
-					SkRlmtBuildPacket(
-						pAC,
-						IoC,
-						PortIdx,
-						SK_PACKET_ALIVE,
-						&pAC->Addr.Port[PortIdx].CurrentMacAddress,
-						&pRPort->PortCheck[j].CheckAddr)
-						) != NULL) {
-					SkEventQueue(
-						pAC,
-						SKGE_DRV,
-						SK_DRV_RLMT_SEND,
-						Para);
+				if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
+					SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
+					&pRPort->PortCheck[j].CheckAddr)) != NULL) {
+					SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
 				}
 			}
 		}
 	}
 
-	if ((pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_SEG) &&
-		(pAC->Rlmt.CheckingState & SK_RLMT_RCS_SEND_SEG)) {
-
+	if ((pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
+		(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEND_SEG)) {
 		/*
 		 * Send a BPDU packet to make a connected switch tell us
 		 * the correct root bridge.
 		 */
-
 		if ((Para.pParaPtr =
-			SkRlmtBuildSpanningTreePacket(
-				pAC,
-				IoC,
-				PortIdx)
-			) != NULL) {
-			
-			pAC->Rlmt.CheckingState &= ~SK_RLMT_RCS_SEND_SEG;
+			SkRlmtBuildSpanningTreePacket(pAC, IoC, PortNumber)) != NULL) {
+			pAC->Rlmt.Port[PortNumber].Net->CheckingState &= ~SK_RLMT_RCS_SEND_SEG;
 			pRPort->RootIdSet = SK_FALSE;
 
-			SkEventQueue(
-				pAC,
-				SKGE_DRV,
-				SK_DRV_RLMT_SEND,
-				Para);
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_TX,
-				("SkRlmtSend: BPDU Packet on Port %u.\n",
-					PortIdx))
+			SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
+			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX,
+				("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber))
 		}
-	}
-
-	return;
-
+	}   
+	return;   
 }	/* SkRlmtSend */
 
 
@@ -1099,61 +976,51 @@
  *	This routine checks if a port who received a non-BPDU packet
  *	needs to go up or needs to be stopped going down.
  *
-* Context:
+ * Context:
  *	runtime, pageable?
  *
  * Returns:
  *	Nothing.
  */
 RLMT_STATIC void	SkRlmtPortReceives(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* I/O context */
-SK_U32	PortIdx)	/* port to check */
+SK_AC	*pAC,			/* Adapter Context */
+SK_IOC	IoC,			/* I/O Context */
+SK_U32	PortNumber)		/* Port to check */
 {
 	SK_RLMT_PORT	*pRPort;
-	SK_EVPARA	Para;
+	SK_EVPARA		Para;
 
-	pRPort = &pAC->Rlmt.Port[PortIdx];
+	pRPort = &pAC->Rlmt.Port[PortNumber];
 	pRPort->PortNoRx = SK_FALSE;
 
 	if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
 		!(pRPort->CheckingState & SK_RLMT_PCS_TX)) {
-
 		/*
 		 * Port is marked down (rx), but received a non-BPDU packet.
 		 * Bring it up.
 		 */
-
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_RX,
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
 			("SkRlmtPacketReceive: Received on PortDown.\n"))
 
 		pRPort->PortState = SK_RLMT_PS_GOING_UP;
 		pRPort->GuTimeStamp = SkOsGetTime(pAC);
-		Para.Para32[0] = PortIdx;
-		SkTimerStart(
-			pAC,
-			IoC,
-			&pRPort->UpTimer,
-			SK_RLMT_PORTUP_TIM_VAL,
-			SKGE_RLMT,
-			SK_RLMT_PORTUP_TIM,
-			Para);
-		SkRlmtCheckSwitch(pAC, IoC);
-	}
+		Para.Para32[0] = PortNumber;
+		Para.Para32[1] = (SK_U32)-1;
+		SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
+			SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para);
+		pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
+		/* pAC->Rlmt.CheckSwitch = SK_TRUE; */
+		SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
+	}	/* PortDown && !SuspectTx */
 	else if (pRPort->CheckingState & SK_RLMT_PCS_RX) {
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_RX,
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
 			("SkRlmtPacketReceive: Stop bringing port down.\n"))
 		SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
-		SkRlmtCheckSwitch(pAC, IoC);
-	}
+		pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
+		/* pAC->Rlmt.CheckSwitch = SK_TRUE; */
+		SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
+	}	/* PortGoingDown */
 
-	pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
 	return;
 }	/* SkRlmtPortReceives */
 
@@ -1163,7 +1030,7 @@
  *	SkRlmtPacketReceive - receive a packet for closer examination
  *
  * Description:
- *	This routine examines a packet more closely than SkRlmtLookahead*().
+ *	This routine examines a packet more closely than SK_RLMT_LOOKAHEAD.
  *
  * Context:
  *	runtime, pageable?
@@ -1172,32 +1039,29 @@
  *	Nothing.
  */
 RLMT_STATIC void	SkRlmtPacketReceive(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* I/O context */
-SK_MBUF	*pMb)	/* received packet */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
+SK_MBUF	*pMb)	/* Received packet */
 {
 #ifdef xDEBUG
 	extern	void DumpData(char *p, int size);
 #endif	/* DEBUG */
-	int			i;
-	unsigned		j;
-	SK_U16			PacketType;
-	SK_U32			PortIdx;
+	int					i;
+	unsigned			j;
+	SK_U16				PacketType;
+	SK_U32				PortNumber;
 	SK_ADDR_PORT		*pAPort;
 	SK_RLMT_PORT		*pRPort;
 	SK_RLMT_PACKET		*pRPacket;
 	SK_SPTREE_PACKET	*pSPacket;
-	SK_EVPARA		Para;
+	SK_EVPARA			Para;
+
+	PortNumber	= pMb->PortIdx;
+	pAPort = &pAC->Addr.Port[PortNumber];
+	pRPort = &pAC->Rlmt.Port[PortNumber];
 
-	PortIdx	= pMb->PortIdx;
-	pAPort = &pAC->Addr.Port[PortIdx];
-	pRPort = &pAC->Rlmt.Port[PortIdx];
-
-	SK_DBG_MSG(
-		pAC,
-		SK_DBGMOD_RLMT,
-		SK_DBGCAT_RX,
-		("SkRlmtPacketReceive: PortIdx == %d.\n", PortIdx))
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+		("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber))
 
 	pRPacket = (SK_RLMT_PACKET*)pMb->pData;
 	pSPacket = (SK_SPTREE_PACKET*)pRPacket;
@@ -1207,7 +1071,7 @@
 #endif	/* DEBUG */
 
 	if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) != 0) {
-		SkRlmtPortReceives(pAC, IoC, PortIdx);
+		SkRlmtPortReceives(pAC, IoC, PortNumber);
 	}
 	
 	/* Check destination address. */
@@ -1216,15 +1080,8 @@
 		!SK_ADDR_EQUAL(SkRlmtMcAddr.a, pRPacket->DstAddr) &&
 		!SK_ADDR_EQUAL(BridgeMcAddr.a, pRPacket->DstAddr)) {
 
-		/*
-		 * Not sent to current MAC or registered MC address
-		 * => Trash it.
-		 */
-
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_RX,
+		/* Not sent to current MAC or registered MC address => Trash it. */
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
 			("SkRlmtPacketReceive: Not for me.\n"))
 
 		SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
@@ -1241,19 +1098,17 @@
 		 * Check for duplicate address here:
 		 * If Packet.Random != My.Random => DupAddr.
 		 */
-
 		for (i = 3; i >= 0; i--) {
-			if (pRPort->Random[i] !=
-				pRPacket->Random[i]) {
+			if (pRPort->Random[i] != pRPacket->Random[i]) {
 				break;
 			}
 		}
 
 		/*
-		 * CAUTION: Do not check for duplicate MAC
-		 * address in RLMT Alive Reply packets.
+		 * CAUTION: Do not check for duplicate MAC address in RLMT Alive Reply
+		 * packets (they have the LLC_COMMAND_RESPONSE_BIT set in
+		 * pRPacket->SSap).
 		 */
-
 		if (i >= 0 && pRPacket->DSap == SK_RLMT_DSAP &&
 			pRPacket->Ctrl == SK_RLMT_CTRL &&
 			pRPacket->SSap == SK_RLMT_SSAP &&
@@ -1264,43 +1119,28 @@
 			pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
 			pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
 			pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_RX,
+			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
 				("SkRlmtPacketReceive: Duplicate MAC Address.\n"))
 
 			/* Error Log entry. */
-
-			SK_ERR_LOG(
-				pAC,
-				SK_ERRCL_COMM,
-				SKERR_RLMT_E006,
-				SKERR_RLMT_E006_MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG);
 		}
 		else {
 			/* Simply trash it. */
-
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_RX,
+			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
 				("SkRlmtPacketReceive: Sent by me.\n"))
 		}
 
 		SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-
 		return;
 	}
 
 	/* Check SuspectTx entries. */
-
 	if (pRPort->PortsSuspect > 0) {
 		for (j = 0; j < pRPort->PortsChecked; j++) {
 			if (pRPort->PortCheck[j].SuspectTx &&
 				SK_ADDR_EQUAL(
-					pRPacket->SrcAddr,
-					pRPort->PortCheck[j].CheckAddr.a)) {
+					pRPacket->SrcAddr, pRPort->PortCheck[j].CheckAddr.a)) {
 				pRPort->PortCheck[j].SuspectTx = SK_FALSE;
 				pRPort->PortsSuspect--;
 				break;
@@ -1309,7 +1149,6 @@
 	}
 
 	/* Determine type of packet. */
-
 	if (pRPacket->DSap == SK_RLMT_DSAP &&
 		pRPacket->Ctrl == SK_RLMT_CTRL &&
 		(pRPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SSAP &&
@@ -1322,7 +1161,6 @@
 		pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
 
 		/* It's an RLMT packet. */
-
 		PacketType = (SK_U16)((pRPacket->RlmtPacketType[0] << 8) |
 			pRPacket->RlmtPacketType[1]);
 
@@ -1330,14 +1168,10 @@
 		case SK_PACKET_ANNOUNCE:	/* Not yet used. */
 #if 0
 			/* Build the check chain. */
-
 			SkRlmtBuildCheckChain(pAC);
 #endif	/* 0 */
 
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_RX,
+			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
 				("SkRlmtPacketReceive: Announce.\n"))
 
 			SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
@@ -1345,221 +1179,145 @@
 
 		case SK_PACKET_ALIVE:
 			if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) {
-				SK_DBG_MSG(
-					pAC,
-					SK_DBGMOD_RLMT,
-					SK_DBGCAT_RX,
+				SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
 					("SkRlmtPacketReceive: Alive Reply.\n"))
 
-				/* Alive Reply Packet. */
-
-#if 0
-				pRPort->RlmtAcksPerTimeSlot++;
-#endif	/* 0 */
-
-				if (!(pAC->Addr.Port[PortIdx].PromMode &
-					SK_PROM_MODE_LLC) ||
+				if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) ||
 					SK_ADDR_EQUAL(
-						pRPacket->DstAddr,
-						pAPort->CurrentMacAddress.a)) {
-
+						pRPacket->DstAddr, pAPort->CurrentMacAddress.a)) {
 					/* Obviously we could send something. */
-
-					if (pRPort->CheckingState &
-						SK_RLMT_PCS_TX) {
-						pRPort->CheckingState &=
-							~SK_RLMT_PCS_TX;
-						SkTimerStop(
-							pAC,
-							IoC,
-							&pRPort->DownTxTimer);
+					if (pRPort->CheckingState & SK_RLMT_PCS_TX) {
+						pRPort->CheckingState &=  ~SK_RLMT_PCS_TX;
+						SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
 					}
 
-					if ((pRPort->PortState ==
-						SK_RLMT_PS_DOWN) &&
-						!(pRPort->CheckingState &
-						SK_RLMT_PCS_RX)) {
-						pRPort->PortState =
-							SK_RLMT_PS_GOING_UP;
-						pRPort->GuTimeStamp =
-							SkOsGetTime(pAC);
-
-						SkTimerStop(
-							pAC,
-							IoC,
-							&pRPort->DownTxTimer);
-
-						Para.Para32[0] = PortIdx;
-						SkTimerStart(
-							pAC,
-							IoC,
-							&pRPort->UpTimer,
-							SK_RLMT_PORTUP_TIM_VAL,
-							SKGE_RLMT,
-							SK_RLMT_PORTUP_TIM,
-							Para);
+					if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
+						!(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
+						pRPort->PortState = SK_RLMT_PS_GOING_UP;
+						pRPort->GuTimeStamp = SkOsGetTime(pAC);
+
+						SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
+
+						Para.Para32[0] = PortNumber;
+						Para.Para32[1] = (SK_U32)-1;
+						SkTimerStart(pAC, IoC, &pRPort->UpTimer,
+							SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT,
+							SK_RLMT_PORTUP_TIM, Para);
 					}
 				}
 
 				/* Mark sending port as alive? */
-
 				SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
 			}
 			else {	/* Alive Request Packet. */
-				SK_DBG_MSG(
-					pAC,
-					SK_DBGMOD_RLMT,
-					SK_DBGCAT_RX,
+				SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
 					("SkRlmtPacketReceive: Alive Request.\n"))
 
 				pRPort->RxHelloCts++;
-#if 0
-				pRPort->RlmtChksPerTimeSlot++;
-#endif	/* 0 */
 
 				/* Answer. */
-
 				for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
-					pRPacket->DstAddr[i] =
-						pRPacket->SrcAddr[i];
-					pRPacket->SrcAddr[i] = pAC->Addr.Port[
-						PortIdx].CurrentMacAddress.a[i];
+					pRPacket->DstAddr[i] = pRPacket->SrcAddr[i];
+					pRPacket->SrcAddr[i] =
+						pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
 				}
 				pRPacket->SSap |= LLC_COMMAND_RESPONSE_BIT;
 
 				Para.pParaPtr = pMb;
-				SkEventQueue(
-					pAC,
-					SKGE_DRV,
-					SK_DRV_RLMT_SEND,
-					Para);
+				SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
 			}
 			break;
 
 		case SK_PACKET_CHECK_TX:
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_RX,
+			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
 				("SkRlmtPacketReceive: Check your tx line.\n"))
 
-			/*
-			 * A port checking us requests us to check our tx line.
-			 */
-
+			/* A port checking us requests us to check our tx line. */
 			pRPort->CheckingState |= SK_RLMT_PCS_TX;
 
 			/* Start PortDownTx timer. */
-
-			Para.Para32[0] = PortIdx;
-			SkTimerStart(
-				pAC,
-				IoC,
-				&pRPort->DownTxTimer,
-				SK_RLMT_PORTDOWN_TIM_VAL,
-				SKGE_RLMT,
-				SK_RLMT_PORTDOWN_TX_TIM,
-				Para);
+			Para.Para32[0] = PortNumber;
+			Para.Para32[1] = (SK_U32)-1;
+			SkTimerStart(pAC, IoC, &pRPort->DownTxTimer,
+				SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
+				SK_RLMT_PORTDOWN_TX_TIM, Para);
 
 			SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
 
-			if ((Para.pParaPtr = SkRlmtBuildPacket(
-				pAC,
-				IoC,
-				PortIdx,
-				SK_PACKET_ALIVE,
-				&pAC->Addr.Port[PortIdx].CurrentMacAddress,
+			if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
+				SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
 				&SkRlmtMcAddr)) != NULL) {
-				SkEventQueue(
-					pAC,
-					SKGE_DRV,
-					SK_DRV_RLMT_SEND,
-					Para);
+				SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
 			}
 			break;
 
 		case SK_PACKET_ADDR_CHANGED:
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_RX,
+			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
 				("SkRlmtPacketReceive: Address Change.\n"))
 
 			/* Build the check chain. */
-
-			SkRlmtBuildCheckChain(pAC);
+			SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
 			SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
 			break;
 
 		default:
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_RX,
+			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
 				("SkRlmtPacketReceive: Unknown RLMT packet.\n"))
 
 			/* RA;:;: ??? */
-
 			SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
 		}
 	}
 	else if (pSPacket->DSap == SK_RLMT_SPT_DSAP &&
 		pSPacket->Ctrl == SK_RLMT_SPT_CTRL &&
-		(pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) ==
-		SK_RLMT_SPT_SSAP) {
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_RX,
+		(pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
 			("SkRlmtPacketReceive: BPDU Packet.\n"))
 
 		/* Spanning Tree packet. */
-
 		pRPort->RxSpHelloCts++;
 
-		if (!SK_ADDR_EQUAL(
-			&pSPacket->RootId[2],
-			&pAC->Addr.CurrentMacAddress.a[0])) {
-
+		if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pAC->Addr.Net[pAC->Rlmt.
+			Port[PortNumber].Net->NetNumber].CurrentMacAddress.a[0])) {
 			/*
 			 * Check segmentation if a new root bridge is set and
 			 * the segmentation check is not currently running.
 			 */
-
-			if (!SK_ADDR_EQUAL(
-					&pSPacket->RootId[2],
-					&pRPort->Root.Id[2]) &&
-				(pAC->Rlmt.LinksUp > 1) &&
-				(pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_SEG) &&
-				!(pAC->Rlmt.CheckingState & SK_RLMT_RCS_SEG)) {
-				pAC->Rlmt.CheckingState |=
-					SK_RLMT_RCS_START_SEG |
-					SK_RLMT_RCS_SEND_SEG;
+			if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pRPort->Root.Id[2]) &&
+				(pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
+				(pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG)
+				!= 0 && (pAC->Rlmt.Port[PortNumber].Net->CheckingState &
+				SK_RLMT_RCS_SEG) == 0) {
+				pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
+					SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
 			}
 
 			/* Store tree view of this port. */
-
 			for (i = 0; i < 8; i++) {
 				pRPort->Root.Id[i] = pSPacket->RootId[i];
 			}
 			pRPort->RootIdSet = SK_TRUE;
+
+			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
+				("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
+					PortNumber,
+					pRPort->Root.Id[0], pRPort->Root.Id[1],
+					pRPort->Root.Id[2], pRPort->Root.Id[3],
+					pRPort->Root.Id[4], pRPort->Root.Id[5],
+					pRPort->Root.Id[6], pRPort->Root.Id[7]))      
 		}
 
 		SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-
-		if (pAC->Rlmt.CheckingState & SK_RLMT_RCS_REPORT_SEG) {
-			SkRlmtCheckSeg(pAC, IoC);
+		if ((pAC->Rlmt.Port[PortNumber].Net->CheckingState &
+			SK_RLMT_RCS_REPORT_SEG) != 0) {
+			SkRlmtCheckSeg(pAC, IoC, pAC->Rlmt.Port[PortNumber].Net->NetNumber);
 		}
 	}
 	else {
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_RX,
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
 			("SkRlmtPacketReceive: Unknown Packet Type.\n"))
 
 		/* Unknown packet. */
-
 		SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
 	}
 	return;
@@ -1625,25 +1383,21 @@
  *	New timeout value.
  */
 RLMT_STATIC SK_U32	SkRlmtCheckPort(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* I/O context */
-SK_U32	PortIdx)	/* port to check */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
+SK_U32	PortNumber)	/* Port to check */
 {
-	unsigned	i;
-	SK_U32		NewTimeout;
+	unsigned		i;
+	SK_U32			NewTimeout;
 	SK_RLMT_PORT	*pRPort;
-	SK_EVPARA	Para;
+	SK_EVPARA		Para;
 
-	pRPort = &pAC->Rlmt.Port[PortIdx];
+	pRPort = &pAC->Rlmt.Port[PortNumber];
 
 	if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) {
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
 			("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n",
-				PortIdx,
-				pRPort->PacketsPerTimeSlot))
+				PortNumber, pRPort->PacketsPerTimeSlot))
 
 		/*
 		 * Check segmentation if there was no receive at least twice
@@ -1651,46 +1405,35 @@
 		 * check is not currently running.
 		 */
 
-		if (pRPort->PortNoRx && (pAC->Rlmt.LinksUp > 1) &&
-			(pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_SEG) &&
-			!(pAC->Rlmt.CheckingState & SK_RLMT_RCS_SEG)) {
-			pAC->Rlmt.CheckingState |=
+		if (pRPort->PortNoRx && (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
+			(pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
+			!(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEG)) {
+			pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
 				SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
 		}
 
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
 			("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n",
-				pRPort->PortsSuspect,
-				pRPort->CheckingState & SK_RLMT_PCS_RX))
+				pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX))
 
 		if (pRPort->PortState != SK_RLMT_PS_DOWN) {
-			NewTimeout = TO_SHORTEN(pAC->Rlmt.TimeoutValue);
+			NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue);
 			if (NewTimeout < SK_RLMT_MIN_TO_VAL) {
 				NewTimeout = SK_RLMT_MIN_TO_VAL;
 			}
 
 			if (!(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
-				Para.Para32[0] = PortIdx;
+				Para.Para32[0] = PortNumber;
 				pRPort->CheckingState |= SK_RLMT_PCS_RX;
 
 				/*
-				 * What shall we do if the port checked
-				 * by this one receives our request
-				 * frames?  What's bad - our rx line
-				 * or his tx line?
+				 * What shall we do if the port checked by this one receives
+				 * our request frames?  What's bad - our rx line or his tx line?
 				 */
-
-				SkTimerStart(
-					pAC,
-					IoC,
-					&pRPort->DownRxTimer,
-					SK_RLMT_PORTDOWN_TIM_VAL,
-					SKGE_RLMT,
-					SK_RLMT_PORTDOWN_RX_TIM,
-					Para);
+				Para.Para32[1] = (SK_U32)-1;
+				SkTimerStart(pAC, IoC, &pRPort->DownRxTimer,
+					SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
+					SK_RLMT_PORTDOWN_RX_TIM, Para);
 
 				for (i = 0; i < pRPort->PortsChecked; i++) {
 					if (pRPort->PortCheck[i].SuspectTx) {
@@ -1699,19 +1442,10 @@
 					pRPort->PortCheck[i].SuspectTx = SK_TRUE;
 					pRPort->PortsSuspect++;
 					if ((Para.pParaPtr =
-						SkRlmtBuildPacket(
-							pAC,
-							IoC,
-							PortIdx,
-							SK_PACKET_CHECK_TX,
-							&pAC->Addr.Port[PortIdx].CurrentMacAddress,
-							&pRPort->PortCheck[i].CheckAddr)
-							) != NULL) {
-						SkEventQueue(
-							pAC,
-							SKGE_DRV,
-							SK_DRV_RLMT_SEND,
-							Para);
+						SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_CHECK_TX,
+							&pAC->Addr.Port[PortNumber].CurrentMacAddress,
+							&pRPort->PortCheck[i].CheckAddr)) != NULL) {
+						SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
 					}
 				}
 			}
@@ -1722,17 +1456,17 @@
 		pRPort->PortNoRx = SK_TRUE;
 	}
 	else {	/* A non-BPDU packet was received. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
 			("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n",
-				PortIdx,
-                                pRPort->PacketsPerTimeSlot -
-					pRPort->BpduPacketsPerTimeSlot,
+				PortNumber,
+				pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot,
 				pRPort->PacketsPerTimeSlot))
 		
-		SkRlmtPortReceives(pAC, IoC, PortIdx);
+		SkRlmtPortReceives(pAC, IoC, PortNumber);
+		if (pAC->Rlmt.CheckSwitch) {
+			SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
+		}
+
 		NewTimeout = SK_RLMT_DEF_TO_VAL;              
 	}
 
@@ -1755,82 +1489,69 @@
  *	SK_BOOL
  */
 RLMT_STATIC SK_BOOL	SkRlmtSelectBcRx(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* I/O context */
-SK_U32	A,	/* active port */
-SK_U32	P,	/* preferred port */
-SK_U32	*N)	/* new active port */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
+SK_U32	Active,		/* Active port */
+SK_U32	PrefPort,	/* Preferred port */
+SK_U32	*pSelect)	/* New active port */
 {
 	SK_U64		BcTimeStamp;
 	SK_U32		i;
 	SK_BOOL		PortFound;
 
-        BcTimeStamp = 0;	/* Not totally necessary, but feeling better. */
+	BcTimeStamp = 0;	/* Not totally necessary, but feeling better. */
 	PortFound = SK_FALSE;
 	
 	/* Select port with the latest TimeStamp. */
-
 	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("TimeStamp Port %d: %.08x%.08x.\n",
-			i,
-			*((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32),
-			*((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)))
-		if (!pAC->Rlmt.Port[i].PortDown &&
-			!pAC->Rlmt.Port[i].PortNoRx) {
-			if (!PortFound ||
-				pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) {
+#ifdef xDEBUG
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("TimeStamp Port %d: %08x %08x.\n",
+				i,
+				*((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32),
+				*((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)))
+#endif	/* DEBUG */
+		if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) {
+			if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) {
 				BcTimeStamp = pAC->Rlmt.Port[i].BcTimeStamp;
-				*N = i;
+				*pSelect = i;
 				PortFound = SK_TRUE;
 			}
 		}
 	}
 
 	if (PortFound) {
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("Port %d received the last broadcast.\n", *N))
+#if 0
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Port %d received the last broadcast.\n", *pSelect))
+#endif	/* 0 */
 
 		/* Look if another port's time stamp is similar. */
-
 		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-			if (i == *N) {
+			if (i == *pSelect) {
 				continue;
 			}
-			if (!pAC->Rlmt.Port[i].PortDown &&
-				!pAC->Rlmt.Port[i].PortNoRx &&
+			if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx &&
 				(pAC->Rlmt.Port[i].BcTimeStamp >
-				BcTimeStamp - SK_RLMT_BC_DELTA ||
-				pAC->Rlmt.Port[i].BcTimeStamp
-				+ SK_RLMT_BC_DELTA > BcTimeStamp)) {
+				 BcTimeStamp - SK_RLMT_BC_DELTA ||
+				pAC->Rlmt.Port[i].BcTimeStamp +
+				 SK_RLMT_BC_DELTA > BcTimeStamp)) {
 				PortFound = SK_FALSE;
-				SK_DBG_MSG(
-					pAC,
-					SK_DBGMOD_RLMT,
-					SK_DBGCAT_CTRL,
-					("Port %d received a broadcast %s.\n",
-					i,
-					"at a similar time"))
+#ifdef xDEBUG
+				SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+					("Port %d received a broadcast at a similar time.\n", i))
+#endif	/* DEBUG */
 				break;
 			}
 		}
 	}
 
-#ifdef DEBUG
+#ifdef xDEBUG
 	if (PortFound) {
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_CHECK_SWITCH found Port %d receiving %s.\n",
-				*N,
-				"the substantially latest broadcast"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_CHECK_SWITCH found Port %d receiving the substantially latest broadcast (%d).\n",
+				*pSelect,
+				BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp))
 	}
 #endif	/* DEBUG */
 
@@ -1852,11 +1573,11 @@
  *	SK_BOOL
  */
 RLMT_STATIC SK_BOOL	SkRlmtSelectNotSuspect(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* I/O context */
-SK_U32	A,	/* active port */
-SK_U32	P,	/* preferred port */
-SK_U32	*N)	/* new active port */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
+SK_U32	Active,		/* Active port */
+SK_U32	PrefPort,	/* Preferred port */
+SK_U32	*pSelect)	/* New active port */
 {
 	SK_U32		i;
 	SK_BOOL		PortFound;
@@ -1864,32 +1585,25 @@
 	PortFound = SK_FALSE;
 
 	/* Select first port that is PortUp && !SuspectRx. */
-
 	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
 		if (!pAC->Rlmt.Port[i].PortDown &&
 			!(pAC->Rlmt.Port[i].CheckingState & SK_RLMT_PCS_RX)) {
-			*N = i;
-			if (!pAC->Rlmt.Port[A].PortDown &&
-				!(pAC->Rlmt.Port[A].CheckingState &
-				SK_RLMT_PCS_RX)) {
-				*N = A;
-			}
-			if (!pAC->Rlmt.Port[P].PortDown &&
-				!(pAC->Rlmt.Port[P].CheckingState &
-				SK_RLMT_PCS_RX)) {
-				*N = P;
+			*pSelect = i;
+			if (!pAC->Rlmt.Port[Active].PortDown &&
+				!(pAC->Rlmt.Port[Active].CheckingState & SK_RLMT_PCS_RX)) {
+				*pSelect = Active;
+			}
+			if (!pAC->Rlmt.Port[PrefPort].PortDown &&
+				!(pAC->Rlmt.Port[PrefPort].CheckingState & SK_RLMT_PCS_RX)) {
+				*pSelect = PrefPort;
 			}
 			PortFound = SK_TRUE;
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_CTRL,
+			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
 				("SK_RLMT_CHECK_SWITCH found Port %d up and not check RX.\n",
-					*N))
+					*pSelect))
 			break;
 		}
 	}
-
 	return (PortFound);
 }	/* SkRlmtSelectNotSuspect */
 
@@ -1908,12 +1622,12 @@
  *	SK_BOOL
  */
 RLMT_STATIC SK_BOOL	SkRlmtSelectUp(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* I/O context */
-SK_U32	A,	/* active port */
-SK_U32	P,	/* preferred port */
-SK_U32	*N,	/* new active port */
-SK_BOOL	AutoNegDone)	/* successfully auto-negotiated? */
+SK_AC	*pAC,			/* Adapter Context */
+SK_IOC	IoC,			/* I/O Context */
+SK_U32	Active,			/* Active port */
+SK_U32	PrefPort,		/* Preferred port */
+SK_U32	*pSelect,		/* New active port */
+SK_BOOL	AutoNegDone)	/* Successfully auto-negotiated? */
 {
 	SK_U32		i;
 	SK_BOOL		PortFound;
@@ -1921,30 +1635,24 @@
 	PortFound = SK_FALSE;
 
 	/* Select first port that is PortUp. */
-
 	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
 		if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_UP &&
 			pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
-			*N = i;
-			if (pAC->Rlmt.Port[A].PortState == SK_RLMT_PS_UP &&
-				pAC->GIni.GP[A].PAutoNegFail != AutoNegDone) {
-				*N = A;
-			}
-			if (pAC->Rlmt.Port[P].PortState == SK_RLMT_PS_UP &&
-				pAC->GIni.GP[P].PAutoNegFail != AutoNegDone) {
-				*N = P;
+			*pSelect = i;
+			if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_UP &&
+				pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
+				*pSelect = Active;
+			}
+			if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_UP &&
+				pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
+				*pSelect = PrefPort;
 			}
 			PortFound = SK_TRUE;
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_CTRL,
-				("SK_RLMT_CHECK_SWITCH found Port %d up.\n",
-					*N))
+			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+				("SK_RLMT_CHECK_SWITCH found Port %d up.\n", *pSelect))
 			break;
 		}
 	}
-
 	return (PortFound);
 }	/* SkRlmtSelectUp */
 
@@ -1963,26 +1671,26 @@
  *	SK_BOOL
  */
 RLMT_STATIC SK_BOOL	SkRlmtSelectGoingUp(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* I/O context */
-SK_U32	A,	/* active port */
-SK_U32	P,	/* preferred port */
-SK_U32	*N,	/* new active port */
-SK_BOOL	AutoNegDone)	/* successfully auto-negotiated? */
+SK_AC	*pAC,			/* Adapter Context */
+SK_IOC	IoC,			/* I/O Context */
+SK_U32	Active,			/* Active port */
+SK_U32	PrefPort,		/* Preferred port */
+SK_U32	*pSelect,		/* New active port */
+SK_BOOL	AutoNegDone)	/* Successfully auto-negotiated? */
 {
-	SK_U64		GuTimeStamp=0;
+	SK_U64		GuTimeStamp;
 	SK_U32		i;
 	SK_BOOL		PortFound;
 
+	GuTimeStamp = 0;
 	PortFound = SK_FALSE;
 
 	/* Select port that is PortGoingUp for the longest time. */
-
 	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
 		if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
 			pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
-                        GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
-			*N = i;
+			GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
+			*pSelect = i;
 			PortFound = SK_TRUE;
 			break;
 		}
@@ -1992,22 +1700,17 @@
 		return (SK_FALSE);
 	}
 
-	for (i = *N + 1; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
+	for (i = *pSelect + 1; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
 		if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
-                        pAC->Rlmt.Port[i].GuTimeStamp < GuTimeStamp &&
+			pAC->Rlmt.Port[i].GuTimeStamp < GuTimeStamp &&
 			pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
-
-                        GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
-			*N = i;
+			GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
+			*pSelect = i;
 		}
 	}
 
-	SK_DBG_MSG(
-		pAC,
-		SK_DBGMOD_RLMT,
-		SK_DBGCAT_CTRL,
-		("SK_RLMT_CHECK_SWITCH found Port %d going up.\n", *N))
-
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_CHECK_SWITCH found Port %d going up.\n", *pSelect))
 	return (SK_TRUE);
 }	/* SkRlmtSelectGoingUp */
 
@@ -2026,12 +1729,12 @@
  *	SK_BOOL
  */
 RLMT_STATIC SK_BOOL	SkRlmtSelectDown(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* I/O context */
-SK_U32	A,	/* active port */
-SK_U32	P,	/* preferred port */
-SK_U32	*N,	/* new active port */
-SK_BOOL	AutoNegDone)	/* successfully auto-negotiated? */
+SK_AC	*pAC,			/* Adapter Context */
+SK_IOC	IoC,			/* I/O Context */
+SK_U32	Active,			/* Active port */
+SK_U32	PrefPort,		/* Preferred port */
+SK_U32	*pSelect,		/* New active port */
+SK_BOOL	AutoNegDone)	/* Successfully auto-negotiated? */
 {
 	SK_U32		i;
 	SK_BOOL		PortFound;
@@ -2039,30 +1742,24 @@
 	PortFound = SK_FALSE;
 
 	/* Select first port that is PortDown. */
-
 	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
 		if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_DOWN &&
 			pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
-			*N = i;
-			if (pAC->Rlmt.Port[A].PortState == SK_RLMT_PS_DOWN &&
-				pAC->GIni.GP[A].PAutoNegFail != AutoNegDone) {
-				*N = A;
-			}
-			if (pAC->Rlmt.Port[P].PortState == SK_RLMT_PS_DOWN &&
-				pAC->GIni.GP[P].PAutoNegFail != AutoNegDone) {
-				*N = P;
+			*pSelect = i;
+			if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_DOWN &&
+				pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
+				*pSelect = Active;
+			}
+			if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_DOWN &&
+				pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
+				*pSelect = PrefPort;
 			}
 			PortFound = SK_TRUE;
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_CTRL,
-				("SK_RLMT_CHECK_SWITCH found Port %d down.\n",
-					*N))
+			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+				("SK_RLMT_CHECK_SWITCH found Port %d down.\n", *pSelect))
 			break;
 		}
 	}
-
 	return (PortFound);
 }	/* SkRlmtSelectDown */
 
@@ -2082,58 +1779,50 @@
  *	Nothing.
  */
 RLMT_STATIC void	SkRlmtCheckSwitch(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC)	/* I/O context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
+SK_U32	NetIdx)	/* Net index */
 {
 	SK_EVPARA	Para;
-	SK_U32		A;
-	SK_U32		P;
+	SK_U32		Active;
+	SK_U32		PrefPort;
 	SK_U32		i;
 	SK_BOOL		PortFound;
 
-	if (pAC->Rlmt.RlmtState == SK_RLMT_RS_INIT) {
-		return;
-	}
-
-	A = pAC->Rlmt.MacActive;	/* Index of active port. */
-	P = pAC->Rlmt.PrefPort;		/* Index of preferred port. */
+	Active = pAC->Rlmt.Net[NetIdx].ActivePort;	/* Index of active port. */
+	PrefPort = pAC->Rlmt.Net[NetIdx].PrefPort;	/* Index of preferred port. */
 	PortFound = SK_FALSE;
+	pAC->Rlmt.CheckSwitch = SK_FALSE;
 
-	if (pAC->Rlmt.LinksUp == 0) {
-
-		/*
-		 * Last link went down - shut down the net.
-		 */
-
-		pAC->Rlmt.RlmtState = SK_RLMT_RS_NET_DOWN;
+	if (pAC->Rlmt.Net[NetIdx].LinksUp == 0) {
+		/* Last link went down - shut down the net. */
+		pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_DOWN;
 		Para.Para32[0] = SK_RLMT_NET_DOWN_TEMP;
-		SkEventQueue(
-			pAC,
-			SKGE_DRV,
-			SK_DRV_NET_DOWN,
-			Para);
+		Para.Para32[1] = NetIdx;
+		SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para);
 
+		Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
+			Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
+		Para.Para32[1] = NetIdx;
+		SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
 		return;
-	}
-	else if (pAC->Rlmt.LinksUp == 1 &&
-		pAC->Rlmt.RlmtState == SK_RLMT_RS_NET_DOWN) {
-
+	}	/* pAC->Rlmt.LinksUp == 0 */
+	else if (pAC->Rlmt.Net[NetIdx].LinksUp == 1 &&
+		pAC->Rlmt.Net[NetIdx].RlmtState == SK_RLMT_RS_NET_DOWN) {
 		/* First link came up - get the net up. */
-
-		pAC->Rlmt.RlmtState = SK_RLMT_RS_NET_UP;
+		pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_UP;
 
 		/*
-		 * If pAC->Rlmt.MacActive != Para.Para32[0],
+		 * If pAC->Rlmt.ActivePort != Para.Para32[0],
 		 * the DRV switches to the port that came up.
 		 */
-
-		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-			if (!pAC->Rlmt.Port[i].LinkDown) {
-				if (!pAC->Rlmt.Port[A].LinkDown) {
-					i = A;
+		for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
+			if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
+				if (!pAC->Rlmt.Net[NetIdx].Port[Active]->LinkDown) {
+					i = Active;
 				}
-				if (!pAC->Rlmt.Port[P].LinkDown) {
-					i = P;
+				if (!pAC->Rlmt.Net[NetIdx].Port[PrefPort]->LinkDown) {
+					i = PrefPort;
 				}
 				PortFound = SK_TRUE;
 				break;
@@ -2141,184 +1830,143 @@
 		}
 
 		if (PortFound) {
-			Para.Para32[0] = pAC->Rlmt.MacActive;
-			Para.Para32[1] = i;
-			SkEventQueue(
-				pAC,
-				SKGE_PNMI,
-				SK_PNMI_EVT_RLMT_PORT_SWITCH,
-				Para);
-
-			pAC->Rlmt.MacActive = i;
-			Para.Para32[0] = i;
+			Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
+			Para.Para32[1] = NetIdx;
+			SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
+
+			pAC->Rlmt.Net[NetIdx].ActivePort = i;
+			Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
+			Para.Para32[1] = NetIdx;
 			SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para);
 
-			if ((Para.pParaPtr = SkRlmtBuildPacket(
-					pAC,
-					IoC,
-					i,
-					SK_PACKET_ANNOUNCE,
-					&pAC->Addr.CurrentMacAddress,
-					&SkRlmtMcAddr)
-				) != NULL) {
-
+			if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
+				(Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC,
+				pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber,
+				SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].
+				CurrentMacAddress, &SkRlmtMcAddr)) != NULL) {
 				/*
-				 * Send packet to RLMT multicast address
-				 * to force switches to learn the new
-				 * location of the address.
+				 * Send announce packet to RLMT multicast address to force
+				 * switches to learn the new location of the logical MAC address.
 				 */
-
-				SkEventQueue(
-					pAC,
-					SKGE_DRV,
-					SK_DRV_RLMT_SEND,
-					Para);
+				SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
 			}
 		}
 		else {
-			SK_ERR_LOG(
-				pAC,
-				SK_ERRCL_SW,
-				SKERR_RLMT_E007,
-				SKERR_RLMT_E007_MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E007, SKERR_RLMT_E007_MSG);
 		}
 
 		return;
-	}
-	else {
-		Para.Para32[0] = A;
+	}	/* LinksUp == 1 && RlmtState == SK_RLMT_RS_NET_DOWN */
+	else {	/* Cannot be reached in dual-net mode. */
+		Para.Para32[0] = Active;
 
 		/*
 		 * Preselection:
-		 *   If RLMT Mode != CheckLinkState
-		 *     select port that received a broadcast frame
-		 *     substantially later than all other ports
-		 *   else select first port that is not SuspectRx
-		 *   else select first port that is PortUp
-		 *   else select port that is PortGoingUp for the longest time
-		 *   else select first port that is PortDown
-		 *   else stop.
+		 *	If RLMT Mode != CheckLinkState
+		 *		select port that received a broadcast frame substantially later
+		 *		than all other ports
+		 *	else select first port that is not SuspectRx
+		 *	else select first port that is PortUp
+		 *	else select port that is PortGoingUp for the longest time
+		 *	else select first port that is PortDown
+		 *	else stop.
 		 *
 		 * For the preselected port:
-		 *   If ActivePort is equal in quality, select ActivePort.
+		 *	If ActivePort is equal in quality, select ActivePort.
 		 *
-		 *   If PrefPort is equal in quality, select PrefPort.
+		 *	If PrefPort is equal in quality, select PrefPort.
 		 *
-		 *   If MacActive != SelectedPort,
-		 *     If old ActivePort is LinkDown,
-		 *       SwitchHard
-		 *     else
-		 *       SwitchSoft
+		 *	If ActivePort != SelectedPort,
+		 *		If old ActivePort is LinkDown,
+		 *			SwitchHard
+		 *		else
+		 *			SwitchSoft
 		 */
-
-		if (pAC->Rlmt.RlmtMode != SK_RLMT_CHECK_LINK) {
+		if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) {
 			if (!PortFound) {
-				PortFound = SkRlmtSelectBcRx(pAC, IoC,
-					A, P, &Para.Para32[1]);
+				PortFound = SkRlmtSelectBcRx(
+					pAC, IoC, Active, PrefPort, &Para.Para32[1]);
 			}
 
 			if (!PortFound) {
-				PortFound = SkRlmtSelectNotSuspect(pAC, IoC,
-					A, P, &Para.Para32[1]);
+				PortFound = SkRlmtSelectNotSuspect(
+					pAC, IoC, Active, PrefPort, &Para.Para32[1]);
 			}
-		}
+		}	/* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
 
 		if (!PortFound) {
-			PortFound = SkRlmtSelectUp(pAC, IoC,
-				A, P, &Para.Para32[1], AUTONEG_SUCCESS);
+			PortFound = SkRlmtSelectUp(
+				pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
 		}
 
 		if (!PortFound) {
-			PortFound = SkRlmtSelectUp(pAC, IoC,
-				A, P, &Para.Para32[1], AUTONEG_FAILED);
+			PortFound = SkRlmtSelectUp(
+				pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
 		}
 
 		if (!PortFound) {
-			PortFound = SkRlmtSelectGoingUp(pAC, IoC,
-				A, P, &Para.Para32[1], AUTONEG_SUCCESS);
+			PortFound = SkRlmtSelectGoingUp(
+				pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
 		}
 
 		if (!PortFound) {
-			PortFound = SkRlmtSelectGoingUp(pAC, IoC,
-				A, P,&Para.Para32[1], AUTONEG_FAILED);
+			PortFound = SkRlmtSelectGoingUp(
+				pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
 		}
 
-		if (pAC->Rlmt.RlmtMode != SK_RLMT_CHECK_LINK) {
+		if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) {
 			if (!PortFound) {
 				PortFound = SkRlmtSelectDown(pAC, IoC,
-					A, P,&Para.Para32[1], AUTONEG_SUCCESS);
+					Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
 			}
 
 			if (!PortFound) {
 				PortFound = SkRlmtSelectDown(pAC, IoC,
-					A, P,&Para.Para32[1], AUTONEG_FAILED);
+					Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
 			}
-		}
+		}	/* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
 
 		if (PortFound) {
-			if (Para.Para32[1] != A) {
-				pAC->Rlmt.MacActive = Para.Para32[1];
-				SK_HWAC_LINK_LED(
-					pAC,
-					IoC,
-					Para.Para32[1],
-					SK_LED_ACTIVE);
-				if (pAC->Rlmt.Port[A].LinkDown) {
-					SkEventQueue(
-						pAC,
-						SKGE_DRV,
-						SK_DRV_SWITCH_HARD,
-						Para);
+			if (Para.Para32[1] != Active) {
+				SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+					("Active: %d, Para1: %d.\n", Active, Para.Para32[1]))
+				pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1];
+				Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
+					Port[Para.Para32[0]]->PortNumber;
+				Para.Para32[1] = pAC->Rlmt.Net[NetIdx].
+					Port[Para.Para32[1]]->PortNumber;
+				SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[1], SK_LED_ACTIVE);
+				if (pAC->Rlmt.Port[Active].LinkDown) {
+					SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_HARD, Para);
 				}
 				else {
-					SK_HWAC_LINK_LED(
-						pAC,
-						IoC,
-						Para.Para32[0],
-						SK_LED_STANDBY);
-					SkEventQueue(
-						pAC,
-						SKGE_DRV,
-						SK_DRV_SWITCH_SOFT,
-						Para);
+					SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
+					SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_SOFT, Para);
 				}
-				SkEventQueue(
-					pAC,
-					SKGE_PNMI,
-					SK_PNMI_EVT_RLMT_PORT_SWITCH,
-					Para);
-				if ((Para.pParaPtr = SkRlmtBuildPacket(
-						pAC,
-						IoC,
-						Para.Para32[1],
-						SK_PACKET_ANNOUNCE,
-						&pAC->Addr.CurrentMacAddress,
-						&SkRlmtMcAddr)
-					) != NULL) {
-
+				Para.Para32[1] = NetIdx;
+				Para.Para32[0] =
+					pAC->Rlmt.Net[NetIdx].Port[Para.Para32[0]]->PortNumber;
+				SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
+				Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
+					Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
+				SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
+				if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
+					(Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0],
+					SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].CurrentMacAddress,
+					&SkRlmtMcAddr)) != NULL) {
 					/*
-					 * Send "new" packet to RLMT multicast
-					 * address to force switches to learn
-					 * the new location of the MAC address.
+					 * Send announce packet to RLMT multicast address to force
+					 * switches to learn the new location of the logical
+					 * MAC address.
 					 */
-
-					SkEventQueue(
-						pAC,
-						SKGE_DRV,
-						SK_DRV_RLMT_SEND,
-						Para);
-				}
-			}
-		}
+					SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
+				}	/* (Para.pParaPtr = SkRlmtBuildPacket(...)) != NULL */
+			}	/* Para.Para32[1] != Active */
+		}	/* PortFound */
 		else {
-			SK_ERR_LOG(
-				pAC,
-				SK_ERRCL_SW,
-				SKERR_RLMT_E004,
-				SKERR_RLMT_E004_MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E004, SKERR_RLMT_E004_MSG);
 		}
-	}
-
+	}	/* LinksUp > 1 || LinksUp == 1 && RlmtState != SK_RLMT_RS_NET_DOWN */
 	return;
 }	/* SkRlmtCheckSwitch */
 
@@ -2338,66 +1986,65 @@
  *	Nothing.
  */
 RLMT_STATIC void	SkRlmtCheckSeg(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC)	/* I/O context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
+SK_U32	NetIdx)	/* Net number */
 {
-	SK_BOOL	Equal;
-	SK_U32	i, j;
+	SK_EVPARA	Para;
+	SK_RLMT_NET	*pNet;
+	SK_U32		i, j;
+	SK_BOOL		Equal;
 
-	pAC->Rlmt.RootIdSet = SK_FALSE;
+	pNet = &pAC->Rlmt.Net[NetIdx];
+	pNet->RootIdSet = SK_FALSE;
 	Equal = SK_TRUE;
-	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-		if (pAC->Rlmt.Port[i].LinkDown ||
-			!pAC->Rlmt.Port[i].RootIdSet) {
+
+	for (i = 0; i < pNet->NumPorts; i++) {
+		if (pNet->Port[i]->LinkDown || !pNet->Port[i]->RootIdSet) {
 			continue;
 		}
 
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
-				i,
-				pAC->Rlmt.Port[i].Root.Id[0],
-				pAC->Rlmt.Port[i].Root.Id[1],
-				pAC->Rlmt.Port[i].Root.Id[2],
-				pAC->Rlmt.Port[i].Root.Id[3],
-				pAC->Rlmt.Port[i].Root.Id[4],
-				pAC->Rlmt.Port[i].Root.Id[5],
-				pAC->Rlmt.Port[i].Root.Id[6],
-				pAC->Rlmt.Port[i].Root.Id[7]))
-
-		if (!pAC->Rlmt.RootIdSet) {
-			pAC->Rlmt.Root = pAC->Rlmt.Port[i].Root;
-			pAC->Rlmt.RootIdSet = SK_TRUE;
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
+			("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", i,
+				pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1],
+				pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3],
+				pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5],
+				pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7]))
+
+		if (!pNet->RootIdSet) {
+			pNet->Root = pNet->Port[i]->Root;
+			pNet->RootIdSet = SK_TRUE;
 			continue;
 		}
 
 		for (j = 0; j < 8; j ++) {
-			Equal &= pAC->Rlmt.Port[i].Root.Id[j] ==
-				pAC->Rlmt.Root.Id[j];
+			Equal &= pNet->Port[i]->Root.Id[j] == pNet->Root.Id[j];
 			if (!Equal) {
 				break;
 			}
 		}
 		
 		if (!Equal) {
-			SK_ERR_LOG(
-				pAC,
-				SK_ERRCL_COMM,
-				SKERR_RLMT_E005,
-				SKERR_RLMT_E005_MSG);
-#ifdef SK_PNMI_EVT_SEGMENTATION
-			SkEventQueue(
-				pAC,
-				SKGE_PNMI,
-				SK_PNMI_EVT_SEGMENTATION,
-				Para);
-#endif	/* SK_PNMI_EVT_SEGMENTATION */
-			pAC->Rlmt.CheckingState &= ~SK_RLMT_RCS_REPORT_SEG;
+			SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E005, SKERR_RLMT_E005_MSG);
+			Para.Para32[0] = NetIdx;
+			Para.Para32[1] = (SK_U32)-1;
+			SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SEGMENTATION, Para);
+
+			pNet->CheckingState &= ~SK_RLMT_RCS_REPORT_SEG;
+
+			/* 2000-03-06 RA: New. */
+			Para.Para32[0] = NetIdx;
+			Para.Para32[1] = (SK_U32)-1;
+			SkTimerStart(pAC, IoC, &pNet->SegTimer, SK_RLMT_SEG_TO_VAL,
+				SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
 			break;
 		}
-	}
+	}	/* for (i = 0; i < pNet->NumPorts; i++) */
+
+	/* 2000-03-06 RA: Moved here. */
+	/* Segmentation check not running anymore. */
+	pNet->CheckingState &= ~SK_RLMT_RCS_SEG;
+
 }	/* SkRlmtCheckSeg */
 
 
@@ -2417,1005 +2064,1340 @@
  *	Nothing
  */
 RLMT_STATIC void	SkRlmtPortStart(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* I/O context */
-SK_U32	PortIdx)	/* event code */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
+SK_U32	PortNumber)	/* Port number */
 {
 	SK_EVPARA	Para;
 
-	pAC->Rlmt.Port[PortIdx].PortState = SK_RLMT_PS_LINK_DOWN;
-	pAC->Rlmt.Port[PortIdx].PortStarted = SK_TRUE;
-	pAC->Rlmt.Port[PortIdx].LinkDown = SK_TRUE;
-	pAC->Rlmt.Port[PortIdx].PortDown = SK_TRUE;
-	pAC->Rlmt.Port[PortIdx].CheckingState = 0;
-	pAC->Rlmt.Port[PortIdx].RootIdSet = SK_FALSE;
-	Para.Para32[0] = PortIdx;
+	pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_LINK_DOWN;
+	pAC->Rlmt.Port[PortNumber].PortStarted = SK_TRUE;
+	pAC->Rlmt.Port[PortNumber].LinkDown = SK_TRUE;
+	pAC->Rlmt.Port[PortNumber].PortDown = SK_TRUE;
+	pAC->Rlmt.Port[PortNumber].CheckingState = 0;
+	pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
+	Para.Para32[0] = PortNumber;
+	Para.Para32[1] = (SK_U32)-1;
 	SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
 }	/* SkRlmtPortStart */
 
 
 /******************************************************************************
  *
- *	SkRlmtEvent - a PORT- or an RLMT-specific event happened
+ *	SkRlmtEvtPortStartTim - PORT_START_TIM
  *
  * Description:
- *	This routine handles PORT- and RLMT-specific events.
+ *	This routine handles PORT_START_TIM events.
  *
  * Context:
  *	runtime, pageable?
  *	may be called after SK_INIT_IO
  *
  * Returns:
- *	0
+ *	Nothing
  */
-int	SkRlmtEvent(
-SK_AC		*pAC,	/* adapter context */
-SK_IOC		IoC,	/* I/O context */
-SK_U32		Event,	/* event code */
-SK_EVPARA	Para)	/* event-specific parameter */
+RLMT_STATIC void	SkRlmtEvtPortStartTim(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_U32 PortNumber; SK_U32 -1 */
 {
-	SK_U32		i, j;
-	SK_RLMT_PORT	*pRPort;
-	SK_EVPARA	Para2;
-	SK_MBUF		*pMb;
-	SK_MBUF		*pNextMb;
-	SK_MAC_ADDR	*pOldMacAddr;
-	SK_MAC_ADDR	*pNewMacAddr;
-	SK_U32		Timeout;
-	SK_U32		NewTimeout;
-	SK_U32		PrevRlmtMode;
-
-	switch (Event) {
-	case SK_RLMT_PORTSTART_TIM:	/* From RLMT via TIME. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_PORTSTART_TIMEOUT Port %d Event (%d) BEGIN.\n", Para.Para32[0], Event))
-
-		/*
-		 * Used to start non-preferred ports if the preferred one
-		 * does not come up.
-		 * This timeout needs only be set when starting the first
-		 * (preferred) port.
-		 */
+	SK_U32			i;
 
-		if (pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0]))
 
-			/* PORT_START failed. */
+		if (Para.Para32[1] != (SK_U32)-1) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad Parameter.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n"))
+		return;
+	}
 
-			for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-				if (!pAC->Rlmt.Port[i].PortStarted) {
-					SkRlmtPortStart(pAC, IoC, i);
-				}
+	/*
+	 * Used to start non-preferred ports if the preferred one
+	 * does not come up.
+	 * This timeout needs only be set when starting the first
+	 * (preferred) port.
+	 */
+	if (pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
+		/* PORT_START failed. */
+		for (i = 0; i < pAC->Rlmt.Port[Para.Para32[0]].Net->NumPorts; i++) {
+			if (!pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortStarted) {
+				SkRlmtPortStart(pAC, IoC,
+					pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortNumber);
 			}
 		}
+	}
 
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_PORTSTART_TIMEOUT Event (%d) END.\n", Event))
-		break;
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_PORTSTART_TIMEOUT Event END.\n"))
+}	/* SkRlmtEvtPortStartTim */
 
-	case SK_RLMT_LINK_UP:		/* From SIRQ. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_LINK_UP Port %d Event (%d) BEGIN.\n",
-				Para.Para32[0], Event))
-
-		pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
-
-		if (!pRPort->PortStarted) {
-			SK_ERR_LOG(
-				pAC,
-				SK_ERRCL_SW,
-				SKERR_RLMT_E008,
-				SKERR_RLMT_E008_MSG);
-
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_CTRL,
-				("SK_RLMT_LINK_UP Event (%d) EMPTY.\n", Event))
-			break;
-		}
 
-		if (!pRPort->LinkDown) {
-			/* RA;:;: Any better solution? */
+/******************************************************************************
+ *
+ *	SkRlmtEvtLinkUp - LINK_UP
+ *
+ * Description:
+ *	This routine handles LLINK_UP events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtLinkUp(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_U32 PortNumber; SK_U32 Undefined */
+{
+	SK_U32			i;
+	SK_RLMT_PORT	*pRPort;
+	SK_EVPARA		Para2;
 
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_CTRL,
-				("SK_RLMT_LINK_UP Event (%d) EMPTY.\n", Event))
-			break;
-		}
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0]))
 
-		SkTimerStop(pAC, IoC, &pRPort->UpTimer);
-		SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
-		SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
+	pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
+	if (!pRPort->PortStarted) {
+		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG);
 
-		/* Do something if timer already fired? */
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+				("SK_RLMT_LINK_UP Event EMPTY.\n"))
+		return;
+	}
 
-		pRPort->LinkDown = SK_FALSE;
-		pRPort->PortState = SK_RLMT_PS_GOING_UP;
-		pRPort->GuTimeStamp = SkOsGetTime(pAC);
-		pRPort->BcTimeStamp = 0;
-		if (pAC->Rlmt.LinksUp == 0) {
-			SK_HWAC_LINK_LED(
-				pAC,
-				IoC,
-				Para.Para32[0],
-				SK_LED_ACTIVE);
-		}
-		else {
-			SK_HWAC_LINK_LED(
-				pAC,
-				IoC,
-				Para.Para32[0],
-				SK_LED_STANDBY);
+	if (!pRPort->LinkDown) {
+		/* RA;:;: Any better solution? */
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_LINK_UP Event EMPTY.\n"))
+		return;
+	}
+
+	SkTimerStop(pAC, IoC, &pRPort->UpTimer);
+	SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
+	SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
+
+	/* Do something if timer already fired? */
+
+	pRPort->LinkDown = SK_FALSE;
+	pRPort->PortState = SK_RLMT_PS_GOING_UP;
+	pRPort->GuTimeStamp = SkOsGetTime(pAC);
+	pRPort->BcTimeStamp = 0;
+	pRPort->Net->LinksUp++;
+	if (pRPort->Net->LinksUp == 1) {
+		SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_ACTIVE);
+	}
+	else {
+		SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
+	}
+
+	for (i = 0; i < pRPort->Net->NumPorts; i++) {
+		if (!pRPort->Net->Port[i]->PortStarted) {
+			SkRlmtPortStart(pAC, IoC, pRPort->Net->Port[i]->PortNumber);
 		}
-		pAC->Rlmt.LinksUp++;
+	}
 
-		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-			if (!pAC->Rlmt.Port[i].PortStarted) {
-				SkRlmtPortStart(pAC, IoC, i);
-			}
+	SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
+
+	if (pRPort->Net->LinksUp >= 2) {
+		if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
+			/* Build the check chain. */
+			SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
 		}
+	}
 
-		SkRlmtCheckSwitch(pAC, IoC);
+	/* If the first link comes up, start the periodical RLMT timeout. */
+	if (pRPort->Net->NumPorts > 1 && pRPort->Net->LinksUp == 1 &&
+		(pRPort->Net->RlmtMode & SK_RLMT_CHECK_OTHERS) != 0) {
+		Para2.Para32[0] = pRPort->Net->NetNumber;
+		Para2.Para32[1] = (SK_U32)-1;
+		SkTimerStart(pAC, IoC, &pRPort->Net->LocTimer,
+			pRPort->Net->TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, Para2);
+	}
 
-		if (pAC->Rlmt.LinksUp >= 2) {
-			if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
+	Para2 = Para;
+	Para2.Para32[1] = (SK_U32)-1;
+	SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
+		SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2);
+	
+	/* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */
+	if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
+		(pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 &&
+		(Para2.pParaPtr =
+			SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE,
+			&pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr)
+		) != NULL) {
+		/* Send "new" packet to RLMT multicast address. */
+		SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
+	}
+
+	if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) {
+		if ((Para2.pParaPtr =
+			SkRlmtBuildSpanningTreePacket(pAC, IoC, Para.Para32[0])) != NULL) {
+			pAC->Rlmt.Port[Para.Para32[0]].RootIdSet = SK_FALSE;
+			pRPort->Net->CheckingState |=
+				SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
 
-				/* Build the check chain. */
+			SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
 
-				SkRlmtBuildCheckChain(pAC);
-			}
+			Para.Para32[1] = (SK_U32)-1;
+			SkTimerStart(pAC, IoC, &pRPort->Net->SegTimer,
+				SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
 		}
+	}
 
-		/*
-		 * If the first link comes up, start the periodical
-		 * RLMT timeout.
-		 */
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_LINK_UP Event END.\n"))
+}	/* SkRlmtEvtLinkUp */
 
-		if (pAC->GIni.GIMacsFound > 1 && pAC->Rlmt.LinksUp == 1 &&
-			(pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_OTHERS)) {
-			SkTimerStart(
-				pAC,
-				IoC,
-				&pAC->Rlmt.LocTimer,
-				pAC->Rlmt.TimeoutValue,
-				SKGE_RLMT,
-				SK_RLMT_TIM,
-				Para);
-		}
-
-		SkTimerStart(
-			pAC,
-			IoC,
-			&pRPort->UpTimer,
-			SK_RLMT_PORTUP_TIM_VAL,
-			SKGE_RLMT,
-			SK_RLMT_PORTUP_TIM,
-			Para);
 
-		/*
-		 * Later:
-		 * if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) &&
-		 */
+/******************************************************************************
+ *
+ *	SkRlmtEvtPortUpTim - PORT_UP_TIM
+ *
+ * Description:
+ *	This routine handles PORT_UP_TIM events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtPortUpTim(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_U32 PortNumber; SK_U32 -1 */
+{
+	SK_RLMT_PORT	*pRPort;
 
-		if ((pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LINK) &&
-			(Para2.pParaPtr = SkRlmtBuildPacket(
-				pAC,
-				IoC,
-				Para.Para32[0],
-				SK_PACKET_ANNOUNCE,
-				&pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress,
-				&SkRlmtMcAddr)
-			) != NULL) {
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0]))
 
-			/* Send "new" packet to RLMT multicast address. */
+	if (Para.Para32[1] != (SK_U32)-1) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad Parameter.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_PORTUP_TIM Event EMPTY.\n"))
+		return;
+	}
 
-			SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
-		}
+	pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
+	if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0]))
+		return;
+	}
 
-		if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_SEG) {
-			if ((Para2.pParaPtr =
-				SkRlmtBuildSpanningTreePacket(
-					pAC,
-					IoC,
-					Para.Para32[0])
-				) != NULL) {
-				
-				pAC->Rlmt.Port[Para.Para32[0]].RootIdSet =
-					SK_FALSE;
-				pAC->Rlmt.CheckingState |=
-					SK_RLMT_RCS_SEG |
-					SK_RLMT_RCS_REPORT_SEG;
-				
-				SkEventQueue(
-					pAC,
-					SKGE_DRV,
-					SK_DRV_RLMT_SEND,
-					Para2);
-
-				SkTimerStart(
-					pAC,
-					IoC,
-					&pAC->Rlmt.SegTimer,
-					SK_RLMT_SEG_TO_VAL,
-					SKGE_RLMT,
-					SK_RLMT_SEG_TIM,
-					Para);
-			}
+	pRPort->PortDown = SK_FALSE;
+	pRPort->PortState = SK_RLMT_PS_UP;
+	pRPort->Net->PortsUp++;
+	if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
+		if (pAC->Rlmt.NumNets <= 1) {
+			SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
 		}
+		SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_UP, Para);
+	}
 
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_LINK_UP Event (%d) END.\n", Event))
-		break;
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_PORTUP_TIM Event END.\n"))
+}	/* SkRlmtEvtPortUpTim */
 
-	case SK_RLMT_PORTUP_TIM:	/* From RLMT via TIME. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_PORTUP_TIM Port %d Event (%d) BEGIN.\n", Para.Para32[0], Event))
-
-		pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
-
-		if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) {
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_CTRL,
-				("SK_RLMT_PORTUP_TIM Port %d Event (%d) EMPTY.\n",
-					Para.Para32[0],
-					Event))
-			break;
-		}
 
-		pRPort->PortDown = SK_FALSE;
-                pRPort->PortState = SK_RLMT_PS_UP;
-		pAC->Rlmt.PortsUp++;
+/******************************************************************************
+ *
+ *	SkRlmtEvtPortDownTim - PORT_DOWN_*
+ *
+ * Description:
+ *	This routine handles PORT_DOWN_* events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtPortDownX(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_U32		Event,	/* Event code */
+SK_EVPARA	Para)	/* SK_U32 PortNumber; SK_U32 -1 */
+{
+	SK_RLMT_PORT	*pRPort;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n",
+			Para.Para32[0], Event))
+
+	if (Para.Para32[1] != (SK_U32)-1) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad Parameter.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_PORTDOWN* Event EMPTY.\n"))
+		return;
+	}
 
-		if (pAC->Rlmt.RlmtState != SK_RLMT_RS_INIT) {
-			SkRlmtCheckSwitch(pAC, IoC);
+	pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
+	if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM &&
+		!(pRPort->CheckingState & SK_RLMT_PCS_TX))) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event))
+		return;
+	}
+	
+	/* Stop port's timers. */
+	SkTimerStop(pAC, IoC, &pRPort->UpTimer);
+	SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
+	SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
 
-			SkEventQueue(
-				pAC,
-				SKGE_PNMI,
-				SK_PNMI_EVT_RLMT_PORT_UP,
-				Para);
-		}
+	if (pRPort->PortState != SK_RLMT_PS_LINK_DOWN) {
+		pRPort->PortState = SK_RLMT_PS_DOWN;
+	}
 
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_PORTUP_TIM Event (%d) END.\n", Event))
-		break;
+	if (!pRPort->PortDown) {
+		pRPort->Net->PortsUp--;
+		pRPort->PortDown = SK_TRUE;
+		SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_DOWN, Para);
+	}
 
-	case SK_RLMT_PORTDOWN:		/* From RLMT. */
-	case SK_RLMT_PORTDOWN_RX_TIM:	/* From RLMT via TIME. */
-	case SK_RLMT_PORTDOWN_TX_TIM:	/* From RLMT via TIME. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n", Para.Para32[0], Event))
-
-		pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
-
-		if (!pRPort->PortStarted ||
-			(Event == SK_RLMT_PORTDOWN_TX_TIM &&
-			!(pRPort->CheckingState & SK_RLMT_PCS_TX))) {
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_CTRL,
-				("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event))
-			break;
+	pRPort->PacketsPerTimeSlot = 0;
+	/* pRPort->DataPacketsPerTimeSlot = 0; */
+	pRPort->BpduPacketsPerTimeSlot = 0;
+
+	/*
+	 * RA;:;: To be checked:
+	 * - actions at RLMT_STOP: We should not switch anymore.
+	 */
+	if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
+		if (Para.Para32[0] ==
+			pRPort->Net->Port[pRPort->Net->ActivePort]->PortNumber) {
+			/* Active Port went down. */
+			SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
 		}
-		/* Stop port's timers. */
+	}
 
-		SkTimerStop(pAC, IoC, &pRPort->UpTimer);
-		SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
-		SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event))
+}	/* SkRlmtEvtPortDownX */
 
-		if (pRPort->PortState != SK_RLMT_PS_LINK_DOWN) {
-			pRPort->PortState = SK_RLMT_PS_DOWN;
-		}
 
-		if (!pRPort->PortDown) {
-			pAC->Rlmt.PortsUp--;
-			pRPort->PortDown = SK_TRUE;
+/******************************************************************************
+ *
+ *	SkRlmtEvtLinkDown - LINK_DOWN
+ *
+ * Description:
+ *	This routine handles LINK_DOWN events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtLinkDown(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_U32 PortNumber; SK_U32 Undefined */
+{
+	SK_RLMT_PORT	*pRPort;
 
-			SkEventQueue(
-				pAC,
-				SKGE_PNMI,
-				SK_PNMI_EVT_RLMT_PORT_DOWN,
-				Para);
+	pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0]))
+
+	if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
+		pRPort->Net->LinksUp--;
+		pRPort->LinkDown = SK_TRUE;
+		pRPort->PortState = SK_RLMT_PS_LINK_DOWN;
+		SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_OFF);
+
+		if ((pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) != 0) {
+			/* Build the check chain. */
+			SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
 		}
 
-		pRPort->PacketsPerTimeSlot = 0;
-		pRPort->DataPacketsPerTimeSlot = 0;
-		pRPort->BpduPacketsPerTimeSlot = 0;
-#if 0
-		pRPort->RlmtChksPerTimeSlot = 0;
-		pRPort->RlmtAcksPerTimeSlot = 0;
-#endif	/* 0 */
+		/* Ensure that port is marked down. */
+		Para.Para32[1] = -1;
+		(void)SkRlmtEvent(pAC, IoC, SK_RLMT_PORTDOWN, Para);
+	}
 
-		/*
-		 * RA;:;: To be checked:
-		 * - actions at RLMT_STOP: We should not switch anymore.
-		 */
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_LINK_DOWN Event END.\n"))
+}	/* SkRlmtEvtLinkDown */
+
+
+/******************************************************************************
+ *
+ *	SkRlmtEvtPortAddr - PORT_ADDR
+ *
+ * Description:
+ *	This routine handles PORT_ADDR events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtPortAddr(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_U32 PortNumber; SK_U32 -1 */
+{
+	SK_U32			i, j;
+	SK_RLMT_PORT	*pRPort;
+	SK_MAC_ADDR		*pOldMacAddr;
+	SK_MAC_ADDR		*pNewMacAddr;
 
-		if (pAC->Rlmt.RlmtState != SK_RLMT_RS_INIT) {
-			if (Para.Para32[0] == pAC->Rlmt.MacActive) {
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0]))
 
-				/* Active Port went down. */
+	if (Para.Para32[1] != (SK_U32)-1) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad Parameter.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_PORT_ADDR Event EMPTY.\n"))
+		return;
+	}
 
-				SkRlmtCheckSwitch(pAC, IoC);
+	/* Port's physical MAC address changed. */
+	pOldMacAddr = &pAC->Addr.Port[Para.Para32[0]].PreviousMacAddress;
+	pNewMacAddr = &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress;
+
+	/*
+	 * NOTE: This is not scalable for solutions where ports are
+	 *	 checked remotely.  There, we need to send an RLMT
+	 *	 address change packet - and how do we ensure delivery?
+	 */
+	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
+		pRPort = &pAC->Rlmt.Port[i];
+		for (j = 0; j < pRPort->PortsChecked; j++) {
+			if (SK_ADDR_EQUAL(
+				pRPort->PortCheck[j].CheckAddr.a, pOldMacAddr->a)) {
+				pRPort->PortCheck[j].CheckAddr = *pNewMacAddr;
 			}
 		}
+	}
 
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event))
-		break;
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_PORT_ADDR Event END.\n"))
+}	/* SkRlmtEvtPortAddr */
 
-	case SK_RLMT_LINK_DOWN:		/* From SIRQ. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_LINK_DOWN Port %d Event (%d) BEGIN.\n",
-				Para.Para32[0], Event))
-
-		if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
-			pAC->Rlmt.LinksUp--;
-			pAC->Rlmt.Port[Para.Para32[0]].LinkDown = SK_TRUE;
-			pAC->Rlmt.Port[Para.Para32[0]].PortState =
-					SK_RLMT_PS_LINK_DOWN;
-			SK_HWAC_LINK_LED(
-				pAC,
-				IoC,
-				Para.Para32[0],
-				SK_LED_OFF);
-
-			if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
-
-				/* Build the check chain. */
-
-				SkRlmtBuildCheckChain(pAC);
-			}
-
-			/* Ensure that port is marked down. */
-
-			(void)SkRlmtEvent(
-				pAC,
-				IoC,
-				SK_RLMT_PORTDOWN,
-				Para);
-		}
-
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_LINK_DOWN Event (%d) END.\n", Event))
-		break;
 
-	case SK_RLMT_PORT_ADDR:		/* From ADDR. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_PORT_ADDR Port %d Event (%d) BEGIN.\n", Para.Para32[0], Event))
-
-		/* Port's physical MAC address changed. */
-
-		pOldMacAddr =
-			&pAC->Addr.Port[Para.Para32[0]].PreviousMacAddress;
-		pNewMacAddr =
-			&pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress;
+/******************************************************************************
+ *
+ *	SkRlmtEvtStart - START
+ *
+ * Description:
+ *	This routine handles START events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtStart(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_U32 NetNumber; SK_U32 -1 */
+{
+	SK_EVPARA	Para2;
+	SK_U32		PortIdx;
+	SK_U32		PortNumber;
 
-		/*
-		 * NOTE: This is not scalable for solutions where ports are
-		 *	 checked remotely.  There, we need to send an RLMT
-		 *	 address change packet - and how do we ensure delivery?
-		 */
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0]))
 
-		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-			pRPort = &pAC->Rlmt.Port[i];
-			for (j = 0; j < pRPort->PortsChecked; j++) {
-				if (SK_ADDR_EQUAL(
-					pRPort->PortCheck[j].CheckAddr.a,
-					pOldMacAddr->a)) {
-					pRPort->PortCheck[j].CheckAddr =
-						*pNewMacAddr;
-				}
-			}
-		}
+	if (Para.Para32[1] != (SK_U32)-1) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad Parameter.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_START Event EMPTY.\n"))
+		return;
+	}
 
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_PORT_ADDR Event (%d) END.\n", Event))
-		break;
+	if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad NetNumber %d.\n", Para.Para32[0]))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_START Event EMPTY.\n"))
+		return;
+	}
 
-	/* ----- RLMT events ----- */
+	if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_START Event EMPTY.\n"))
+		return;
+	}
 
-	case SK_RLMT_START:		/* From DRV. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_START Event (%d) BEGIN.\n", Event))
-
-		if (pAC->Rlmt.RlmtState != SK_RLMT_RS_INIT) {
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_CTRL,
-				("SK_RLMT_START Event (%d) EMPTY.\n", Event))
-			break;
-		}
+	if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("All nets should have been started.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_START Event EMPTY.\n"))
+		return;
+	}
 
-		if (pAC->Rlmt.PrefPort >= (SK_U32)pAC->GIni.GIMacsFound) {
-			SK_ERR_LOG(
-				pAC,
-				SK_ERRCL_SW,
-				SKERR_RLMT_E009,
-				SKERR_RLMT_E009_MSG);
-
-			/* Change PrefPort to internal default. */
-
-			Para.Para32[0] = 0xFFFFFFFF;
-			(void)SkRlmtEvent(
-				pAC,
-				IoC,
-				SK_RLMT_PREFPORT_CHANGE,
-				Para);
-		}
-#if 0
-		if (pAC->GIni.GIMacsFound == 1 &&
-			pAC->Rlmt.RlmtMode != SK_RLMT_CHECK_LINK) {
-			Para.Para32[0] = SK_RLMT_CHECK_LINK;
-			(void)SkRlmtEvent(
-				pAC,
-				IoC,
-				SK_RLMT_MODE_CHANGE,
-				Para);
-		}
-#endif	/* 0 */
-		pAC->Rlmt.LinksUp = 0;
-		pAC->Rlmt.PortsUp = 0;
-		pAC->Rlmt.CheckingState = 0;
-		pAC->Rlmt.RlmtState = SK_RLMT_RS_NET_DOWN;
-
-		SkRlmtPortStart(pAC, IoC, pAC->Rlmt.PrefPort);
-
-		/* Start Timer (for first port only). */
-
-		Para2.Para32[0] = pAC->Rlmt.PrefPort;
-		SkTimerStart(
-			pAC,
-			IoC,
-			&pAC->Rlmt.Port[pAC->Rlmt.PrefPort].UpTimer,
-			SK_RLMT_PORTSTART_TIM_VAL,
-			SKGE_RLMT,
-			SK_RLMT_PORTSTART_TIM,
-			Para2);
-
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_START Event (%d) END.\n", Event))
-		break;
+	if (pAC->Rlmt.Net[Para.Para32[0]].PrefPort >=
+		pAC->Rlmt.Net[Para.Para32[0]].NumPorts) {
+		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E009, SKERR_RLMT_E009_MSG);
 
-	case SK_RLMT_STOP:		/* From DRV. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_STOP Event (%d) BEGIN.\n", Event))
-
-		if (pAC->Rlmt.RlmtState == SK_RLMT_RS_INIT) {
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_CTRL,
-				("SK_RLMT_STOP Event (%d) EMPTY.\n", Event))
-			break;
-		}
+		/* Change PrefPort to internal default. */
+		Para2.Para32[0] = 0xFFFFFFFF;
+		Para2.Para32[1] = Para.Para32[0];
+		(void)SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, Para2);
+	}
 
-		/* Stop RLMT timers. */
+	PortIdx = pAC->Rlmt.Net[Para.Para32[0]].PrefPort;
+	PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[PortIdx]->PortNumber;
 
-		SkTimerStop(pAC, IoC, &pAC->Rlmt.LocTimer); 
-		SkTimerStop(pAC, IoC, &pAC->Rlmt.SegTimer);
+	pAC->Rlmt.Net[Para.Para32[0]].LinksUp = 0;
+	pAC->Rlmt.Net[Para.Para32[0]].PortsUp = 0;
+	pAC->Rlmt.Net[Para.Para32[0]].CheckingState = 0;
+	pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_NET_DOWN;
 
-		/* Stop Net. */
+	/* Start preferred port. */
+	SkRlmtPortStart(pAC, IoC, PortNumber);
 
-		pAC->Rlmt.RlmtState = SK_RLMT_RS_INIT;
-		pAC->Rlmt.RootIdSet = SK_FALSE;
-		Para2.Para32[0] = SK_RLMT_NET_DOWN_FINAL;
-		SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para2);
+	/* Start Timer (for first port only). */
+	Para2.Para32[0] = PortNumber;
+	Para2.Para32[1] = (SK_U32)-1;
+	SkTimerStart(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer,
+		SK_RLMT_PORTSTART_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTSTART_TIM, Para2);
 
-		/* Stop ports. */
+	pAC->Rlmt.NetsStarted++;
 
-		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-			if (pAC->Rlmt.Port[i].PortState != SK_RLMT_PS_INIT) {
-				SkTimerStop(
-					pAC,
-					IoC,
-					&pAC->Rlmt.Port[i].UpTimer);
-				SkTimerStop(
-					pAC,
-					IoC,
-					&pAC->Rlmt.Port[i].DownRxTimer);
-				SkTimerStop(
-					pAC,
-					IoC,
-					&pAC->Rlmt.Port[i].DownTxTimer);
-
-				pAC->Rlmt.Port[i].PortState = SK_RLMT_PS_INIT;
-				pAC->Rlmt.Port[i].RootIdSet = SK_FALSE;
-				pAC->Rlmt.Port[i].PortStarted = SK_FALSE;
-				Para2.Para32[0] = i;
-				SkEventQueue(
-					pAC,
-					SKGE_HWAC,
-					SK_HWEV_PORT_STOP,
-					Para2);
-			}
-		}
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_START Event END.\n"))
+}	/* SkRlmtEvtStart */
 
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_STOP Event (%d) END.\n", Event))
-		break;
 
-	case SK_RLMT_TIM:		/* From RLMT via TIME. */
-#if 0
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_TIM Event (%d) BEGIN.\n", Event))
-#endif	/* 0 */
+/******************************************************************************
+ *
+ *	SkRlmtEvtStop - STOP
+ *
+ * Description:
+ *	This routine handles STOP events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtStop(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_U32 NetNumber; SK_U32 -1 */
+{
+	SK_EVPARA	Para2;
+	SK_U32		PortNumber;
+	SK_U32		i;
 
-		if (!(pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_OTHERS) ||
-			pAC->Rlmt.LinksUp == 0) {
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0]))
 
-			/*
-			 * Mode changed or all links down:
-			 * No more link checking.
-			 */
+	if (Para.Para32[1] != (SK_U32)-1) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad Parameter.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_STOP Event EMPTY.\n"))
+		return;
+	}
 
-			break;
+	if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad NetNumber %d.\n", Para.Para32[0]))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_STOP Event EMPTY.\n"))
+		return;
+	}
+
+	if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_STOP Event EMPTY.\n"))
+		return;
+	}
+
+	if (pAC->Rlmt.NetsStarted == 0) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("All nets are stopped.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_STOP Event EMPTY.\n"))
+		return;
+	}
+
+	/* Stop RLMT timers. */
+	SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer); 
+	SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer);
+
+	/* Stop net. */
+	pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_INIT;
+	pAC->Rlmt.Net[Para.Para32[0]].RootIdSet = SK_FALSE;
+	Para2.Para32[0] = SK_RLMT_NET_DOWN_FINAL;
+	Para2.Para32[1] = Para.Para32[0];			/* Net# */
+	SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para2);
+
+	/* Stop ports. */
+	for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
+		PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
+		if (pAC->Rlmt.Port[PortNumber].PortState != SK_RLMT_PS_INIT) {
+			SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer);
+			SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownRxTimer);
+			SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownTxTimer);
+
+			pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_INIT;
+			pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
+			pAC->Rlmt.Port[PortNumber].PortStarted = SK_FALSE;
+			Para2.Para32[0] = PortNumber;
+			Para2.Para32[1] = (SK_U32)-1;
+			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para2);
 		}
+	}
+
+	pAC->Rlmt.NetsStarted--;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_STOP Event END.\n"))
+}	/* SkRlmtEvtStop */
+
+
+/******************************************************************************
+ *
+ *	SkRlmtEvtTim - TIM
+ *
+ * Description:
+ *	This routine handles TIM events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtTim(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_U32 NetNumber; SK_U32 -1 */
+{
+	SK_RLMT_PORT	*pRPort;
+	SK_U32			Timeout;
+	SK_U32			NewTimeout;
+	SK_U32			PortNumber;
+	SK_U32			i;
 
 #if 0
-                pAC->Rlmt.SwitchCheckCounter--;
-		if (pAC->Rlmt.SwitchCheckCounter == 0) {
-			pAC->Rlmt.SwitchCheckCounter;
-		}
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_TIM Event BEGIN.\n"))
 #endif	/* 0 */
 
-		NewTimeout = SK_RLMT_DEF_TO_VAL;
-		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-			pRPort = &pAC->Rlmt.Port[i];
-			if (!pRPort->LinkDown) {
-				Timeout = SkRlmtCheckPort(pAC, IoC, i);
-				if (Timeout < NewTimeout) {
-					NewTimeout = Timeout;
-				}
+	if (Para.Para32[1] != (SK_U32)-1) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad Parameter.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_TIM Event EMPTY.\n"))
+		return;
+	}
 
-				/*
-				 * This counter should be set to 0 for all
-				 * ports before the first frame is sent in the
-				 * next loop.
-				 */
+	if ((pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_OTHERS) == 0 ||
+		pAC->Rlmt.Net[Para.Para32[0]].LinksUp == 0) {
+		/* Mode changed or all links down: No more link checking. */
+		return;
+	}
 
-				pRPort->PacketsPerTimeSlot = 0;
-				pRPort->DataPacketsPerTimeSlot = 0;
-				pRPort->BpduPacketsPerTimeSlot = 0;
 #if 0
-				pRPort->RlmtChksPerTimeSlot = 0;
-				pRPort->RlmtAcksPerTimeSlot = 0;
+	pAC->Rlmt.SwitchCheckCounter--;
+	if (pAC->Rlmt.SwitchCheckCounter == 0) {
+		pAC->Rlmt.SwitchCheckCounter;
+	}
 #endif	/* 0 */
+
+	NewTimeout = SK_RLMT_DEF_TO_VAL;
+	for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
+		PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
+		pRPort = &pAC->Rlmt.Port[PortNumber];
+		if (!pRPort->LinkDown) {
+			Timeout = SkRlmtCheckPort(pAC, IoC, PortNumber);
+			if (Timeout < NewTimeout) {
+				NewTimeout = Timeout;
 			}
-		}
-		pAC->Rlmt.TimeoutValue = NewTimeout;
 
-		if (pAC->Rlmt.LinksUp > 1) {
 			/*
-			 * If checking remote ports, also send packets if
-			 *   (LinksUp == 1) &&
-			 *   this port checks at least one (remote) port.
+			 * These counters should be set to 0 for all ports before the
+			 * first frame is sent in the next loop.
 			 */
+			pRPort->PacketsPerTimeSlot = 0;
+			/* pRPort->DataPacketsPerTimeSlot = 0; */
+			pRPort->BpduPacketsPerTimeSlot = 0;
+		}
+	}
+	pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue = NewTimeout;
 
-			/*
-			 * Must be new loop, as SkRlmtCheckPort can request to
-			 * check segmentation when e.g. checking the last port.
-			 */
+	if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1) {
+		/*
+		 * If checking remote ports, also send packets if
+		 *   (LinksUp == 1) &&
+		 *   this port checks at least one (remote) port.
+		 */
 
-			for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-				pRPort = &pAC->Rlmt.Port[i];
-				if (!pRPort->LinkDown) {	/* !PortDown? */
-					SkRlmtSend(pAC, IoC, i);
-				}
+		/*
+		 * Must be new loop, as SkRlmtCheckPort can request to
+		 * check segmentation when e.g. checking the last port.
+		 */
+		for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
+			if (!pAC->Rlmt.Net[Para.Para32[0]].Port[i]->LinkDown) {
+				SkRlmtSend(pAC, IoC,
+					pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber);
 			}
 		}
+	}
 
-		SkTimerStart(
-			pAC,
-			IoC,
-			&pAC->Rlmt.LocTimer,
-			pAC->Rlmt.TimeoutValue,
-			SKGE_RLMT,
-			SK_RLMT_TIM,
-			Para);
-
-		if (pAC->Rlmt.LinksUp > 1 &&
-			(pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_SEG) &&
-			(pAC->Rlmt.CheckingState & SK_RLMT_RCS_START_SEG)) {
-			SkTimerStart(
-				pAC,
-				IoC,
-				&pAC->Rlmt.SegTimer,
-				SK_RLMT_SEG_TO_VAL,
-				SKGE_RLMT,
-				SK_RLMT_SEG_TIM,
-				Para);
-			pAC->Rlmt.CheckingState &=
-				~SK_RLMT_RCS_START_SEG;
-			pAC->Rlmt.CheckingState |=
-				SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
-		}
+	SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer,
+		pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue, SKGE_RLMT, SK_RLMT_TIM,
+		Para);
+
+	if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1 &&
+		(pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_SEG) &&
+		(pAC->Rlmt.Net[Para.Para32[0]].CheckingState & SK_RLMT_RCS_START_SEG)) {
+		SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer,
+			SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
+		pAC->Rlmt.Net[Para.Para32[0]].CheckingState &= ~SK_RLMT_RCS_START_SEG;
+		pAC->Rlmt.Net[Para.Para32[0]].CheckingState |=
+			SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
+	}
 
 #if 0
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_TIM Event (%d) END.\n", Event))
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_TIM Event END.\n"))
 #endif	/* 0 */
-		break;
+}	/* SkRlmtEvtTim */
 
-	case SK_RLMT_SEG_TIM:
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_SEG_TIM Event (%d) BEGIN.\n", Event))
 
-#ifdef DEBUG
-		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-			SK_U8		InAddr8[6];
-			SK_U16		*InAddr;
-			SK_ADDR_PORT	*pAPort;
-
-			InAddr = (SK_U16 *)&InAddr8[0];
-			pAPort = &pAC->Addr.Port[i];
-			for (j = 0;
-				j < pAPort->NextExactMatchRlmt;
-				j++) {
-
-				/* Get exact match address j from port i. */
-
-				XM_INADDR(IoC, i, XM_EXM(j), InAddr);
-				SK_DBG_MSG(
-					pAC,
-					SK_DBGMOD_RLMT,
-					SK_DBGCAT_CTRL,
-					("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x --  %02x %02x %02x %02x %02x %02x.\n",
-						j,
-       						i,
-       						InAddr8[0],
-       						InAddr8[1],
-       						InAddr8[2],
-       						InAddr8[3],
-       						InAddr8[4],
-       						InAddr8[5],
-						pAPort->Exact[j].a[0],
-						pAPort->Exact[j].a[1],
-						pAPort->Exact[j].a[2],
-						pAPort->Exact[j].a[3],
-						pAPort->Exact[j].a[4],
-						pAPort->Exact[j].a[5]))
-			}
+/******************************************************************************
+ *
+ *	SkRlmtEvtSegTim - SEG_TIM
+ *
+ * Description:
+ *	This routine handles SEG_TIM events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtSegTim(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_U32 NetNumber; SK_U32 -1 */
+{
+#ifdef XDEBUG
+	int j;
+#endif	/* DEBUG */
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_SEG_TIM Event BEGIN.\n"))
+
+	if (Para.Para32[1] != (SK_U32)-1) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad Parameter.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_SEG_TIM Event EMPTY.\n"))
+		return;
+	}
+
+#ifdef xDEBUG
+	for (j = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; j++) {
+		SK_ADDR_PORT	*pAPort;
+		SK_U32			k;
+		SK_U16			*InAddr;
+		SK_U8			InAddr8[6];
+
+		InAddr = (SK_U16 *)&InAddr8[0];
+		pAPort = pAC->Rlmt.Net[Para.Para32[0]].Port[j]->AddrPort;
+		for (k = 0; k < pAPort->NextExactMatchRlmt; k++) {
+			/* Get exact match address k from port j. */
+			XM_INADDR(IoC, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
+				XM_EXM(k), InAddr);
+			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+				("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x --  %02x %02x %02x %02x %02x %02x.\n",
+					k, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
+					InAddr8[0], InAddr8[1], InAddr8[2],
+					InAddr8[3], InAddr8[4], InAddr8[5],
+					pAPort->Exact[k].a[0], pAPort->Exact[k].a[1],
+					pAPort->Exact[k].a[2], pAPort->Exact[k].a[3],
+					pAPort->Exact[k].a[4], pAPort->Exact[k].a[5]))
 		}
+	}
 #endif	/* DEBUG */
 				   
-		pAC->Rlmt.CheckingState &= ~SK_RLMT_RCS_SEG;
+	SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]);
 
-		SkRlmtCheckSeg(pAC, IoC);
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_SEG_TIM Event END.\n"))
+}	/* SkRlmtEvtSegTim */
 
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_SEG_TIM Event (%d) END.\n", Event))
-		break;
 
-	case SK_RLMT_PACKET_RECEIVED:	/* From DRV. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_PACKET_RECEIVED Event (%d) BEGIN.\n", Event))
+/******************************************************************************
+ *
+ *	SkRlmtEvtPacketRx - PACKET_RECEIVED
+ *
+ * Description:
+ *	This routine handles PACKET_RECEIVED events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtPacketRx(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_MBUF *pMb */
+{
+	SK_MBUF	*pMb;
+	SK_MBUF	*pNextMb;
+	SK_U32	NetNumber;
+
+#if 0
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n"))
+#endif	/* 0 */
 
-		/* Should we ignore frames during port switching? */
+	/* Should we ignore frames during port switching? */
 
 #ifdef DEBUG
-		pMb = Para.pParaPtr;
-		if (pMb == NULL) {
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_CTRL,
-				("No mbuf.\n"))
-		}
-		else if (pMb->pNext != NULL) {
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_CTRL,
-				("More than one mbuf or pMb->pNext not set.\n"))
-		}
+	pMb = Para.pParaPtr;
+	if (pMb == NULL) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n"))
+	}
+	else if (pMb->pNext != NULL) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("More than one mbuf or pMb->pNext not set.\n"))
+	}
 #endif	/* DEBUG */
 
-		for (pMb = Para.pParaPtr; pMb != NULL; pMb = pNextMb) {
-			pNextMb = pMb->pNext;
-			pMb->pNext = NULL;
+	for (pMb = Para.pParaPtr; pMb != NULL; pMb = pNextMb) {
+		pNextMb = pMb->pNext;
+		pMb->pNext = NULL;
+
+		NetNumber = pAC->Rlmt.Port[pMb->PortIdx].Net->NetNumber;
+		if (pAC->Rlmt.Net[NetNumber].RlmtState == SK_RLMT_RS_INIT) {
+			SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+		}
+		else {
 			SkRlmtPacketReceive(pAC, IoC, pMb);
 		}
+	}
 
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_PACKET_RECEIVED Event (%d) END.\n", Event))
-		break;
+#if 0
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_PACKET_RECEIVED Event END.\n"))
+#endif	/* 0 */
+}	/* SkRlmtEvtPacketRx */
 
-	case SK_RLMT_STATS_CLEAR:	/* From PNMI. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_STATS_CLEAR Event (%d) BEGIN.\n", Event))
 
-		/* Clear statistics for virtual and physical ports. */
+/******************************************************************************
+ *
+ *	SkRlmtEvtStatsClear - STATS_CLEAR
+ *
+ * Description:
+ *	This routine handles STATS_CLEAR events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtStatsClear(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_U32 NetNumber; SK_U32 -1 */
+{
+	SK_U32			i;
+	SK_RLMT_PORT	*pRPort;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_STATS_CLEAR Event BEGIN.\n"))
 
-		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-			pAC->Rlmt.Port[i].TxHelloCts = 0;
-			pAC->Rlmt.Port[i].RxHelloCts = 0;
-			pAC->Rlmt.Port[i].TxSpHelloReqCts = 0;
-			pAC->Rlmt.Port[i].RxSpHelloCts = 0;
-		}
+	if (Para.Para32[1] != (SK_U32)-1) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad Parameter.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
+		return;
+	}
 
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_STATS_CLEAR Event (%d) END.\n", Event))
-		break;
+	if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad NetNumber %d.\n", Para.Para32[0]))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
+		return;
+	}
+
+	/* Clear statistics for logical and physical ports. */
+	for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
+		pRPort =
+			&pAC->Rlmt.Port[pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber];
+		pRPort->TxHelloCts = 0;
+		pRPort->RxHelloCts = 0;
+		pRPort->TxSpHelloReqCts = 0;
+		pRPort->RxSpHelloCts = 0;
+	}
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_STATS_CLEAR Event END.\n"))
+}	/* SkRlmtEvtStatsClear */
+
+
+/******************************************************************************
+ *
+ *	SkRlmtEvtStatsUpdate - STATS_UPDATE
+ *
+ * Description:
+ *	This routine handles STATS_UPDATE events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtStatsUpdate(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_U32 NetNumber; SK_U32 -1 */
+{
+	if (Para.Para32[1] != (SK_U32)-1) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad Parameter.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
+		return;
+	}
+
+	if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad NetNumber %d.\n", Para.Para32[0]))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
+		return;
+	}
 
-	case SK_RLMT_STATS_UPDATE:	/* From PNMI. */
 #if 0
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_STATS_UPDATE Event (%d) BEGIN.\n", Event))
-
-		/* Update statistics. */
-
-		/* Currently always up-to-date. */
-
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_STATS_UPDATE Event (%d) END.\n", Event))
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_STATS_UPDATE Event BEGIN.\n"))
+
+	/* Update statistics - currently always up-to-date. */
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_STATS_UPDATE Event END.\n"))
 #endif	/* 0 */
-		break;
+}	/* SkRlmtEvtStatsUpdate */
 
-	case SK_RLMT_PREFPORT_CHANGE:	/* From PNMI. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_PREFPORT_CHANGE to Port %d Event (%d) BEGIN.\n", Para.Para32[0], Event))
 
-		/* 0xFFFFFFFF == auto-mode. */
+/******************************************************************************
+ *
+ *	SkRlmtEvtPrefportChange - PREFPORT_CHANGE
+ *
+ * Description:
+ *	This routine handles PREFPORT_CHANGE events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtPrefportChange(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_U32 PortIndex; SK_U32 NetNumber */
+{
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0]))
+
+	if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad NetNumber %d.\n", Para.Para32[1]))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
+		return;
+	}
 
-		if (Para.Para32[0] == 0xFFFFFFFF) {
-			pAC->Rlmt.PrefPort = SK_RLMT_DEF_PREF_PORT;
-		}
-		else {
-			if (Para.Para32[0] >= (SK_U32)pAC->GIni.GIMacsFound) {
-				SK_ERR_LOG(
-					pAC,
-					SK_ERRCL_SW,
-					SKERR_RLMT_E010,
-					SKERR_RLMT_E010_MSG);
-
-				SK_DBG_MSG(
-					pAC,
-					SK_DBGMOD_RLMT,
-					SK_DBGCAT_CTRL,
-					("SK_RLMT_PREFPORT_CHANGE Event (%d) EMPTY.\n", Event))
-				break;
-			}
+	/* 0xFFFFFFFF == auto-mode. */
+	if (Para.Para32[0] == 0xFFFFFFFF) {
+		pAC->Rlmt.Net[Para.Para32[1]].PrefPort = SK_RLMT_DEF_PREF_PORT;
+	}
+	else {
+		if (Para.Para32[0] >= pAC->Rlmt.Net[Para.Para32[1]].NumPorts) {
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG);
 
-			pAC->Rlmt.PrefPort = Para.Para32[0];
+			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+				("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
+			return;
 		}
 
-		pAC->Rlmt.MacPreferred = Para.Para32[0];
+		pAC->Rlmt.Net[Para.Para32[1]].PrefPort = Para.Para32[0];
+	}
 
-		SkRlmtCheckSwitch(pAC, IoC);
+	pAC->Rlmt.Net[Para.Para32[1]].Preference = Para.Para32[0];
 
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_PREFPORT_CHANGE Event (%d) END.\n", Event))
-		break;
+	if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
+		SkRlmtCheckSwitch(pAC, IoC, Para.Para32[1]);
+	}
 
-	case SK_RLMT_MODE_CHANGE:	/* From PNMI. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_MODE_CHANGE Event (%d) BEGIN.\n", Event))
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_PREFPORT_CHANGE Event END.\n"))
+}	/* SkRlmtEvtPrefportChange */
 
-		if (pAC->GIni.GIMacsFound < 2) {
-			pAC->Rlmt.RlmtMode = SK_RLMT_CHECK_LINK;
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_CTRL,
-				("Forced RLMT mode to CLS on single link adapter.\n"))
-			SK_DBG_MSG(
-				pAC,
-				SK_DBGMOD_RLMT,
-				SK_DBGCAT_CTRL,
-				("SK_RLMT_MODE_CHANGE Event (%d) EMPTY.\n",
-					Event))
-			break;
+
+/******************************************************************************
+ *
+ *	SkRlmtEvtSetNets - SET_NETS
+ *
+ * Description:
+ *	This routine handles SET_NETS events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtSetNets(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_U32 NumNets; SK_U32 -1 */
+{
+	int i;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_SET_NETS Event BEGIN.\n"))
+
+	if (Para.Para32[1] != (SK_U32)-1) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad Parameter.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_SET_NETS Event EMPTY.\n"))
+		return;
+	}
+
+	if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS ||
+		Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad number of nets: %d.\n", Para.Para32[0]))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_SET_NETS Event EMPTY.\n"))
+		return;
+	}
+
+	if (Para.Para32[0] == pAC->Rlmt.NumNets) {	/* No change. */
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_SET_NETS Event EMPTY.\n"))
+		return;
+	}
+
+	/* Entering and leaving dual mode only allowed while nets are stopped. */
+	if (pAC->Rlmt.NetsStarted > 0) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Changing dual mode only allowed while all nets are stopped.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_SET_NETS Event EMPTY.\n"))
+		return;
+	}
+
+	if (Para.Para32[0] == 1) {
+		if (pAC->Rlmt.NumNets > 1) {
+			/* Clear logical MAC addr from second net's active port. */
+			(void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
+				Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_CLEAR_LOGICAL);
+			pAC->Rlmt.Net[1].NumPorts = 0;
+		}
+
+		pAC->Rlmt.NumNets = Para.Para32[0];
+		for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
+			pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
+			pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
+			pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;	  /* "Automatic" */
+			pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
+			/* Just assuming. */
+			pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
+			pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
+			pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
+			pAC->Rlmt.Net[i].NetNumber = i;
+		}
+
+		pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[0];
+		pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
+
+		SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
+
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("RLMT: Changed to one net with two ports.\n"))
+	}
+	else if (Para.Para32[0] == 2) {
+		pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1];
+		pAC->Rlmt.Net[1].NumPorts = pAC->GIni.GIMacsFound - 1;
+		pAC->Rlmt.Net[0].NumPorts =
+			pAC->GIni.GIMacsFound - pAC->Rlmt.Net[1].NumPorts;
+		
+		pAC->Rlmt.NumNets = Para.Para32[0];
+		for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
+			pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
+			pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
+			pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;	  /* "Automatic" */
+			pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
+			/* Just assuming. */
+			pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
+			pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
+			pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
+
+			pAC->Rlmt.Net[i].NetNumber = i;
+		}
+
+		/* Set logical MAC addr on second net's active port. */
+		(void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
+			Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_SET_LOGICAL);
+
+		SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
+
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("RLMT: Changed to two nets with one port each.\n"))
+	}
+	else {
+		/* Not implemented for more than two nets. */
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SetNets not implemented for more than two nets.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_SET_NETS Event EMPTY.\n"))
+		return;
+	}
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_SET_NETS Event END.\n"))
+}	/* SkRlmtSetNets */
+
+
+/******************************************************************************
+ *
+ *	SkRlmtEvtModeChange - MODE_CHANGE
+ *
+ * Description:
+ *	This routine handles MODE_CHANGE events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	Nothing
+ */
+RLMT_STATIC void	SkRlmtEvtModeChange(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_EVPARA	Para)	/* SK_U32 NewMode; SK_U32 NetNumber */
+{
+	SK_EVPARA	Para2;
+	SK_U32		i;
+	SK_U32		PrevRlmtMode;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+		("SK_RLMT_MODE_CHANGE Event BEGIN.\n"))
+
+	if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Bad NetNumber %d.\n", Para.Para32[1]))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
+		return;
+	}
+
+	Para.Para32[0] |= SK_RLMT_CHECK_LINK;
+
+	if (pAC->Rlmt.Net[Para.Para32[1]].NumPorts < 2 &&
+		Para.Para32[0] != SK_RLMT_MODE_CLS) {
+		pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS;
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("Forced RLMT mode to CLS on single port net.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
+		return;
+	}
+
+	/* Update RLMT mode. */
+	PrevRlmtMode = pAC->Rlmt.Net[Para.Para32[1]].RlmtMode;
+	pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = Para.Para32[0];
+
+	if ((PrevRlmtMode & SK_RLMT_CHECK_LOC_LINK) !=
+		(pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
+		/* SK_RLMT_CHECK_LOC_LINK bit changed. */
+		if ((PrevRlmtMode & SK_RLMT_CHECK_OTHERS) == 0 &&
+			pAC->Rlmt.Net[Para.Para32[1]].NumPorts > 1 &&
+			pAC->Rlmt.Net[Para.Para32[1]].PortsUp >= 1) {
+			/* 20001207 RA: Was "PortsUp == 1". */
+			Para2.Para32[0] = Para.Para32[1];
+			Para2.Para32[1] = (SK_U32)-1;
+			SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].LocTimer,
+				pAC->Rlmt.Net[Para.Para32[1]].TimeoutValue,
+				SKGE_RLMT, SK_RLMT_TIM, Para2);
 		}
+	}
 
-		/* Update RLMT mode. */
+	if ((PrevRlmtMode & SK_RLMT_CHECK_SEG) !=
+		(pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG)) {
+		/* SK_RLMT_CHECK_SEG bit changed. */
+		for (i = 0; i < pAC->Rlmt.Net[Para.Para32[1]].NumPorts; i++) {
+			(void)SkAddrMcClear(pAC, IoC,
+				pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
+				SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
 
-		PrevRlmtMode = pAC->Rlmt.RlmtMode;
-		pAC->Rlmt.RlmtMode = Para.Para32[0] | SK_RLMT_CHECK_LINK;
+			/* Add RLMT MC address. */
+			(void)SkAddrMcAdd(pAC, IoC,
+				pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
+				&SkRlmtMcAddr, SK_ADDR_PERMANENT);
 
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("RLMT: Changed Mode to %X.\n", pAC->Rlmt.RlmtMode))
-
-		if ((PrevRlmtMode & SK_RLMT_CHECK_LOC_LINK) !=
-			(pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
-			if (!(PrevRlmtMode & SK_RLMT_CHECK_OTHERS) &&
-				pAC->GIni.GIMacsFound > 1 &&
-				pAC->Rlmt.PortsUp == 1) {
-				SkTimerStart(
-					pAC,
-					IoC,
-					&pAC->Rlmt.LocTimer,
-					pAC->Rlmt.TimeoutValue,
-					SKGE_RLMT,
-					SK_RLMT_TIM,
-					Para);
-			}
-		}
-
-		if ((PrevRlmtMode & SK_RLMT_CHECK_SEG) !=
-			(pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_SEG)) {
-
-			for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-				(void)SkAddrMcClear(
-					pAC,
-					IoC,
-					i,
-					SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
-
-				/* Add RLMT MC address. */
-
-				(void)SkAddrMcAdd(
-					pAC,
-					IoC,
-					i,
-					&SkRlmtMcAddr,
-					SK_ADDR_PERMANENT);
-
-				if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_SEG) {
-					/* Add BPDU MC address. */
-
-					(void)SkAddrMcAdd(
-						pAC,
-						IoC,
-						i,
-						&BridgeMcAddr,
-						SK_ADDR_PERMANENT);
-
-					if (pAC->Rlmt.RlmtState !=
-						SK_RLMT_RS_INIT) {
-						if (!pAC->Rlmt.Port[i].LinkDown &&
-							(Para2.pParaPtr =
-							SkRlmtBuildSpanningTreePacket(
-								pAC,
-								IoC,
-								i)
-							) != NULL) {
-							
-							pAC->Rlmt.Port[i
-								].RootIdSet =
-								SK_FALSE;
-
-							SkEventQueue(
-								pAC,
-								SKGE_DRV,
-								SK_DRV_RLMT_SEND,
-								Para2);
-						}
+			if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode &
+				SK_RLMT_CHECK_SEG) != 0) {
+				/* Add BPDU MC address. */
+				(void)SkAddrMcAdd(pAC, IoC,
+					pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
+					&BridgeMcAddr, SK_ADDR_PERMANENT);
+
+				if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
+					if (!pAC->Rlmt.Net[Para.Para32[1]].Port[i]->LinkDown &&
+						(Para2.pParaPtr = SkRlmtBuildSpanningTreePacket(
+						pAC, IoC, i)) != NULL) {
+						pAC->Rlmt.Net[Para.Para32[1]].Port[i]->RootIdSet =
+							SK_FALSE;
+						SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
 					}
 				}
-
-				(void)SkAddrMcUpdate(pAC, IoC, i);
 			}
+			(void)SkAddrMcUpdate(pAC, IoC,
+				pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber);
+		}	/* for ... */
+
+		if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG) != 0) {
+			Para2.Para32[0] = Para.Para32[1];
+			Para2.Para32[1] = (SK_U32)-1;
+			SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].SegTimer,
+				SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para2);
+		}
+	}	/* SK_RLMT_CHECK_SEG bit changed. */
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+			("SK_RLMT_MODE_CHANGE Event END.\n"))
+}	/* SkRlmtEvtModeChange */
 
-			if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_SEG) {
-				SkTimerStart(
-					pAC,
-					IoC,
-					&pAC->Rlmt.SegTimer,
-					SK_RLMT_SEG_TO_VAL,
-					SKGE_RLMT,
-					SK_RLMT_SEG_TIM,
-					Para);
-			}
-		}
 
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
-			("SK_RLMT_MODE_CHANGE Event (%d) END.\n", Event))
+/******************************************************************************
+ *
+ *	SkRlmtEvent - a PORT- or an RLMT-specific event happened
+ *
+ * Description:
+ *	This routine calls subroutines to handle PORT- and RLMT-specific events.
+ *
+ * Context:
+ *	runtime, pageable?
+ *	may be called after SK_INIT_IO
+ *
+ * Returns:
+ *	0
+ */
+int	SkRlmtEvent(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_U32		Event,	/* Event code */
+SK_EVPARA	Para)	/* Event-specific parameter */
+{
+	switch (Event) {
+	
+	/* ----- PORT events ----- */
+
+	case SK_RLMT_PORTSTART_TIM:	/* From RLMT via TIME. */
+		SkRlmtEvtPortStartTim(pAC, IoC, Para);
+		break;
+	case SK_RLMT_LINK_UP:		/* From SIRQ. */
+		SkRlmtEvtLinkUp(pAC, IoC, Para);
+		break;
+	case SK_RLMT_PORTUP_TIM:	/* From RLMT via TIME. */
+		SkRlmtEvtPortUpTim(pAC, IoC, Para);
 		break;
+	case SK_RLMT_PORTDOWN:			/* From RLMT. */
+	case SK_RLMT_PORTDOWN_RX_TIM:	/* From RLMT via TIME. */
+	case SK_RLMT_PORTDOWN_TX_TIM:	/* From RLMT via TIME. */
+		SkRlmtEvtPortDownX(pAC, IoC, Event, Para);
+		break;
+	case SK_RLMT_LINK_DOWN:		/* From SIRQ. */
+		SkRlmtEvtLinkDown(pAC, IoC, Para);
+		break;
+	case SK_RLMT_PORT_ADDR:		/* From ADDR. */
+		SkRlmtEvtPortAddr(pAC, IoC, Para);
+		break;
+
+	/* ----- RLMT events ----- */
+
+	case SK_RLMT_START:		/* From DRV. */
+		SkRlmtEvtStart(pAC, IoC, Para);
+		break;
+	case SK_RLMT_STOP:		/* From DRV. */
+		SkRlmtEvtStop(pAC, IoC, Para);
+		break;
+	case SK_RLMT_TIM:		/* From RLMT via TIME. */
+		SkRlmtEvtTim(pAC, IoC, Para);
+		break;
+	case SK_RLMT_SEG_TIM:
+		SkRlmtEvtSegTim(pAC, IoC, Para);
+		break;
+	case SK_RLMT_PACKET_RECEIVED:	/* From DRV. */
+		SkRlmtEvtPacketRx(pAC, IoC, Para);
+		break;
+	case SK_RLMT_STATS_CLEAR:	/* From PNMI. */
+		SkRlmtEvtStatsClear(pAC, IoC, Para);
+		break;
+	case SK_RLMT_STATS_UPDATE:	/* From PNMI. */
+		SkRlmtEvtStatsUpdate(pAC, IoC, Para);
+		break;
+	case SK_RLMT_PREFPORT_CHANGE:	/* From PNMI. */
+		SkRlmtEvtPrefportChange(pAC, IoC, Para);
+		break;
+	case SK_RLMT_MODE_CHANGE:	/* From PNMI. */
+		SkRlmtEvtModeChange(pAC, IoC, Para);
+		break;
+	case SK_RLMT_SET_NETS:	/* From DRV. */
+		SkRlmtEvtSetNets(pAC, IoC, Para);
+		break;
+
+	/* ----- Unknown events ----- */
 
 	default:	/* Create error log entry. */
-		SK_DBG_MSG(
-			pAC,
-			SK_DBGMOD_RLMT,
-			SK_DBGCAT_CTRL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
 			("Unknown RLMT Event %d.\n", Event))
-
-		SK_ERR_LOG(
-			pAC,
-			SK_ERRCL_SW,
-			SKERR_RLMT_E003,
-			SKERR_RLMT_E003_MSG);
+		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG);
 		break;
-	}
+	}	/* switch() */
 
 	return (0);       
 }	/* SkRlmtEvent */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/sktimer.c linux/drivers/net/sk98lin/sktimer.c
--- v2.4.6/linux/drivers/net/sk98lin/sktimer.c	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/sktimer.c	Wed Jul  4 11:50:39 2001
@@ -1,23 +1,32 @@
 /******************************************************************************
  *
  * Name:	sktimer.c
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.12 $
- * Date:	$Date: 1999/11/22 13:38:51 $
+ * Project:	PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 1.11 $
+ * Date:	$Date: 1998/12/17 13:24:13 $
  * Purpose:	High level timer functions.
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
+ *	(C)Copyright 1989-1998 SysKonnect,
  *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	All Rights Reserved
  *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
+ *	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT
+ *	The copyright notice above does not evidence any
+ *	actual or intended publication of such source code.
+ *
+ *	This Module contains Proprietary Information of SysKonnect
+ *	and should be treated as Confidential.
+ *
+ *	The information in this file is provided for the exclusive use of
+ *	the licensees of SysKonnect.
+ *	Such users have the right to use, modify, and incorporate this code
+ *	into products for purposes authorized by the license agreement
+ *	provided they include this notice and the associated copyright notice
+ *	with any such product.
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -27,9 +36,6 @@
  * History:
  *
  *	$Log: sktimer.c,v $
- *	Revision 1.12  1999/11/22 13:38:51  cgoos
- *	Changed license header to GPL.
- *	
  *	Revision 1.11  1998/12/17 13:24:13  gklug
  *	fix: restart problem: do NOT destroy timer queue if init 1 is done
  *	
@@ -76,7 +82,7 @@
 	Event queue and dispatcher
 */
 static const char SysKonnectFileId[] =
-	"$Header: /usr56/projects/ge/schedule/sktimer.c,v 1.12 1999/11/22 13:38:51 cgoos Exp $" ;
+	"$Header: /usr56/projects/ge/schedule/sktimer.c,v 1.11 1998/12/17 13:24:13 gklug Exp $" ;
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
 #include "h/skdrv2nd.h"		/* Adapter Control- and Driver specific Def. */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/skvpd.c linux/drivers/net/sk98lin/skvpd.c
--- v2.4.6/linux/drivers/net/sk98lin/skvpd.c	Fri Sep 15 14:34:19 2000
+++ linux/drivers/net/sk98lin/skvpd.c	Wed Jul  4 11:50:39 2001
@@ -2,15 +2,15 @@
  *
  * Name:	skvpd.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.27 $
- * Date:	$Date: 2000/08/10 11:29:06 $
+ * Version:	$Revision: 1.26 $
+ * Date:	$Date: 2000/06/13 08:00:01 $
  * Purpose:	Shared software to read and write VPD data
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2000 SysKonnect,
+ *	(C)Copyright 1998,1999 SysKonnect,
  *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -27,12 +27,6 @@
  * History:
  *
  *	$Log: skvpd.c,v $
- *	Revision 1.27  2000/08/10 11:29:06  rassmann
- *	Editorial changes.
- *	Preserving 32-bit alignment in structs for the adapter context.
- *	Removed unused function VpdWriteDword() (#if 0).
- *	Made VpdReadKeyword() available for SKDIAG only.
- *	
  *	Revision 1.26  2000/06/13 08:00:01  mkarl
  *	additional cast to avoid compile problems in 64 bit environment
  *	
@@ -72,7 +66,7 @@
  *	
  *	Revision 1.14  1998/10/28 07:20:38  gklug
  *	chg: Interface functions to use IoC as parameter as well
- *	fix: VpdRead/WriteDWord now returns SK_U32
+ *	fix: VpdRead/WriteDWord now return SK_U32
  *	chg: VPD_IN/OUT names conform to SK_IN/OUT
  *	add: usage of VPD_IN/OUT8 macros
  *	add: VpdRead/Write Stream functions to r/w a stream of data
@@ -130,7 +124,7 @@
 	Please refer skvpd.txt for infomation how to include this module
  */
 static const char SysKonnectFileId[] =
-	"@(#)$Id: skvpd.c,v 1.27 2000/08/10 11:29:06 rassmann Exp $ (C) SK";
+	"@(#)$Id: skvpd.c,v 1.26 2000/06/13 08:00:01 mkarl Exp $ (C) SK" ;
 
 #include "h/skdrv1st.h"
 #include "h/sktypes.h"
@@ -144,9 +138,9 @@
 static SK_VPD_PARA	*vpd_find_para(
 	SK_AC	*pAC,
 	char		*key,
-	SK_VPD_PARA *p);
+	SK_VPD_PARA *p) ;
 #else	/* SK_KR_PROTO */
-static SK_VPD_PARA	*vpd_find_para();
+static SK_VPD_PARA	*vpd_find_para() ;
 #endif	/* SK_KR_PROTO */
 
 /*
@@ -161,29 +155,28 @@
 SK_IOC		IoC,	/* IO Context */
 int		event)	/* event to wait for (VPD_READ / VPD_write) completion*/
 {
-	SK_U64	start_time;
-	SK_U16	state;
+	SK_U64	start_time ;
+	SK_U16	state ;
 
 	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
-		("vpd wait for %s\n",event?"Write":"Read"));
-	start_time = SkOsGetTime(pAC);
+		("vpd wait for %s\n",event?"Write":"Read")) ;
+	start_time = SkOsGetTime(pAC) ;
 	do {
 		if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC/16) {
-			VPD_STOP(pAC,IoC);
+			VPD_STOP(pAC,IoC) ;
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,
 				SK_DBGCAT_FATAL|SK_DBGCAT_ERR,
-				("ERROR:vpd wait timeout\n"));
-			return(1);
+				("ERROR:vpd wait timeout\n")) ;
+			return(1) ;
 		}
-		VPD_IN16(pAC,IoC,PCI_VPD_ADR_REG,&state);
+		VPD_IN16(pAC,IoC,PCI_VPD_ADR_REG,&state) ;
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
-			("state = %x, event %x\n",state,event));
-	} while((int)(state & PCI_VPD_FLAG) == event);
+			("state = %x, event %x\n",state,event)) ;
+	} while((int)(state & PCI_VPD_FLAG) == event) ;
 
-	return(0);
+	return(0) ;
 }
 
-#ifdef SKDIAG
 
 /*
  * Read the dword at address 'addr' from the VPD EEPROM.
@@ -200,31 +193,27 @@
 SK_IOC		IoC,	/* IO Context */
 int		addr)	/* VPD address */
 {
-	SK_U32	Rtv;
+	SK_U32	Rtv ;
 
 	/* start VPD read */
 	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
-		("vpd read dword at 0x%x\n",addr));
-	addr &= ~VPD_WRITE;		/* ensure the R/W bit is set to read */
+		("vpd read dword at 0x%x\n",addr)) ;
+	addr &= ~VPD_WRITE ;		/* ensure the R/W bit is set to read */
 
-	VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, (SK_U16) addr);
+	VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, (SK_U16) addr) ;
 
 	/* ignore return code here */
-	(void)VpdWait(pAC,IoC,VPD_READ);
+	(void)VpdWait(pAC,IoC,VPD_READ) ;
 
 	/* Don't swap here, it's a data stream of bytes */
-	Rtv = 0;
+	Rtv = 0 ;
 
-	VPD_IN32(pAC,IoC,PCI_VPD_DAT_REG,&Rtv);
+	VPD_IN32(pAC,IoC,PCI_VPD_DAT_REG,&Rtv) ;
 	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
-		("vpd read dword data = 0x%x\n",Rtv));
-	return (Rtv);
+		("vpd read dword data = 0x%x\n",Rtv)) ;
+	return (Rtv) ;
 }
 
-#endif	// SKDIAG
-
-#if 0
-
 /*
 	Write the dword 'data' at address 'addr' into the VPD EEPROM, and
 	verify that the data is written.
@@ -244,8 +233,8 @@
 
 
  Returns	0:	success
-			1:	error,	I2C transfer does not terminate
-			2:	error,	data verify error
+		1:	error,	I2C transfer does not terminate
+		2:	error,	data verify error
 
  */
 static int	VpdWriteDWord(
@@ -257,30 +246,28 @@
 	/* start VPD write */
 	/* Don't swap here, it's a data stream of bytes */
 	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
-		("vpd write dword at addr 0x%x, data = 0x%x\n",addr,data));
-	VPD_OUT32(pAC,IoC,PCI_VPD_DAT_REG, (SK_U32)data);
+		("vpd write dword at addr 0x%x, data = 0x%x\n",addr,data)) ;
+	VPD_OUT32(pAC,IoC,PCI_VPD_DAT_REG, (SK_U32)data) ;
 	/* But do it here */
-	addr |= VPD_WRITE;
+	addr |= VPD_WRITE ;
 
-	VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, (SK_U16)(addr | VPD_WRITE));
+	VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, (SK_U16)(addr | VPD_WRITE)) ;
 
 	/* this may take up to 10,6 ms */
 	if (VpdWait(pAC,IoC,VPD_WRITE)) {
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-			("Write Timed Out\n"));
-		return(1);
-	};
+			("Write Timed Out\n")) ;
+		return(1) ;
+	} ;
 
 	/* verify data */
 	if (VpdReadDWord(pAC,IoC,addr) != data) {
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR|SK_DBGCAT_FATAL,
-			("Data Verify Error\n"));
-		return(2);
+			("Data Verify Error\n")) ;
+		return(2) ;
 	}
-	return(0);
-}	/* VpdWriteDWord */
-
-#endif	/* 0 */
+	return(0) ;
+}
 
 /*
  *	Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
@@ -295,12 +282,12 @@
 int		Addr,	/* VPD start address */
 int		Len)	/* number of bytes to read / to write */
 {
-	int		i;
-	int		j;
-	SK_U16		AdrReg;
-	int		Rtv;
+	int		i ;
+	int		j ;
+	SK_U16		AdrReg ;
+	int		Rtv ;
 	SK_U8		* pComp;	/* Compare pointer */
-	SK_U8		Data;		/* Input Data for Compare */
+	SK_U8		Data ;		/* Input Data for Compare */
 
 	/* Init Compare Pointer */
 	pComp = (SK_U8 *) buf;
@@ -312,56 +299,56 @@
 			 * So it is initialized even if only a few bytes
 			 * are written.
 			 */
-			AdrReg = (SK_U16) Addr;
-			AdrReg &= ~VPD_WRITE;	/* READ operation */
+			AdrReg = (SK_U16) Addr ;
+			AdrReg &= ~VPD_WRITE ;	/* READ operation */
 
-			VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg);
+			VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg) ;
 
 			/* ignore return code here */
-			Rtv = VpdWait(pAC,IoC,VPD_READ);
+			Rtv = VpdWait(pAC,IoC,VPD_READ) ;
 			if (Rtv != 0) {
-				return(i);
+				return(i) ;
 			}
 		}
 
 		/* Write current Byte */
 		VPD_OUT8(pAC,IoC,PCI_VPD_DAT_REG+(i%sizeof(SK_U32)),
-				*(SK_U8*)buf);
+				*(SK_U8*)buf) ;
 
 		if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) {
 			/* New Address needs to be written to VPD_ADDR reg */
-			AdrReg = (SK_U16) Addr;
+			AdrReg = (SK_U16) Addr ;
 			Addr += sizeof(SK_U32);
-			AdrReg |= VPD_WRITE;	/* WRITE operation */
+			AdrReg |= VPD_WRITE ;	/* WRITE operation */
 
-			VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg);
+			VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg) ;
 
 			/* Wait for termination */
-			Rtv = VpdWait(pAC,IoC,VPD_WRITE);
+			Rtv = VpdWait(pAC,IoC,VPD_WRITE) ;
 			if (Rtv != 0) {
 				SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-					("Write Timed Out\n"));
-				return(i - (i%sizeof(SK_U32)));
+					("Write Timed Out\n")) ;
+				return(i - (i%sizeof(SK_U32))) ;
 			}
 
 			/*
 			 * Now re-read to verify
 			 */
-			AdrReg &= ~VPD_WRITE;	/* READ operation */
+			AdrReg &= ~VPD_WRITE ;	/* READ operation */
 
-			VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg);
+			VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg) ;
 
 			/* Wait for termination */
-			Rtv = VpdWait(pAC,IoC,VPD_READ);
+			Rtv = VpdWait(pAC,IoC,VPD_READ) ;
 			if (Rtv != 0) {
 				SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-					("Verify Timed Out\n"));
-				return(i - (i%sizeof(SK_U32)));
+					("Verify Timed Out\n")) ;
+				return(i - (i%sizeof(SK_U32))) ;
 			}
 
 			for (j = 0; j <= (int) (i%sizeof(SK_U32));
 				j ++, pComp ++ ) {
-				VPD_IN8(pAC,IoC,PCI_VPD_DAT_REG+j, &Data);
+				VPD_IN8(pAC,IoC,PCI_VPD_DAT_REG+j, &Data) ;
 				if (Data != *pComp) {
 					/* Verify Error */
 					SK_DBG_MSG(pAC,SK_DBGMOD_VPD,
@@ -391,31 +378,31 @@
 int		Addr,	/* VPD start address */
 int		Len)	/* number of bytes to read / to write */
 {
-	int		i;
-	SK_U16		AdrReg;
-	int		Rtv;
+	int		i ;
+	SK_U16		AdrReg ;
+	int		Rtv ;
 
 	for (i=0; i < Len; i ++, buf++) {
 		if ((i%sizeof(SK_U32)) == 0) {
 			/* New Address needs to be written to VPD_ADDR reg */
-			AdrReg = (SK_U16) Addr;
+			AdrReg = (SK_U16) Addr ;
 			Addr += sizeof(SK_U32);
-			AdrReg &= ~VPD_WRITE;	/* READ operation */
+			AdrReg &= ~VPD_WRITE ;	/* READ operation */
 
-			VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg);
+			VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg) ;
 
 			/* ignore return code here */
-			Rtv = VpdWait(pAC,IoC,VPD_READ);
+			Rtv = VpdWait(pAC,IoC,VPD_READ) ;
 			if (Rtv != 0) {
-				return(i);
+				return(i) ;
 			}
 
 		}
 		VPD_IN8(pAC,IoC,PCI_VPD_DAT_REG+(i%sizeof(SK_U32)),
-			(SK_U8 *)buf);
+			(SK_U8 *)buf) ;
 	}
 
-	return(Len);
+	return(Len) ;
 }
 
 /*
@@ -432,29 +419,29 @@
 int		len,	/* number of bytes to read / to write */
 int		dir)	/* transfer direction may be VPD_READ or VPD_WRITE */
 {
-	int		Rtv;	/* Return value */
-	int		vpd_rom_size;
-	SK_U32		our_reg2;
+	int		Rtv ;	/* Return value */
+	int		vpd_rom_size ;
+	SK_U32		our_reg2 ;
 
 	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
 		("vpd %s block, addr = 0x%x, len = %d\n",
-		dir?"write":"read",addr,len));
+		dir?"write":"read",addr,len)) ;
 
 	if (len == 0)
-		return (0);
+		return (0) ;
 
-	VPD_IN32(pAC,IoC,PCI_OUR_REG_2,&our_reg2);
+	VPD_IN32(pAC,IoC,PCI_OUR_REG_2,&our_reg2) ;
 	vpd_rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14);
 	if (addr > vpd_rom_size - 4) {
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR|SK_DBGCAT_FATAL,
 			("Address error: 0x%x, exp. < 0x%x\n",
-			addr, vpd_rom_size - 4));
-		return (0);
+			addr, vpd_rom_size - 4)) ;
+		return (0) ;
 	}
 	if (addr + len > vpd_rom_size) {
-		len = vpd_rom_size - addr;
+		len = vpd_rom_size - addr ;
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-			("Warning: len was cut to %d\n",len));
+			("Warning: len was cut to %d\n",len)) ;
 	}
 
 	if (dir == VPD_READ) {
@@ -463,7 +450,7 @@
 		Rtv = VpdWriteStream(pAC, IoC, buf, addr, len);
 	}
 
-	return (Rtv);
+	return (Rtv) ;
 }
 
 #ifdef SKDIAG
@@ -480,7 +467,7 @@
 int		addr,	/* start reading at the VPD address */
 int		len)	/* number of bytes to read */
 {
-	return (VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ));
+	return (VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ)) ;
 }
 
 /*
@@ -495,7 +482,7 @@
 int		addr,	/* start writing at the VPD address */
 int		len)	/* number of bytes to write */
 {
-	return (VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE));
+	return (VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE)) ;
 }
 #endif	/* SKDIAG */
 
@@ -512,64 +499,64 @@
 SK_AC		*pAC,	/* Adapters context */
 SK_IOC		IoC)	/* IO Context */
 {
-	SK_VPD_PARA *r, rp;	/* RW or RV */
-	int		i;
-	unsigned char	x;
+	SK_VPD_PARA *r, rp ;	/* RW or RV */
+	int		i ;
+	unsigned char	x ;
 
-	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_INIT,("VpdInit .. "));
+	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_INIT,("VpdInit .. ")) ;
 	/* read the VPD data into the VPD buffer */
 	if (VpdTransferBlock(pAC,IoC,pAC->vpd.vpd_buf,0,VPD_SIZE,VPD_READ)
 		!= VPD_SIZE) {
 
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-			("Block Read Error\n"));
-		return(1);
+			("Block Read Error\n")) ;
+		return(1) ;
 	}
 
 	/* find the end tag of the RO area */
 	if (!(r = vpd_find_para(pAC,VPD_RV,&rp))) {
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-			("Encoding Error: RV Tag not found\n"));
-		return (1);
+			("Encoding Error: RV Tag not found\n")) ;
+		return (1) ;
 	}
 	if (r->p_val + r->p_len > pAC->vpd.vpd_buf + VPD_SIZE/2) {
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-			("Encoding Error: Invalid VPD struct size\n"));
-		return (1);
+			("Encoding Error: Invalid VPD struct size\n")) ;
+		return (1) ;
 	}
-	pAC->vpd.v.vpd_free_ro = r->p_len - 1;
+	pAC->vpd.v.vpd_free_ro = r->p_len - 1 ;
 
 	/* test the checksum */
 	for (i = 0, x = 0; (unsigned)i<=(unsigned)VPD_SIZE/2 - r->p_len; i++) {
-		x += pAC->vpd.vpd_buf[i];
+		x += pAC->vpd.vpd_buf[i] ;
 	}
 	if (x != 0) {
 		/* checksum error */
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-			("VPD Checksum Error\n"));
-		return (1);
+			("VPD Checksum Error\n")) ;
+		return (1) ;
 	}
 
 	/* find and check the end tag of the RW area */
 	if (!(r = vpd_find_para(pAC,VPD_RW,&rp))) {
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-			("Encoding Error: RV Tag not found\n"));
-		return (1);
+			("Encoding Error: RV Tag not found\n")) ;
+		return (1) ;
 	}
 	if (r->p_val < pAC->vpd.vpd_buf + VPD_SIZE/2) {
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-			("Encoding Error: Invalid VPD struct size\n"));
-		return (1);
+			("Encoding Error: Invalid VPD struct size\n")) ;
+		return (1) ;
 	}
-	pAC->vpd.v.vpd_free_rw = r->p_len;
+	pAC->vpd.v.vpd_free_rw = r->p_len ;
 
 	/* everything seems to be ok */
-	pAC->vpd.v.vpd_status |= VPD_VALID;
+	pAC->vpd.v.vpd_status |= VPD_VALID ;
 	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_INIT,
 		("done. Free RO = %d, Free RW = %d\n",
-		pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
+		pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw)) ;
 
-	return(0);
+	return(0) ;
 }
 
 /*
@@ -585,62 +572,62 @@
 SK_VPD_PARA *p)	/* parameter description struct */
 {
 	char *v	;	/* points to vpd buffer */
-	int max;	/* Maximum Number of Iterations */
+	int max ;	/* Maximum Number of Iterations */
 
-	v = pAC->vpd.vpd_buf;
-	max = 128;
+	v = pAC->vpd.vpd_buf ;
+	max = 128 ;
 
 	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
-		("vpd find para %s .. ",key));
+		("vpd find para %s .. ",key)) ;
 
 	/* check mandatory resource type ID string (Product Name) */
 	if (*v != (char) RES_ID) {
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-			("Error: 0x%x missing\n",RES_ID));
-		return (0);
+			("Error: 0x%x missing\n",RES_ID)) ;
+		return (0) ;
 	}
 
 	if (strcmp(key,VPD_NAME) == 0) {
-		p->p_len = VPD_GET_RES_LEN(v);
-		p->p_val = VPD_GET_VAL(v);
+		p->p_len = VPD_GET_RES_LEN(v) ;
+		p->p_val = VPD_GET_VAL(v) ;
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
-			("found, len = %d\n",p->p_len));
-		return(p);
+			("found, len = %d\n",p->p_len)) ;
+		return(p) ;
 	}
 
-	v += 3 + VPD_GET_RES_LEN(v) + 3;
-	for (;; ) {
+	v += 3 + VPD_GET_RES_LEN(v) + 3 ;
+	for ( ; ; ) {
 		if (SK_MEMCMP(key,v,2) == 0) {
-			p->p_len = VPD_GET_VPD_LEN(v);
-			p->p_val = VPD_GET_VAL(v);
+			p->p_len = VPD_GET_VPD_LEN(v) ;
+			p->p_val = VPD_GET_VAL(v) ;
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
-				("found, len = %d\n",p->p_len));
-			return (p);
+				("found, len = %d\n",p->p_len)) ;
+			return (p) ;
 		}
 
 		/* exit when reaching the "RW" Tag or the maximum of itera. */
-		max--;
+		max-- ;
 		if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) {
-			break;
+			break ;
 		}
 
 		if (SK_MEMCMP(VPD_RV,v,2) == 0) {
-			v += 3 + VPD_GET_VPD_LEN(v) + 3;	/* skip VPD-W */
+			v += 3 + VPD_GET_VPD_LEN(v) + 3 ;	/* skip VPD-W */
 		} else {
-			v += 3 + VPD_GET_VPD_LEN(v);
+			v += 3 + VPD_GET_VPD_LEN(v) ;
 		}
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
-			("scanning '%c%c' len = %d\n",v[0],v[1],v[2]));
+			("scanning '%c%c' len = %d\n",v[0],v[1],v[2])) ;
 	}
 
 #ifdef DEBUG
-	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,("not found\n"));
+	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,("not found\n")) ;
 	if (max == 0) {
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-			("Key/Len Encoding error\n"));
+			("Key/Len Encoding error\n")) ;
 	}
 #endif
-	return (0);
+	return (0) ;
 }
 
 /*
@@ -654,24 +641,24 @@
 char *end,		/* end of memory block to move */
 int n)			/* number of bytes the memory block has to be moved */
 {
-	char *p;
-	int i;		/* number of byte copied */
+	char *p ;
+	int i ;		/* number of byte copied */
 
 	if (n == 0)
-		return;
+		return ;
 
-	i = (int) (end - start + 1);
+	i = (int) (end - start + 1) ;
 	if (n < 0) {
-		p = start + n;
+		p = start + n ;
 		while (i != 0) {
-			*p++ = *start++;
-			i--;
+			*p++ = *start++ ;
+			i-- ;
 		}
 	} else {
-		p = end + n;
+		p = end + n ;
 		while (i != 0) {
-			*p-- = *end--;
-			i--;
+			*p-- = *end-- ;
+			i-- ;
 		}
 	}
 }
@@ -687,13 +674,13 @@
 int len,		/* length of the value string */
 char *ip)		/* inseration point */
 {
-	SK_VPD_KEY *p;
+	SK_VPD_KEY *p ;
 
-	p = (SK_VPD_KEY *) ip;
-	p->p_key[0] = key[0];
-	p->p_key[1] = key[1];
-	p->p_len = (unsigned char) len;
-	SK_MEMCPY(&p->p_val,buf,len);
+	p = (SK_VPD_KEY *) ip ;
+	p->p_key[0] = key[0] ;
+	p->p_key[1] = key[1] ;
+	p->p_len = (unsigned char) len ;
+	SK_MEMCPY(&p->p_val,buf,len) ;
 }
 
 /*
@@ -707,46 +694,46 @@
 SK_AC *pAC,	/* common data base */
 char *etp)		/* end pointer input position */
 {
-	SK_VPD_KEY *p;
-	unsigned char	x;
-	int	i;
+	SK_VPD_KEY *p ;
+	unsigned char	x ;
+	int	i ;
 
 	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
-		("vpd modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1]));
+		("vpd modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1])) ;
 
-	p = (SK_VPD_KEY *) etp;
+	p = (SK_VPD_KEY *) etp ;
 
 	if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) {
 		/* something wrong here, encoding error */
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-			("Encoding Error: invalid end tag\n"));
-		return(1);
+			("Encoding Error: invalid end tag\n")) ;
+		return(1) ;
 	}
 	if (etp > pAC->vpd.vpd_buf + VPD_SIZE/2) {
 		/* create "RW" tag */
-		p->p_len = (unsigned char)(pAC->vpd.vpd_buf+VPD_SIZE-etp-3-1);
-		pAC->vpd.v.vpd_free_rw = (int) p->p_len;
-		i = pAC->vpd.v.vpd_free_rw;
-		etp += 3;
+		p->p_len = (unsigned char)(pAC->vpd.vpd_buf+VPD_SIZE-etp-3-1) ;
+		pAC->vpd.v.vpd_free_rw = (int) p->p_len ;
+		i = pAC->vpd.v.vpd_free_rw ;
+		etp += 3 ;
 	} else {
 		/* create "RV" tag */
-		p->p_len = (unsigned char)(pAC->vpd.vpd_buf+VPD_SIZE/2-etp-3);
-		pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1;
+		p->p_len = (unsigned char)(pAC->vpd.vpd_buf+VPD_SIZE/2-etp-3) ;
+		pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1 ;
 
 		/* setup checksum */
 		for (i = 0, x = 0; i < VPD_SIZE/2 - p->p_len; i++) {
-			x += pAC->vpd.vpd_buf[i];
+			x += pAC->vpd.vpd_buf[i] ;
 		}
-		p->p_val = (char) 0 - x;
-		i = pAC->vpd.v.vpd_free_ro;
-		etp += 4;
+		p->p_val = (char) 0 - x ;
+		i = pAC->vpd.v.vpd_free_ro ;
+		etp += 4 ;
 	}
 	while (i) {
-		*etp++ = 0x00;
-		i--;
+		*etp++ = 0x00 ;
+		i-- ;
 	}
 
-	return (0);
+	return (0) ;
 }
 
 /*
@@ -771,76 +758,76 @@
 int	type,		/* VPD_RO_KEY or VPD_RW_KEY */
 int	op)			/* operation to do: ADD_KEY or OWR_KEY */
 {
-	SK_VPD_PARA vp;
-	char	*etp;		/* end tag position */
-	int	free;		/* remaining space in selected area */
-	char	*ip;		/* input position inside the VPD buffer */
-	int	rtv;		/* return code */
-	int	head;		/* additional haeder bytes to move */
-	int	found;		/* additinoal bytes if the keyword was found */
+	SK_VPD_PARA vp ;
+	char	*etp ;		/* end tag position */
+	int	free ;		/* remaining space in selected area */
+	char	*ip ;		/* input position inside the VPD buffer */
+	int	rtv ;		/* return code */
+	int	head ;		/* additional haeder bytes to move */
+	int	found ;		/* additinoal bytes if the keyword was found */
 
 	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
-		("vpd setup para key = %s, val = %s\n",key,buf));
+		("vpd setup para key = %s, val = %s\n",key,buf)) ;
 
-	rtv = 0;
-	ip = 0;
+	rtv = 0 ;
+	ip = 0 ;
 	if (type == VPD_RW_KEY) {
 		/* end tag is "RW" */
-		free = pAC->vpd.v.vpd_free_rw;
-		etp = pAC->vpd.vpd_buf + (VPD_SIZE - free - 1 - 3);
+		free = pAC->vpd.v.vpd_free_rw ;
+		etp = pAC->vpd.vpd_buf + (VPD_SIZE - free - 1 - 3) ;
 	} else {
 		/* end tag is "RV" */
-		free = pAC->vpd.v.vpd_free_ro;
-		etp = pAC->vpd.vpd_buf + (VPD_SIZE/2 - free - 4);
+		free = pAC->vpd.v.vpd_free_ro ;
+		etp = pAC->vpd.vpd_buf + (VPD_SIZE/2 - free - 4) ;
 	}
 	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
 		("Free RO = %d, Free RW = %d\n",
-		pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
+		pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw)) ;
 
-	head = 0;
-	found = 0;
+	head = 0 ;
+	found = 0 ;
 	if (op == OWR_KEY) {
 		if (vpd_find_para(pAC,key,&vp)) {
-			found = 3;
-			ip = vp.p_val - 3;
-			free += vp.p_len + 3;
+			found = 3 ;
+			ip = vp.p_val - 3 ;
+			free += vp.p_len + 3 ;
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
-				("Overwrite Key\n"));
+				("Overwrite Key\n")) ;
 		} else {
-			op = ADD_KEY;
+			op = ADD_KEY ;
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
-				("Add Key\n"));
+				("Add Key\n")) ;
 		}
 	}
 	if (op == ADD_KEY) {
-		ip = etp;
-		vp.p_len = 0;
-		head = 3;
+		ip = etp ;
+		vp.p_len = 0 ;
+		head = 3 ;
 	}
 
 	if (len + 3 > free) {
 		if (free < 7) {
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
 				("VPD Buffer Overflow, keyword not written\n"));
-			return (4);
+			return (4) ;
 		}
 		/* cut it again */
-		len = free - 3;
-		rtv = 2;
+		len = free - 3 ;
+		rtv = 2 ;
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-			("VPD Buffer Full, Keyword was cut\n"));
+			("VPD Buffer Full, Keyword was cut\n")) ;
 	}
 
-	vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head);
-	vpd_insert_key(key, buf, len, ip);
+	vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head) ;
+	vpd_insert_key(key, buf, len, ip) ;
 	if (vpd_mod_endtag(pAC, etp + len - vp.p_len + head)) {
-		pAC->vpd.v.vpd_status &= ~VPD_VALID;
+		pAC->vpd.v.vpd_status &= ~VPD_VALID ;
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-			("VPD Encoding Error\n"));
-		return(6);
+			("VPD Encoding Error\n")) ;
+		return(6) ;
 	}
 
-	return (rtv);
+	return (rtv) ;
 }
 
 
@@ -848,7 +835,7 @@
  *	Read the contents of the VPD EEPROM and copy it to the
  *	VPD buffer if not already done.
  *
- * return:	A pointer to the vpd_status structure. The structure contains
+ * return:	A pointer to the vpd_status structure. The structure contain
  *		this fields.
  */
 SK_VPD_STATUS	*VpdStat(
@@ -856,9 +843,9 @@
 SK_IOC		IoC)	/* IO Context */
 {
 	if (!(pAC->vpd.v.vpd_status & VPD_VALID)) {
-		(void)VpdInit(pAC,IoC);
+		(void)VpdInit(pAC,IoC) ;
 	}
-	return(&pAC->vpd.v);
+	return(&pAC->vpd.v) ;
 }
 
 
@@ -891,67 +878,67 @@
 int		*len,		/* buffer length */
 int		*elements)	/* number of keywords returned */
 {
-	char *v;
-	int n;
+	char *v ;
+	int n ;
 
-	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("list vpd keys .. "));
-	*elements = 0;
+	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("list vpd keys .. ")) ;
+	*elements = 0 ;
 	if (!(pAC->vpd.v.vpd_status & VPD_VALID)) {
 		if (VpdInit(pAC,IoC) != 0 ) {
-			*len = 0;
+			*len = 0 ;
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-				("VPD Init Error, terminated\n"));
-			return(6);
+				("VPD Init Error, terminated\n")) ;
+			return(6) ;
 		}
 	}
 
 	if ((signed)strlen(VPD_NAME) + 1 <= *len) {
-		v = pAC->vpd.vpd_buf;
-		strcpy(buf,VPD_NAME);
-		n = strlen(VPD_NAME) + 1;
-		buf += n;
-		*elements = 1;
+		v = pAC->vpd.vpd_buf ;
+		strcpy(buf,VPD_NAME) ;
+		n = strlen(VPD_NAME) + 1 ;
+		buf += n ;
+		*elements = 1 ;
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,
-			("'%c%c' ",v[0],v[1]));
+			("'%c%c' ",v[0],v[1])) ;
 	} else {
-		*len = 0;
+		*len = 0 ;
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-			("buffer overflow\n"));
-		return(2);
+			("buffer overflow\n")) ;
+		return(2) ;
 	}
 
-	v += 3 + VPD_GET_RES_LEN(v) + 3;
-	for (;; ) {
+	v += 3 + VPD_GET_RES_LEN(v) + 3 ;
+	for ( ; ; ) {
 		/* exit when reaching the "RW" Tag */
 		if (SK_MEMCMP(VPD_RW,v,2) == 0) {
-			break;
+			break ;
 		}
 
 		if (SK_MEMCMP(VPD_RV,v,2) == 0) {
-			v += 3 + VPD_GET_VPD_LEN(v) + 3;	/* skip VPD-W */
-			continue;
+			v += 3 + VPD_GET_VPD_LEN(v) + 3 ;	/* skip VPD-W */
+			continue ;
 		}
 
 		if (n+3 <= *len) {
-			SK_MEMCPY(buf,v,2);
-			buf += 2;
-			*buf++ = '\0';
-			n += 3;
-			v += 3 + VPD_GET_VPD_LEN(v);
-			*elements += 1;
+			SK_MEMCPY(buf,v,2) ;
+			buf += 2 ;
+			*buf++ = '\0' ;
+			n += 3 ;
+			v += 3 + VPD_GET_VPD_LEN(v) ;
+			*elements += 1 ;
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,
-				("'%c%c' ",v[0],v[1]));
+				("'%c%c' ",v[0],v[1])) ;
 		} else {
-			*len = n;
+			*len = n ;
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-				("buffer overflow\n"));
-			return (2);
+				("buffer overflow\n")) ;
+			return (2) ;
 		}
 	}
 
-	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("\n"));
-	*len = n;
-	return(0);
+	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("\n")) ;
+	*len = n ;
+	return(0) ;
 }
 
 
@@ -975,34 +962,34 @@
 char		*buf,	/* buffer where to copy the keyword value */
 int		*len)	/* buffer length */
 {
-	SK_VPD_PARA *p, vp;
+	SK_VPD_PARA *p, vp ;
 
-	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("vpd read %s .. ",key));
+	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("vpd read %s .. ",key)) ;
 	if (!(pAC->vpd.v.vpd_status & VPD_VALID)) {
 		if (VpdInit(pAC,IoC) != 0 ) {
-			*len = 0;
+			*len = 0 ;
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-				("vpd init error\n"));
-			return(6);
+				("vpd init error\n")) ;
+			return(6) ;
 		}
 	}
 
 	if ((p = vpd_find_para(pAC,key,&vp))) {
 		if (p->p_len > (*(unsigned *)len)-1) {
-			p->p_len = *len - 1;
+			p->p_len = *len - 1 ;
 		}
-		SK_MEMCPY(buf,p->p_val,p->p_len);
-		buf[p->p_len] = '\0';
-		*len = p->p_len;
+		SK_MEMCPY(buf,p->p_val,p->p_len) ;
+		buf[p->p_len] = '\0' ;
+		*len = p->p_len ;
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,
 			("%c%c%c%c.., len = %d\n",
-			buf[0],buf[1],buf[2],buf[3],*len));
+			buf[0],buf[1],buf[2],buf[3],*len)) ;
 	} else {
-		*len = 0;
-		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,("not found\n"));
-		return (1);
+		*len = 0 ;
+		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,("not found\n")) ;
+		return (1) ;
 	}
-	return (0);
+	return (0) ;
 }
 
 
@@ -1020,9 +1007,9 @@
 		key[1] < '0' || key[1] > 'Z' ||
 		(key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
 
-		return (SK_FALSE);
+		return (SK_FALSE) ;
 	}
-	return (SK_TRUE);
+	return (SK_TRUE) ;
 }
 
 /*
@@ -1044,46 +1031,46 @@
 char		*key,	/* keyword to write (allowed values "Yx", "Vx") */
 char		*buf)	/* buffer where the keyword value can be read from */
 {
-	int len;			/* lenght of the keyword to write */
-	int rtv;			/* return code */
-	int rtv2;
+	int len ;			/* lenght of the keyword to write */
+	int rtv ;			/* return code */
+	int rtv2 ;
 
 	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,
-		("vpd write %s = %s\n",key,buf));
+		("vpd write %s = %s\n",key,buf)) ;
 
 	if ((*key != 'Y' && *key != 'V') ||
 		key[1] < '0' || key[1] > 'Z' ||
 		(key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
 
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-			("illegal key tag, keyword not written\n"));
-		return (5);
+			("illegal key tag, keyword not written\n")) ;
+		return (5) ;
 	}
 
 	if (!(pAC->vpd.v.vpd_status & VPD_VALID)) {
 		if (VpdInit(pAC,IoC) != 0 ) {
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-				("vpd init error\n"));
-			return(6);
+				("vpd init error\n")) ;
+			return(6) ;
 		}
 	}
 
-	rtv = 0;
-	len = strlen(buf);
+	rtv = 0 ;
+	len = strlen(buf) ;
 	if (len > VPD_MAX_LEN) {
 		/* cut it */
-		len = VPD_MAX_LEN;
-		rtv = 2;
+		len = VPD_MAX_LEN ;
+		rtv = 2 ;
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-			("keyword to long, cut after %d bytes\n",VPD_MAX_LEN));
+			("keyword to long, cut after %d bytes\n",VPD_MAX_LEN)) ;
 	}
 	if ((rtv2 = VpdSetupPara(pAC,key,buf,len,VPD_RW_KEY,OWR_KEY)) != 0) {
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-			("vpd write error\n"));
-		return(rtv2);
+			("vpd write error\n")) ;
+		return(rtv2) ;
 	}
 
-	return (rtv);
+	return (rtv) ;
 }
 
 /*
@@ -1103,15 +1090,15 @@
 SK_IOC		IoC,	/* IO Context */
 char		*key)	/* keyword to read (e.g. "MN") */
 {
-	SK_VPD_PARA *p, vp;
-	char *etp;
+	SK_VPD_PARA *p, vp ;
+	char *etp ;
 
-	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("vpd delete key %s\n",key));
+	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("vpd delete key %s\n",key)) ;
 	if (!(pAC->vpd.v.vpd_status & VPD_VALID)) {
 		if (VpdInit(pAC,IoC) != 0 ) {
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-				("vpd init error\n"));
-			return(6);
+				("vpd init error\n")) ;
+			return(6) ;
 		}
 	}
 
@@ -1119,27 +1106,27 @@
 		if (p->p_val < pAC->vpd.vpd_buf + VPD_SIZE/2) {
 			/* try to delete read only keyword */
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-				("cannot delete RO keyword\n"));
-			return (5);
+				("cannot delete RO keyword\n")) ;
+			return (5) ;
 		}
 
-		etp = pAC->vpd.vpd_buf + (VPD_SIZE-pAC->vpd.v.vpd_free_rw-1-3);
+		etp = pAC->vpd.vpd_buf + (VPD_SIZE-pAC->vpd.v.vpd_free_rw-1-3) ;
 
 		vpd_move_para(vp.p_val+vp.p_len, etp+2,
-			- ((int)(vp.p_len + 3)));
+			- ((int)(vp.p_len + 3))) ;
 		if (vpd_mod_endtag(pAC, etp - vp.p_len - 3)) {
-			pAC->vpd.v.vpd_status &= ~VPD_VALID;
+			pAC->vpd.v.vpd_status &= ~VPD_VALID ;
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-				("vpd encoding error\n"));
-			return(6);
+				("vpd encoding error\n")) ;
+			return(6) ;
 		}
 	} else {
 		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-			("keyword not found\n"));
-		return (1);
+			("keyword not found\n")) ;
+		return (1) ;
 	}
 
-	return (0);
+	return (0) ;
 }
 
 /*
@@ -1153,18 +1140,18 @@
 SK_AC		*pAC,	/* Adapters context */
 SK_IOC		IoC)	/* IO Context */
 {
-	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("vpd update .. "));
+	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("vpd update .. ")) ;
 	if (pAC->vpd.v.vpd_status & VPD_VALID) {
 		if (VpdTransferBlock(pAC,IoC,pAC->vpd.vpd_buf + VPD_SIZE/2,
 			VPD_SIZE/2, VPD_SIZE/2, VPD_WRITE) != VPD_SIZE/2) {
 
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-				("transfer timed out\n"));
-			return(3);
+				("transfer timed out\n")) ;
+			return(3) ;
 		}
 	}
-	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("done\n"));
-	return (0);
+	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("done\n")) ;
+	return (0) ;
 }
 
 
@@ -1184,32 +1171,32 @@
 SK_IOC		IoC,	/* IO Context */
 char		*msg)	/* error log message */
 {
-	SK_VPD_PARA *v, vf;	/* VF */
-	int len;
+	SK_VPD_PARA *v, vf ;	/* VF */
+	int len ;
 
 	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,
-		("vpd error log msg %s\n",msg));
+		("vpd error log msg %s\n",msg)) ;
 	if (!(pAC->vpd.v.vpd_status & VPD_VALID)) {
 		if (VpdInit(pAC,IoC) != 0 ) {
 			SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-				("vpd init error\n"));
-			return;
+				("vpd init error\n")) ;
+			return ;
 		}
 	}
 
-	len = strlen(msg);
+	len = strlen(msg) ;
 	if (len > VPD_MAX_LEN) {
 		/* cut it */
-		len = VPD_MAX_LEN;
+		len = VPD_MAX_LEN ;
 	}
 	if ((v = vpd_find_para(pAC,VPD_VF,&vf))) {
-		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("overwrite VL\n"));
-		(void)VpdSetupPara(pAC,VPD_VL,msg,len,VPD_RW_KEY,OWR_KEY);
+		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("overwrite VL\n")) ;
+		(void)VpdSetupPara(pAC,VPD_VL,msg,len,VPD_RW_KEY,OWR_KEY) ;
 	} else {
-		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("write VF\n"));
-		(void)VpdSetupPara(pAC,VPD_VF,msg,len,VPD_RW_KEY,ADD_KEY);
+		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("write VF\n")) ;
+		(void)VpdSetupPara(pAC,VPD_VF,msg,len,VPD_RW_KEY,ADD_KEY) ;
 	}
 
-	(void)VpdUpdate(pAC,IoC);
+	(void)VpdUpdate(pAC,IoC) ;
 }
 
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/skxmac2.c linux/drivers/net/sk98lin/skxmac2.c
--- v2.4.6/linux/drivers/net/sk98lin/skxmac2.c	Tue Mar 20 12:04:59 2001
+++ linux/drivers/net/sk98lin/skxmac2.c	Wed Jul  4 11:50:39 2001
@@ -2,16 +2,15 @@
  *
  * Name:	skxmac2.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.53 $
- * Date:	$Date: 2000/07/27 12:22:11 $
+ * Version:	$Revision: 1.61 $
+ * Date:	$Date: 2001/02/09 15:40:59 $
  * Purpose:	Contains functions to initialize the XMAC II
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998,1999 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,6 +26,30 @@
  * History:
  *
  *	$Log: skxmac2.c,v $
+ *	Revision 1.61  2001/02/09 15:40:59  rassmann
+ *	Editorial changes.
+ *	
+ *	Revision 1.60  2001/02/07 15:02:01  cgoos
+ *	Added workaround for Fujitsu switch link down.
+ *	
+ *	Revision 1.59  2001/01/10 09:38:06  cgoos
+ *	Fixed Broadcom C0/A1 Id check for workaround.
+ *	
+ *	Revision 1.58  2000/11/29 11:30:38  cgoos
+ *	Changed DEBUG sections with NW output to xDEBUG
+ *	
+ *	Revision 1.57  2000/11/27 12:40:40  rassmann
+ *	Suppressing preamble after first access to BCom, not before (#10556).
+ *	
+ *	Revision 1.56  2000/11/09 12:32:48  rassmann
+ *	Renamed variables.
+ *	
+ *	Revision 1.55  2000/11/09 11:30:10  rassmann
+ *	WA: Waiting after releasing reset until BCom chip is accessible.
+ *	
+ *	Revision 1.54  2000/10/02 14:10:27  rassmann
+ *	Reading BCOM PHY after releasing reset until it returns a valid value.
+ *	
  *	Revision 1.53  2000/07/27 12:22:11  gklug
  *	fix: possible endless loop in XmHardRst.
  *	
@@ -40,10 +63,10 @@
  *	Changed license header to GPL.
  *	
  *	Revision 1.49  1999/11/22 08:12:13  malthoff
- *	Add workaround for power consumption feature of Bcom C0 chip.
+ *	Add workaround for power consumption feature of BCom C0 chip.
  *	
  *	Revision 1.48  1999/11/16 08:39:01  malthoff
- *	Fix: MDIO preamble suppression is port dependend.
+ *	Fix: MDIO preamble suppression is port dependent.
  *	
  *	Revision 1.47  1999/08/27 08:55:35  malthoff
  *	1000BT: Optimizing MDIO transfer by oppressing MDIO preamble.
@@ -79,8 +102,7 @@
  *	Changes for 1000Base-T.
  *	
  *	Revision 1.38  1999/04/08 14:35:10  malthoff
- *	Add code for enabling signal detect. Enabling signal
- *	detect is disabled.
+ *	Add code for enabling signal detect. Enabling signal detect is disabled.
  *	
  *	Revision 1.37  1999/03/12 13:42:54  malthoff
  *	Add: Jumbo Frame Support.
@@ -234,11 +256,11 @@
 /* local variables ************************************************************/
 
 static const char SysKonnectFileId[] =
-	"@(#)$Id: skxmac2.c,v 1.53 2000/07/27 12:22:11 gklug Exp $ (C) SK ";
+	"@(#)$Id: skxmac2.c,v 1.61 2001/02/09 15:40:59 rassmann Exp $ (C) SK ";
 
 /* BCOM PHY magic pattern list */
 typedef struct s_PhyHack {
-	int	PhyReg;		/* Phy register */
+	int		PhyReg;		/* Phy register */
 	SK_U16	PhyVal;		/* Value to write */
 } BCOM_HACK;
 
@@ -278,7 +300,7 @@
  *	 o don't set XMR_FS_ERR in frame	SK_BIG_PK_OK_ON/OFF
  *	   status for frames > 1514 bytes
  *
- *	for incoming packets may be enabled/disabled by this function.
+ *	for incomming packets may be enabled/disabled by this function.
  *	Additional modes may be added later.
  *	Multiple modes can be enabled/disabled at the same time.
  *	The new configuration is stored into the HWAC port configuration
@@ -293,12 +315,12 @@
 void SkXmSetRxCmd(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port,		/* The XMAC to handle with belongs to this Port */
-int	Mode)		/* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
-				SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
+int		Port,		/* The XMAC to handle with belongs to this Port */
+int		Mode)		/* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
+					   SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
 {
-	SK_GEPORT *pPrt;
-	SK_U16	OldRxMode;
+	SK_GEPORT	*pPrt;
+	SK_U16		OldRxMode;
 
 	pPrt = &pAC->GIni.GP[Port];
 	OldRxMode = pPrt->PRxCmd;
@@ -343,7 +365,8 @@
 	if (OldRxMode != pPrt->PRxCmd) {
 		XM_OUT16(IoC, Port, XM_RX_CMD, pPrt->PRxCmd);
 	}
-}
+}	/* SkXmSetRxCmd*/
+
 
 /******************************************************************************
  *
@@ -360,12 +383,12 @@
 void SkXmClrExactAddr(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port,		/* The XMAC to handle with belongs to this Port */
-int	StartNum,	/* Begin with this Address Register Index (0..15) */
-int	StopNum)	/* Stop after finished with this Register Idx (0..15) */
+int		Port,		/* The XMAC to handle with belongs to this Port */
+int		StartNum,	/* Begin with this Address Register Index (0..15) */
+int		StopNum)	/* Stop after finished with this Register Idx (0..15) */
 {
-	int	i;
-	SK_U16	ZeroAddr[3] = { 0x0000, 0x0000, 0x0000 };
+	int		i;
+	SK_U16	ZeroAddr[3] = {0x0000, 0x0000, 0x0000};
 
 	if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 ||
 		StartNum > StopNum) {
@@ -377,7 +400,8 @@
 	for (i = StartNum; i <= StopNum; i++) {
 		XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]);
 	}
-}
+}	/* SkXmClrExactAddr */
+
 
 /******************************************************************************
  *
@@ -393,12 +417,13 @@
 static void SkXmClrSrcCheck(
 SK_AC	*pAC,	/* adapter context */
 SK_IOC	IoC,	/* IO context */
-int	Port)	/* The XMAC to handle with belongs to this Port (MAC_1 + n) */
+int		Port)	/* The XMAC to handle with belongs to this Port (MAC_1 + n) */
 {
-	SK_U16	ZeroAddr[3] = { 0x0000, 0x0000, 0x0000 };
+	SK_U16	ZeroAddr[3] = {0x0000, 0x0000, 0x0000};
 
 	XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr);
-}
+}	/* SkXmClrSrcCheck */
+
 
 /******************************************************************************
  *
@@ -413,12 +438,13 @@
 static void SkXmClrHashAddr(
 SK_AC	*pAC,	/* adapter context */
 SK_IOC	IoC,	/* IO context */
-int	Port)	/* The XMAC to handle with belongs to this Port (MAC_1 + n) */
+int		Port)	/* The XMAC to handle with belongs to this Port (MAC_1 + n) */
 {
-	SK_U16	ZeroAddr[4] = { 0x0000, 0x0000, 0x0000, 0x0000 };
+	SK_U16	ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000};
 
 	XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr);
-}
+}	/* SkXmClrHashAddr*/
+
 
 /******************************************************************************
  *
@@ -433,14 +459,15 @@
 void SkXmFlushTxFifo(
 SK_AC	*pAC,	/* adapter context */
 SK_IOC	IoC,	/* IO context */
-int	Port)	/* The XMAC to handle with belongs to this Port (MAC_1 + n) */
+int		Port)	/* The XMAC to handle with belongs to this Port (MAC_1 + n) */
 {
 	SK_U32	MdReg;
 
 	XM_IN32(IoC, Port, XM_MODE, &MdReg);
 	MdReg |= XM_MD_FTF;
 	XM_OUT32(IoC, Port, XM_MODE, MdReg);
-}
+}	/* SkXmFlushTxFifo */
+
 
 /******************************************************************************
  *
@@ -455,14 +482,15 @@
 void SkXmFlushRxFifo(
 SK_AC	*pAC,	/* adapter context */
 SK_IOC	IoC,	/* IO context */
-int	Port)	/* The XMAC to handle with belongs to this Port (MAC_1 + n) */
+int		Port)	/* The XMAC to handle with belongs to this Port (MAC_1 + n) */
 {
 	SK_U32	MdReg;
 
 	XM_IN32(IoC, Port, XM_MODE, &MdReg);
 	MdReg |= XM_MD_FRF;
 	XM_OUT32(IoC, Port, XM_MODE, MdReg);
-}
+}	/* SkXmFlushRxFifo*/
+
 
 /******************************************************************************
  *
@@ -502,10 +530,10 @@
 void SkXmSoftRst(
 SK_AC	*pAC,	/* adapter context */
 SK_IOC	IoC,	/* IO context */
-int	Port)	/* port to stop (MAC_1 + n) */
+int		Port)	/* port to stop (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
-	SK_U16	Word;
+	SK_U16		Word;
 
 	pPrt = &pAC->GIni.GP[Port];
 
@@ -527,13 +555,11 @@
 	
 	/* disable all PHY IRQs */
 	switch (pAC->GIni.GP[Port].PhyType) {
-		case SK_PHY_BCOM:
-			PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK, 
-				0xffff);
+	case SK_PHY_BCOM:
+			PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK, 0xffff);
 			break;
 		case SK_PHY_LONE:
-			PHY_WRITE(IoC, pPrt, Port, PHY_LONE_INT_ENAB, 
-				0x0);
+			PHY_WRITE(IoC, pPrt, Port, PHY_LONE_INT_ENAB, 0x0);
 			break;
 		case SK_PHY_NAT:
 			/* todo: National
@@ -554,7 +580,8 @@
 	SkXmFlushRxFifo(pAC, IoC, Port);
 
 	pAC->GIni.GP[Port].PState = SK_PRT_STOP;
-}
+}	/* SkXmSoftRst*/
+
 
 /******************************************************************************
  *
@@ -578,18 +605,17 @@
 void SkXmHardRst(
 SK_AC	*pAC,	/* adapter context */
 SK_IOC	IoC,	/* IO context */
-int	Port)	/* port to stop (MAC_1 + n) */
+int		Port)	/* port to stop (MAC_1 + n) */
 {
-	SK_U16	Word;
-	int	i;
-	int	TOut;
 	SK_U32	Reg;
+	int		i;
+	int		TOut;
+	SK_U16	Word;
 
-	for (i=0; i<4; i++) {
+	for (i = 0; i < 4; i++) {
 		/* TX_MFF_CTRL1 is a 32 bit register but only the lowest 16 */
 		/* bit contains buttoms to press */
-		SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1),
-			(SK_U16) MFF_CLR_MAC_RST);
+		SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), (SK_U16)MFF_CLR_MAC_RST);
 
 		TOut = 0;
 		do {
@@ -610,7 +636,6 @@
 
 	/* For external PHYs there must be special handling */
 	if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
-
 		/* reset external PHY */
 		SK_IN32(IoC, B2_GP_IO, &Reg);
 		if (Port == 0) {
@@ -628,7 +653,8 @@
 	}
 
 	pAC->GIni.GP[Port].PState = SK_PRT_RESET;
-}
+}	/* SkXmHardRst */
+
 
 /******************************************************************************
  *
@@ -639,8 +665,7 @@
  *	The XMAC must be reset or stopped before calling this function.
  *
  * Note:
- *	The XMACs Rx and Tx state machine is still disabled when
- *	returning.
+ *	The XMAC's Rx and Tx state machine is still disabled when returning.
  *
  * Returns:
  *	nothing
@@ -648,12 +673,13 @@
 void SkXmInitMac(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port)		/* Port Index (MAC_1 + n) */
+int		Port)		/* Port Index (MAC_1 + n) */
 {
-	SK_GEPORT *pPrt;
-	SK_U16	SWord;
-	int	i;
-	SK_U32	Reg;
+	SK_GEPORT	*pPrt;
+	SK_U32		Reg;
+	int			i;
+	SK_U16		SWord;
+	SK_U16		PhyId;
 
 	pPrt = &pAC->GIni.GP[Port];
 
@@ -661,79 +687,118 @@
 		/* Port State: SK_PRT_STOP */
 		/* Verify that the reset bit is cleared */
 		SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
-		if (SWord & (SK_U16) MFF_SET_MAC_RST) {
+		if (SWord & (SK_U16)MFF_SET_MAC_RST) {
 			/* PState does not match HW state */
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006,
-				SKERR_HWI_E006MSG);
-			/* correct it */
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
+			/* Correct it. */
 			pPrt->PState = SK_PRT_RESET;
 		}
 	}
+
 	if (pPrt->PState == SK_PRT_RESET) {
 		/*
 		 * clear HW reset
 		 * Note: The SW reset is self clearing, therefore there is
 		 *	 nothing to do here.
 		 */
-		SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1),
-			(SK_U16) MFF_CLR_MAC_RST);
-		
-		/*
-		 * clear PHY reset
-		 */
-		if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
+		SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), (SK_U16)MFF_CLR_MAC_RST);
 
+		/* Ensure that XMAC reset release is done (errata from LReinbold?). */
+		SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
+
+		/* Clear PHY reset. */
+		if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
 			SK_IN32(IoC, B2_GP_IO, &Reg);
 			if (Port == 0) {
-				Reg |= GP_DIR_0; /* set to output */
+				Reg |= GP_DIR_0; /* Set to output. */
 				Reg |= GP_IO_0;
 			}
 			else {
-				Reg |= GP_DIR_2; /* set to output */
+				Reg |= GP_DIR_2; /* Set to output. */
 				Reg |= GP_IO_2;
 			}
 			SK_OUT32(IoC, B2_GP_IO, Reg);
 
-			/* enable GMII interface */
+			/* Enable GMII interface. */
 			XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
 
-			/* optimize MDIO transfer by oppressing preamble */
+			PHY_READ(IoC, pPrt, Port, PHY_XMAC_ID1, &PhyId);
+#ifdef xDEBUG
+			if (SWord == 0xFFFF) {
+				i = 1;
+				do {
+					PHY_READ(IoC, pPrt, Port, PHY_XMAC_ID1, &SWord);
+					i++;
+					/* Limit retries; else machine may hang. */
+				} while (SWord == 0xFFFF && i < 500000);
+
+				CMSMPrintString(
+					pAC->pConfigTable,
+					MSG_TYPE_RUNTIME_INFO,
+					"ID1 is %x after %d reads.",
+					(void *)SWord,
+					(void *)i);
+
+				/* Trigger PCI analyzer */
+				/* SK_IN32(IoC, 0x012c, &Reg); */
+			}
+#endif	/* DEBUG */
+
+			/*
+			 * Optimize MDIO transfer by suppressing preamble.
+			 * Must be done AFTER first access to BCOM chip.
+			 */
 			XM_IN16(IoC, Port, XM_MMU_CMD, &SWord);
 			XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE);
 
-			/* Workaround BCOM Errata for the A1 type */
-			/* Write magic patterns to reserved registers */
-			PHY_READ(IoC, pPrt, Port, PHY_XMAC_ID1, &SWord);
-			if (SWord == 0x6041) {
+			if (PhyId == 0x6044) {
+				/* Workaround BCOM Errata for the C0 type. */
+				/* Write magic patterns to reserved registers. */
 				i = 0;
-				while (BcomRegA1Hack[i].PhyReg != 0) {
-					PHY_WRITE(IoC, pPrt, Port,
-						BcomRegA1Hack[i].PhyReg,
-						BcomRegA1Hack[i].PhyVal);
+				while (BcomRegC0Hack[i].PhyReg != 0) {
+					PHY_WRITE(IoC, pPrt, Port, BcomRegC0Hack[i].PhyReg,
+						BcomRegC0Hack[i].PhyVal);
 					i++;
 				}
 			}
-			/* Workaround BCOM Errata for the C0 type */
-			/* Write magic patterns to reserved registers */
-			if (SWord == 0x6044) {
+			else if (PhyId == 0x6041) {
+				/* Workaround BCOM Errata for the A1 type. */
+				/* Write magic patterns to reserved registers. */
 				i = 0;
-				while (BcomRegC0Hack[i].PhyReg != 0) {
-					PHY_WRITE(IoC, pPrt, Port,
-						BcomRegC0Hack[i].PhyReg,
-						BcomRegC0Hack[i].PhyVal);
+				while (BcomRegA1Hack[i].PhyReg != 0) {
+					PHY_WRITE(IoC, pPrt, Port, BcomRegA1Hack[i].PhyReg,
+						BcomRegA1Hack[i].PhyVal);
 					i++;
 				}
 			}
-			/* Workaround BCOM Errata (#10523) for all BCom PHYs*/
-			/* Disable Power Management after reset */
+
+			/* Workaround BCOM Errata (#10523) for all BCom PHYs. */
+			/* Disable Power Management after reset. */
 			PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &SWord);
+#ifdef xDEBUG
+			if (SWord == 0xFFFF) {
+				i = 1;
+				do {
+					PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &SWord);
+					i++;
+					/* Limit retries; else machine may hang. */
+				} while (SWord == 0xFFFF && i < 500000);
+
+				CMSMPrintString(
+					pAC->pConfigTable,
+					MSG_TYPE_RUNTIME_INFO,
+					"AUX_CTRL is %x after %d reads.",
+					(void *)SWord,
+					(void *)i);
+
+				/* Trigger PCI analyzer */
+				/* SK_IN32(IoC, 0x012c, &Reg); */
+			}
+#endif	/* DEBUG */
 			PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL,
 				SWord | PHY_B_AC_DIS_PM);
 
-			/*
-			 * PHY LED initialization is performed in
-			 * SkGeXmitLED() (but not here).
-			 */
+			/* PHY LED initialization is done in SkGeXmitLED(), not here. */
 		}
 
 		/* Dummy read the Interrupt source register */
@@ -741,7 +806,7 @@
 		
 		/*
 		 * The autonegotiation process starts immediately after
-		 * clearing the reset. Autonegotiation process should be
+		 * clearing the reset. The autonegotiation process should be
 		 * started by the SIRQ, therefore stop it here immediately.
 		 */
 		SkXmInitPhy(pAC, IoC, Port, SK_FALSE);
@@ -755,8 +820,8 @@
 
 	/*
 	 * configure the XMACs Station Address
-	 * B2_MAC_2 = xx xx xx xx xx x1 is programmed to XMAC A
-	 * B2_MAC_3 = xx xx xx xx xx x2 is programmed to XMAC B
+	 * B2_MAC_2 = xx xx xx xx xx x1 is programed to XMAC A
+	 * B2_MAC_3 = xx xx xx xx xx x2 is programed to XMAC B
 	 */
 	for (i = 0; i < 3; i++) {
 		/*
@@ -849,7 +914,8 @@
 	 * This should be done after the autonegotiation process
 	 * has been completed successfully.
 	 */
-}
+}	/* SkXmInitMac*/
+
 
 /******************************************************************************
  *
@@ -866,7 +932,7 @@
 void SkXmInitDupMd(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port)		/* Port Index (MAC_1 + n) */
+int		Port)		/* Port Index (MAC_1 + n) */
 {
 	switch (pAC->GIni.GP[Port].PLinkModeStatus) {
 	case SK_LMODE_STAT_AUTOHALF:
@@ -895,7 +961,8 @@
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E007, SKERR_HWI_E007MSG);
 		break;
 	}
-}
+}	/* SkXmInitDupMd */
+
 
 /******************************************************************************
  *
@@ -913,11 +980,11 @@
 void SkXmInitPauseMd(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port)		/* Port Index (MAC_1 + n) */
+int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
-	SK_U16		Word;
 	SK_U32		DWord;
+	SK_U16		Word;
 
 	pPrt = &pAC->GIni.GP[Port];
 
@@ -976,8 +1043,7 @@
 		/* Disable Pause Mode in MAC Rx FIFO */
 		SK_OUT16(IoC, MR_ADDR(Port,RX_MFF_CTRL1), MFF_DIS_PAUSE);
 	}
-
-}
+}	/* SkXmInitPauseMd*/
 
 
 /******************************************************************************
@@ -995,7 +1061,7 @@
 void SkXmInitPhy(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port,		/* Port Index (MAC_1 + n) */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	DoLoop)		/* Should a Phy LOOback be set-up? */
 {
 	SK_GEPORT	*pPrt;
@@ -1015,7 +1081,8 @@
 		SkXmInitPhyNat(pAC, IoC, Port, DoLoop);
 		break;
 	}
-}
+}	/* SkXmInitPhy*/
+
 
 /******************************************************************************
  *
@@ -1032,11 +1099,11 @@
 static void SkXmInitPhyXmac(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port,		/* Port Index (MAC_1 + n) */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	DoLoop)		/* Should a Phy LOOback be set-up? */
 {
 	SK_GEPORT	*pPrt;
-	SK_U16		Crtl;
+	SK_U16		Ctrl;
 
 	pPrt = &pAC->GIni.GP[Port];
 
@@ -1047,67 +1114,69 @@
 			("InitPhyXmac: no autonegotiation Port %d\n", Port));
 		/* No Autonegiotiation */
 		/* Set DuplexMode in Config register */
-		Crtl = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
+		Ctrl = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
 
 		/*
 		 * Do NOT enable Autonegotiation here. This would hold
 		 * the link down because no IDLES are transmitted
 		 */
-	} else {
+	}
+	else {
 		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
 			("InitPhyXmac: with autonegotiation Port %d\n", Port));
 		/* Set Autonegotiation advertisement */
-		Crtl = 0;
+		Ctrl = 0;
 
 		/* Set Full/half duplex capabilities */
 		switch (pPrt->PLinkMode) {
 		case SK_LMODE_AUTOHALF:
-			Crtl |= PHY_X_AN_HD;
+			Ctrl |= PHY_X_AN_HD;
 			break;
 		case SK_LMODE_AUTOFULL:
-			Crtl |= PHY_X_AN_FD;
+			Ctrl |= PHY_X_AN_FD;
 			break;
 		case SK_LMODE_AUTOBOTH:
-			Crtl |= PHY_X_AN_FD | PHY_X_AN_HD;
+			Ctrl |= PHY_X_AN_FD | PHY_X_AN_HD;
 			break;
 		default:
 			SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,
-				SKERR_HWI_E015, SKERR_HWI_E015MSG) ;
+				SKERR_HWI_E015, SKERR_HWI_E015MSG);
 		}
 
 		switch (pPrt->PFlowCtrlMode) {
 		case SK_FLOW_MODE_NONE:
-			Crtl |= PHY_X_P_NO_PAUSE;
+			Ctrl |= PHY_X_P_NO_PAUSE;
 			break;
 		case SK_FLOW_MODE_LOC_SEND:
-			Crtl |= PHY_X_P_ASYM_MD;
+			Ctrl |= PHY_X_P_ASYM_MD;
 			break;
 		case SK_FLOW_MODE_SYMMETRIC:
-			Crtl |= PHY_X_P_SYM_MD;
+			Ctrl |= PHY_X_P_SYM_MD;
 			break;
 		case SK_FLOW_MODE_SYM_OR_REM:
-			Crtl |= PHY_X_P_BOTH_MD;
+			Ctrl |= PHY_X_P_BOTH_MD;
 			break;
 		default:
 			SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,
-				SKERR_HWI_E016, SKERR_HWI_E016MSG) ;
+				SKERR_HWI_E016, SKERR_HWI_E016MSG);
 		}
 
 		/* Write AutoNeg Advertisement Register */
-		PHY_WRITE(IoC, pPrt, Port, PHY_XMAC_AUNE_ADV, Crtl) ;
+		PHY_WRITE(IoC, pPrt, Port, PHY_XMAC_AUNE_ADV, Ctrl);
 
 		/* Restart Autonegotiation */
-		Crtl = PHY_CT_ANE | PHY_CT_RE_CFG;
+		Ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
 	}
 
 	if (DoLoop) {
 		/* Set the Phy Loopback bit, too */
-		Crtl |= PHY_CT_LOOP;
+		Ctrl |= PHY_CT_LOOP;
 	}
 
 	/* Write to the Phy control register */
-	PHY_WRITE(IoC, pPrt, Port, PHY_XMAC_CTRL, Crtl) ;
-}
+	PHY_WRITE(IoC, pPrt, Port, PHY_XMAC_CTRL, Ctrl);
+}	/* SkXmInitPhyXmac*/
+
 
 /******************************************************************************
  *
@@ -1124,23 +1193,29 @@
 static void SkXmInitPhyBcom(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port,		/* Port Index (MAC_1 + n) */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	DoLoop)		/* Should a Phy LOOback be set-up? */
 {
 	SK_GEPORT	*pPrt;
-	SK_U16		Crtl1 = PHY_B_CT_SP1000;
-	SK_U16		Crtl2 = 0;
-	SK_U16		Crtl3 = PHY_SEL_TYPE;
-	SK_U16		Crtl4 = PHY_B_PEC_EN_LTR;
-	SK_U16		Crtl5 = PHY_B_AC_TX_TST;
+	SK_U16		Ctrl1;
+	SK_U16		Ctrl2;
+	SK_U16		Ctrl3;
+	SK_U16		Ctrl4;
+	SK_U16		Ctrl5;
+
+	Ctrl1 = PHY_B_CT_SP1000;
+	Ctrl2 = 0;
+	Ctrl3 = PHY_SEL_TYPE;
+	Ctrl4 = PHY_B_PEC_EN_LTR;
+	Ctrl5 = PHY_B_AC_TX_TST;
 
 	pPrt = &pAC->GIni.GP[Port];
 
-	/* manuell Master/Slave ? */
+	/* manually Master/Slave ? */
 	if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
-		Crtl2 |= PHY_B_1000C_MSE;
+		Ctrl2 |= PHY_B_1000C_MSE;
 		if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
-			Crtl2 |= PHY_B_1000C_MSC;
+			Ctrl2 |= PHY_B_1000C_MSC;
 		}
 	}
 	/* Autonegotiation ? */
@@ -1150,18 +1225,19 @@
 			("InitPhyBcom: no autonegotiation Port %d\n", Port));
 		/* No Autonegiotiation */
 		/* Set DuplexMode in Config register */
-		Crtl1 |= (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
+		Ctrl1 |= (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
 
-		/* Determine Master/Slave manuell if not already done */
+		/* Determine Master/Slave manually if not already done. */
 		if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
-			Crtl2 |= PHY_B_1000C_MSE;	/* set it to Slave */
+			Ctrl2 |= PHY_B_1000C_MSE;	/* set it to Slave */
 		}
 
 		/*
 		 * Do NOT enable Autonegotiation here. This would hold
 		 * the link down because no IDLES are transmitted
 		 */
-	} else {
+	}
+	else {
 		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
 			("InitPhyBcom: with autonegotiation Port %d\n", Port));
 		/* Set Autonegotiation advertisement */
@@ -1169,31 +1245,31 @@
 		/* Set Full/half duplex capabilities */
 		switch (pPrt->PLinkMode) {
 		case SK_LMODE_AUTOHALF:
-			Crtl2 |= PHY_B_1000C_AHD;
+			Ctrl2 |= PHY_B_1000C_AHD;
 			break;
 		case SK_LMODE_AUTOFULL:
-			Crtl2 |= PHY_B_1000C_AFD;
+			Ctrl2 |= PHY_B_1000C_AFD;
 			break;
 		case SK_LMODE_AUTOBOTH:
-			Crtl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD;
+			Ctrl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD;
 			break;
 		default:
 			SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,
-				SKERR_HWI_E015, SKERR_HWI_E015MSG) ;
+				SKERR_HWI_E015, SKERR_HWI_E015MSG);
 		}
 
 		switch (pPrt->PFlowCtrlMode) {
 		case SK_FLOW_MODE_NONE:
-			Crtl3 |= PHY_B_P_NO_PAUSE;
+			Ctrl3 |= PHY_B_P_NO_PAUSE;
 			break;
 		case SK_FLOW_MODE_LOC_SEND:
-			Crtl3 |= PHY_B_P_ASYM_MD;
+			Ctrl3 |= PHY_B_P_ASYM_MD;
 			break;
 		case SK_FLOW_MODE_SYMMETRIC:
-			Crtl3 |= PHY_B_P_SYM_MD;
+			Ctrl3 |= PHY_B_P_SYM_MD;
 			break;
 		case SK_FLOW_MODE_SYM_OR_REM:
-			Crtl3 |= PHY_B_P_BOTH_MD;
+			Ctrl3 |= PHY_B_P_BOTH_MD;
 			break;
 		default:
 			SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,
@@ -1201,7 +1277,7 @@
 		}
 
 		/* Restart Autonegotiation */
-		Crtl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
+		Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
 
 	}
 	
@@ -1210,39 +1286,40 @@
 	   init order of LEDs and XMAC. (MAl) */
 	
 	/* Write 1000Base-T Control Register */
-	PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_1000T_CTRL, Crtl2);
+	PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
 	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
-		("1000Base-T Control Reg = %x\n", Crtl2));
+		("1000Base-T Control Reg = %x\n", Ctrl2));
 	
 	/* Write AutoNeg Advertisement Register */
-	PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUNE_ADV, Crtl3);
+	PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
 	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
-		("AutoNeg Advertisment Reg = %x\n", Crtl3));
+		("AutoNeg Advertisment Reg = %x\n", Ctrl3));
 	
 
 	if (DoLoop) {
 		/* Set the Phy Loopback bit, too */
-		Crtl1 |= PHY_CT_LOOP;
+		Ctrl1 |= PHY_CT_LOOP;
 	}
 
 	if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
 		/* configure fifo to high latency for xmission of ext. packets*/
-		Crtl4 |= PHY_B_PEC_HIGH_LA;
+		Ctrl4 |= PHY_B_PEC_HIGH_LA;
 
 		/* configure reception of extended packets */
-		Crtl5 |= PHY_B_AC_LONG_PACK;
+		Ctrl5 |= PHY_B_AC_LONG_PACK;
 
-		PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, Crtl5);
+		PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, Ctrl5);
 	}
 
 	/* Configure LED Traffic Mode and Jumbo Frame usage if specified */
-	PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_P_EXT_CTRL, Crtl4);
+	PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4);
 	
 	/* Write to the Phy control register */
-	PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, Crtl1);
+	PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, Ctrl1);
 	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
-		("PHY Control Reg = %x\n", Crtl1));
-}
+		("PHY Control Reg = %x\n", Ctrl1));
+}	/* SkXmInitPhyBcom */
+
 
 /******************************************************************************
  *
@@ -1259,21 +1336,25 @@
 static void SkXmInitPhyLone(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port,		/* Port Index (MAC_1 + n) */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	DoLoop)		/* Should a Phy LOOback be set-up? */
 {
 	SK_GEPORT	*pPrt;
-	SK_U16		Crtl1 = PHY_L_CT_SP1000;
-	SK_U16		Crtl2 = 0;
-	SK_U16		Crtl3 = PHY_SEL_TYPE;
+	SK_U16		Ctrl1;
+	SK_U16		Ctrl2;
+	SK_U16		Ctrl3;
+
+	Ctrl1 = PHY_L_CT_SP1000;
+	Ctrl2 = 0;
+	Ctrl3 = PHY_SEL_TYPE;
 
 	pPrt = &pAC->GIni.GP[Port];
 
-	/* manuell Master/Slave ? */
+	/* manually Master/Slave ? */
 	if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
-		Crtl2 |= PHY_L_1000C_MSE;
+		Ctrl2 |= PHY_L_1000C_MSE;
 		if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
-			Crtl2 |= PHY_L_1000C_MSC;
+			Ctrl2 |= PHY_L_1000C_MSC;
 		}
 	}
 	/* Autonegotiation ? */
@@ -1289,18 +1370,19 @@
 			("InitPhyLone: no autonegotiation Port %d\n", Port));
 		/* No Autonegiotiation */
 		/* Set DuplexMode in Config register */
-		Crtl1 = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
+		Ctrl1 = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
 
-		/* Determine Master/Slave manuell if not already done */
+		/* Determine Master/Slave manually if not already done. */
 		if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
-			Crtl2 |= PHY_L_1000C_MSE;	/* set it to Slave */
+			Ctrl2 |= PHY_L_1000C_MSE;	/* set it to Slave */
 		}
 
 		/*
 		 * Do NOT enable Autonegotiation here. This would hold
 		 * the link down because no IDLES are transmitted
 		 */
-	} else {
+	}
+	else {
 		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
 			("InitPhyLone: with autonegotiation Port %d\n", Port));
 		/* Set Autonegotiation advertisement */
@@ -1308,31 +1390,31 @@
 		/* Set Full/half duplex capabilities */
 		switch (pPrt->PLinkMode) {
 		case SK_LMODE_AUTOHALF:
-			Crtl2 |= PHY_L_1000C_AHD;
+			Ctrl2 |= PHY_L_1000C_AHD;
 			break;
 		case SK_LMODE_AUTOFULL:
-			Crtl2 |= PHY_L_1000C_AFD;
+			Ctrl2 |= PHY_L_1000C_AFD;
 			break;
 		case SK_LMODE_AUTOBOTH:
-			Crtl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD;
+			Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD;
 			break;
 		default:
 			SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,
-				SKERR_HWI_E015, SKERR_HWI_E015MSG) ;
+				SKERR_HWI_E015, SKERR_HWI_E015MSG);
 		}
 
 		switch (pPrt->PFlowCtrlMode) {
 		case SK_FLOW_MODE_NONE:
-			Crtl3 |= PHY_L_P_NO_PAUSE;
+			Ctrl3 |= PHY_L_P_NO_PAUSE;
 			break;
 		case SK_FLOW_MODE_LOC_SEND:
-			Crtl3 |= PHY_L_P_ASYM_MD;
+			Ctrl3 |= PHY_L_P_ASYM_MD;
 			break;
 		case SK_FLOW_MODE_SYMMETRIC:
-			Crtl3 |= PHY_L_P_SYM_MD;
+			Ctrl3 |= PHY_L_P_SYM_MD;
 			break;
 		case SK_FLOW_MODE_SYM_OR_REM:
-			Crtl3 |= PHY_L_P_BOTH_MD;
+			Ctrl3 |= PHY_L_P_BOTH_MD;
 			break;
 		default:
 			SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,
@@ -1340,7 +1422,7 @@
 		}
 
 		/* Restart Autonegotiation */
-		Crtl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
+		Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
 
 	}
 	
@@ -1349,19 +1431,19 @@
 	   init order of LEDs and XMAC. (MAl) */
 	
 	/* Write 1000Base-T Control Register */
-	PHY_WRITE(IoC, pPrt, Port, PHY_LONE_1000T_CTRL, Crtl2);
+	PHY_WRITE(IoC, pPrt, Port, PHY_LONE_1000T_CTRL, Ctrl2);
 	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
-		("1000Base-T Control Reg = %x\n", Crtl2));
+		("1000Base-T Control Reg = %x\n", Ctrl2));
 	
 	/* Write AutoNeg Advertisement Register */
-	PHY_WRITE(IoC, pPrt, Port, PHY_LONE_AUNE_ADV, Crtl3);
+	PHY_WRITE(IoC, pPrt, Port, PHY_LONE_AUNE_ADV, Ctrl3);
 	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
-		("AutoNeg Advertisment Reg = %x\n", Crtl3));
+		("AutoNeg Advertisment Reg = %x\n", Ctrl3));
 	
 
 	if (DoLoop) {
 		/* Set the Phy Loopback bit, too */
-		Crtl1 |= PHY_CT_LOOP;
+		Ctrl1 |= PHY_CT_LOOP;
 	}
 
 	if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
@@ -1372,10 +1454,11 @@
 	}
 	
 	/* Write to the Phy control register */
-	PHY_WRITE(IoC, pPrt, Port, PHY_LONE_CTRL, Crtl1);
+	PHY_WRITE(IoC, pPrt, Port, PHY_LONE_CTRL, Ctrl1);
 	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
-		("PHY Control Reg = %x\n", Crtl1));
-}
+		("PHY Control Reg = %x\n", Ctrl1));
+}	/* SkXmInitPhyLone*/
+
 
 /******************************************************************************
  *
@@ -1392,11 +1475,12 @@
 static void SkXmInitPhyNat(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port,		/* Port Index (MAC_1 + n) */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	DoLoop)		/* Should a Phy LOOback be set-up? */
 {
 /* todo: National */
-}
+}	/* SkXmInitPhyNat*/
+
 
 /******************************************************************************
  *
@@ -1409,7 +1493,7 @@
 void	SkXmAutoNegLipaXmac(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port,		/* Port Index (MAC_1 + n) */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_U16	IStatus)	/* Interrupt Status word to analyse */
 {
 	SK_GEPORT	*pPrt;
@@ -1423,7 +1507,8 @@
 			("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, IStatus));
 		pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
 	}
-}
+}	/* SkXmAutoNegLipaXmac*/
+
 
 /******************************************************************************
  *
@@ -1436,21 +1521,20 @@
 void	SkXmAutoNegLipaBcom(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port,		/* Port Index (MAC_1 + n) */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_U16	PhyStat)	/* PHY Status word to analyse */
 {
 	SK_GEPORT	*pPrt;
 
 	pPrt = &pAC->GIni.GP[Port];
 
-	if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
-		(PhyStat & (PHY_ST_AN_OVER))) {
-
+	if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && (PhyStat & PHY_ST_AN_OVER)) {
 		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
 			("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, PhyStat));
 		pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
 	}
-}
+}	/* SkXmAutoNegLipaBcom*/
+
 
 /******************************************************************************
  *
@@ -1477,7 +1561,8 @@
 			("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, PhyStat));
 		pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
 	}
-}
+}	/* SkXmAutoNegLipaLone*/
+
 
 /******************************************************************************
  *
@@ -1490,7 +1575,7 @@
 void	SkXmAutoNegLipaNat(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port,		/* Port Index (MAC_1 + n) */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_U16	PhyStat)	/* PHY Status word to analyse */
 {
 	SK_GEPORT	*pPrt;
@@ -1504,7 +1589,9 @@
 			("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, PhyStat));
 		pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
 	}
-}
+}	/* SkXmAutoNegLipaNat*/
+
+
 /******************************************************************************
  *
  *	SkXmAutoNegDone() - Auto negotiation handling
@@ -1525,13 +1612,9 @@
 int	SkXmAutoNegDone(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port)		/* Port Index (MAC_1 + n) */
+int		Port)		/* Port Index (MAC_1 + n) */
 {
-	SK_GEPORT	*pPrt;
-
-	pPrt = &pAC->GIni.GP[Port];
-
-	switch (pPrt->PhyType) {
+	switch (pAC->GIni.GP[Port].PhyType) {
 	case SK_PHY_XMAC:
 		return (SkXmAutoNegDoneXmac(pAC, IoC, Port));
 	case SK_PHY_BCOM:
@@ -1541,8 +1624,9 @@
 	case SK_PHY_NAT:
 		return (SkXmAutoNegDoneNat(pAC, IoC, Port));
 	}
-	return(SK_AND_OTHER);
-}
+	return (SK_AND_OTHER);
+}	/* SkXmAutoNegDone*/
+
 
 /******************************************************************************
  *
@@ -1562,11 +1646,11 @@
 static int	SkXmAutoNegDoneXmac(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port)		/* Port Index (MAC_1 + n) */
+int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
-	SK_U16		ResAb ;		/* Resolved Ability */
-	SK_U16		LPAb ;		/* Link Partner Ability */
+	SK_U16		ResAb;		/* Resolved Ability */
+	SK_U16		LPAb;		/* Link Partner Ability */
 
 	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegDoneXmac"
 		"Port %d\n",Port));
@@ -1582,21 +1666,23 @@
 		/* Error */
 		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
 			("AutoNegFail: Remote fault bit set Port %d\n", Port));
-		pPrt->PAutoNegFail = SK_TRUE ;
-		return (SK_AND_OTHER) ;
+		pPrt->PAutoNegFail = SK_TRUE;
+		return (SK_AND_OTHER);
 	}
 
 	/* Check Duplex mismatch */
 	if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) {
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL ;
-	} else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF ;
-	} else {
+		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+	}
+	else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {
+		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
+	}
+	else {
 		/* Error */
 		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
 			("AutoNegFail: Duplex mode mismatch port %d\n", Port));
-		pPrt->PAutoNegFail = SK_TRUE ;
-		return (SK_AND_DUP_CAP) ;
+		pPrt->PAutoNegFail = SK_TRUE;
+		return (SK_AND_DUP_CAP);
 	}
 
 	/* Check PAUSE mismatch */
@@ -1607,25 +1693,29 @@
 	    (LPAb & PHY_X_P_SYM_MD)) {
 		/* Symmetric PAUSE */
 		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
-	} else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM &&
+	}
+	else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM &&
 		   (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {
 		/* Enable PAUSE receive, disable PAUSE transmit */
 		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
-	} else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND &&
+	}
+	else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND &&
 		   (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {
 		/* Disable PAUSE receive, enable PAUSE transmit */
 		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
-	} else {
+	}
+	else {
 		/* PAUSE mismatch -> no PAUSE */
 		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
 	}
 
 	/* We checked everything and may now enable the link */
-	pPrt->PAutoNegFail = SK_FALSE ;
+	pPrt->PAutoNegFail = SK_FALSE;
 
 	SkXmRxTxEnable(pAC, IoC, Port);
-	return(SK_AND_OK) ;
-}
+	return (SK_AND_OK);
+}	/* SkXmAutoNegDoneXmac*/
+
 
 /******************************************************************************
  *
@@ -1645,82 +1735,99 @@
 static int	SkXmAutoNegDoneBcom(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port)		/* Port Index (MAC_1 + n) */
+int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
-	SK_U16		ResAb ;		/* Resolved Ability */
-	SK_U16		LPAb ;		/* Link Partner Ability */
+	SK_U16		LPAb;		/* Link Partner Ability */
 	SK_U16		AuxStat;	/* Auxiliary Status */
 
-	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegDoneBcom,"
-		" Port %d\n",Port));
+#if 0
+01-Sep-2000 RA;:;:
+	SK_U16		ResAb;		/* Resolved Ability */
+#endif	/* 0 */
+
+	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
+		("AutoNegDoneBcom, Port %d\n", Port));
 	pPrt = &pAC->GIni.GP[Port];
 
-	/* Get PHY parameters */
+	/* Get PHY parameters. */
 	PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUNE_LP, &LPAb);
+#if 0
+01-Sep-2000 RA;:;:
 	PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb);
+#endif	/* 0 */
 	PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_STAT, &AuxStat);
 
 	if (LPAb & PHY_B_AN_RF) {
-		/* Remote fault bit is set */
-		/* Error */
-		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
+		/* Remote fault bit is set: Error. */
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 			("AutoNegFail: Remote fault bit set Port %d\n", Port));
-		pPrt->PAutoNegFail = SK_TRUE ;
-		return (SK_AND_OTHER) ;
+		pPrt->PAutoNegFail = SK_TRUE;
+		return (SK_AND_OTHER);
 	}
 
-	/* Check Duplex mismatch */
+	/* Check Duplex mismatch. */
 	if ((AuxStat & PHY_B_AS_AN_RES) == PHY_B_RES_1000FD) {
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL ;
-	} else 	if ((AuxStat & PHY_B_AS_AN_RES) == PHY_B_RES_1000HD) {
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF ;
-	} else {
-		/* Error */
+		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+	}
+	else if ((AuxStat & PHY_B_AS_AN_RES) == PHY_B_RES_1000HD) {
+		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
+	}
+	else {
+		/* Error. */
 		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
 			("AutoNegFail: Duplex mode mismatch port %d\n", Port));
-		pPrt->PAutoNegFail = SK_TRUE ;
-		return (SK_AND_DUP_CAP) ;
+		pPrt->PAutoNegFail = SK_TRUE;
+		return (SK_AND_DUP_CAP);
 	}
 	
-	/* Check Master/Slave resolution */
-	if (ResAb & (PHY_B_1000S_MSF)) {
-		/* Error */
-		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
+#if 0
+01-Sep-2000 RA;:;:
+	/* Check Master/Slave resolution. */
+	if (ResAb & PHY_B_1000S_MSF) {
+		/* Error. */
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 			("Master/Slave Fault port %d\n", Port));
 		pPrt->PAutoNegFail = SK_TRUE;
 		pPrt->PMSStatus = SK_MS_STAT_FAULT;
 		return (SK_AND_OTHER);
-	} else if (ResAb & PHY_B_1000S_MSR) {
-		pPrt->PMSStatus = SK_MS_STAT_MASTER ;
-	} else {
-		pPrt->PMSStatus = SK_MS_STAT_SLAVE ;
 	}
+	else if (ResAb & PHY_B_1000S_MSR) {
+		pPrt->PMSStatus = SK_MS_STAT_MASTER;
+	}
+	else {
+		pPrt->PMSStatus = SK_MS_STAT_SLAVE;
+	}
+#endif	/* 0 */
 
-	/* Check PAUSE mismatch */
-	/* We are NOT using chapter 4.23 of the Xaqti manual */
-	/* We are using IEEE 802.3z/D5.0 Table 37-4 */
+	/* Check PAUSE mismatch. */
+	/* We are NOT using chapter 4.23 of the Xaqti manual. */
+	/* We are using IEEE 802.3z/D5.0 Table 37-4. */
 	if ((AuxStat & (PHY_B_AS_PRR | PHY_B_AS_PRT)) == 
 		(PHY_B_AS_PRR | PHY_B_AS_PRT)) {
-		/* Symmetric PAUSE */
+		/* Symmetric PAUSE. */
 		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
-	} else if ((AuxStat & (PHY_B_AS_PRR | PHY_B_AS_PRT)) == PHY_B_AS_PRR) {
-		/* Enable PAUSE receive, disable PAUSE transmit */
+	}
+	else if ((AuxStat & (PHY_B_AS_PRR | PHY_B_AS_PRT)) == PHY_B_AS_PRR) {
+		/* Enable PAUSE receive, disable PAUSE transmit. */
 		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
-	} else if ((AuxStat & (PHY_B_AS_PRR | PHY_B_AS_PRT)) == PHY_B_AS_PRT) {
-		/* Disable PAUSE receive, enable PAUSE transmit */
+	}
+	else if ((AuxStat & (PHY_B_AS_PRR | PHY_B_AS_PRT)) == PHY_B_AS_PRT) {
+		/* Disable PAUSE receive, enable PAUSE transmit. */
 		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
-	} else {
-		/* PAUSE mismatch -> no PAUSE */
+	}
+	else {
+		/* PAUSE mismatch -> no PAUSE. */
 		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
 	}
 
-	/* We checked everything and may now enable the link */
-	pPrt->PAutoNegFail = SK_FALSE ;
+	/* We checked everything and may now enable the link. */
+	pPrt->PAutoNegFail = SK_FALSE;
 
 	SkXmRxTxEnable(pAC, IoC, Port);
-	return(SK_AND_OK) ;
-}
+	return (SK_AND_OK);
+}	/* SkXmAutoNegDoneBcom*/
+
 
 /******************************************************************************
  *
@@ -1740,11 +1847,11 @@
 static int	SkXmAutoNegDoneLone(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port)		/* Port Index (MAC_1 + n) */
+int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
-	SK_U16		ResAb ;		/* Resolved Ability */
-	SK_U16		LPAb ;		/* Link Partner Ability */
+	SK_U16		ResAb;		/* Resolved Ability */
+	SK_U16		LPAb;		/* Link Partner Ability */
 	SK_U16		QuickStat;	/* Auxiliary Status */
 
 	SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegDoneLone"
@@ -1761,15 +1868,16 @@
 		/* Error */
 		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
 			("AutoNegFail: Remote fault bit set Port %d\n", Port));
-		pPrt->PAutoNegFail = SK_TRUE ;
-		return (SK_AND_OTHER) ;
+		pPrt->PAutoNegFail = SK_TRUE;
+		return (SK_AND_OTHER);
 	}
 
 	/* Check Duplex mismatch */
 	if (QuickStat & PHY_L_QS_DUP_MOD) {
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL ;
-	} else {
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF ;
+		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+	}
+	else {
+		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
 	}
 	
 	/* Check Master/Slave resolution */
@@ -1778,12 +1886,14 @@
 		SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
 			("Master/Slave Fault port %d\n", Port));
 		pPrt->PAutoNegFail = SK_TRUE;
-		pPrt->PMSStatus = SK_MS_STAT_FAULT ;
+		pPrt->PMSStatus = SK_MS_STAT_FAULT;
 		return (SK_AND_OTHER);
-	} else if (ResAb & PHY_L_1000S_MSR) {
-		pPrt->PMSStatus = SK_MS_STAT_MASTER ;
-	} else {
-		pPrt->PMSStatus = SK_MS_STAT_SLAVE ;
+	}
+	else if (ResAb & PHY_L_1000S_MSR) {
+		pPrt->PMSStatus = SK_MS_STAT_MASTER;
+	}
+	else {
+		pPrt->PMSStatus = SK_MS_STAT_SLAVE;
 	}
 
 	/* Check PAUSE mismatch */
@@ -1825,11 +1935,12 @@
 	}
 
 	/* We checked everything and may now enable the link */
-	pPrt->PAutoNegFail = SK_FALSE ;
+	pPrt->PAutoNegFail = SK_FALSE;
 
 	SkXmRxTxEnable(pAC, IoC, Port);
-	return(SK_AND_OK);
-}
+	return (SK_AND_OK);
+}	/* SkXmAutoNegDoneLone */
+
 
 /******************************************************************************
  *
@@ -1851,11 +1962,12 @@
 static int	SkXmAutoNegDoneNat(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port)		/* Port Index (MAC_1 + n) */
+int		Port)		/* Port Index (MAC_1 + n) */
 {
 /* todo: National */
-	return(SK_AND_OK);
-}
+	return (SK_AND_OK);
+}	/* SkXmAutoNegDoneNat*/
+
 
 /******************************************************************************
  *
@@ -1873,10 +1985,10 @@
 int SkXmRxTxEnable(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port)		/* Port Index (MAC_1 + n) */
+int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
-	SK_U16		Reg ;		/* 16bit register value */
+	SK_U16		Reg;		/* 16bit register value */
 	SK_U16		IntMask;	/* XMac interrupt mask */
 	SK_U16		SWord;
 
@@ -1884,7 +1996,7 @@
 
 	if (!pPrt->PHWLinkUp) {
 		/* The Hardware link is NOT up */
-		return(0) ;
+		return (0);
 	}
 
 	if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF ||
@@ -1892,7 +2004,7 @@
 	     pPrt->PLinkMode == SK_LMODE_AUTOBOTH) &&
 	     pPrt->PAutoNegFail) {
 		/* Autonegotiation is not done or failed */
-		return(0) ;
+		return (0);
 	}
 
 	/* Set Dup Mode and Pause Mode */
@@ -1929,14 +2041,11 @@
 		/* Workaround BCOM Errata (#10523) for all BCom Phys */
 		/* Enable Power Management after link up */
 		PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &SWord);
-		PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL,	
-			SWord & ~PHY_B_AC_DIS_PM);
-		PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK, 
-			PHY_B_DEF_MSK);
+		PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, SWord & ~PHY_B_AC_DIS_PM);
+		PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
 		break;
 	case SK_PHY_LONE:
-		PHY_WRITE(IoC, pPrt, Port, PHY_LONE_INT_ENAB, 
-			PHY_L_DEF_MSK);
+		PHY_WRITE(IoC, pPrt, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK);
 		break;
 	case SK_PHY_NAT:
 		/* todo National:
@@ -1948,9 +2057,10 @@
 	XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
 				      
 	return (0);
-}
+}	/* SkXmRxTxEnable*/
 
 #ifndef SK_DIAG
+
 /******************************************************************************
  *
  *	SkXmIrq() - Interrupt service routine
@@ -1976,11 +2086,12 @@
 void SkXmIrq(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* IO context */
-int	Port,		/* Port Index (MAC_1 + n) */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_U16	IStatus)	/* Interrupt status read from the XMAC */
 {
 	SK_GEPORT	*pPrt;
 	SK_EVPARA	Para;
+	SK_U16		IStatus2;
 
 	pPrt = &pAC->GIni.GP[Port];
 	
@@ -1992,7 +2103,7 @@
 	}
 	
 	/*
-	 * LinkPartner Autonegable ?
+	 * LinkPartner Autonegable?
 	 */
 	if (pPrt->PhyType == SK_PHY_XMAC) {
 		SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus);
@@ -2004,11 +2115,22 @@
 	if (!pPrt->PHWLinkUp) {
 		/* Spurious XMAC interrupt */
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-			("SkXmIrq: spurious interrupt on port %d\n",
-			 Port));
+			("SkXmIrq: spurious interrupt on port %d\n", Port));
 		return;
 	}
 
+	if (IStatus & XM_IS_INP_ASS) {
+		/* Reread ISR Register if link is not in sync */
+		XM_IN16(IoC, Port, XM_ISRC, &IStatus2);
+
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+			("SkXmIrq: Link async. Double check port %d %x %x\n",
+			 Port, IStatus, IStatus2));
+		IStatus &= ~XM_IS_INP_ASS;
+		IStatus |= IStatus2;
+
+	}
+
 	if (IStatus & XM_IS_LNK_AE) {
 		/* not used GP0 is used instead */
 	}
@@ -2030,7 +2152,7 @@
 
 		/* Start workaround Errata #2 timer */
 		SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer,
-			SK_WA_INA_TIME,SKGE_HWAC,SK_HWEV_WATIM,Para);
+			SK_WA_INA_TIME, SKGE_HWAC, SK_HWEV_WATIM, Para);
 	}
 
 	if (IStatus & XM_IS_RX_PAGE) {
@@ -2069,7 +2191,7 @@
 	if (IStatus & XM_IS_TXF_UR) {
 		/* may NOT happen -> error log */
 		SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E020,
-			SKERR_SIRQ_E020MSG) ;
+			SKERR_SIRQ_E020MSG);
 	}
 
 	if (IStatus & XM_IS_TX_COMP) {
@@ -2080,7 +2202,8 @@
 		/* not served here */
 	}
 
-}
+}	/* SkXmIrq*/
+
 #endif /* !SK_DIAG */
 
 /* End of file */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c
--- v2.4.6/linux/drivers/net/sk_g16.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/sk_g16.c	Wed Jul  4 11:50:39 2001
@@ -542,12 +542,13 @@
 {
 	int ioaddr;			   /* I/O port address used for POS regs */
 	int *port, ports[] = SK_IO_PORTS;  /* SK_G16 supported ports */
+	static unsigned version_printed;
 
 	/* get preconfigured base_addr from dev which is done in Space.c */
 	int base_addr = dev->base_addr; 
 
-        PRINTK(("%s: %s", SK_NAME, rcsid));
-        rcsid = NULL;                 /* We do not want to use this further */
+	if (version_printed++ == 0)
+	        PRINTK(("%s: %s", SK_NAME, rcsid));
 
 	if (base_addr > 0x0ff)        /* Check a single specified address */
 	{
@@ -2078,7 +2079,7 @@
  *     YY/MM/DD  uid  Description
 -*/
 
-void SK_print_ram(struct net_device *dev)
+void __init SK_print_ram(struct net_device *dev)
 {
 
     int i;    
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk_mca.c linux/drivers/net/sk_mca.c
--- v2.4.6/linux/drivers/net/sk_mca.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/sk_mca.c	Wed Jul  4 11:50:39 2001
@@ -91,6 +91,7 @@
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/mca.h>
+#include <linux/init.h>
 #include <asm/processor.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -151,7 +152,7 @@
 
 /* deduce resources out of POS registers */
 
-static void getaddrs(int slot, int junior, int *base, int *irq,
+static void __init getaddrs(int slot, int junior, int *base, int *irq,
 		     skmca_medium * medium)
 {
 	u_char pos0, pos1, pos2;
@@ -197,7 +198,7 @@
    is disabled and won't get detected using the standard probe.  We
    therefore have to scan the slots manually :-( */
 
-static int dofind(int *junior, int firstslot)
+static int __init dofind(int *junior, int firstslot)
 {
 	int slot;
 	unsigned int id;
@@ -524,7 +525,7 @@
 
 /* probe for device's irq */
 
-static int ProbeIRQ(struct SKMCA_NETDEV *dev)
+static int __init ProbeIRQ(struct SKMCA_NETDEV *dev)
 {
 	unsigned long imaskval, njiffies, irq;
 	u16 csr0val;
@@ -1072,7 +1073,7 @@
 
 static int startslot;		/* counts through slots when probing multiple devices */
 
-int skmca_probe(struct SKMCA_NETDEV *dev)
+int __init skmca_probe(struct SKMCA_NETDEV *dev)
 {
 	int force_detect = 0;
 	int junior, slot, i;
@@ -1250,8 +1251,8 @@
 };
 #endif
 
-int irq = 0;
-int io = 0;
+int irq;
+int io;
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.6/linux/drivers/net/skfp/ess.c linux/drivers/net/skfp/ess.c
--- v2.4.6/linux/drivers/net/skfp/ess.c	Wed Jul  5 10:56:13 2000
+++ linux/drivers/net/skfp/ess.c	Wed Jul  4 11:50:39 2001
@@ -258,8 +258,16 @@
 		 * Extract message parameters
 		 */
 		p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
+                if (!p) {
+                        printk(KERN_ERR "ESS: sm_to_para failed");
+                        return fs;
+                }       
 		payload = ((struct smt_p_320f *)p)->mib_payload ;
 		p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
+                if (!p) {
+                        printk(KERN_ERR "ESS: sm_to_para failed");
+                        return fs;
+                }       
 		overhead = ((struct smt_p_3210 *)p)->mib_overhead ;
 
 		DB_ESSN(2,"payload= %lx	overhead= %lx\n",payload,overhead) ;
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sun3lance.c linux/drivers/net/sun3lance.c
--- v2.4.6/linux/drivers/net/sun3lance.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/sun3lance.c	Wed Jul  4 11:50:39 2001
@@ -881,7 +881,7 @@
 
 
 #ifdef MODULE
-static char devicename[9] = { 0, };
+static char devicename[9];
 
 static struct net_device sun3lance_dev =
 {
diff -u --recursive --new-file v2.4.6/linux/drivers/net/tokenring/ibmtr.c linux/drivers/net/tokenring/ibmtr.c
--- v2.4.6/linux/drivers/net/tokenring/ibmtr.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/tokenring/ibmtr.c	Wed Jul  4 11:50:39 2001
@@ -10,7 +10,8 @@
  *	I used Donald Becker's (becker@cesdis.gsfc.nasa.gov) device driver work
  *	as a base for most of my initial work.
  *
- *	Changes by Peter De Schrijver (Peter.Deschrijver@linux.cc.kuleuven.ac.be) :
+ *	Changes by Peter De Schrijver
+ *		(Peter.Deschrijver@linux.cc.kuleuven.ac.be) :
  *
  *	+ changed name to ibmtr.c in anticipation of other tr boards.
  *	+ changed reset code and adapter open code.
@@ -47,6 +48,7 @@
  *	+ added -DPCMCIA to support PCMCIA
  *	+ detecting PCMCIA Card Removal in interrupt handler.  If
  *	  ISRP is FF, then a PCMCIA card has been removed
+ *        10/2000 Burt needed a new method to avoid crashing the OS
  *
  *	Changes by Paul Norton (pnorton@cts.com) :
  *	+ restructured the READ.LOG logic to prevent the transmit SRB
@@ -83,7 +85,7 @@
  *      Changes by Jochen Friedrich to enable RFC1469 Option 2 multicasting
  *      i.e. using functional address C0 00 00 04 00 00 to transmit and 
  *      receive multicast packets.
- * 
+ *
  *      Changes by Mike Sullivan (based on original sram patch by Dave Grothe
  *      to support windowing into on adapter shared ram.
  *      i.e. Use LANAID to setup a PnP configuration with 16K RAM. Paging
@@ -91,6 +93,13 @@
  *
  *      Changes by Peter De Schrijver (p2@mind.be) :
  *      + fixed a problem with PCMCIA card removal
+ *
+ *      Change by Mike Sullivan et al.:
+ *      + added turbo card support. No need to use lanaid to configure
+ *      the adapter into isa compatiblity mode.
+ *
+ *      Changes by Burt Silverman to allow the computer to behave nicely when
+ *	a cable is pulled or not in place, or a PCMCIA card is removed hot.
  */
 
 /* change the define of IBMTR_DEBUG_MESSAGES to a nonzero value 
@@ -100,207 +109,247 @@
 
 #include <linux/module.h>
 
-#define NO_AUTODETECT 1
-#undef NO_AUTODETECT
-/* #undef ENABLE_PAGING */
-#define ENABLE_PAGING 1
-
+#ifdef PCMCIA
+#undef MODULE
+#undef ENABLE_PAGING
+#else
+#define ENABLE_PAGING 1		
+#endif
 
 #define FALSE 0
 #define TRUE (!FALSE)
 
-/* changes the output format of driver initialisation */
-#define TR_NEWFORMAT	1
+/* changes the output format of driver initialization */
 #define TR_VERBOSE	0
 
 /* some 95 OS send many non UI frame; this allow removing the warning */
 #define TR_FILTERNONUI	1
 
-/* version and credits */
-static char *version =
-"ibmtr.c: v1.3.57   8/ 7/94 Peter De Schrijver and Mark Swanson\n"
-"         v2.1.125 10/20/98 Paul Norton <pnorton@ieee.org>\n"
-"         v2.2.0   12/30/98 Joel Sloan <jjs@c-me.com>\n"
-"         v2.2.1   02/08/00 Mike Sullivan <sullivam@us.ibm.com>\n";
-
-static char pcchannelid[] = {
-	0x05, 0x00, 0x04, 0x09,
-	0x04, 0x03, 0x04, 0x0f,
-	0x03, 0x06, 0x03, 0x01,
-	0x03, 0x01, 0x03, 0x00,
-	0x03, 0x09, 0x03, 0x09,
-	0x03, 0x00, 0x02, 0x00
-};
-
-static char mcchannelid[] = {
-	0x04, 0x0d, 0x04, 0x01,
-	0x05, 0x02, 0x05, 0x03,
-	0x03, 0x06, 0x03, 0x03,
-	0x05, 0x08, 0x03, 0x04,
-	0x03, 0x05, 0x03, 0x01,
-	0x03, 0x08, 0x02, 0x00
-};
-
-#include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/in.h>
 #include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/skbuff.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/trdevice.h>
-#include <linux/stddef.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
 #include <linux/ibmtr.h>
 #include <net/checksum.h>
 
 #include <asm/io.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-
-
 
 #define DPRINTK(format, args...) printk("%s: " format, dev->name , ## args)
 #define DPRINTD(format, args...) DummyCall("%s: " format, dev->name , ## args)
 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
 #define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
 
-#if TR_NEWFORMAT
+/* version and credits */
+#ifndef PCMCIA
+static char version[] __initdata =
+    "\nibmtr.c: v1.3.57   8/ 7/94 Peter De Schrijver and Mark Swanson\n"
+    "         v2.1.125 10/20/98 Paul Norton    <pnorton@ieee.org>\n"
+    "         v2.2.0   12/30/98 Joel Sloan     <jjs@c-me.com>\n"
+    "         v2.2.1   02/08/00 Mike Sullivan  <sullivam@us.ibm.com>\n" 
+    "         v2.2.2   07/27/00 Burt Silverman <burts@us.ibm.com>\n" 
+    "         v2.4.0   03/01/01 Mike Sullivan <sullivan@us.ibm.com>\n";
+#endif
+
 /* this allows displaying full adapter information */
 
-const char *channel_def[] __initdata = { 
-	"ISA", "MCA", "ISA P&P" 
+char *channel_def[] __initdata = { "ISA", "MCA", "ISA P&P" };
+
+static char pcchannelid[] __devinitdata = {
+	0x05, 0x00, 0x04, 0x09,
+	0x04, 0x03, 0x04, 0x0f,
+	0x03, 0x06, 0x03, 0x01,
+	0x03, 0x01, 0x03, 0x00,
+	0x03, 0x09, 0x03, 0x09,
+	0x03, 0x00, 0x02, 0x00
+};
+
+static char mcchannelid[] __devinitdata =  {
+	0x04, 0x0d, 0x04, 0x01,
+	0x05, 0x02, 0x05, 0x03,
+	0x03, 0x06, 0x03, 0x03,
+	0x05, 0x08, 0x03, 0x04,
+	0x03, 0x05, 0x03, 0x01,
+	0x03, 0x08, 0x02, 0x00
 };
 
-char __init *adapter_def(char type)
+char __devinit *adapter_def(char type)
 {
-	switch (type) 
-	{
-	      case 0xF : return "PC Adapter | PC Adapter II | Adapter/A";
-	      case 0xE : return "16/4 Adapter | 16/4 Adapter/A (long)";
-	      case 0xD : return "16/4 Adapter/A (short) | 16/4 ISA-16 Adapter";
-	      case 0xC : return "Auto 16/4 Adapter";
-	      default  : return "adapter (unknown type)";
+	switch (type) {
+	case 0xF: return "PC Adapter | PC Adapter II | Adapter/A";
+	case 0xE: return "16/4 Adapter | 16/4 Adapter/A (long)";
+	case 0xD: return "16/4 Adapter/A (short) | 16/4 ISA-16 Adapter";
+	case 0xC: return "Auto 16/4 Adapter";
+	default: return "adapter (unknown type)";
 	};
 };
-#endif
 
-#if !TR_NEWFORMAT
-unsigned char ibmtr_debug_trace=1;  /*  Patch or otherwise alter to
-                                         control tokenring tracing.  */
-#else
-unsigned char ibmtr_debug_trace=0;
-#endif
-#define TRC_INIT 0x01              /*  Trace initialization & PROBEs */
-#define TRC_INITV 0x02             /*  verbose init trace points     */
+#define TRC_INIT 0x01		/*  Trace initialization & PROBEs */
+#define TRC_INITV 0x02		/*  verbose init trace points     */
+unsigned char ibmtr_debug_trace = 0;
 
-int		ibmtr_probe(struct net_device *dev);
+int 		ibmtr_probe(struct net_device *dev);
 static int	ibmtr_probe1(struct net_device *dev, int ioaddr);
-static unsigned char	get_sram_size(struct tok_info *adapt_info);
-#ifdef PCMCIA
-extern unsigned char 	pcmcia_reality_check(unsigned char gss);
-#endif
-static int	tok_init_card(struct net_device *dev);
-void		tok_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static int	trdev_init(struct net_device *dev);
+static unsigned char get_sram_size(struct tok_info *adapt_info);
+static int 	trdev_init(struct net_device *dev);
+static int 	tok_open(struct net_device *dev);
+static int 	tok_init_card(struct net_device *dev);
+void 		tok_open_adapter(unsigned long dev_addr);
+static void 	open_sap(unsigned char type, struct net_device *dev);
+static void 	tok_set_multicast_list(struct net_device *dev);
+static int 	tok_send_packet(struct sk_buff *skb, struct net_device *dev);
+static int 	tok_close(struct net_device *dev);
+void 		tok_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void 	initial_tok_int(struct net_device *dev);
-static void 	open_sap(unsigned char type,struct net_device *dev);
-void		tok_open_adapter(unsigned long dev_addr);
-static		void tr_rx(struct net_device *dev);
-static		void tr_tx(struct net_device *dev);
-static int	tok_open(struct net_device *dev);
-static int	tok_close(struct net_device *dev);
-static int	tok_send_packet(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats * tok_get_stats(struct net_device *dev);
-static void	tok_set_multicast_list(struct net_device *dev);
-void		ibmtr_readlog(struct net_device *dev);
-void		ibmtr_reset_timer(struct timer_list *tmr, struct net_device *dev);
-int             ibmtr_change_mtu(struct net_device *dev, int mtu);
+static void 	tr_tx(struct net_device *dev);
+static void 	tr_rx(struct net_device *dev);
+void 		ibmtr_reset_timer(struct timer_list*tmr,struct net_device *dev);
+static void	tok_rerun(unsigned long dev_addr);
+void 		ibmtr_readlog(struct net_device *dev);
+static struct 	net_device_stats *tok_get_stats(struct net_device *dev);
+int 		ibmtr_change_mtu(struct net_device *dev, int mtu);
+static void	find_turbo_adapters(int *iolist);
 
-static unsigned int ibmtr_portlist[] __initdata = {
-	0xa20, 0xa24, 0
+static int ibmtr_portlist[IBMTR_MAX_ADAPTERS+1] __devinitdata = {
+	0xa20, 0xa24, 0, 0, 0
 };
+static int __devinitdata turbo_io[IBMTR_MAX_ADAPTERS] = {0};
+static int __devinitdata turbo_irq[IBMTR_MAX_ADAPTERS] = {0};
+static int __devinitdata turbo_searched = 0;
 
-static __u32 ibmtr_mem_base = 0xd0000;
+#ifndef PCMCIA
+static __u32 ibmtr_mem_base __initdata = 0xd0000;
+#endif
 
-static void __init PrtChanID(char *pcid, short stride) 
+static void __devinit PrtChanID(char *pcid, short stride)
 {
 	short i, j;
-	for (i=0, j=0; i<24; i++, j+=stride)
+	for (i = 0, j = 0; i < 24; i++, j += stride)
 		printk("%1x", ((int) pcid[j]) & 0x0f);
 	printk("\n");
 }
 
-static void __init HWPrtChanID (__u32 pcid, short stride)
+static void __devinit HWPrtChanID(__u32 pcid, short stride)
 {
 	short i, j;
-	for (i=0, j=0; i<24; i++, j+=stride)
-		printk("%1x", ((int)isa_readb(pcid + j)) & 0x0f);
+	for (i = 0, j = 0; i < 24; i++, j += stride)
+		printk("%1x", ((int) readb(pcid + j)) & 0x0f);
 	printk("\n");
 }
 
-/*
+static void __devinit find_turbo_adapters(int *iolist) {
+	int ram_addr;
+	int index=0;
+	__u32 chanid;
+	int found_turbo=0;
+	unsigned char *tchanid, ctemp;
+	int i,j;
+  
+	if (turbo_searched == 1) return;
+	turbo_searched=1;
+	for (ram_addr=0xC0000; ram_addr < 0xE0000; ram_addr+=0x2000) {
+
+		__u32 intf_tbl=0;
+
+		found_turbo=1;
+		chanid=(CHANNEL_ID + ram_addr);
+		tchanid=pcchannelid;
+		ctemp=isa_readb(chanid) & 0x0f;
+		if (ctemp != *tchanid) continue;
+		for (i=2,j=1; i<=46; i=i+2,j++) {
+			if ((isa_readb(chanid+i) & 0x0f) != tchanid[j]){
+				found_turbo=0;
+				break;
+			}
+		}
+		if (!found_turbo) continue;
+
+		isa_writeb(0x90, ram_addr+0x1E01);
+		for(i=2; i<0x0f; i++) {
+			isa_writeb(0x00, ram_addr+0x1E01+i);
+		}
+		isa_writeb(0x00, ram_addr+0x1E01);
+		for(i=jiffies+TR_BUSY_INTERVAL; time_before_eq(jiffies,i););
+		intf_tbl=ntohs(isa_readw(ram_addr+ACA_OFFSET+ACA_RW+WRBR_EVEN));
+		if (intf_tbl) {
+#if IBMTR_DEBUG_MESSAGES
+			printk("ibmtr::find_turbo_adapters, Turbo found at "
+				"ram_addr %x\n",ram_addr);
+			printk("ibmtr::find_turbo_adapters, interface_table ");
+			for(i=0; i<6; i++) {
+				printk("%x:",isa_readb(ram_addr+intf_tbl+i));
+			}
+			printk("\n");
+#endif
+			turbo_io[index]=ntohs(isa_readw(ram_addr+intf_tbl+4));
+			turbo_irq[index]=isa_readb(ram_addr+intf_tbl+3);
+			outb(0, turbo_io[index] + ADAPTRESET);
+			for(i=jiffies+TR_RST_TIME;time_before_eq(jiffies,i););
+			outb(0, turbo_io[index] + ADAPTRESETREL);
+			index++;
+			continue;
+		}
+#if IBMTR_DEBUG_MESSAGES 
+		printk("ibmtr::find_turbo_adapters, ibmtr card found at"
+			" %x but not a Turbo model\n",ram_addr);
+#endif
+	}
+	for(i=0; i<IBMTR_MAX_ADAPTERS; i++) {
+		if(!turbo_io[i]) break;
+		for (j=0; j<IBMTR_MAX_ADAPTERS; j++) {
+			if ( iolist[j] && iolist[j] != turbo_io[i]) continue;
+			iolist[j]=turbo_io[i];
+			break;
+		}
+	}
+}
+
+/****************************************************************************
  *	ibmtr_probe():  Routine specified in the network device structure
  *	to probe for an IBM Token Ring Adapter.  Routine outline:
  *	I.    Interrogate hardware to determine if an adapter exists
  *	      and what the speeds and feeds are
  *	II.   Setup data structures to control execution based upon
  *	      adapter characteristics.
- *	III.  Initialize adapter operation
  *
  *	We expect ibmtr_probe to be called once for each device entry
  *	which references it.
- *
- *	Argument 'dev' should never be NULL.  If we are built into
- *	the kernel, Space.c passed up a net_device.  If we are
- *	-DMODULE, init_module allocates net_devices for us.
- */
- 
-int __init ibmtr_probe(struct net_device *dev)
+ ****************************************************************************/
+
+int __devinit ibmtr_probe(struct net_device *dev)
 {
-        int i;
-        int base_addr = dev->base_addr;
+	int i;
+	int base_addr = dev->base_addr;
 
-        if (base_addr > 0x1ff) 
-        { 
-        	/*
-        	 *	Check a single specified location. 
- 		 */
- 		 
-	        if (ibmtr_probe1(dev, base_addr)) 
-		       return -ENODEV;
-		else
-		       return 0;
+	if (base_addr && base_addr <= 0x1ff) /* Don't probe at all. */
+		return -ENXIO;
+	if (base_addr > 0x1ff) { /* Check a single specified location.  */
+		if (!ibmtr_probe1(dev, base_addr)) return 0;
+		return -ENODEV;
 	}
-        else if (base_addr != 0)   /* Don't probe at all. */
-	        return -ENXIO;
-
-	for (i = 0; ibmtr_portlist[i]; i++) 
-	{
-	        int ioaddr = ibmtr_portlist[i];
-		if (check_region(ioaddr, IBMTR_IO_EXTENT))
-		        continue;
-		if (!ibmtr_probe1(dev, ioaddr))
-			return 0;
-        }
+	find_turbo_adapters(ibmtr_portlist);
+	for (i = 0; ibmtr_portlist[i]; i++) {
+		int ioaddr = ibmtr_portlist[i];
 
-        return -ENODEV;
+		if (check_region(ioaddr, IBMTR_IO_EXTENT)) continue;
+		if (!ibmtr_probe1(dev, ioaddr)) return 0;
+	}
+	return -ENODEV;
 }
 
-static int __init ibmtr_probe1(struct net_device *dev, int PIOaddr)
+/*****************************************************************************/
+
+static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
 {
-	unsigned char segment=0, intr=0, irq=0, i=0, j=0, cardpresent=NOTOK,temp=0;
-	__u32 t_mmio=0;
-	struct tok_info *ti=0;
+
+	unsigned char segment, intr=0, irq=0, i, j, cardpresent=NOTOK, temp=0;
+	__u32 t_mmio = 0;
+	struct tok_info *ti = 0;
 	__u32 cd_chanid;
 	unsigned char *tchanid, ctemp;
 #ifndef PCMCIA
-	unsigned long timeout;
+	unsigned char t_irq=0;
+        unsigned long timeout;
+	static int version_printed;
 #endif
 
 #ifndef MODULE
@@ -309,466 +358,414 @@
 #endif
 #endif
 
-	/*	Query the adapter PIO base port which will return
-	 *	indication of where MMIO was placed. We also have a
-	 *	coded interrupt number.
-	 */
-
-       	segment = inb(PIOaddr);
-
-	/*
-	 *	Out of range values so we'll assume non-existent IO device 
+	/*    Query the adapter PIO base port which will return
+	 *    indication of where MMIO was placed. We also have a
+	 *    coded interrupt number.
 	 */
-	 
-	if (segment < 0x40 || segment > 0xe0)
-                return -ENODEV;
-
+	segment = inb(PIOaddr);
+	if (segment < 0x40 || segment > 0xe0) {
+		/* Out of range values so we'll assume non-existent IO device
+		 * but this is not necessarily a problem, esp if a turbo
+		 * adapter is being used.  */
+#if IBMTR_DEBUG_MESSAGES
+		DPRINTK("ibmtr_probe1(): unhappy that inb(0x%X) == 0x%X, "
+			"Hardware Problem?\n",PIOaddr,segment);
+#endif
+		return -ENODEV;
+	}
 	/*
-	 *	Compute the linear base address of the MMIO area
-	 *	as LINUX doesn't care about segments
+	 *    Compute the linear base address of the MMIO area
+	 *    as LINUX doesn't care about segments
 	 */
-
-	t_mmio=(((__u32)(segment & 0xfc) << 11) + 0x80000);
-	intr = segment & 0x03;   /* low bits is coded interrupt # */
+	t_mmio = (u32)ioremap(((__u32) (segment & 0xfc) << 11) + 0x80000,2048);
+	if (!t_mmio) { 
+		DPRINTK("Cannot remap mmiobase memory area") ; 
+		return -ENODEV ; 
+	} 
+	intr = segment & 0x03;	/* low bits is coded interrupt # */
 	if (ibmtr_debug_trace & TRC_INIT)
-		DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %08X intr: %d\n",
-                         PIOaddr, (int)segment, t_mmio, (int)intr);
-
-	/*
-	 *	Now we will compare expected 'channelid' strings with
-	 *	what we is there to learn of ISA/MCA or not TR card
-	 */
-	 
-	cd_chanid = (CHANNEL_ID + t_mmio);  /* for efficiency */
-	tchanid=pcchannelid;
-	cardpresent=TR_ISA;  /* try ISA */
+		DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %08X intr: %d\n"
+				, PIOaddr, (int) segment, t_mmio, (int) intr);
 
 	/*
-	 *	Suboptimize knowing first byte different
+	 *    Now we will compare expected 'channelid' strings with
+	 *    what we is there to learn of ISA/MCA or not TR card
 	 */
-
-	ctemp = isa_readb(cd_chanid) & 0x0f;
-	if (ctemp != *tchanid) { /* NOT ISA card, try MCA */
-		tchanid=mcchannelid;
-		cardpresent=TR_MCA;
-		if (ctemp != *tchanid)  /* Neither ISA nor MCA */
-			cardpresent=NOTOK;
-	}
-
-	if (cardpresent != NOTOK) 
-	{
-		/* 
-		 *	Know presumed type, try rest of ID 
-		 */
-		for (i=2,j=1; i<=46; i=i+2,j++) 
-		{
-			if ((isa_readb(cd_chanid+i) & 0x0f) != tchanid[j]) {
-				cardpresent=NOTOK;   /* match failed, not TR card */
-				break;
-			}
+#ifdef PCMCIA
+	ti = dev->priv;		/*BMS moved up here */
+	t_mmio = ti->mmio;	/*BMS to get virtual address */
+	irq = ti->irq;		/*BMS to display the irq!   */
+#endif
+	cd_chanid = (CHANNEL_ID + t_mmio);	/* for efficiency */
+	tchanid = pcchannelid;
+	cardpresent = TR_ISA;	/* try ISA */
+
+	/*    Suboptimize knowing first byte different */
+	ctemp = readb(cd_chanid) & 0x0f;
+	if (ctemp != *tchanid) {	/* NOT ISA card, try MCA */
+		tchanid = mcchannelid;
+		cardpresent = TR_MCA;
+		if (ctemp != *tchanid)	/* Neither ISA nor MCA */
+			cardpresent = NOTOK;
+	}
+	if (cardpresent != NOTOK) {
+		/*       Know presumed type, try rest of ID */
+		for (i = 2, j = 1; i <= 46; i = i + 2, j++) {
+			if( (readb(cd_chanid+i)&0x0f) == tchanid[j]) continue;
+			/* match failed, not TR card */
+			cardpresent = NOTOK;
+			break;
 		}
 	}
-
 	/* 
-	 *	If we have an ISA board check for the ISA P&P version,
-	 *	as it has different IRQ settings 
+	 *    If we have an ISA board check for the ISA P&P version,
+	 *    as it has different IRQ settings 
 	 */
-
-	if (cardpresent == TR_ISA && (isa_readb(AIPFID + t_mmio)==0x0e))
-	        cardpresent=TR_ISAPNP;
-
-	if (cardpresent == NOTOK) { /* "channel_id" did not match, report */
-		if (ibmtr_debug_trace & TRC_INIT) {
-			DPRINTK("Channel ID string not found for PIOaddr: %4hx\n", PIOaddr);
-			DPRINTK("Expected for ISA: ");  PrtChanID(pcchannelid,1);
-			DPRINTK("           found: ");  HWPrtChanID(cd_chanid,2);
-			DPRINTK("Expected for MCA: ");  PrtChanID(mcchannelid,1);
-		}
-                return -ENODEV;
+	if (cardpresent == TR_ISA && (readb(AIPFID + t_mmio) == 0x0e))
+		cardpresent = TR_ISAPNP;
+	if (cardpresent == NOTOK) {	/* "channel_id" did not match, report */
+		if (!(ibmtr_debug_trace & TRC_INIT)) return -ENODEV;
+		DPRINTK( "Channel ID string not found for PIOaddr: %4hx\n",
+								PIOaddr);
+		DPRINTK("Expected for ISA: ");
+		PrtChanID(pcchannelid, 1);
+		DPRINTK("           found: ");
+/* BMS Note that this can be misleading, when hardware is flaky, because you
+   are reading it a second time here. So with my flaky hardware, I'll see my-
+   self in this block, with the HW ID matching the ISA ID exactly! */
+		HWPrtChanID(cd_chanid, 2);
+		DPRINTK("Expected for MCA: ");
+		PrtChanID(mcchannelid, 1);
 	}
-
 	/* Now, allocate some of the pl0 buffers for this driver.. */
-
-	/* If called from PCMCIA, ti is already set up, so no need to 
+	/* If called from PCMCIA, it is already set up, so no need to 
 	   waste the memory, just use the existing structure */
-
 #ifndef PCMCIA
-	ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL);
-	if (ti == NULL) 
-		return -ENOMEM;
-
+	ti = (struct tok_info *) kmalloc(sizeof(struct tok_info), GFP_KERNEL);
+	if (ti == NULL) return -ENOMEM;
 	memset(ti, 0, sizeof(struct tok_info));
-#else
-	ti = dev->priv ; 
+	ti->mmio = t_mmio;
+	dev->priv = ti;		/* this seems like the logical use of the
+				   field ... let's try some empirical tests
+				   using the token-info structure -- that
+				   should fit with out future hope of multiple
+				   adapter support as well /dwm   */
+        for(i=0; i<IBMTR_MAX_ADAPTERS; i++) {
+                if (turbo_io[i] != PIOaddr) continue;
+#if IBMTR_DEBUG_MESSAGES 
+		printk("ibmtr::tr_probe1, setting PIOaddr %x to Turbo\n" ,
+							PIOaddr);
+#endif
+		ti->turbo=1;
+		t_irq=turbo_irq[i];
+        }
 #endif
-	ti->mmio= t_mmio;
 	ti->readlog_pending = 0;
-	init_waitqueue_head(&ti->wait_for_tok_int);
 	init_waitqueue_head(&ti->wait_for_reset);
 
-	dev->priv = ti;     /* this seems like the logical use of the
-                         field ... let's try some empirical tests
-                         using the token-info structure -- that
-                         should fit with out future hope of multiple
-                         adapter support as well /dwm   */
-
-	/* if PCMCIA, then the card is recognized as TR_ISAPNP 
-	 * and there is no need to set up the interrupt, it is already done. */
-        
+	/* if PCMCIA, the card can be recognized as either TR_ISA or TR_ISAPNP
+	 * depending which card is inserted.	*/
+	
 #ifndef PCMCIA
-	switch (cardpresent) 
-	{
-		case TR_ISA:
-			if (intr==0)
-				irq=9; /* irq2 really is irq9 */
-			if (intr==1)
-				irq=3;
-			if (intr==2)
-				irq=6;
-			if (intr==3)
-				irq=7;
-			ti->global_int_enable=GLOBAL_INT_ENABLE+((irq==9) ? 2 : irq);
-			ti->adapter_int_enable=PIOaddr+ADAPTINTREL;
-			ti->sram=0;
-#if !TR_NEWFORMAT
-			DPRINTK("ti->global_int_enable: %04X\n",ti->global_int_enable);
-#endif
-			break;
-		case TR_MCA:
-			if (intr==0)
-				irq=9;
-			if (intr==1)
-				irq=3;
-			if (intr==2)
-				irq=10;
-			if (intr==3)
-				irq=11;
-			ti->global_int_enable=0;
-			ti->adapter_int_enable=0;
-			ti->sram=((__u32)(inb(PIOaddr+ADAPTRESETREL) & 0xfe) << 12);
-			break;
-		case TR_ISAPNP:
-			if (intr==0)
-				irq=9;
-			if (intr==1)
-				irq=3;
-			if (intr==2)
-				irq=10;
-			if (intr==3)
-				irq=11;
-			timeout = jiffies + TR_SPIN_INTERVAL;
-			while(!isa_readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN))
-				if (time_after(jiffies, timeout)) {
-					DPRINTK("Hardware timeout during initialization.\n");
-					kfree(ti);
-					return -ENODEV;
-			        }
-
-			ti->sram=((__u32)isa_readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)<<12);
-			ti->global_int_enable=PIOaddr+ADAPTINTREL;
-			ti->adapter_int_enable=PIOaddr+ADAPTINTREL;
-			break;
-	}
-#endif
+	switch (cardpresent) {
+	case TR_ISA:
+		if (intr == 0) irq = 9;	/* irq2 really is irq9 */
+		if (intr == 1) irq = 3;
+		if (intr == 2) irq = 6;
+		if (intr == 3) irq = 7;
+		ti->adapter_int_enable = PIOaddr + ADAPTINTREL;
+		break;
+	case TR_MCA:
+		if (intr == 0) irq = 9;
+		if (intr == 1) irq = 3;
+		if (intr == 2) irq = 10;
+		if (intr == 3) irq = 11;
+		ti->global_int_enable = 0;
+		ti->adapter_int_enable = 0;
+		ti->sram_virt=(__u32)(inb(PIOaddr+ADAPTRESETREL) & 0xfe) << 12;
+		break;
+	case TR_ISAPNP:
+		if (!t_irq) {
+			if (intr == 0) irq = 9;
+			if (intr == 1) irq = 3;
+			if (intr == 2) irq = 10;
+			if (intr == 3) irq = 11;
+		} else
+			irq=t_irq;
+		timeout = jiffies + TR_SPIN_INTERVAL;
+		while (!readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)){
+			if (!time_after(jiffies, timeout)) continue;
+			DPRINTK( "Hardware timeout during initialization.\n");
+			kfree(ti);
+			return -ENODEV;
+		}
+		ti->sram_virt =
+		     ((__u32)readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_EVEN)<<12);
+		ti->adapter_int_enable = PIOaddr + ADAPTINTREL;
+		break;
+	} /*end switch (cardpresent) */
+#endif	/*not PCMCIA */
 
-	if (ibmtr_debug_trace & TRC_INIT) { /* just report int */
-		DPRINTK("irq=%d",irq);
-		if (ibmtr_debug_trace & TRC_INITV) { /* full chat in verbose only */
-			DPRINTK(", ti->mmio=%08X",ti->mmio);
-			printk(", segment=%02X",segment);
+	if (ibmtr_debug_trace & TRC_INIT) {	/* just report int */
+		DPRINTK("irq=%d", irq);
+		printk(", sram_virt=0x%x", ti->sram_virt);
+		if(ibmtr_debug_trace&TRC_INITV){ /* full chat in verbose only */
+			DPRINTK(", ti->mmio=%08X", ti->mmio);
+			printk(", segment=%02X", segment);
 		}
 		printk(".\n");
 	}
 
 	/* Get hw address of token ring card */
-#if !TR_NEWFORMAT
-	DPRINTK("hw address: ");
-#endif
-	j=0;
-	for (i=0; i<0x18; i=i+2) 
-	{
+	j = 0;
+	for (i = 0; i < 0x18; i = i + 2) {
 		/* technical reference states to do this */
-		temp = isa_readb(ti->mmio + AIP + i) & 0x0f;
-#if !TR_NEWFORMAT
-		printk("%1X",ti->hw_address[j]=temp);
-#else
-		ti->hw_address[j]=temp;
-#endif
-		if(j&1)
-			dev->dev_addr[(j/2)]=ti->hw_address[j]+(ti->hw_address[j-1]<<4);
+		temp = readb(ti->mmio + AIP + i) & 0x0f;
+		ti->hw_address[j] = temp;
+		if (j & 1)
+			dev->dev_addr[(j / 2)] =
+				ti->hw_address[j]+ (ti->hw_address[j - 1] << 4);
 		++j;
 	}
-#ifndef TR_NEWFORMAT
-	printk("\n");
-#endif
-
-	/* get Adapter type:  'F' = Adapter/A, 'E' = 16/4 Adapter II,...*/
-	ti->adapter_type = isa_readb(ti->mmio + AIPADAPTYPE);
+	/* get Adapter type:  'F' = Adapter/A, 'E' = 16/4 Adapter II,... */
+	ti->adapter_type = readb(ti->mmio + AIPADAPTYPE);
 
 	/* get Data Rate:  F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */
-	ti->data_rate = isa_readb(ti->mmio + AIPDATARATE);
+	ti->data_rate = readb(ti->mmio + AIPDATARATE);
 
 	/* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */
-	ti->token_release = isa_readb(ti->mmio + AIPEARLYTOKEN);
+	ti->token_release = readb(ti->mmio + AIPEARLYTOKEN);
 
 	/* How much shared RAM is on adapter ? */
-#ifdef PCMCIA
-	ti->avail_shared_ram = pcmcia_reality_check(get_sram_size(ti));
-	ibmtr_mem_base = ti->sram_base << 12 ; 
-#else
-	ti->avail_shared_ram = get_sram_size(ti);
-#endif
-	/* We need to set or do a bunch of work here based on previous results.. */
+	if (ti->turbo) {
+		ti->avail_shared_ram=127;
+	} else {
+		ti->avail_shared_ram = get_sram_size(ti);/*in 512 byte units */
+	}
+	/* We need to set or do a bunch of work here based on previous results*/
 	/* Support paging?  What sizes?:  F=no, E=16k, D=32k, C=16 & 32k */
-	ti->shared_ram_paging = isa_readb(ti->mmio + AIPSHRAMPAGE);
+	ti->shared_ram_paging = readb(ti->mmio + AIPSHRAMPAGE);
 
-        /* Available DHB  4Mb size:   F=2048, E=4096, D=4464 */
-	switch (isa_readb(ti->mmio + AIP4MBDHB)) {
-	case 0xe : 
-		ti->dhb_size4mb = 4096;
-		break; 
-	case 0xd : 
-		ti->dhb_size4mb = 4464;
-		break; 
-	default  : 
-		ti->dhb_size4mb = 2048;
-		break; 
+	/* Available DHB  4Mb size:   F=2048, E=4096, D=4464 */
+	switch (readb(ti->mmio + AIP4MBDHB)) {
+	case 0xe: ti->dhb_size4mb = 4096; break;
+	case 0xd: ti->dhb_size4mb = 4464; break;
+	default:  ti->dhb_size4mb = 2048; break;
 	}
 
 	/* Available DHB 16Mb size:  F=2048, E=4096, D=8192, C=16384, B=17960 */
-	switch (isa_readb(ti->mmio + AIP16MBDHB)) {
-	case 0xe : 
-		ti->dhb_size16mb = 4096;
-		break; 
-	case 0xd : 
-		ti->dhb_size16mb = 8192;
-		break; 
-	case 0xc : 
-		ti->dhb_size16mb = 16384;
-		break; 
-	case 0xb : 
-		ti->dhb_size16mb = 17960;
-		break; 
-	default  : 
-		ti->dhb_size16mb = 2048;
-		break; 
+	switch (readb(ti->mmio + AIP16MBDHB)) {
+	case 0xe: ti->dhb_size16mb = 4096; break;
+	case 0xd: ti->dhb_size16mb = 8192; break;
+	case 0xc: ti->dhb_size16mb = 16384; break;
+	case 0xb: ti->dhb_size16mb = 17960; break;
+	default:  ti->dhb_size16mb = 2048; break;
 	}
 
-#if !TR_NEWFORMAT
-	DPRINTK("atype=%x, drate=%x, trel=%x, asram=%dK, srp=%x, "
-		"dhb(4mb=%x, 16mb=%x)\n",ti->adapter_type,
-		ti->data_rate, ti->token_release, ti->avail_shared_ram/2,
-		ti->shared_ram_paging, ti->dhb_size4mb, ti->dhb_size16mb);
-#endif
-
-	/*	We must figure out how much shared memory space this adapter
-	 *	will occupy so that if there are two adapters we can fit both
-	 *	in.  Given a choice, we will limit this adapter to 32K.  The
-	 *	maximum space will will use for two adapters is 64K so if the
-	 *	adapter we are working on demands 64K (it also doesn't support
-	 *	paging), then only one adapter can be supported.  
+	/*    We must figure out how much shared memory space this adapter
+	 *    will occupy so that if there are two adapters we can fit both
+	 *    in.  Given a choice, we will limit this adapter to 32K.  The
+	 *    maximum space will will use for two adapters is 64K so if the
+	 *    adapter we are working on demands 64K (it also doesn't support
+	 *    paging), then only one adapter can be supported.  
 	 */
 
 	/*
-	 *	determine how much of total RAM is mapped into PC space 
+	 *    determine how much of total RAM is mapped into PC space 
 	 */
-	ti->mapped_ram_size=1<<((((isa_readb(ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)) >>2) & 0x03) + 4);
-	ti->page_mask=0;
-	if (ti->shared_ram_paging == 0xf) { /* No paging in adapter */
-		ti->mapped_ram_size = ti->avail_shared_ram;
-	} else {
-#ifdef ENABLE_PAGING
-		unsigned char pg_size=0;
-#endif
-
-#if !TR_NEWFORMAT
-		DPRINTK("shared ram page size: %dK\n",ti->mapped_ram_size/2);
-#endif
+	ti->mapped_ram_size= /*sixteen to onehundredtwentyeight 512byte blocks*/
+	    1<< ((readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_ODD) >> 2 & 0x03) + 4);
+	ti->page_mask = 0;
+	if (ti->turbo)  ti->page_mask=0xf0;
+	else if (ti->shared_ram_paging == 0xf);  /* No paging in adapter */
+	else {
 #ifdef ENABLE_PAGING
-	switch(ti->shared_ram_paging) 
-	{
+		unsigned char pg_size = 0;
+		/* BMS:   page size: PCMCIA, use configuration register;
+		   ISAPNP, use LANAIDC config tool from www.ibm.com  */
+		switch (ti->shared_ram_paging) {
 		case 0xf:
 			break;
 		case 0xe:
-			ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
-			pg_size=32;   /* 16KB page size */
+			ti->page_mask = (ti->mapped_ram_size == 32) ? 0xc0 : 0;
+			pg_size = 32;	/* 16KB page size */
 			break;
 		case 0xd:
-			ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
-			pg_size=64;   /* 32KB page size */
+			ti->page_mask = (ti->mapped_ram_size == 64) ? 0x80 : 0;
+			pg_size = 64;	/* 32KB page size */
 			break;
 		case 0xc:
-		        switch (ti->mapped_ram_size) {
-			  case 32:
-			    ti->page_mask=0xc0;
-                            pg_size=32;
-                            break;
-			  case 64:
-                            ti->page_mask=0x80;
-                            pg_size=64;
-                            break;
-                        }
+			switch (ti->mapped_ram_size) {
+			case 32:
+				ti->page_mask = 0xc0;
+				pg_size = 32;
+				break;
+			case 64:
+				ti->page_mask = 0x80;
+				pg_size = 64;
+				break;
+			}
 			break;
 		default:
-			DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging);
+			DPRINTK("Unknown shared ram paging info %01X\n",
+							ti->shared_ram_paging);
 			kfree(ti);
 			return -ENODEV;
 			break;
-	}
+		} /*end switch shared_ram_paging */
 
- 	if (ibmtr_debug_trace & TRC_INIT)
- 	  DPRINTK("Shared RAM paging code: "
- 		 "%02X mapped RAM size: %dK shared RAM size: %dK page mask: %0xX\n:",
- 		 ti->shared_ram_paging, ti->mapped_ram_size/2, ti->avail_shared_ram/2, ti->page_mask);
-
-	if (ti->page_mask) {
-		if (pg_size > ti->mapped_ram_size) {
-			DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n",
-				pg_size/2, ti->mapped_ram_size/2);
-				ti->page_mask = 0;    /* reset paging */
-                }
-	} else if (pg_size > ti->mapped_ram_size) {
-	                DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n",
-				pg_size/2, ti->mapped_ram_size/2);
-	}
-#endif
+		if (ibmtr_debug_trace & TRC_INIT)
+			DPRINTK("Shared RAM paging code: %02X, "
+				"mapped RAM size: %dK, shared RAM size: %dK, "
+				"page mask: %02X\n:",
+				ti->shared_ram_paging, ti->mapped_ram_size / 2,
+				ti->avail_shared_ram / 2, ti->page_mask);
+#endif	/*ENABLE_PAGING */
 	}
+
+#ifndef PCMCIA
 	/* finish figuring the shared RAM address */
-	if (cardpresent==TR_ISA) {
-		static __u32 ram_bndry_mask[]={0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000};
+	if (cardpresent == TR_ISA) {
+		static __u32 ram_bndry_mask[] =
+			{ 0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000 };
 		__u32 new_base, rrr_32, chk_base, rbm;
 
-		rrr_32 = ((isa_readb(ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2) & 0x00000003;
+		rrr_32=readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_ODD) >> 2 & 0x03;
 		rbm = ram_bndry_mask[rrr_32];
-		new_base = (ibmtr_mem_base + (~rbm)) & rbm; /* up to boundary */
-		chk_base = new_base + (ti->mapped_ram_size<<9);
+		new_base = (ibmtr_mem_base + (~rbm)) & rbm;/* up to boundary */
+		chk_base = new_base + (ti->mapped_ram_size << 9);
 		if (chk_base > (ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE)) {
-			DPRINTK("Shared RAM for this adapter (%05x) exceeds driver"
-				" limit (%05x), adapter not started.\n",
-				chk_base, ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE);
+			DPRINTK("Shared RAM for this adapter (%05x) exceeds "
+			"driver limit (%05x), adapter not started.\n",
+			chk_base, ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE);
 			kfree(ti);
-                        return -ENODEV;
-		} else {  /* seems cool, record what we have figured out */
+			return -ENODEV;
+		} else { /* seems cool, record what we have figured out */
 			ti->sram_base = new_base >> 12;
 			ibmtr_mem_base = chk_base;
 		}
 	}
-
-#if !TR_NEWFORMAT
-	DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2);
-#endif
+	else  ti->sram_base = ti->sram_virt >> 12;
 
 	/* The PCMCIA has already got the interrupt line and the io port, 
 	   so no chance of anybody else getting it - MLP */
-
-#ifndef PCMCIA
-	if (request_irq (dev->irq = irq, &tok_interrupt,0,"ibmtr", dev) != 0) {
-		DPRINTK("Could not grab irq %d.  Halting Token Ring driver.\n",irq);
+	if (request_irq(dev->irq = irq, &tok_interrupt, 0, "ibmtr", dev) != 0) {
+		DPRINTK("Could not grab irq %d.  Halting Token Ring driver.\n",
+					irq);
 		kfree(ti);
 		return -ENODEV;
 	}
- 
 	/*?? Now, allocate some of the PIO PORTs for this driver.. */
-	request_region(PIOaddr,IBMTR_IO_EXTENT,"ibmtr");  /* record PIOaddr range as busy */
+	/* record PIOaddr range as busy */
+	request_region(PIOaddr, IBMTR_IO_EXTENT, "ibmtr");
+	if (!version_printed++) {
+		printk(version);
+	}
 #endif
-
-#if !TR_NEWFORMAT
-	DPRINTK("%s",version); /* As we have passed card identification,
-                                  let the world know we're here! */
-#else
-
-	if (version) {
-	        printk("%s",version);
-                version = NULL;
-        }
 	DPRINTK("%s %s found\n",
-		channel_def[cardpresent-1], adapter_def(ti->adapter_type));
+		channel_def[cardpresent - 1], adapter_def(ti->adapter_type));
 	DPRINTK("using irq %d, PIOaddr %hx, %dK shared RAM.\n",
-	        irq, PIOaddr, ti->mapped_ram_size/2);
+			irq, PIOaddr, ti->mapped_ram_size / 2);
 	DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n",
 		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
 		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
- 	if (ti->page_mask)
- 	  DPRINTK("Shared RAM paging enabled. Page size: %uK Shared Ram size %dK\n",
- 		  ((ti->page_mask ^ 0xff)+1)>>2,ti->avail_shared_ram/2);
- 	else
- 	  DPRINTK("Shared RAM paging disabled. ti->page_mask %x\n",ti->page_mask);
-#endif
+	if (ti->page_mask)
+		DPRINTK("Shared RAM paging enabled. "
+			"Page size: %uK Shared Ram size %dK\n",
+			((ti->page_mask^0xff)+1) >>2, ti->avail_shared_ram / 2);
+	else
+		DPRINTK("Shared RAM paging disabled. ti->page_mask %x\n",
+								ti->page_mask);
+
 	/* Calculate the maximum DHB we can use */
+	/* two cases where avail_shared_ram doesn't equal mapped_ram_size:
+	    1. avail_shared_ram is 127 but mapped_ram_size is 128 (typical)
+	    2. user has configured adapter for less than avail_shared_ram
+	       but is not using paging (she should use paging, I believe)
+	*/
 	if (!ti->page_mask) {
-	  ti->avail_shared_ram=ti->mapped_ram_size;
+		ti->avail_shared_ram=
+				MIN(ti->mapped_ram_size,ti->avail_shared_ram);
 	}
+
 	switch (ti->avail_shared_ram) {
-	case  16 : /* 8KB shared RAM */
-		ti->dhb_size4mb  = MIN(ti->dhb_size4mb, 2048);
+	case 16:		/* 8KB shared RAM */
+		ti->dhb_size4mb = MIN(ti->dhb_size4mb, 2048);
 		ti->rbuf_len4 = 1032;
-		ti->rbuf_cnt4 = 2;
+		ti->rbuf_cnt4=2;
 		ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048);
 		ti->rbuf_len16 = 1032;
-		ti->rbuf_cnt16 = 2;
+		ti->rbuf_cnt16=2;
 		break;
-	case  32 : /* 16KB shared RAM */
-		ti->dhb_size4mb  = MIN(ti->dhb_size4mb, 2048);
-		ti->rbuf_len4 = 520;
-		ti->rbuf_cnt4 = 9;
-		ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048);
-		ti->rbuf_len16 = 1032; /* 1024 usable */
-		ti->rbuf_cnt16 = 4;
+	case 32:		/* 16KB shared RAM */
+		ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464);
+		ti->rbuf_len4 = 1032;
+		ti->rbuf_cnt4=4;
+		ti->dhb_size16mb = MIN(ti->dhb_size16mb, 4096);
+		ti->rbuf_len16 = 1032;	/*1024 usable */
+		ti->rbuf_cnt16=4;
 		break;
-	case  64 : /* 32KB shared RAM */
-		ti->dhb_size4mb  = MIN(ti->dhb_size4mb, 2048);
+	case 64:		/* 32KB shared RAM */
+		ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464);
 		ti->rbuf_len4 = 1032;
-		ti->rbuf_cnt4 = 6;
-		ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048);
+		ti->rbuf_cnt4=6;
+		ti->dhb_size16mb = MIN(ti->dhb_size16mb, 10240);
 		ti->rbuf_len16 = 1032;
-		ti->rbuf_cnt16 = 10;
+		ti->rbuf_cnt16=6;
 		break;
-	case 127 : /* 63KB shared RAM */
-		ti->dhb_size4mb  = MIN(ti->dhb_size4mb, 2048);
+	case 127:		/* 63.5KB shared RAM */
+		ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464);
 		ti->rbuf_len4 = 1032;
-		ti->rbuf_cnt4 = 6;
-		ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048);
+		ti->rbuf_cnt4=6;
+		ti->dhb_size16mb = MIN(ti->dhb_size16mb, 16384);
 		ti->rbuf_len16 = 1032;
-		ti->rbuf_cnt16 = 16;
+		ti->rbuf_cnt16=16;
 		break;
-	case 128 : /* 64KB shared RAM */
-		ti->dhb_size4mb  = MIN(ti->dhb_size4mb, 2048);
+	case 128:		/* 64KB   shared RAM */
+		ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464);
 		ti->rbuf_len4 = 1032;
-		ti->rbuf_cnt4 = 6;
-		ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048);
+		ti->rbuf_cnt4=6;
+		ti->dhb_size16mb = MIN(ti->dhb_size16mb, 17960);
 		ti->rbuf_len16 = 1032;
-		ti->rbuf_cnt16 = 18;
+		ti->rbuf_cnt16=16;
 		break;
-	default  :
-		ti->dhb_size4mb  = 2048;
+	default:
+		ti->dhb_size4mb = 2048;
 		ti->rbuf_len4 = 1032;
-		ti->rbuf_cnt4 = 2;
+		ti->rbuf_cnt4=2;
 		ti->dhb_size16mb = 2048;
 		ti->rbuf_len16 = 1032;
-		ti->rbuf_cnt16 = 2;
+		ti->rbuf_cnt16=2;
 		break;
 	}
-
-	ti->maxmtu16 = (ti->rbuf_len16*ti->rbuf_cnt16)-((ti->rbuf_cnt16)<<3)-TR_HLEN;
-	ti->maxmtu4  = (ti->rbuf_len4*ti->rbuf_cnt4)-((ti->rbuf_cnt4)<<3)-TR_HLEN;
-	DPRINTK("Maximum MTU 16Mbps: %d, 4Mbps: %d\n",
-		ti->maxmtu16, ti->maxmtu4);
-
-	dev->base_addr=PIOaddr; /* set the value for device */
-
+	/* this formula is not smart enough for the paging case
+	ti->rbuf_cnt<x> = (ti->avail_shared_ram * BLOCKSZ - ADAPT_PRIVATE -
+			ARBLENGTH - SSBLENGTH - DLC_MAX_SAP * SAPLENGTH -
+			DLC_MAX_STA * STALENGTH - ti->dhb_size<x>mb * NUM_DHB -
+			SRBLENGTH - ASBLENGTH) / ti->rbuf_len<x>;
+	*/
+	ti->maxmtu16 = (ti->rbuf_len16 - 8) * ti->rbuf_cnt16  - TR_HLEN;
+	ti->maxmtu4 = (ti->rbuf_len4 - 8) * ti->rbuf_cnt4 - TR_HLEN;
+	/*BMS assuming 18 bytes of Routing Information (usually works) */
+	DPRINTK("Maximum Receive Internet Protocol MTU 16Mbps: %d, 4Mbps: %d\n",
+						     ti->maxmtu16, ti->maxmtu4);
+
+	dev->base_addr = PIOaddr;	/* set the value for device */
+	dev->mem_start = ti->sram_base << 12;
+	dev->mem_end = dev->mem_start + (ti->mapped_ram_size << 9) - 1;
 	trdev_init(dev);
-	tok_init_card(dev);
+	return 0;   /* Return 0 to indicate we have found a Token Ring card. */
+}				/*ibmtr_probe1() */
 
-	return 0;  /* Return 0 to indicate we have found a Token Ring card. */
-}
+/*****************************************************************************/
 
 /* query the adapter for the size of shared RAM  */
+/* the function returns the RAM size in units of 512 bytes */
 
-static unsigned char __init get_sram_size(struct tok_info *adapt_info)
+static unsigned char __devinit get_sram_size(struct tok_info *adapt_info)
 {
-
 	unsigned char avail_sram_code;
-	static unsigned char size_code[]={ 0,16,32,64,127,128 };
+	static unsigned char size_code[] = { 0, 16, 32, 64, 127, 128 };
 	/* Adapter gives
 	   'F' -- use RRR bits 3,2
 	   'E' -- 8kb   'D' -- 16kb
@@ -776,30 +773,27 @@
 	   'B' - 64KB less 512 bytes at top
 	   (WARNING ... must zero top bytes in INIT */
 
-	avail_sram_code=0xf-isa_readb(adapt_info->mmio + AIPAVAILSHRAM);
-	if (avail_sram_code)
-		return size_code[avail_sram_code];
-	else  /* for code 'F', must compute size from RRR(3,2) bits */
-		return 1<<((isa_readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4);
+	avail_sram_code = 0xf - readb(adapt_info->mmio + AIPAVAILSHRAM);
+	if (avail_sram_code) return size_code[avail_sram_code];
+	else		/* for code 'F', must compute size from RRR(3,2) bits */
+		return 1 <<
+		 ((readb(adapt_info->mmio+ACA_OFFSET+ACA_RW+RRR_ODD)>>2&3)+4);
 }
 
-static int __init trdev_init(struct net_device *dev)
-{
-	struct tok_info *ti=(struct tok_info *)dev->priv;
+/*****************************************************************************/
 
-	/* init the spinlock */
-	spin_lock_init(&ti->lock);
+static int __devinit trdev_init(struct net_device *dev)
+{
+	struct tok_info *ti = (struct tok_info *) dev->priv;
 
 	SET_PAGE(ti->srb_page);
-	ti->open_status		= CLOSED;
-
-	dev->init		= tok_init_card;
-	dev->open		= tok_open;
-	dev->stop		= tok_close;
-	dev->hard_start_xmit	= tok_send_packet;
-	dev->get_stats 		= tok_get_stats;
+        ti->open_failure = NO    ;
+	dev->open = tok_open;
+	dev->stop = tok_close;
+	dev->hard_start_xmit = tok_send_packet;
+	dev->get_stats = tok_get_stats;
 	dev->set_multicast_list = tok_set_multicast_list;
-	dev->change_mtu         = ibmtr_change_mtu;
+	dev->change_mtu = ibmtr_change_mtu;
 
 #ifndef MODULE
 #ifndef PCMCIA
@@ -809,23 +803,173 @@
 	return 0;
 }
 
+/*****************************************************************************/
+
+static int tok_init_card(struct net_device *dev)
+{
+	struct tok_info *ti;
+	short PIOaddr;
+	unsigned long i;
+
+	PIOaddr = dev->base_addr;
+	ti = (struct tok_info *) dev->priv;
+	/* Special processing for first interrupt after reset */
+	ti->do_tok_int = FIRST_INT;
+	/* Reset adapter */
+	writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
+	outb(0, PIOaddr + ADAPTRESET);
+
+	current->state=TASK_UNINTERRUPTIBLE;
+	schedule_timeout(TR_RST_TIME); /* wait 50ms */
+
+	outb(0, PIOaddr + ADAPTRESETREL);
+#ifdef ENABLE_PAGING
+	if (ti->page_mask)
+		writeb(SRPR_ENABLE_PAGING,ti->mmio+ACA_OFFSET+ACA_RW+SRPR_EVEN);
+#endif
+	writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+	i = sleep_on_timeout(&ti->wait_for_reset, 4 * HZ);
+	return i? 0 : -EAGAIN;
+}
+
+/*****************************************************************************/
+static int tok_open(struct net_device *dev)
+{
+	struct tok_info *ti = (struct tok_info *) dev->priv;
+	int i;
+
+	/*the case we were left in a failure state during a previous open */
+	if (ti->open_failure == YES) {
+		DPRINTK("Last time you were disconnected, how about now?\n");
+		printk("You can't insert with an ICS connector half-cocked.\n");
+	}
+
+	ti->open_status  = CLOSED; /* CLOSED or OPEN      */
+	ti->sap_status   = CLOSED; /* CLOSED or OPEN      */
+	ti->open_failure =     NO; /* NO     or YES       */
+	ti->open_mode    = MANUAL; /* MANUAL or AUTOMATIC */
+	/* 12/2000 not typical Linux, but we can use RUNNING to let us know when
+	the network has crapped out or cables are disconnected. Useful because
+	the IFF_UP flag stays up the whole time, until ifconfig tr0 down.
+	*/
+	dev->flags &= ~IFF_RUNNING;
+
+	ti->sram_virt &= ~1; /* to reverse what we do in tok_close */
+	/* init the spinlock */
+	ti->lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
+
+	i = tok_init_card(dev);
+	if (i) return i;
+
+	while (1){
+		tok_open_adapter((unsigned long) dev);
+		i= interruptible_sleep_on_timeout(&ti->wait_for_reset, 25 * HZ);
+		/* sig catch: estimate opening adapter takes more than .5 sec*/
+		if (i>(245*HZ)/10) break; /* fancier than if (i==25*HZ) */
+		if (i==0) break;
+		if (ti->open_status == OPEN && ti->sap_status==OPEN) {
+			netif_start_queue(dev);
+			MOD_INC_USE_COUNT;
+			DPRINTK("Adapter is up and running\n");
+			return 0;
+		}
+		current->state=TASK_INTERRUPTIBLE;
+		i=schedule_timeout(TR_RETRY_INTERVAL); /* wait 30 seconds */
+		if(i!=0) break; /*prob. a signal, like the i>24*HZ case above */
+	}
+	outb(0, dev->base_addr + ADAPTRESET);/* kill pending interrupts*/
+	DPRINTK("TERMINATED via signal\n");	/*BMS useful */
+	return -EAGAIN;
+}
+
+/*****************************************************************************/
+
+#define COMMAND_OFST             0
+#define OPEN_OPTIONS_OFST        8
+#define NUM_RCV_BUF_OFST        24
+#define RCV_BUF_LEN_OFST        26
+#define DHB_LENGTH_OFST         28
+#define NUM_DHB_OFST            30
+#define DLC_MAX_SAP_OFST        32
+#define DLC_MAX_STA_OFST        33
+
+void tok_open_adapter(unsigned long dev_addr)
+{
+	struct net_device *dev = (struct net_device *) dev_addr;
+	struct tok_info *ti;
+	int i;
+
+	ti = (struct tok_info *) dev->priv;
+	SET_PAGE(ti->init_srb_page); 
+	writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+	for (i = 0; i < sizeof(struct dir_open_adapter); i++)
+		writeb(0, ti->init_srb + i);
+	writeb(DIR_OPEN_ADAPTER, ti->init_srb + COMMAND_OFST);
+	writew(htons(OPEN_PASS_BCON_MAC), ti->init_srb + OPEN_OPTIONS_OFST);
+	if (ti->ring_speed == 16) {
+		writew(htons(ti->dhb_size16mb), ti->init_srb + DHB_LENGTH_OFST);
+		writew(htons(ti->rbuf_cnt16), ti->init_srb + NUM_RCV_BUF_OFST);
+		writew(htons(ti->rbuf_len16), ti->init_srb + RCV_BUF_LEN_OFST);
+	} else {
+		writew(htons(ti->dhb_size4mb), ti->init_srb + DHB_LENGTH_OFST);
+		writew(htons(ti->rbuf_cnt4), ti->init_srb + NUM_RCV_BUF_OFST);
+		writew(htons(ti->rbuf_len4), ti->init_srb + RCV_BUF_LEN_OFST);
+	}
+	writeb(NUM_DHB,		/* always 2 */ ti->init_srb + NUM_DHB_OFST);
+	writeb(DLC_MAX_SAP, ti->init_srb + DLC_MAX_SAP_OFST);
+	writeb(DLC_MAX_STA, ti->init_srb + DLC_MAX_STA_OFST);
+	ti->srb = ti->init_srb;	/* We use this one in the interrupt handler */
+	ti->srb_page = ti->init_srb_page;
+	DPRINTK("Opening adapter: Xmit bfrs: %d X %d, Rcv bfrs: %d X %d\n",
+		readb(ti->init_srb + NUM_DHB_OFST),
+		ntohs(readw(ti->init_srb + DHB_LENGTH_OFST)),
+		ntohs(readw(ti->init_srb + NUM_RCV_BUF_OFST)),
+		ntohs(readw(ti->init_srb + RCV_BUF_LEN_OFST)));
+	writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+	writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+}
+
+/*****************************************************************************/
+
+static void open_sap(unsigned char type, struct net_device *dev)
+{
+	int i;
+	struct tok_info *ti = (struct tok_info *) dev->priv;
+
+	SET_PAGE(ti->srb_page);
+	for (i = 0; i < sizeof(struct dlc_open_sap); i++)
+		writeb(0, ti->srb + i);
+
+#define MAX_I_FIELD_OFST        14
+#define SAP_VALUE_OFST          16
+#define SAP_OPTIONS_OFST        17
+#define STATION_COUNT_OFST      18
+
+	writeb(DLC_OPEN_SAP, ti->srb + COMMAND_OFST);
+	writew(htons(MAX_I_FIELD), ti->srb + MAX_I_FIELD_OFST);
+	writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY, ti->srb+ SAP_OPTIONS_OFST);
+	writeb(SAP_OPEN_STATION_CNT, ti->srb + STATION_COUNT_OFST);
+	writeb(type, ti->srb + SAP_VALUE_OFST);
+	writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+}
+
+
+/*****************************************************************************/
 
 static void tok_set_multicast_list(struct net_device *dev)
 {
-	struct tok_info *ti=(struct tok_info *)dev->priv;
+	struct tok_info *ti = (struct tok_info *) dev->priv;
 	struct dev_mc_list *mclist;
 	unsigned char address[4];
 
 	int i;
 
-	if(ti->open_status==CLOSED)
-		return;
-
+	/*BMS the next line is CRUCIAL or you may be sad when you */
+	/*BMS ifconfig tr down or hot unplug a PCMCIA card ??hownowbrowncow*/
+	if (/*BMSHELPdev->start == 0 ||*/ ti->open_status != OPEN) return;
 	address[0] = address[1] = address[2] = address[3] = 0;
-
 	mclist = dev->mc_list;
-	for (i=0; i< dev->mc_count; i++)
-	{
+	for (i = 0; i < dev->mc_count; i++) {
 		address[0] |= mclist->dmi_addr[2];
 		address[1] |= mclist->dmi_addr[3];
 		address[2] |= mclist->dmi_addr[4];
@@ -833,76 +977,168 @@
 		mclist = mclist->next;
 	}
 	SET_PAGE(ti->srb_page);
-	for (i=0; i<sizeof(struct srb_set_funct_addr); i++)
-		isa_writeb(0, ti->srb+i);
+	for (i = 0; i < sizeof(struct srb_set_funct_addr); i++)
+		writeb(0, ti->srb + i);
 
-	isa_writeb(DIR_SET_FUNC_ADDR, 
-               ti->srb + offsetof(struct srb_set_funct_addr, command));
+#define FUNCT_ADDRESS_OFST 6
 
+	writeb(DIR_SET_FUNC_ADDR, ti->srb + COMMAND_OFST);
+	for (i = 0; i < 4; i++) 
+		writeb(address[i], ti->srb + FUNCT_ADDRESS_OFST + i);
+	writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+#if TR_VERBOSE
 	DPRINTK("Setting functional address: ");
-
-	for (i=0; i<4; i++)
-	{
-		isa_writeb(address[i], 
-		ti->srb + offsetof(struct srb_set_funct_addr, funct_address)+i);
-		printk("%02X ", address[i]);
-	}
-	isa_writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+	for (i=0;i<4;i++)  printk("%02X ", address[i]);
 	printk("\n");
+#endif
 }
 
-static int tok_open(struct net_device *dev)
-{
-	struct tok_info *ti=(struct tok_info *)dev->priv;
+/*****************************************************************************/
 
-	if (ti->open_status==CLOSED) tok_init_card(dev);
+#define STATION_ID_OFST 4
 
-	if (ti->open_status==IN_PROGRESS) sleep_on(&ti->wait_for_reset);
+static int tok_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+	struct tok_info *ti;
+	unsigned long flags;
+	ti = (struct tok_info *) dev->priv;
 
-	if (ti->open_status==SUCCESS) {
-		/* NEED to see smem size *AND* reset high 512 bytes if needed */
-		netif_start_queue(dev);
-		MOD_INC_USE_COUNT;
+        netif_stop_queue(dev);
 
-		return 0;
-	} else return -EAGAIN;
+	/* lock against other CPUs */
+	spin_lock_irqsave(&(ti->lock), flags);
 
-}
+	/* Save skb; we'll need it when the adapter asks for the data */
+	ti->current_skb = skb;
+	SET_PAGE(ti->srb_page);
+	writeb(XMIT_UI_FRAME, ti->srb + COMMAND_OFST);
+	writew(ti->exsap_station_id, ti->srb + STATION_ID_OFST);
+	writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+	spin_unlock_irqrestore(&(ti->lock), flags);
+	dev->trans_start = jiffies;
+	return 0;
+}
+
+/*****************************************************************************/
 
 static int tok_close(struct net_device *dev)
 {
+	struct tok_info *ti = (struct tok_info *) dev->priv;
 
-	struct tok_info *ti=(struct tok_info *) dev->priv;
-
-	if(ti->open_status!=CLOSED) {
-		netif_stop_queue(dev);
-		SET_PAGE(ti->srb_page);	
-		isa_writeb(DIR_CLOSE_ADAPTER,
-	       	ti->srb + offsetof(struct srb_close_adapter, command));
-		isa_writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-
-		ti->open_status=CLOSED;
+	/* Important for PCMCIA hot unplug, otherwise, we'll pull the card, */
+	/* unloading the module from memory, and then if a timer pops, ouch */
+	del_timer(&ti->tr_timer);
+	outb(0, dev->base_addr + ADAPTRESET);
+	ti->sram_virt |= 1;
+	ti->open_status = CLOSED;
 
-		sleep_on(&ti->wait_for_tok_int);
+	netif_stop_queue(dev);
+	DPRINTK("Adapter is closed.\n");
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
 
-		SET_PAGE(ti->srb_page);
-		if (isa_readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)))
-			DPRINTK("close adapter failed: %02X\n",
-				(int)isa_readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)));
+/*****************************************************************************/
 
-#ifdef PCMCIA
-		ti->sram = 0 ;
-#endif
-		DPRINTK("Adapter closed.\n");
-		MOD_DEC_USE_COUNT;
+#define RETCODE_OFST		2
+#define OPEN_ERROR_CODE_OFST	6
+#define ASB_ADDRESS_OFST        8
+#define SRB_ADDRESS_OFST        10
+#define ARB_ADDRESS_OFST        12
+#define SSB_ADDRESS_OFST        14
+
+static char *printphase[]= {"Lobe media test","Physical insertion",
+	      "Address verification","Roll call poll","Request Parameters"};
+static char *printerror[]={"Function failure","Signal loss","Reserved",
+		"Frequency error","Timeout","Ring failure","Ring beaconing",
+		"Duplicate node address",
+		"Parameter request-retry count exceeded","Remove received",
+		"IMPL force received","Duplicate modifier",
+		"No monitor detected","Monitor contention failed for RPL"};
+
+void dir_open_adapter (struct net_device *dev) {
+
+        struct tok_info *ti = (struct tok_info *) dev->priv;
+        unsigned char ret_code;
+        __u16 err;
+
+        ti->srb = ntohs(readw(ti->init_srb + SRB_ADDRESS_OFST));
+        ti->ssb = ntohs(readw(ti->init_srb + SSB_ADDRESS_OFST));
+        ti->arb = ntohs(readw(ti->init_srb + ARB_ADDRESS_OFST));
+        ti->asb = ntohs(readw(ti->init_srb + ASB_ADDRESS_OFST));
+        if (ti->page_mask) {
+                ti->srb_page = (ti->srb >> 8) & ti->page_mask;
+                ti->srb &= ~(ti->page_mask << 8);
+                ti->ssb_page = (ti->ssb >> 8) & ti->page_mask;
+                ti->ssb &= ~(ti->page_mask << 8);
+                ti->arb_page = (ti->arb >> 8) & ti->page_mask;
+                ti->arb &= ~(ti->page_mask << 8);
+                ti->asb_page = (ti->asb >> 8) & ti->page_mask;
+                ti->asb &= ~(ti->page_mask << 8);
+        }
+        ti->srb += ti->sram_virt;
+        ti->ssb += ti->sram_virt;
+        ti->arb += ti->sram_virt;
+        ti->asb += ti->sram_virt;
+        ti->current_skb = NULL;
+        ret_code = readb(ti->init_srb + RETCODE_OFST);
+        err = ntohs(readw(ti->init_srb + OPEN_ERROR_CODE_OFST));
+        if (!ret_code) {
+		ti->open_status = OPEN; /* TR adapter is now available */
+                if (ti->open_mode == AUTOMATIC) {
+			DPRINTK("Adapter reopened.\n");
+                }
+                writeb(~SRB_RESP_INT, ti->mmio+ACA_OFFSET+ACA_RESET+ISRP_ODD);
+                open_sap(EXTENDED_SAP, dev);
+		return;
 	}
-
-	return 0;
+	ti->open_failure = YES;
+	if (ret_code == 7){
+               if (err == 0x24) {
+			if (!ti->auto_speedsave) {
+				DPRINTK("Open failed: Adapter speed must match "
+                                 "ring speed if Automatic Ring Speed Save is "
+				 "disabled.\n");
+				ti->open_action = FAIL;
+			}else
+				DPRINTK("Retrying open to adjust to "
+					"ring speed, ");
+                } else if (err == 0x2d) {
+			DPRINTK("Physical Insertion: No Monitor Detected, ");
+			printk("retrying after %ds delay...\n",
+					TR_RETRY_INTERVAL/HZ);
+                } else if (err == 0x11) {
+			DPRINTK("Lobe Media Function Failure (0x11), ");
+			printk(" retrying after %ds delay...\n",
+					TR_RETRY_INTERVAL/HZ);
+                } else {
+			char **prphase = printphase;
+			char **prerror = printerror;
+			DPRINTK("TR Adapter misc open failure, error code = ");
+			printk("0x%x, Phase: %s, Error: %s\n",
+				err, prphase[err/16 -1], prerror[err%16 -1]);
+			printk(" retrying after %ds delay...\n",
+					TR_RETRY_INTERVAL/HZ);
+                }
+        } else DPRINTK("open failed: ret_code = %02X..., ", ret_code);
+	if (ti->open_action != FAIL) {
+		if (ti->open_mode==AUTOMATIC){
+			ti->open_action = REOPEN;
+			ibmtr_reset_timer(&(ti->tr_timer), dev);
+			return;
+		}
+		wake_up(&ti->wait_for_reset);
+		return;
+	}
+	DPRINTK("FAILURE, CAPUT\n");
 }
 
-void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
+/******************************************************************************/
+
+void tok_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned char status;
+	/*  unsigned char status_even ; */
 	struct tok_info *ti;
 	struct net_device *dev;
 #ifdef ENABLE_PAGING
@@ -911,839 +1147,621 @@
 
 	dev = dev_id;
 #if TR_VERBOSE
-	DPRINTK("Int from tok_driver, dev : %p\n",dev);
+	DPRINTK("Int from tok_driver, dev : %p irq%d regs=%p\n", dev,irq,regs);
 #endif
-	ti  = (struct tok_info *) dev->priv;
+	ti = (struct tok_info *) dev->priv;
+	if (ti->sram_virt & 1)
+		return;         /* PCMCIA card extraction flag */
 	spin_lock(&(ti->lock));
 #ifdef ENABLE_PAGING
-	save_srpr=isa_readb(ti->mmio+ACA_OFFSET+ACA_RW+SRPR_EVEN);
+	save_srpr = readb(ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
 #endif
 
-      	/* Disable interrupts till processing is finished */
-	isa_writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
+	/* Disable interrupts till processing is finished */
+	writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
 
 	/* Reset interrupt for ISA boards */
-        if (ti->adapter_int_enable)
-                outb(0,ti->adapter_int_enable);
-	else
-		outb(0,ti->global_int_enable);
-
-
-	switch (ti->do_tok_int) {
-
-	      case NOT_FIRST:
-
-		/*  Begin the regular interrupt handler HERE inline to avoid
-		    the extra levels of logic and call depth for the
-		    original solution.   */
-
-		status=isa_readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);
-#ifdef PCMCIA
-      		/* Check if the PCMCIA card was pulled. */
-    		if (status == 0xFF)
-       		{
-		          DPRINTK("PCMCIA card removed.\n");
-                          ti->open_status=CLOSED;
-			  goto return_point ; 
-       		}
-
-    	        /* Check ISRP EVEN too. */
-      	        if ( isa_readb (ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) == 0xFF)
-    	        {
-         		 DPRINTK("PCMCIA card removed.\n");
-                         ti->open_status=CLOSED;
-			 goto return_point ; 
-      		}
+	if (ti->adapter_int_enable)
+		outb(0, ti->adapter_int_enable);
+	else /* used for PCMCIA cards */
+		outb(0, ti->global_int_enable);
+        if (ti->do_tok_int == FIRST_INT){
+                initial_tok_int(dev);
+#ifdef ENABLE_PAGING
+                writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
 #endif
+                spin_unlock(&(ti->lock));
+                return;
+        }
+	/*  Begin interrupt handler HERE inline to avoid the extra
+	    levels of logic and call depth for the original solution. */
+	status = readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);
+	/*BMSstatus_even = readb (ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) */
+	/*BMSdebugprintk("tok_interrupt: ISRP_ODD = 0x%x ISRP_EVEN = 0x%x\n", */
+	/*BMS                                       status,status_even);      */
 
+	if (status & ADAP_CHK_INT) {
+		int i;
+		__u32 check_reason;
+		__u8 check_reason_page = 0;
+		check_reason =
+			ntohs(readw(ti->mmio+ ACA_OFFSET+ACA_RW + WWCR_EVEN));
+		if (ti->page_mask) {
+			check_reason_page = (check_reason >> 8) & ti->page_mask;
+			check_reason &= ~(ti->page_mask << 8);
+		}
+		check_reason += ti->sram_virt;
+		SET_PAGE(check_reason_page);
 
-		if (status & ADAP_CHK_INT) {
-
-			int i;
-			__u32 check_reason;
-                        __u8  check_reason_page=0;
-
-			check_reason=ntohs(isa_readw(ti->sram + ACA_OFFSET + ACA_RW +WWCR_EVEN));
-			if (ti->page_mask) {
-			  check_reason_page=(check_reason>>8) & ti->page_mask;
-			  check_reason &= ~(ti->page_mask << 8);
+		DPRINTK("Adapter check interrupt\n");
+		DPRINTK("8 reason bytes follow: ");
+		for (i = 0; i < 8; i++, check_reason++)
+			printk("%02X ", (int) readb(check_reason));
+		printk("\n");
+		writeb(~ADAP_CHK_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD);
+		status = readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRA_EVEN);
+		DPRINTK("ISRA_EVEN == 0x02%x\n",status);
+		ti->open_status = CLOSED;
+		ti->sap_status  = CLOSED;
+		ti->open_mode   = AUTOMATIC;
+		dev->flags &= ~IFF_RUNNING;
+		netif_stop_queue(dev);
+		ti->open_action = RESTART;
+		outb(0, dev->base_addr + ADAPTRESET);
+		ibmtr_reset_timer(&(ti->tr_timer), dev);/*BMS try to reopen*/
+		return;
+	}
+	if (readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)
+		& (TCR_INT | ERR_INT | ACCESS_INT)) {
+		DPRINTK("adapter error: ISRP_EVEN : %02x\n",
+			(int)readb(ti->mmio+ ACA_OFFSET + ACA_RW + ISRP_EVEN));
+		writeb(~(TCR_INT | ERR_INT | ACCESS_INT),
+			ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
+		status= readb(ti->mmio+ ACA_OFFSET + ACA_RW + ISRA_EVEN);/*BMS*/
+		DPRINTK("ISRA_EVEN == 0x02%x\n",status);/*BMS*/
+                writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+#ifdef ENABLE_PAGING
+                writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
+#endif
+                spin_unlock(&(ti->lock));
+                return;
+        }
+	if (status & SRB_RESP_INT) {	/* SRB response */
+		SET_PAGE(ti->srb_page);
+#if TR_VERBOSE
+		DPRINTK("SRB resp: cmd=%02X rsp=%02X\n",
+				readb(ti->srb), readb(ti->srb + RETCODE_OFST));
+#endif
+		switch (readb(ti->srb)) {	/* SRB command check */
+		case XMIT_DIR_FRAME:{
+			unsigned char xmit_ret_code;
+			xmit_ret_code = readb(ti->srb + RETCODE_OFST);
+			if (xmit_ret_code == 0xff) break;
+			DPRINTK("error on xmit_dir_frame request: %02X\n",
+								xmit_ret_code);
+			if (ti->current_skb) {
+				dev_kfree_skb_irq(ti->current_skb);
+				ti->current_skb = NULL;
 			}
-			check_reason += ti->sram;
-			SET_PAGE(check_reason_page);
-
-			DPRINTK("Adapter check interrupt\n");
-			DPRINTK("8 reason bytes follow: ");
-			for(i=0; i<8; i++, check_reason++)
-				printk("%02X ", (int)isa_readb(check_reason));
-			printk("\n");
-
-			isa_writeb((~ADAP_CHK_INT), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
-			isa_writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN);
-
-		} else if (isa_readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)
-				 & (TCR_INT | ERR_INT | ACCESS_INT)) {
+			/*dev->tbusy = 0;*/
+			netif_wake_queue(dev);
+			if (ti->readlog_pending)
+				ibmtr_readlog(dev);
+			break;
+		}
+		case XMIT_UI_FRAME:{
+			unsigned char xmit_ret_code;
 
-			DPRINTK("adapter error: ISRP_EVEN : %02x\n",
-				(int)isa_readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN));
-			isa_writeb(~(TCR_INT | ERR_INT | ACCESS_INT),
-			       ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
-			isa_writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN);
-
-		} else if (status
-			   & (SRB_RESP_INT | ASB_FREE_INT | ARB_CMD_INT | SSB_RESP_INT)) {
-			/* SRB, ASB, ARB or SSB response */
+			xmit_ret_code = readb(ti->srb + RETCODE_OFST);
+			if (xmit_ret_code == 0xff) break;
+			DPRINTK("error on xmit_ui_frame request: %02X\n",
+								xmit_ret_code);
+			if (ti->current_skb) {
+				dev_kfree_skb_irq(ti->current_skb);
+				ti->current_skb = NULL;
+			}
+			netif_wake_queue(dev);
+			if (ti->readlog_pending)
+				ibmtr_readlog(dev);
+			break;
+		}
+		case DIR_OPEN_ADAPTER:
+			dir_open_adapter(dev);
+			break;
+		case DLC_OPEN_SAP:
+			if (readb(ti->srb + RETCODE_OFST)) {
+				DPRINTK("open_sap failed: ret_code = %02X, "
+					"retrying\n",
+					(int) readb(ti->srb + RETCODE_OFST));
+				ti->open_action = REOPEN;
+				ibmtr_reset_timer(&(ti->tr_timer), dev);
+				break;
+			}
+			ti->exsap_station_id = readw(ti->srb + STATION_ID_OFST);
+			ti->sap_status = OPEN;/* TR adapter is now available */
+			if (ti->open_mode==MANUAL){
+				wake_up(&ti->wait_for_reset);
+				break;
+			}
+			netif_wake_queue(dev);
+			dev->flags |= IFF_RUNNING;/*BMS 12/2000*/
+			break;
+		case DIR_INTERRUPT:
+		case DIR_MOD_OPEN_PARAMS:
+		case DIR_SET_GRP_ADDR:
+		case DIR_SET_FUNC_ADDR:
+		case DLC_CLOSE_SAP:
+			if (readb(ti->srb + RETCODE_OFST))
+				DPRINTK("error on %02X: %02X\n",
+					(int) readb(ti->srb + COMMAND_OFST),
+					(int) readb(ti->srb + RETCODE_OFST));
+			break;
+		case DIR_READ_LOG:
+			if (readb(ti->srb + RETCODE_OFST)){
+				DPRINTK("error on dir_read_log: %02X\n",
+					(int) readb(ti->srb + RETCODE_OFST));
+				netif_wake_queue(dev);
+				break;
+			}
+#if IBMTR_DEBUG_MESSAGES
 
-			if (status & SRB_RESP_INT) { /* SRB response */
-           		        SET_PAGE(ti->srb_page);
+#define LINE_ERRORS_OFST                 0
+#define INTERNAL_ERRORS_OFST             1
+#define BURST_ERRORS_OFST                2
+#define AC_ERRORS_OFST                   3
+#define ABORT_DELIMITERS_OFST            4
+#define LOST_FRAMES_OFST                 6
+#define RECV_CONGEST_COUNT_OFST          7
+#define FRAME_COPIED_ERRORS_OFST         8
+#define FREQUENCY_ERRORS_OFST            9
+#define TOKEN_ERRORS_OFST               10
+
+			DPRINTK("Line errors %02X, Internal errors %02X, "
+			"Burst errors %02X\n" "A/C errors %02X, "
+			"Abort delimiters %02X, Lost frames %02X\n"
+			"Receive congestion count %02X, "
+			"Frame copied errors %02X\nFrequency errors %02X, "
+			"Token errors %02X\n",
+			(int) readb(ti->srb + LINE_ERRORS_OFST),
+			(int) readb(ti->srb + INTERNAL_ERRORS_OFST),
+			(int) readb(ti->srb + BURST_ERRORS_OFST),
+			(int) readb(ti->srb + AC_ERRORS_OFST),
+			(int) readb(ti->srb + ABORT_DELIMITERS_OFST),
+			(int) readb(ti->srb + LOST_FRAMES_OFST),
+			(int) readb(ti->srb + RECV_CONGEST_COUNT_OFST),
+			(int) readb(ti->srb + FRAME_COPIED_ERRORS_OFST),
+			(int) readb(ti->srb + FREQUENCY_ERRORS_OFST),
+			(int) readb(ti->srb + TOKEN_ERRORS_OFST));
+#endif
+			netif_wake_queue(dev);
+			break;
+		default:
+			DPRINTK("Unknown command %02X encountered\n",
+						(int) readb(ti->srb));
+        	}	/* end switch SRB command check */
+		writeb(~SRB_RESP_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD);
+	}	/* if SRB response */
+	if (status & ASB_FREE_INT) {	/* ASB response */
+		SET_PAGE(ti->asb_page);
 #if TR_VERBOSE
- 				DPRINTK("SRB resp: cmd=%02X rsp=%02X\n",
-					isa_readb(ti->srb),
-					isa_readb(ti->srb + offsetof(struct srb_xmit, ret_code)));
-#endif
-
-				switch(isa_readb(ti->srb)) { /* SRB command check */
-
-				      case XMIT_DIR_FRAME: {
-					      unsigned char xmit_ret_code;
-
-					      xmit_ret_code=isa_readb(ti->srb + offsetof(struct srb_xmit, ret_code));
-					      if (xmit_ret_code != 0xff) {
-						      DPRINTK("error on xmit_dir_frame request: %02X\n",
-							      xmit_ret_code);
-						      if (ti->current_skb) {
-							      dev_kfree_skb_irq(ti->current_skb);
-							      ti->current_skb=NULL;
-						      }
-						      netif_wake_queue(dev);
-						      if (ti->readlog_pending) ibmtr_readlog(dev);
-					      }
-				      }
-				      break;
-
-				      case XMIT_UI_FRAME: {
-					      unsigned char xmit_ret_code;
-
-					      xmit_ret_code=isa_readb(ti->srb + offsetof(struct srb_xmit, ret_code));
-					      if (xmit_ret_code != 0xff) {
-						      DPRINTK("error on xmit_ui_frame request: %02X\n",
-							      xmit_ret_code);
-						      if (ti->current_skb) {
-							      dev_kfree_skb_irq(ti->current_skb);
-							      ti->current_skb=NULL;
-						      }
-						      netif_wake_queue(dev);
-						      if (ti->readlog_pending)
-						      		ibmtr_readlog(dev);
-					      }
-				      }
-				      break;
-
-				      case DIR_OPEN_ADAPTER: {
-					      unsigned char open_ret_code;
-					      __u16 open_error_code;
-
- 					      ti->srb=ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, srb_addr)));
- 					      ti->ssb=ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, ssb_addr)));
- 					      ti->arb=ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, arb_addr)));
- 					      ti->asb=ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, asb_addr)));
-					      if (ti->page_mask) {
-						ti->srb_page=(ti->srb>>8) & ti->page_mask;
-						ti->srb &= ~(ti->page_mask<<8);
-						ti->ssb_page=(ti->ssb>>8) & ti->page_mask;
-						ti->ssb &= ~(ti->page_mask<<8);
-						ti->arb_page=(ti->arb>>8) & ti->page_mask;
-						ti->arb &= ~(ti->page_mask<<8);
-						ti->asb_page=(ti->asb>>8) & ti->page_mask;
-						ti->asb &= ~(ti->page_mask<<8);
-					      }
-					      ti->srb+=ti->sram;
-					      ti->ssb+=ti->sram;
-					      ti->arb+=ti->sram;
-					      ti->asb+=ti->sram;
-
-					      ti->current_skb=NULL;
-
-					      open_ret_code = isa_readb(ti->init_srb +offsetof(struct srb_open_response, ret_code));
-					      open_error_code = ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, error_code)));
-
-					      if (open_ret_code==7) {
-
-						      if (!ti->auto_ringspeedsave && (open_error_code==0x24)) {
-							      DPRINTK("Open failed: Adapter speed must match ring "
-								      "speed if Automatic Ring Speed Save is disabled.\n");
-							      ti->open_status=FAILURE;
-							      wake_up(&ti->wait_for_reset);
-						      } else if (open_error_code==0x24)
-							      DPRINTK("Retrying open to adjust to ring speed.\n");
-						      else if ((open_error_code==0x2d) && ti->auto_ringspeedsave)
-							      DPRINTK("No signal detected for Auto Speed Detection.\n");
-						      else if (open_error_code==0x11)
-						      {
-							      if (ti->retry_count--) 
-								      DPRINTK("Ring broken/disconnected, retrying...\n");
-							      else {
-								      DPRINTK("Ring broken/disconnected, open failed.\n");
-								      ti->open_status = FAILURE;
-							      }
-						      }
-						      else DPRINTK("Unrecoverable error: error code = %04x.\n",
-								   open_error_code);
-
-					      } else if (!open_ret_code) {
-#if !TR_NEWFORMAT
-						      DPRINTK("board opened...\n");
-#else
-						      DPRINTK("Adapter initialized and opened.\n");
+		DPRINTK("ASB resp: cmd=%02X\n", readb(ti->asb));
 #endif
-						      isa_writeb(~(SRB_RESP_INT),
-							     ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
-						      isa_writeb(~(CMD_IN_SRB),
-							     ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
-						      open_sap(EXTENDED_SAP,dev);
-
-						      /* YdW probably hates me */
-						      goto skip_reset;
-					      } else
-						      DPRINTK("open failed: ret_code = %02X, retrying\n",
-							      open_ret_code);
-
-					      if (ti->open_status != FAILURE) {
-						      ibmtr_reset_timer(&(ti->tr_timer), dev);
-					      }
-
-				      }
-				      break;
-
-				      case DIR_CLOSE_ADAPTER:
-					wake_up(&ti->wait_for_tok_int);
-					break;
-
-				      case DLC_OPEN_SAP:
-					if (isa_readb(ti->srb+offsetof(struct dlc_open_sap, ret_code))) {
-						DPRINTK("open_sap failed: ret_code = %02X,retrying\n",
-							(int)isa_readb(ti->srb+offsetof(struct dlc_open_sap, ret_code)));
-						ibmtr_reset_timer(&(ti->tr_timer), dev);
-					} else {
-						ti->exsap_station_id=
-							isa_readw(ti->srb+offsetof(struct dlc_open_sap, station_id));
-						ti->open_status=SUCCESS; /* TR adapter is now available */
-						wake_up(&ti->wait_for_reset);
-					}
-					break;
-
-				      case DIR_INTERRUPT:
-				      case DIR_MOD_OPEN_PARAMS:
-				      case DIR_SET_GRP_ADDR:
-				      case DIR_SET_FUNC_ADDR:
-				      case DLC_CLOSE_SAP:
-					if (isa_readb(ti->srb+offsetof(struct srb_interrupt, ret_code)))
-						DPRINTK("error on %02X: %02X\n",
-							(int)isa_readb(ti->srb+offsetof(struct srb_interrupt, command)),
-							(int)isa_readb(ti->srb+offsetof(struct srb_interrupt, ret_code)));
-					break;
-
-				      case DIR_READ_LOG:
-					if (isa_readb(ti->srb+offsetof(struct srb_read_log, ret_code)))
-						DPRINTK("error on dir_read_log: %02X\n",
-							(int)isa_readb(ti->srb+offsetof(struct srb_read_log, ret_code)));
-					else
-					    if (IBMTR_DEBUG_MESSAGES) {
-						DPRINTK(
-							"Line errors %02X, Internal errors %02X, Burst errors %02X\n"
-							"A/C errors %02X, Abort delimiters %02X, Lost frames %02X\n"
-							"Receive congestion count %02X, Frame copied errors %02X\n"
-							"Frequency errors %02X, Token errors %02X\n",
-							(int)isa_readb(ti->srb+offsetof(struct srb_read_log,
-										    line_errors)),
-							(int)isa_readb(ti->srb+offsetof(struct srb_read_log,
-										    internal_errors)),
-							(int)isa_readb(ti->srb+offsetof(struct srb_read_log,
-										    burst_errors)),
-							(int)isa_readb(ti->srb+offsetof(struct srb_read_log, A_C_errors)),
-							(int)isa_readb(ti->srb+offsetof(struct srb_read_log,
-										    abort_delimiters)),
-							(int)isa_readb(ti->srb+offsetof(struct srb_read_log,
-										    lost_frames)),
-							(int)isa_readb(ti->srb+offsetof(struct srb_read_log,
-												    recv_congest_count)),
-							(int)isa_readb(ti->srb+offsetof(struct srb_read_log,
-										    frame_copied_errors)),
-							(int)isa_readb(ti->srb+offsetof(struct srb_read_log,
-										    frequency_errors)),
-							(int)isa_readb(ti->srb+offsetof(struct srb_read_log,
-												    token_errors)));
-					    }
-					netif_wake_queue(dev);
-					break;
-
-				      default:
-					DPRINTK("Unknown command %02X encountered\n",
-						(int)isa_readb(ti->srb));
-
-				} /* SRB command check */
 
-				isa_writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
-				isa_writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+		switch (readb(ti->asb)) {	/* ASB command check */
+		case REC_DATA:
+		case XMIT_UI_FRAME:
+		case XMIT_DIR_FRAME:
+			break;
+		default:
+			DPRINTK("unknown command in asb %02X\n",
+						(int) readb(ti->asb));
+		}	/* switch ASB command check */
+		if (readb(ti->asb + 2) != 0xff)	/* checks ret_code */
+			DPRINTK("ASB error %02X in cmd %02X\n",
+				(int) readb(ti->asb + 2), (int) readb(ti->asb));
+		writeb(~ASB_FREE_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD);
+	}	/* if ASB response */
 
-			  skip_reset:;
-			} /* SRB response */
+#define STATUS_OFST             6
+#define NETW_STATUS_OFST        6
 
-			if (status & ASB_FREE_INT) { /* ASB response */
-			        SET_PAGE(ti->asb_page);
+	if (status & ARB_CMD_INT) {	/* ARB response */
+		SET_PAGE(ti->arb_page);
 #if TR_VERBOSE
- 				DPRINTK("ASB resp: cmd=%02X\n", isa_readb(ti->asb));
- #endif
-
-				switch(isa_readb(ti->asb)) { /* ASB command check */
-
-				      case REC_DATA:
-				      case XMIT_UI_FRAME:
-				      case XMIT_DIR_FRAME:
-					break;
-
-				      default:
-					DPRINTK("unknown command in asb %02X\n",
-						(int)isa_readb(ti->asb));
-
-				} /* ASB command check */
-
-				if (isa_readb(ti->asb+2)!=0xff) /* checks ret_code */
-				    DPRINTK("ASB error %02X in cmd %02X\n",
-					    (int)isa_readb(ti->asb+2),(int)isa_readb(ti->asb));
-				isa_writeb(~ASB_FREE_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
-
-			} /* ASB response */
-
-			if (status & ARB_CMD_INT) { /* ARB response */
-            		        SET_PAGE(ti->arb_page);
-#if TR_VERBOSE 
- 				DPRINTK("ARB resp: cmd=%02X rsp=%02X\n",
- 					isa_readb(ti->arb),
- 					isa_readb(ti->arb + offsetof(struct arb_dlc_status, status)));
+		DPRINTK("ARB resp: cmd=%02X\n", readb(ti->arb));
 #endif
 
-				switch (isa_readb(ti->arb)) { /* ARB command check */
-
-				      case DLC_STATUS:
-					DPRINTK("DLC_STATUS new status: %02X on station %02X\n",
-						ntohs(isa_readw(ti->arb + offsetof(struct arb_dlc_status, status))),
-						ntohs(isa_readw(ti->arb
-									    +offsetof(struct arb_dlc_status, station_id))));
-					break;
-
-				      case REC_DATA:
-					tr_rx(dev);
-					break;
-
-				      case RING_STAT_CHANGE: {
-					      unsigned short ring_status;
-
-					      ring_status=ntohs(isa_readw(ti->arb
-								      +offsetof(struct arb_ring_stat_change, ring_status)));
-
-					      if (ring_status & (SIGNAL_LOSS | LOBE_FAULT)) {
-
-						      DPRINTK("Signal loss/Lobe fault\n");
-						      DPRINTK("We try to reopen the adapter.\n");
-						      ibmtr_reset_timer(&(ti->tr_timer), dev);
-					      } else if (ring_status & (HARD_ERROR | XMIT_BEACON
-											| AUTO_REMOVAL | REMOVE_RECV | RING_RECOVER))
-						      DPRINTK("New ring status: %02X\n", ring_status);
-
-					      if (ring_status & LOG_OVERFLOW) {
-						      if (netif_queue_stopped(dev))
-                                                              ti->readlog_pending = 1;
-						      else
-                                                              ibmtr_readlog(dev);
-					      }
-				      }
-				      break;
-
-				      case XMIT_DATA_REQ:
-					tr_tx(dev);
-					break;
-
-				      default:
-					DPRINTK("Unknown command %02X in arb\n",
-						(int)isa_readb(ti->arb));
-					break;
-
-				} /* ARB command check */
-
-				isa_writeb(~ARB_CMD_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
-				isa_writeb(ARB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-
-			} /* ARB response */
-
-			if (status & SSB_RESP_INT) { /* SSB response */
-				unsigned char retcode;
- 				SET_PAGE(ti->ssb_page);
+		switch (readb(ti->arb)) {	/* ARB command check */
+		case DLC_STATUS:
+			DPRINTK("DLC_STATUS new status: %02X on station %02X\n",
+				ntohs(readw(ti->arb + STATUS_OFST)),
+				ntohs(readw(ti->arb+ STATION_ID_OFST)));
+			break;
+		case REC_DATA:
+			tr_rx(dev);
+			break;
+		case RING_STAT_CHANGE:{
+			unsigned short ring_status;
+			ring_status= ntohs(readw(ti->arb + NETW_STATUS_OFST));
+			if (ibmtr_debug_trace & TRC_INIT)
+				DPRINTK("Ring Status Change...(0x%x)\n",
+								ring_status);
+			if(ring_status& (REMOVE_RECV|AUTO_REMOVAL|LOBE_FAULT)){
+				netif_stop_queue(dev);
+				dev->flags &= ~IFF_RUNNING;/*not typical Linux*/
+				DPRINTK("Remove received, or Auto-removal error"
+					", or Lobe fault\n");
+				DPRINTK("We'll try to reopen the closed adapter"
+					" after a %d second delay.\n",
+						TR_RETRY_INTERVAL/HZ);
+				/*I was confused: I saw the TR reopening but */
+				/*forgot:with an RJ45 in an RJ45/ICS adapter */
+				/*but adapter not in the ring, the TR will   */
+				/* open, and then soon close and come here.  */
+				ti->open_mode = AUTOMATIC;
+				ti->open_status = CLOSED; /*12/2000 BMS*/
+				ti->open_action = REOPEN;
+				ibmtr_reset_timer(&(ti->tr_timer), dev);
+			} else if (ring_status & LOG_OVERFLOW) {
+				if(netif_queue_stopped(dev))
+					ti->readlog_pending = 1;
+				else
+					ibmtr_readlog(dev);
+			}
+			break;
+          	}
+		case XMIT_DATA_REQ:
+			tr_tx(dev);
+			break;
+		default:
+			DPRINTK("Unknown command %02X in arb\n",
+						(int) readb(ti->arb));
+			break;
+		}	/* switch ARB command check */
+		writeb(~ARB_CMD_INT, ti->mmio+ ACA_OFFSET+ACA_RESET + ISRP_ODD);
+		writeb(ARB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+	}	/* if ARB response */
+	if (status & SSB_RESP_INT) {	/* SSB response */
+		unsigned char retcode;
+		SET_PAGE(ti->ssb_page);
 #if TR_VERBOSE
- 				DPRINTK("SSB resp: cmd=%02X rsp=%02X\n",
- 					isa_readb(ti->ssb), isa_readb(ti->ssb+2));
+		DPRINTK("SSB resp: cmd=%02X rsp=%02X\n",
+				readb(ti->ssb), readb(ti->ssb + 2));
 #endif
-				switch (isa_readb(ti->ssb)) { /* SSB command check */
-				      
-				      case XMIT_DIR_FRAME:
-				      case XMIT_UI_FRAME:
-					retcode = isa_readb(ti->ssb+2);
-					if (retcode && (retcode != 0x22)) /* checks ret_code */
-						DPRINTK("xmit ret_code: %02X xmit error code: %02X\n",
-							(int)retcode, (int)isa_readb(ti->ssb+6));
-					else ti->tr_stats.tx_packets++;
-					break;
-
-				      case XMIT_XID_CMD:
-					DPRINTK("xmit xid ret_code: %02X\n", (int)isa_readb(ti->ssb+2));
-                                        break;
-
-				      default:
-					DPRINTK("Unknown command %02X in ssb\n", (int)isa_readb(ti->ssb));
-
-				} /* SSB command check */
-
-				isa_writeb(~SSB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
-				isa_writeb(SSB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-
-			} /* SSB response */
-
-		}	 /* SRB, ARB, ASB or SSB response */
-
-		isa_writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
-		break;
 
-	      case FIRST_INT:
-		initial_tok_int(dev);
-		break;
-
-	      default:
-		DPRINTK("Unexpected interrupt from tr adapter\n");
-
-	}
-#ifdef PCMCIA
- return_point:
-#endif
+		switch (readb(ti->ssb)) {	/* SSB command check */
+		case XMIT_DIR_FRAME:
+		case XMIT_UI_FRAME:
+			retcode = readb(ti->ssb + 2);
+			if (retcode && (retcode != 0x22))/* checks ret_code */
+				DPRINTK("xmit ret_code: %02X xmit error code: "
+					"%02X\n",
+					(int)retcode, (int)readb(ti->ssb + 6));
+			else
+				ti->tr_stats.tx_packets++;
+			break;
+		case XMIT_XID_CMD:
+			DPRINTK("xmit xid ret_code: %02X\n",
+						(int) readb(ti->ssb + 2));
+		default:
+			DPRINTK("Unknown command %02X in ssb\n",
+						(int) readb(ti->ssb));
+		}	/* SSB command check */
+		writeb(~SSB_RESP_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD);
+		writeb(SSB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+	}	/* if SSB response */
 #ifdef ENABLE_PAGING
- 	isa_writeb(save_srpr, ti->mmio+ACA_OFFSET+ACA_RW+SRPR_EVEN);
+	writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
 #endif
-
+	writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
 	spin_unlock(&(ti->lock));
-}
+}				/*tok_interrupt */
+
+/*****************************************************************************/
+
+#define INIT_STATUS_OFST        1
+#define INIT_STATUS_2_OFST      2
+#define ENCODED_ADDRESS_OFST    8
 
 static void initial_tok_int(struct net_device *dev)
 {
 
-	__u32 encoded_addr;
-	__u32 hw_encoded_addr;
+	__u32 encoded_addr, hw_encoded_addr;
 	struct tok_info *ti;
-	ti=(struct tok_info *) dev->priv;
+        unsigned char init_status; /*BMS 12/2000*/
 
-	ti->do_tok_int=NOT_FIRST;
+	ti = (struct tok_info *) dev->priv;
 
-#ifndef TR_NEWFORMAT
-	DPRINTK("Initial tok int received\n");
-#endif
+	ti->do_tok_int = NOT_FIRST;
 
 	/* we assign the shared-ram address for ISA devices */
-	if(!ti->sram) {
-		isa_writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN);
-		ti->sram=((__u32)ti->sram_base << 12);
-	}
- 	ti->init_srb=ntohs((unsigned short)isa_readw(ti->mmio+ ACA_OFFSET + WRBR_EVEN));
+	writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN);
+#ifndef PCMCIA
+        ti->sram_virt = (u32)ioremap(((__u32)ti->sram_base << 12), ti->avail_shared_ram);
+#endif
+	ti->init_srb = ntohs(readw(ti->mmio + ACA_OFFSET + WRBR_EVEN));
 	if (ti->page_mask) {
-	  ti->init_srb_page=(ti->init_srb>>8)&ti->page_mask;
-	  ti->init_srb &= ~(ti->page_mask<<8);
+		ti->init_srb_page = (ti->init_srb >> 8) & ti->page_mask;
+		ti->init_srb &= ~(ti->page_mask << 8);
+	}
+	ti->init_srb += ti->sram_virt;
+	if (ti->page_mask && ti->avail_shared_ram == 127) {
+		int last_512 = 0xfe00, i;
+		int last_512_page=0;
+		last_512_page=(last_512>>8)&ti->page_mask;
+		last_512 &= ~(ti->page_mask << 8);
+		/* initialize high section of ram (if necessary) */
+		SET_PAGE(last_512_page);
+		for (i = 0; i < 512; i++)
+			writeb(0, ti->sram_virt + last_512 + i);
 	}
-	ti->init_srb+=ti->sram;
-	
-	if (ti->avail_shared_ram == 127) {
-	  int i;
-	  int last_512=0xfe00;
- 	  if (ti->page_mask) {
-	    last_512 &= ~(ti->page_mask<<8);
-	  }
-	  /*  initialize high section of ram (if necessary) */
-	  SET_PAGE(0xc0);
-	  for (i=0; i<512; i++) {
-	    isa_writeb(0,ti->sram+last_512+i);
-	  }
-	}  
 	SET_PAGE(ti->init_srb_page);
 
-	dev->mem_start = ti->sram;
-	dev->mem_end = ti->sram + (ti->mapped_ram_size<<9) - 1;
-
 #if TR_VERBOSE
 	{
-		int i;
-		DPRINTK("init_srb(%lx):", (long)ti->init_srb);
-		for (i=0;i<17;i++) printk("%02X ", (int)isa_readb(ti->init_srb+i));
-		printk("\n");
-	}
-#endif
-
-	hw_encoded_addr = isa_readw(ti->init_srb
-				+ offsetof(struct srb_init_response, encoded_address));
-
-#if !TR_NEWFORMAT
-	DPRINTK("srb_init_response->encoded_address: %04X\n", hw_encoded_addr);
-	DPRINTK("ntohs(srb_init_response->encoded_address): %04X\n",
-		ntohs(hw_encoded_addr));
-#endif
-
-	encoded_addr=(ti->sram + ntohs(hw_encoded_addr));
-	ti->ring_speed = isa_readb(ti->init_srb+offsetof(struct srb_init_response, init_status)) & 0x01 ? 16 : 4;
-#if !TR_NEWFORMAT
-	DPRINTK("encoded addr (%04X,%04X,%08X): ", hw_encoded_addr,
-		ntohs(hw_encoded_addr), encoded_addr);
-#else
-	DPRINTK("Initial interrupt : %d Mbps, shared RAM base %08x.\n",
-		ti->ring_speed, ti->sram);
-#endif
-
-	ti->auto_ringspeedsave=isa_readb(ti->init_srb
-				     +offsetof(struct srb_init_response, init_status_2)) & 0x4 ? TRUE : FALSE;
-
-#if !TR_NEWFORMAT
-	for(i=0;i<TR_ALEN;i++) {
-		dev->dev_addr[i]=isa_readb(encoded_addr + i);
-		printk("%02X%s", dev->dev_addr[i], (i==TR_ALEN-1) ? "" : ":" );
-	}
-	printk("\n");
-#endif
-
-	tok_open_adapter((unsigned long)dev);
-}
-
-static int tok_init_card(struct net_device *dev)
-{
-	struct tok_info *ti;
-	short PIOaddr;
-	unsigned long i;
-	PIOaddr = dev->base_addr;
-	ti=(struct tok_info *) dev->priv;
-
-	/* Special processing for first interrupt after reset */
-	ti->do_tok_int=FIRST_INT;
-
-	/* Reset adapter */
-	netif_stop_queue(dev);
-
-	isa_writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
-
-#if !TR_NEWFORMAT
-	DPRINTK("resetting card\n");
-#endif
-
-	outb(0, PIOaddr+ADAPTRESET);
-	for (i=jiffies+TR_RESET_INTERVAL; time_before_eq(jiffies, i);); /* wait 50ms */
-	outb(0,PIOaddr+ADAPTRESETREL);
-#ifdef ENABLE_PAGING
-	if(ti->page_mask)
-		isa_writeb(SRPR_ENABLE_PAGING, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
-#endif
-
-#if !TR_NEWFORMAT
-	DPRINTK("card reset\n");
-#endif
-
-	ti->open_status=IN_PROGRESS;
-	isa_writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
-	return 0;
-}
-
-static void open_sap(unsigned char type,struct net_device *dev)
-{
 	int i;
-	struct tok_info *ti=(struct tok_info *) dev->priv;
-
-	SET_PAGE(ti->srb_page);
-	for (i=0; i<sizeof(struct dlc_open_sap); i++)
-		isa_writeb(0, ti->srb+i);
 
-	isa_writeb(DLC_OPEN_SAP, ti->srb + offsetof(struct dlc_open_sap, command));
-	isa_writew(htons(MAX_I_FIELD),
-	       ti->srb + offsetof(struct dlc_open_sap, max_i_field));
-	isa_writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY,
-	       ti->srb + offsetof(struct dlc_open_sap, sap_options));
-	isa_writeb(SAP_OPEN_STATION_CNT,
-	       ti->srb + offsetof(struct dlc_open_sap, station_count));
-	isa_writeb(type, ti->srb + offsetof(struct dlc_open_sap, sap_value));
-
-	isa_writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-
-}
-
-void tok_open_adapter(unsigned long dev_addr)
-{
-
-	struct net_device *dev=(struct net_device *)dev_addr;
-	struct tok_info *ti;
-	int i;
-
-	ti=(struct tok_info *) dev->priv;
-
-#if !TR_NEWFORMAT
-	DPRINTK("now opening the board...\n");
+	DPRINTK("ti->init_srb_page=0x%x\n", ti->init_srb_page);
+	DPRINTK("init_srb(%x):", (ti->init_srb) );
+	for (i = 0; i < 20; i++)
+		printk("%02X ", (int) readb(ti->init_srb + i));
+	printk("\n");
+	}
 #endif
 
-	isa_writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
-	isa_writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
+	hw_encoded_addr = readw(ti->init_srb + ENCODED_ADDRESS_OFST);
+	encoded_addr = ntohs(hw_encoded_addr);
+        init_status= /*BMS 12/2000 check for shallow mode possibility (Turbo)*/
+	readb(ti->init_srb+offsetof(struct srb_init_response,init_status));
+	/*printk("Initial interrupt: init_status= 0x%02x\n",init_status);*/
+	ti->ring_speed = init_status & 0x01 ? 16 : 4;
+	DPRINTK("Initial interrupt : %d Mbps, shared RAM base %08x.\n",
+				ti->ring_speed, (unsigned int)dev->mem_start);
+	ti->auto_speedsave=readb(ti->init_srb+INIT_STATUS_2_OFST)&4?TRUE:FALSE;
 
-	for (i=0; i<sizeof(struct dir_open_adapter); i++)
-		isa_writeb(0, ti->init_srb+i);
+        if (ti->open_mode == MANUAL)	wake_up(&ti->wait_for_reset);
+	else				tok_open_adapter((unsigned long)dev);
+        
+} /*initial_tok_int() */
 
-	isa_writeb(DIR_OPEN_ADAPTER,
-	       ti->init_srb + offsetof(struct dir_open_adapter, command));
-	isa_writew(htons(OPEN_PASS_BCON_MAC),
-	       ti->init_srb + offsetof(struct dir_open_adapter, open_options));
-	if (ti->ring_speed == 16) {
-		isa_writew(htons(ti->dhb_size16mb),
-		       ti->init_srb + offsetof(struct dir_open_adapter, dhb_length));
-		isa_writew(htons(ti->rbuf_cnt16),
-		       ti->init_srb + offsetof(struct dir_open_adapter, num_rcv_buf));
-		isa_writew(htons(ti->rbuf_len16),
-		       ti->init_srb + offsetof(struct dir_open_adapter, rcv_buf_len));
-	} else {
-		isa_writew(htons(ti->dhb_size4mb),
-		       ti->init_srb + offsetof(struct dir_open_adapter, dhb_length));
-		isa_writew(htons(ti->rbuf_cnt4),
-		       ti->init_srb + offsetof(struct dir_open_adapter, num_rcv_buf));
-		isa_writew(htons(ti->rbuf_len4),
-		       ti->init_srb + offsetof(struct dir_open_adapter, rcv_buf_len));
-	}
-	isa_writeb(NUM_DHB, /* always 2 */ 
-	       ti->init_srb + offsetof(struct dir_open_adapter, num_dhb));
-	isa_writeb(DLC_MAX_SAP,
-	       ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sap));
-	isa_writeb(DLC_MAX_STA,
-	       ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sta));
-
-	ti->srb=ti->init_srb; /* We use this one in the interrupt handler */
-	ti->srb_page=ti->init_srb_page;
-	DPRINTK("Opend adapter: Xmit bfrs: %d X %d, Rcv bfrs: %d X %d\n",
-		isa_readb(ti->init_srb+offsetof(struct dir_open_adapter,num_dhb)),
-		ntohs(isa_readw(ti->init_srb+offsetof(struct dir_open_adapter,dhb_length))),
-		ntohs(isa_readw(ti->init_srb+offsetof(struct dir_open_adapter,num_rcv_buf))),
-		ntohs(isa_readw(ti->init_srb+offsetof(struct dir_open_adapter,rcv_buf_len))) );
+/*****************************************************************************/
 
-	isa_writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
-	isa_writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+#define CMD_CORRELATE_OFST      1
+#define DHB_ADDRESS_OFST        6
 
-}
+#define FRAME_LENGTH_OFST       6
+#define HEADER_LENGTH_OFST      8
+#define RSAP_VALUE_OFST         9
 
 static void tr_tx(struct net_device *dev)
 {
-	struct tok_info *ti=(struct tok_info *) dev->priv;
-	struct trh_hdr *trhdr=(struct trh_hdr *)ti->current_skb->data;
+	struct tok_info *ti = (struct tok_info *) dev->priv;
+	struct trh_hdr *trhdr = (struct trh_hdr *) ti->current_skb->data;
 	unsigned int hdr_len;
-	__u32 dhb;
+	__u32 dhb=0,dhb_base;
 	unsigned char xmit_command;
-	int i;
-	struct trllc	*llc;
-	struct srb_xmit  xsrb;
-	__u8  dhb_page=0;
-	__u8  llc_ssap;
+	int i,dhb_len=0x4000,src_len,src_offset;
+	struct trllc *llc;
+	struct srb_xmit xsrb;
+	__u8 dhb_page = 0;
+	__u8 llc_ssap;
 
 	SET_PAGE(ti->asb_page);
-	if (isa_readb(ti->asb + offsetof(struct asb_xmit_resp, ret_code))!=0xFF)
-		DPRINTK("ASB not free !!!\n");
 
-	/* in providing the transmit interrupts,
-	   is telling us it is ready for data and
-	   providing a shared memory address for us
-	   to stuff with data.  Here we compute the
-	   effective address where we will place data.*/
-        SET_PAGE(ti->arb_page);
- 	dhb=ntohs(isa_readw(ti->arb + offsetof(struct arb_xmit_req, dhb_address)));
-        if (ti->page_mask) {
-	  dhb_page=(dhb >> 8) & ti->page_mask;
-	  dhb &= ~(ti->page_mask << 8);
-        }
-        dhb+=ti->sram;
-	
+	if (readb(ti->asb+RETCODE_OFST) != 0xFF) DPRINTK("ASB not free !!!\n");
+
+	/* in providing the transmit interrupts, is telling us it is ready for
+	   data and providing a shared memory address for us to stuff with data.
+	   Here we compute the effective address where we will place data.
+	*/
+	SET_PAGE(ti->arb_page);
+	dhb=dhb_base=ntohs(readw(ti->arb + DHB_ADDRESS_OFST));
+	if (ti->page_mask) {
+		dhb_page = (dhb_base >> 8) & ti->page_mask;
+		dhb=dhb_base & ~(ti->page_mask << 8);
+	}
+	dhb += ti->sram_virt;
+
 	/* Figure out the size of the 802.5 header */
-	if (!(trhdr->saddr[0] & 0x80)) /* RIF present? */
-		hdr_len=sizeof(struct trh_hdr)-TR_MAXRIFLEN;
-	else 
-		hdr_len=((ntohs(trhdr->rcf) & TR_RCF_LEN_MASK)>>8)
-			+sizeof(struct trh_hdr)-TR_MAXRIFLEN;
-
-	llc = (struct trllc *)(ti->current_skb->data + hdr_len);
-
-	llc_ssap=llc->ssap;
- 	SET_PAGE(ti->srb_page);
- 	isa_memcpy_fromio(&xsrb, ti->srb, sizeof(xsrb));
- 	SET_PAGE(ti->asb_page);
- 	xmit_command=xsrb.command;
-	
-	isa_writeb(xmit_command, ti->asb + offsetof(struct asb_xmit_resp, command));
-	isa_writew(xsrb.station_id,
-	       ti->asb + offsetof(struct asb_xmit_resp, station_id));
-	isa_writeb(llc_ssap, ti->asb + offsetof(struct asb_xmit_resp, rsap_value));
- 	isa_writeb(xsrb.cmd_corr,
-	       ti->asb + offsetof(struct asb_xmit_resp, cmd_corr));
-	isa_writeb(0, ti->asb + offsetof(struct asb_xmit_resp, ret_code));
-
-	if ((xmit_command==XMIT_XID_CMD) || (xmit_command==XMIT_TEST_CMD)) {
-
-		isa_writew(htons(0x11),
-		       ti->asb + offsetof(struct asb_xmit_resp, frame_length));
-		isa_writeb(0x0e, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
-		SET_PAGE(dhb_page);
-		isa_writeb(AC, dhb);
-		isa_writeb(LLC_FRAME, dhb+1);
+	if (!(trhdr->saddr[0] & 0x80))	/* RIF present? */
+		hdr_len = sizeof(struct trh_hdr) - TR_MAXRIFLEN;
+	else
+		hdr_len = ((ntohs(trhdr->rcf) & TR_RCF_LEN_MASK) >> 8)
+		    + sizeof(struct trh_hdr) - TR_MAXRIFLEN;
 
-		for (i=0; i<TR_ALEN; i++) isa_writeb((int)0x0FF, dhb+i+2);
-		for (i=0; i<TR_ALEN; i++) isa_writeb(0, dhb+i+TR_ALEN+2);
+	llc = (struct trllc *) (ti->current_skb->data + hdr_len);
 
-		isa_writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-		return;
+	llc_ssap = llc->ssap;
+	SET_PAGE(ti->srb_page);
+	memcpy_fromio(&xsrb, ti->srb, sizeof(xsrb));
+	SET_PAGE(ti->asb_page);
+	xmit_command = xsrb.command;
 
+	writeb(xmit_command, ti->asb + COMMAND_OFST);
+	writew(xsrb.station_id, ti->asb + STATION_ID_OFST);
+	writeb(llc_ssap, ti->asb + RSAP_VALUE_OFST);
+	writeb(xsrb.cmd_corr, ti->asb + CMD_CORRELATE_OFST);
+	writeb(0, ti->asb + RETCODE_OFST);
+	if ((xmit_command == XMIT_XID_CMD) || (xmit_command == XMIT_TEST_CMD)) {
+		writew(htons(0x11), ti->asb + FRAME_LENGTH_OFST);
+		writeb(0x0e, ti->asb + HEADER_LENGTH_OFST);
+		SET_PAGE(dhb_page);
+		writeb(AC, dhb);
+		writeb(LLC_FRAME, dhb + 1);
+		for (i = 0; i < TR_ALEN; i++)
+			writeb((int) 0x0FF, dhb + i + 2);
+		for (i = 0; i < TR_ALEN; i++)
+			writeb(0, dhb + i + TR_ALEN + 2);
+		writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+		return;
 	}
-
 	/*
-	 *      the token ring packet is copied from sk_buff to the adapter
-	 *      buffer identified in the command data received with the interrupt.
+	 *    the token ring packet is copied from sk_buff to the adapter
+	 *    buffer identified in the command data received with the interrupt.
 	 */
-	isa_writeb(hdr_len, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
-	isa_writew(htons(ti->current_skb->len),
-	       ti->asb + offsetof(struct asb_xmit_resp, frame_length));
-
-	SET_PAGE(dhb_page);
-	isa_memcpy_toio(dhb, ti->current_skb->data, ti->current_skb->len);
-
-	isa_writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-	ti->tr_stats.tx_bytes+=ti->current_skb->len;
+	writeb(hdr_len, ti->asb + HEADER_LENGTH_OFST);
+	writew(htons(ti->current_skb->len), ti->asb + FRAME_LENGTH_OFST);
+	src_len=ti->current_skb->len;
+	src_offset=0;
+	dhb=dhb_base;
+	while(1) {
+		if (ti->page_mask) {
+			dhb_page=(dhb >> 8) & ti->page_mask;
+			dhb=dhb & ~(ti->page_mask << 8);
+			dhb_len=0x4000-dhb; /* remaining size of this page */
+		}
+		dhb+=ti->sram_virt;
+		SET_PAGE(dhb_page);
+		if (src_len > dhb_len) {
+			memcpy_toio(dhb,&ti->current_skb->data[src_offset],
+					dhb_len);
+			src_len -= dhb_len;
+			src_offset += dhb_len;
+			dhb_base+=dhb_len;
+			dhb=dhb_base;
+			continue;
+		}
+		memcpy_toio(dhb, &ti->current_skb->data[src_offset], src_len);
+		break;
+	}
+	writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+	ti->tr_stats.tx_bytes += ti->current_skb->len;
 	dev_kfree_skb_irq(ti->current_skb);
-	ti->current_skb=NULL;
+	ti->current_skb = NULL;
 	netif_wake_queue(dev);
-	if (ti->readlog_pending) ibmtr_readlog(dev);
-}
+	if (ti->readlog_pending)
+		ibmtr_readlog(dev);
+}				/*tr_tx */
+
+/*****************************************************************************/
+
+
+#define RECEIVE_BUFFER_OFST     6
+#define LAN_HDR_LENGTH_OFST     8
+#define DLC_HDR_LENGTH_OFST     9
+
+#define DSAP_OFST               0
+#define SSAP_OFST               1
+#define LLC_OFST                2
+#define PROTID_OFST             3
+#define ETHERTYPE_OFST          6
 
 static void tr_rx(struct net_device *dev)
 {
-	struct tok_info *ti=(struct tok_info *) dev->priv;
+	struct tok_info *ti = (struct tok_info *) dev->priv;
 	__u32 rbuffer, rbufdata;
-	__u8  rbuffer_page=0;
+	__u8 rbuffer_page = 0;
 	__u32 llc;
 	unsigned char *data;
 	unsigned int rbuffer_len, lan_hdr_len, hdr_len, ip_len, length;
+	unsigned char dlc_hdr_len;
 	struct sk_buff *skb;
 	unsigned int skb_size = 0;
-	int	IPv4_p = 0;
+	int IPv4_p = 0;
 	unsigned int chksum = 0;
 	struct iphdr *iph;
 	struct arb_rec_req rarb;
 
 	SET_PAGE(ti->arb_page);
- 	isa_memcpy_fromio(&rarb, ti->arb, sizeof(rarb));
- 	rbuffer=ntohs(rarb.rec_buf_addr)+2;
+	memcpy_fromio(&rarb, ti->arb, sizeof(rarb));
+	rbuffer = ntohs(rarb.rec_buf_addr) ;
 	if (ti->page_mask) {
-	  rbuffer_page=(rbuffer >> 8) & ti->page_mask;
-	  rbuffer &= ~(ti->page_mask<<8);
+		rbuffer_page = (rbuffer >> 8) & ti->page_mask;
+		rbuffer &= ~(ti->page_mask << 8);
 	}
-	rbuffer += ti->sram;
-	
+	rbuffer += ti->sram_virt;
+
 	SET_PAGE(ti->asb_page);
-	if(isa_readb(ti->asb + offsetof(struct asb_rec, ret_code))!=0xFF)
-		DPRINTK("ASB not free !!!\n");
 
-	isa_writeb(REC_DATA,
-	       ti->asb + offsetof(struct asb_rec, command));
-	isa_writew(rarb.station_id,
-	       ti->asb + offsetof(struct asb_rec, station_id));
-	isa_writew(rarb.rec_buf_addr,
-	       ti->asb + offsetof(struct asb_rec, rec_buf_addr));
+	if (readb(ti->asb + RETCODE_OFST) !=0xFF) DPRINTK("ASB not free !!!\n");
 
-	lan_hdr_len=rarb.lan_hdr_len;
+	writeb(REC_DATA, ti->asb + COMMAND_OFST);
+	writew(rarb.station_id, ti->asb + STATION_ID_OFST);
+	writew(rarb.rec_buf_addr, ti->asb + RECEIVE_BUFFER_OFST);
+
+	lan_hdr_len = rarb.lan_hdr_len;
+	if (lan_hdr_len > sizeof(struct trh_hdr)) {
+		DPRINTK("Linux cannot handle greater than 18 bytes RIF\n");
+		return;
+	}			/*BMS I added this above just to be very safe */
+	dlc_hdr_len = readb(ti->arb + DLC_HDR_LENGTH_OFST);
 	hdr_len = lan_hdr_len + sizeof(struct trllc) + sizeof(struct iphdr);
 
 	SET_PAGE(rbuffer_page);
-	llc=(rbuffer + offsetof(struct rec_buf, data) + lan_hdr_len);
+	llc = (rbuffer + offsetof(struct rec_buf, data) + lan_hdr_len);
 
 #if TR_VERBOSE
 	DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n",
-		(unsigned int)offsetof(struct rec_buf,data), (unsigned int)lan_hdr_len);
-	DPRINTK("llc: %08X rec_buf_addr: %04X ti->sram: %lx\n", llc,
-		ntohs(rarb.rec_buf_addr),
-		(long)ti->sram);
+	(__u32) offsetof(struct rec_buf, data), (unsigned int) lan_hdr_len);
+	DPRINTK("llc: %08X rec_buf_addr: %04X dev->mem_start: %lX\n",
+		llc, ntohs(rarb.rec_buf_addr), dev->mem_start);
 	DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, "
 		"ethertype: %04X\n",
-		(int)isa_readb(llc + offsetof(struct trllc, dsap)),
-		(int)isa_readb(llc + offsetof(struct trllc, ssap)),
-		(int)isa_readb(llc + offsetof(struct trllc, llc)),
-		(int)isa_readb(llc + offsetof(struct trllc, protid)),
-		(int)isa_readb(llc + offsetof(struct trllc, protid)+1),
-		(int)isa_readb(llc + offsetof(struct trllc, protid)+2),
-		(int)isa_readw(llc + offsetof(struct trllc, ethertype)));
-#endif
-	if (isa_readb(llc + offsetof(struct trllc, llc))!=UI_CMD) {
-                SET_PAGE(ti->asb_page);
-		isa_writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
+		(int) readb(llc + DSAP_OFST), (int) readb(llc + SSAP_OFST),
+		(int) readb(llc + LLC_OFST), (int) readb(llc + PROTID_OFST),
+		(int) readb(llc+PROTID_OFST+1),(int)readb(llc+PROTID_OFST + 2),
+		(int) ntohs(readw(llc + ETHERTYPE_OFST)));
+#endif
+	if (readb(llc + offsetof(struct trllc, llc)) != UI_CMD) {
+		SET_PAGE(ti->asb_page);
+		writeb(DATA_LOST, ti->asb + RETCODE_OFST);
 		ti->tr_stats.rx_dropped++;
-		isa_writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+		writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 		return;
 	}
-
 	length = ntohs(rarb.frame_len);
-	if ((isa_readb(llc + offsetof(struct trllc, dsap))==EXTENDED_SAP) &&
-       	    (isa_readb(llc + offsetof(struct trllc, ssap))==EXTENDED_SAP) &&
-		(length>=hdr_len)) {
-       		IPv4_p = 1;
-       	}
-
+	if (readb(llc + DSAP_OFST) == EXTENDED_SAP &&
+	   readb(llc + SSAP_OFST) == EXTENDED_SAP &&
+		length >= hdr_len)	IPv4_p = 1;
 #if TR_VERBOSE
-       	if (!IPv4_p){
+#define SADDR_OFST	8
+#define DADDR_OFST	2
 
-       		__u32 trhhdr;
+	if (!IPv4_p) {
 
-       		trhhdr=(rbuffer+offsetof(struct rec_buf,data));
+		__u32 trhhdr;
 
-       		DPRINTK("Probably non-IP frame received.\n");
-       		DPRINTK("ssap: %02X dsap: %02X saddr: %02X:%02X:%02X:%02X:%02X:%02X "
-       			"daddr: %02X:%02X:%02X:%02X:%02X:%02X\n",
-       			(int)isa_readb(llc + offsetof(struct trllc, ssap)),
-       			(int)isa_readb(llc + offsetof(struct trllc, dsap)),
-       			(int)isa_readb(trhhdr + offsetof(struct trh_hdr, saddr)),
-       			(int)isa_readb(trhhdr + offsetof(struct trh_hdr, saddr)+1),
-       			(int)isa_readb(trhhdr + offsetof(struct trh_hdr, saddr)+2),
-       			(int)isa_readb(trhhdr + offsetof(struct trh_hdr, saddr)+3),
-       			(int)isa_readb(trhhdr + offsetof(struct trh_hdr, saddr)+4),
-       			(int)isa_readb(trhhdr + offsetof(struct trh_hdr, saddr)+5),
-       			(int)isa_readb(trhhdr + offsetof(struct trh_hdr, daddr)),
-       			(int)isa_readb(trhhdr + offsetof(struct trh_hdr, daddr)+1),
-       			(int)isa_readb(trhhdr + offsetof(struct trh_hdr, daddr)+2),
-       			(int)isa_readb(trhhdr + offsetof(struct trh_hdr, daddr)+3),
-       			(int)isa_readb(trhhdr + offsetof(struct trh_hdr, daddr)+4),
-       			(int)isa_readb(trhhdr + offsetof(struct trh_hdr, daddr)+5));
-       	}
-#endif
-
-       	skb_size = length;
- 
-       	if (!(skb=dev_alloc_skb(skb_size))) {
-       		DPRINTK("out of memory. frame dropped.\n");
-       		ti->tr_stats.rx_dropped++;
+		trhhdr = (rbuffer + offsetof(struct rec_buf, data));
+
+		DPRINTK("Probably non-IP frame received.\n");
+		DPRINTK("ssap: %02X dsap: %02X "
+			"saddr: %02X:%02X:%02X:%02X:%02X:%02X "
+			"daddr: %02X:%02X:%02X:%02X:%02X:%02X\n",
+			readb(llc + SSAP_OFST), readb(llc + DSAP_OFST),
+			readb(trhhdr+SADDR_OFST), readb(trhhdr+ SADDR_OFST+1),
+			readb(trhhdr+SADDR_OFST+2), readb(trhhdr+SADDR_OFST+3),
+			readb(trhhdr+SADDR_OFST+4), readb(trhhdr+SADDR_OFST+5),
+			readb(trhhdr+DADDR_OFST), readb(trhhdr+DADDR_OFST + 1),
+			readb(trhhdr+DADDR_OFST+2), readb(trhhdr+DADDR_OFST+3),
+			readb(trhhdr+DADDR_OFST+4), readb(trhhdr+DADDR_OFST+5));
+	}
+#endif
+
+	/*BMS handle the case she comes in with few hops but leaves with many */
+        skb_size=length-lan_hdr_len+sizeof(struct trh_hdr)+sizeof(struct trllc);
+
+	if (!(skb = dev_alloc_skb(skb_size))) {
+		DPRINTK("out of memory. frame dropped.\n");
+		ti->tr_stats.rx_dropped++;
 		SET_PAGE(ti->asb_page);
-       		isa_writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
-       		isa_writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-       		return;
-       	}
-
-      	skb_put(skb, length);
-	skb_reserve(skb, sizeof(struct trh_hdr)-lan_hdr_len+sizeof(struct trllc));
-       	skb->dev=dev;
-       	data=skb->data;
-	rbuffer_len=ntohs(isa_readw(rbuffer + offsetof(struct rec_buf, buf_len)));
-	rbufdata = rbuffer + offsetof(struct rec_buf,data);
+		writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
+		writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+		return;
+	}
+	/*BMS again, if she comes in with few but leaves with many */
+	skb_reserve(skb, sizeof(struct trh_hdr) - lan_hdr_len);
+	skb_put(skb, length);
+	skb->dev = dev;
+	data = skb->data;
+	rbuffer_len = ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)));
+	rbufdata = rbuffer + offsetof(struct rec_buf, data);
 
 	if (IPv4_p) {
-                /* Copy the headers without checksumming */
-		isa_memcpy_fromio(data, rbufdata, hdr_len);
+		/* Copy the headers without checksumming */
+		memcpy_fromio(data, rbufdata, hdr_len);
 
 		/* Watch for padded packets and bogons */
-		iph=(struct iphdr*)(data + lan_hdr_len + sizeof(struct trllc));
+		iph= (struct iphdr *)(data+ lan_hdr_len + sizeof(struct trllc));
 		ip_len = ntohs(iph->tot_len) - sizeof(struct iphdr);
 		length -= hdr_len;
 		if ((ip_len <= length) && (ip_len > 7))
@@ -1751,107 +1769,123 @@
 		data += hdr_len;
 		rbuffer_len -= hdr_len;
 		rbufdata += hdr_len;
-        }
-
+	}
 	/* Copy the payload... */
+#define BUFFER_POINTER_OFST	2
+#define BUFFER_LENGTH_OFST      6
 	for (;;) {
+		if (ibmtr_debug_trace&TRC_INITV && length < rbuffer_len)
+			DPRINTK("CURIOUS, length=%d < rbuffer_len=%d\n",
+						length,rbuffer_len);
 		if (IPv4_p)
-			chksum = csum_partial_copy_nocheck(bus_to_virt(rbufdata), data,
-						   length < rbuffer_len ? length : rbuffer_len,
-						   chksum);
+			chksum=csum_partial_copy_nocheck((void*)rbufdata,
+			    data,length<rbuffer_len?length:rbuffer_len,chksum);
 		else
-			isa_memcpy_fromio(data, rbufdata, rbuffer_len);
-		rbuffer = ntohs(isa_readw(rbuffer));
+			memcpy_fromio(data, rbufdata, rbuffer_len);
+		rbuffer = ntohs(readw(rbuffer+BUFFER_POINTER_OFST)) ;
 		if (!rbuffer)
 			break;
+		rbuffer -= 2;
 		length -= rbuffer_len;
 		data += rbuffer_len;
 		if (ti->page_mask) {
-		  rbuffer_page=(rbuffer>>8) & ti->page_mask;
-		  rbuffer &= ~(ti->page_mask << 8);
+			rbuffer_page = (rbuffer >> 8) & ti->page_mask;
+			rbuffer &= ~(ti->page_mask << 8);
 		}
-		rbuffer += ti->sram;
+		rbuffer += ti->sram_virt;
 		SET_PAGE(rbuffer_page);
-		rbuffer_len = ntohs(isa_readw(rbuffer + offsetof(struct rec_buf, buf_len)));
+		rbuffer_len = ntohs(readw(rbuffer + BUFFER_LENGTH_OFST));
 		rbufdata = rbuffer + offsetof(struct rec_buf, data);
 	}
 
 	SET_PAGE(ti->asb_page);
-       	isa_writeb(0, ti->asb + offsetof(struct asb_rec, ret_code));
+	writeb(0, ti->asb + offsetof(struct asb_rec, ret_code));
 
-       	isa_writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+	writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 
 	ti->tr_stats.rx_bytes += skb->len;
-       	ti->tr_stats.rx_packets++;
+	ti->tr_stats.rx_packets++;
 
-	skb->protocol = tr_type_trans(skb,dev);
- 	if (IPv4_p && (skb->protocol == ETH_P_IP)) { 
-		skb->csum      = chksum;
+	skb->protocol = tr_type_trans(skb, dev);
+	if (IPv4_p) {
+		skb->csum = chksum;
 		skb->ip_summed = 1;
 	}
 	netif_rx(skb);
 	dev->last_rx = jiffies;
+}				/*tr_rx */
+
+/*****************************************************************************/
+
+void ibmtr_reset_timer(struct timer_list *tmr, struct net_device *dev)
+{
+	tmr->expires = jiffies + TR_RETRY_INTERVAL;
+	tmr->data = (unsigned long) dev;
+	tmr->function = tok_rerun;
+	init_timer(tmr);
+	add_timer(tmr);
 }
 
-static int tok_send_packet(struct sk_buff *skb, struct net_device *dev)
+/*****************************************************************************/
+
+void tok_rerun(unsigned long dev_addr){
+
+	struct net_device *dev = (struct net_device *)dev_addr;
+	struct tok_info *ti = (struct tok_info *) dev->priv;
+
+	if ( ti->open_action == RESTART){
+		ti->do_tok_int = FIRST_INT;
+		outb(0, dev->base_addr + ADAPTRESETREL);
+#ifdef ENABLE_PAGING
+		if (ti->page_mask)
+			writeb(SRPR_ENABLE_PAGING,
+				ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
+#endif
+
+		writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+	} else
+		tok_open_adapter(dev_addr);
+}
+
+/*****************************************************************************/
+
+void ibmtr_readlog(struct net_device *dev)
 {
 	struct tok_info *ti;
-	unsigned long flags;
-	ti=(struct tok_info *) dev->priv;
 
-	netif_stop_queue(dev);
-	
-	/* lock against other CPUs */
-	spin_lock_irqsave(&(ti->lock), flags);
+	ti = (struct tok_info *) dev->priv;
 
-	/* Save skb; we'll need it when the adapter asks for the data */
-	ti->current_skb=skb;
+	ti->readlog_pending = 0;
 	SET_PAGE(ti->srb_page);
-	isa_writeb(XMIT_UI_FRAME, ti->srb + offsetof(struct srb_xmit, command));
-	isa_writew(ti->exsap_station_id, ti->srb
-	       +offsetof(struct srb_xmit, station_id));
-	isa_writeb(CMD_IN_SRB, (ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD));
-	spin_unlock_irqrestore(&(ti->lock), flags);
-	dev->trans_start=jiffies;
-	return 0;
-}
+	writeb(DIR_READ_LOG, ti->srb);
+	writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+	writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 
-void ibmtr_reset_timer(struct timer_list *tmr, struct net_device *dev) {
-	tmr->expires  = jiffies + TR_RETRY_INTERVAL;
-	tmr->data     = (unsigned long) dev;
-	tmr->function = tok_open_adapter;
-	init_timer(tmr);
-	add_timer(tmr);
-}
+	netif_stop_queue(dev);
 
-void ibmtr_readlog(struct net_device *dev) {
-	 struct tok_info *ti;
-	 ti=(struct tok_info *) dev->priv;
-
-	 ti->readlog_pending = 0;
-	 SET_PAGE(ti->srb_page);
-	 isa_writeb(DIR_READ_LOG, ti->srb);
-	 isa_writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
-	 isa_writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-	 
-	 netif_stop_queue(dev);
 }
 
+/*****************************************************************************/
+
 /* tok_get_stats():  Basically a scaffold routine which will return
    the address of the tr_statistics structure associated with
    this device -- the tr.... structure is an ethnet look-alike
    so at least for this iteration may suffice.   */
 
-static struct net_device_stats * tok_get_stats(struct net_device *dev) {
+static struct net_device_stats *tok_get_stats(struct net_device *dev)
+{
 
 	struct tok_info *toki;
-	toki=(struct tok_info *) dev->priv;
+	toki = (struct tok_info *) dev->priv;
 	return (struct net_device_stats *) &toki->tr_stats;
 }
 
-int ibmtr_change_mtu(struct net_device *dev, int mtu) {
+/*****************************************************************************/
+
+int ibmtr_change_mtu(struct net_device *dev, int mtu)
+{
 	struct tok_info *ti = (struct tok_info *) dev->priv;
-	
+
 	if (ti->ring_speed == 16 && mtu > ti->maxmtu16)
 		return -EINVAL;
 	if (ti->ring_speed == 4 && mtu > ti->maxmtu4)
@@ -1860,12 +1894,12 @@
 	return 0;
 }
 
-#ifndef PCMCIA
+/*****************************************************************************/
 #ifdef MODULE
 
 /* 3COM 3C619C supports 8 interrupts, 32 I/O ports */
-static struct net_device* dev_ibmtr[IBMTR_MAX_ADAPTERS];
-static int io[IBMTR_MAX_ADAPTERS] = {0xa20,0xa24};
+static struct net_device *dev_ibmtr[IBMTR_MAX_ADAPTERS];
+static int io[IBMTR_MAX_ADAPTERS] = { 0xa20, 0xa24 };
 static int irq[IBMTR_MAX_ADAPTERS];
 static int mem[IBMTR_MAX_ADAPTERS];
 
@@ -1875,50 +1909,61 @@
 
 int init_module(void)
 {
-        int i;
-        for (i = 0; io[i] && (i<IBMTR_MAX_ADAPTERS); i++) {
-	        irq[i] = 0;
+	int i;
+	int count=0;
+
+	find_turbo_adapters(io);
+	for (i = 0; io[i] && (i < IBMTR_MAX_ADAPTERS); i++) {
+		irq[i] = 0;
 		mem[i] = 0;
 		dev_ibmtr[i] = NULL;
-                dev_ibmtr[i] = init_trdev(dev_ibmtr[i], 0);
-                if (dev_ibmtr[i] == NULL) {
-			if (i == 0)
-                        	return -ENOMEM;
-			break;
+		dev_ibmtr[i] = init_trdev(dev_ibmtr[i], 0);
+		if (dev_ibmtr[i] == NULL) { 
+			if (i==0)
+				return -ENOMEM;
+			break ; 
 		}
-
-	        dev_ibmtr[i]->base_addr = io[i];
-	        dev_ibmtr[i]->irq       = irq[i];
+		dev_ibmtr[i]->base_addr = io[i];
+		dev_ibmtr[i]->irq = irq[i];
 		dev_ibmtr[i]->mem_start = mem[i];
-		dev_ibmtr[i]->init      = &ibmtr_probe;
-
-	        if (register_trdev(dev_ibmtr[i]) != 0) {
+		dev_ibmtr[i]->init = &ibmtr_probe;
+		if (register_trdev(dev_ibmtr[i]) != 0) {
 			kfree(dev_ibmtr[i]);
 			dev_ibmtr[i] = NULL;
-		        if (i == 0) {
-			        printk("ibmtr: register_trdev() returned non-zero.\n");
-		                return -EIO;
-			} else {
-			        return 0;
-			}
-	        }
+			continue;
+		}
+		count++;
 	}
-	return 0;
-}
+	if (count) return 0;
+	printk("ibmtr: register_trdev() returned non-zero.\n");
+	return -EIO;
+}				/*init_module */
 
 void cleanup_module(void)
 {
-        int i;
+	int i,j;
 
-        for (i = 0; i < IBMTR_MAX_ADAPTERS; i++)
-	        if (dev_ibmtr[i]) {
-			 unregister_trdev(dev_ibmtr[i]);
-			 free_irq(dev_ibmtr[i]->irq, dev_ibmtr[i]);
-			 release_region(dev_ibmtr[i]->base_addr, IBMTR_IO_EXTENT);
-			 kfree(dev_ibmtr[i]->priv);
-			 kfree(dev_ibmtr[i]);
-			 dev_ibmtr[i] = NULL;
+	for (i = 0; i < IBMTR_MAX_ADAPTERS; i++){
+		if(!dev_ibmtr[i]) continue;
+		if (dev_ibmtr[i]->base_addr) {
+			outb(0,dev_ibmtr[i]->base_addr+ADAPTRESET);
+			for(j=jiffies+TR_RST_TIME;
+				time_before_eq(jiffies,j);) ;
+                        outb(0,dev_ibmtr[i]->base_addr+ADAPTRESETREL);
                 }
+		unregister_trdev(dev_ibmtr[i]);
+		free_irq(dev_ibmtr[i]->irq, dev_ibmtr[i]);
+		release_region(dev_ibmtr[i]->base_addr, IBMTR_IO_EXTENT);
+#ifndef PCMCIA
+		{ 
+		struct tok_info *ti = (struct tok_info *)dev_ibmtr[i]->priv ; 
+		iounmap((u32 *)ti->mmio) ; 
+		iounmap((u32 *)ti->sram_virt) ; 
+		}
+#endif		
+		kfree(dev_ibmtr[i]->priv);
+		kfree(dev_ibmtr[i]);
+		dev_ibmtr[i] = NULL;
+	}
 }
-#endif /* MODULE */
-#endif
+#endif				/* MODULE */
diff -u --recursive --new-file v2.4.6/linux/drivers/net/wan/Config.in linux/drivers/net/wan/Config.in
--- v2.4.6/linux/drivers/net/wan/Config.in	Thu Apr 12 12:11:39 2001
+++ linux/drivers/net/wan/Config.in	Wed Jul  4 11:50:39 2001
@@ -49,7 +49,7 @@
 
    dep_tristate '  Sealevel Systems 4021 support' CONFIG_SEALEVEL_4021 m
 
-   dep_tristate '  SyncLink HDLC/SYNCPPP support' CONFIG_SYNCLINK_SYNCPPP m
+   tristate '  SyncLink HDLC/SYNCPPP support' CONFIG_SYNCLINK_SYNCPPP
 
    tristate '  Generic HDLC driver' CONFIG_HDLC
    if [ "$CONFIG_HDLC" != "n" ]; then
diff -u --recursive --new-file v2.4.6/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v2.4.6/linux/drivers/pci/pci.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/pci/pci.c	Wed Jul  4 09:41:34 2001
@@ -279,7 +279,7 @@
 	 * This doesn't affect PME_Status, disables PME_En, and
 	 * sets PowerState to 0.
 	 */
-	if (dev->current_state == 3)
+	if (dev->current_state >= 3)
 		pmcsr = 0;
 	else {
 		pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
@@ -1175,6 +1175,9 @@
 	class >>= 8;
 
 	DBG("Found %02x:%02x [%04x/%04x] %06x %02x\n", dev->bus->number, dev->devfn, dev->vendor, dev->device, class, dev->hdr_type);
+
+	/* "Unknown power state" */
+	dev->current_state = 4;
 
 	switch (dev->hdr_type) {		    /* header type */
 	case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
diff -u --recursive --new-file v2.4.6/linux/drivers/s390/s390io.c linux/drivers/s390/s390io.c
--- v2.4.6/linux/drivers/s390/s390io.c	Wed Apr 11 19:02:29 2001
+++ linux/drivers/s390/s390io.c	Wed Jul  4 11:50:39 2001
@@ -2157,6 +2157,7 @@
 	 * Get interrupt info from lowcore
 	 */
 	volatile tpi_info_t *tpi_info = (tpi_info_t*)(__LC_SUBCHANNEL_ID);
+	int cpu = smp_processor_id();
 
 	/*
 	 * take fast exit if CPU is in sync. I/O state
@@ -2182,7 +2183,9 @@
 		if ( tpi_info->adapter_IO == 1 &&
 		     tpi_info->int_type == IO_INTERRUPT_TYPE )
 		{
+			irq_enter(cpu, -1);
 			do_adapter_IO( tpi_info->intparm );
+			irq_exit(cpu, -1);
 		} 
 		else 
 		{
@@ -2200,9 +2203,11 @@
 				return;	/* this keeps the device boxed ... */
 			}
 	
+			irq_enter(cpu, irq);
 			s390irq_spin_lock( irq );
 			s390_process_IRQ( irq );
 			s390irq_spin_unlock( irq );
+			irq_exit(cpu, irq);
 		}
 
 #ifdef CONFIG_FAST_IRQ
@@ -3166,8 +3171,11 @@
 
 		} /* endif */
 
-		if ( rc )	// can only happen if stsch/msch fails
+		if ( rc )	/* can only happen if stsch/msch fails */
+		{
 			sync_isc_cnt = 0;
+			atomic_set( &sync_isc, -1);
+		}
 	}
 	else
 	{
@@ -4276,12 +4284,7 @@
 		{
 			ret = enable_cpu_sync_isc( irq );
 
-			if ( ret )
-			{
-				free_irq( irq, &devstat );
-				return; // fixme ! fast exit ... grr
-			}
-			else
+			if ( !ret )
 			{
 				ioinfo[irq]->ui.flags.unknown = 0;
 
@@ -5270,24 +5273,28 @@
 
 					} /* endif */
 				}
-				else if ( ret )
+				else if ( ret == -EIO )
 				{
-
 #ifdef CONFIG_DEBUG_IO
-						printk( "PathVerification(%04X) "
-						        "- Device %04X doesn't "
-						        " support path grouping\n",
-						        irq,
-						        ioinfo[irq]->schib.pmcw.dev);
-
+					printk("PathVerification(%04X) - I/O error "
+					       "on device %04X\n", irq,
+					       ioinfo[irq]->schib.pmcw.dev);
 #endif
-
 					ioinfo[irq]->ui.flags.pgid_supp = 0;
-
+		    
+				} else {
+#ifdef CONFIG_DEBUG_IO
+					printk( "PathVerification(%04X) "
+						"- Unexpected error on device %04X\n",
+						irq,
+						ioinfo[irq]->schib.pmcw.dev);
+#endif
+					ioinfo[irq]->ui.flags.pgid_supp = 0;
+					
 				} /* endif */
 
 			} /* endif */
-
+			
 		} /* endfor */
 
 	} /* endif */
@@ -5442,9 +5449,9 @@
 
 						} /* endif */
 					}
-#ifdef CONFIG_DEBUG_IO
 					else
 					{
+#ifdef CONFIG_DEBUG_IO
 						printk( "SPID - device %04X,"
 						        " unit check,"
 						        " retry %d, cnt %02d,"
@@ -5462,8 +5469,10 @@
 						        pdevstat->ii.sense.data[6],
 						        pdevstat->ii.sense.data[7]);
 
-					} /* endif */
 #endif
+						retry--;
+
+					} /* endif */
 				}
 				else if ( pdevstat->flag & DEVSTAT_NOT_OPER )
 				{
@@ -5474,6 +5483,7 @@
 					        irq);
 
 					retry = 0;
+					irq_ret = -EIO;
 
 				} /* endif */
 			}
@@ -5489,6 +5499,12 @@
 
 		} while ( retry > 0 );
 
+		if ( retry == 0 )
+		{
+			irq_ret = -EIO;
+
+		} /* endif */		
+
 		if ( init_IRQ_complete )
 		{
 			kfree( spid_ccw );
@@ -5693,6 +5709,12 @@
 
 		} while ( retry > 0 );
 
+		if ( retry == 0 )
+		{
+			irq_ret = -EIO;
+
+		} /* endif */
+
 		if ( init_IRQ_complete )
 		{
 			kfree( snid_ccw );
@@ -5936,7 +5958,10 @@
 		}
 	}
 
-	do_reipl( 0x10000 | sch );
+	if (MACHINE_IS_VM)
+		cpcmd("IPL", NULL, 0);
+	else
+		do_reipl( 0x10000 | sch );
 }
 
 /* Display info on subchannels in /proc/subchannels. *
diff -u --recursive --new-file v2.4.6/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c
--- v2.4.6/linux/drivers/scsi/hosts.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/scsi/hosts.c	Wed Jul  4 11:50:39 2001
@@ -69,7 +69,7 @@
  *  idiocy.
  */
 
-Scsi_Host_Template * scsi_hosts = NULL;
+Scsi_Host_Template * scsi_hosts;
 
 
 /*
@@ -77,12 +77,12 @@
  *      MAX_SCSI_HOSTS here.
  */
 
-Scsi_Host_Name * scsi_host_no_list = NULL;
-struct Scsi_Host * scsi_hostlist = NULL;
-struct Scsi_Device_Template * scsi_devicelist = NULL;
+Scsi_Host_Name * scsi_host_no_list;
+struct Scsi_Host * scsi_hostlist;
+struct Scsi_Device_Template * scsi_devicelist;
 
-int max_scsi_hosts = 0;
-int next_scsi_host = 0;
+int max_scsi_hosts;
+int next_scsi_host;
 
 void
 scsi_unregister(struct Scsi_Host * sh){
diff -u --recursive --new-file v2.4.6/linux/drivers/scsi/megaraid.c linux/drivers/scsi/megaraid.c
--- v2.4.6/linux/drivers/scsi/megaraid.c	Fri Apr 27 13:59:18 2001
+++ linux/drivers/scsi/megaraid.c	Wed Jul  4 11:50:39 2001
@@ -9,7 +9,7 @@
  *              as published by the Free Software Foundation; either version
  *              2 of the License, or (at your option) any later version.
  *
- * Version : v1.14g (Feb 5, 2001)
+ * Version : v1.15d(May 30, 2001)
  *
  * Description: Linux device driver for AMI MegaRAID controller
  *
@@ -296,6 +296,63 @@
  *	Version 1.14g-ac2 - 22/03/01
  *	Fixed a non obvious dereference after free in the driver unload path
  *
+ *	Version 1.14i
+ *	changes for making 32bit application run on IA64
+ *
+ *	Version 1.14j
+ *	Tue Mar 13 14:27:54 EST 2001 - AM
+ *	Changes made in the driver to be able to run applications if the
+ *	system has memory >4GB.
+ *
+ *
+ *	Version 1.14k
+ *	Thu Mar 15 18:38:11 EST 2001 - AM
+ *
+ *	Firmware version check removed if subsysid==0x1111 and
+ *	subsysvid==0x1111, since its not yet initialized.
+ *
+ *	changes made to correctly calculate the base in mega_findCard.
+ *
+ *	Driver informational messages now appear on the console as well as
+ *	with dmesg
+ *
+ *	Older ioctl interface is returned failure on newer(2.4.xx) kernels.
+ *
+ *	Inclusion of "modversions.h" is still a debatable question. It is
+ *	included anyway with this release.
+ *
+ *	Version 1.14l
+ *	Mon Mar 19 17:39:46 EST 2001 - AM
+ *
+ *	Assorted changes to remove compilation error in 1.14k when compiled
+ *	with kernel < 2.4.0
+ *
+ *	Version 1.15
+ *	Thu Apr 19 09:38:38 EDT 2001 - AM
+ *
+ *	1.14l rollover to 1.15
+ *
+ *	Version 1.15b
+ *  Wed May 16 20:10:01 EDT 2001 - AM
+ *
+ *	"modeversions.h" is no longer included in the code.
+ *	2.4.xx style mutex initialization used for older kernels also
+ *	Brought in-sync with Alan's changes in 2.4.4
+ *	Note: 1.15a is on OBDR brabch(main trunk), and is not merged with yet.
+ *
+ * Version 1.15c
+ * Mon May 21 23:10:42 EDT 2001 - AM
+ *
+ * ioctl interface uses 2.4.x conforming pci dma calls
+ * similar calls used for older kernels
+ *
+ * Version 1.15d
+ * Wed May 30 17:30:41 EDT 2001 - AM
+ *
+ * NULL is not a valid first argument for pci_alloc_consistent() on
+ * IA64(2.4.3-2.10.1). Code shuffling done in ioctl interface to get
+ * "pci_dev" before making calls to pci interface routines.
+
  * BUGS:
  *     Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that
  *     fails to detect the controller as a pci device on the system.
@@ -399,7 +456,11 @@
 #define cpuid smp_processor_id()
 #endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/* 0x020100 */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)
+#define scsi_set_pci_device(x,y)
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/* 0x020400 */
 
 /*
  *	Linux 2.4 and higher
@@ -447,10 +508,12 @@
 #define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags);
 
 #define pci_free_consistent(a,b,c,d)
-#define pci_unmap_single(a,b,c,d,e)
+#define pci_unmap_single(a,b,c,d)
+
+#define init_MUTEX_LOCKED(x)    (*(x)=MUTEX_LOCKED)
+#define init_MUTEX(x)           (*(x)=MUTEX)
 
-#define init_MUTEX_LOCKED(x)	((x)=MUTEX_LOCKED)
-#define init_MUTEX(x)		((x)=MUTEX)
+#define pci_enable_device(x) (0)
 
 #define queue_task_irq(a,b)     queue_task(a,b)
 #define queue_task_irq_off(a,b) queue_task(a,b)
@@ -480,10 +543,12 @@
 #define cpu_to_le32(x) (x)
 
 #define pci_free_consistent(a,b,c,d)
-#define pci_unmap_single(a,b,c,d,e)
+#define pci_unmap_single(a,b,c,d)
+
+#define init_MUTEX_LOCKED(x)    (*(x)=MUTEX_LOCKED)
+#define init_MUTEX(x)           (*(x)=MUTEX)
 
-#define init_MUTEX_LOCKED(x)	((x)=MUTEX_LOCKED)
-#define init_MUTEX(x)		((x)=MUTEX)
+#define pci_enable_device(x) (0)
 
 /*
  *	2.0 lacks spinlocks, iounmap/ioremap
@@ -508,6 +573,16 @@
 #endif
 
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/* 0x020400 */
+#define dma_alloc_consistent pci_alloc_consistent
+#define dma_free_consistent pci_free_consistent
+#else
+typedef unsigned long dma_addr_t;
+void *dma_alloc_consistent(void *, size_t, dma_addr_t *);
+void dma_free_consistent(void *, size_t, void *, dma_addr_t);
+int mega_get_order(int);
+int pow_2(int);
+#endif
 
 /* set SERDEBUG to 1 to enable serial debugging */
 #define SERDEBUG 0
@@ -973,10 +1048,16 @@
 	if ((SCpnt->cmnd[0] == MEGADEVIOC))
 		return megadev_doioctl (megaCfg, SCpnt);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
 	if ((SCpnt->cmnd[0] == M_RD_IOCTL_CMD)
-	    || (SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW))
+		    || (SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW))
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)  
 		return mega_ioctl (megaCfg, SCpnt);	/* Handle IOCTL command */
+#else
+	{
+		printk(KERN_WARNING "megaraid ioctl: older interface - "
+				"not supported.\n");
+		return NULL;
+	}
 #endif
 
 	islogical = (SCpnt->channel == megaCfg->host->max_channel);
@@ -1407,7 +1488,7 @@
 		 *   cmnd[4..7] = external user buffer     *
 		 *   cmnd[8..11] = length of buffer        *
 		 *                                         */
-		char *user_area = *((char **) &SCpnt->cmnd[4]);
+      	char *user_area = (char *)*((u32*)&SCpnt->cmnd[4]);
 		u32 xfer_size = *((u32 *) & SCpnt->cmnd[8]);
 		switch (data[0]) {
 		case FW_FIRE_WRITE:
@@ -1598,8 +1679,8 @@
 	mbox->xferaddr = virt_to_bus (pScb->sgList);
 	mbox->numsgelements = idx;
 }
+#endif
 
-#endif				/* KERNEL_VERSION(2,3,0) */
 
 #if DEBUG
 static unsigned int cum_time = 0;
@@ -2348,7 +2429,7 @@
 	megaCfg->biosVer[4] = 0;
 #endif
 
-	printk (KERN_INFO "megaraid: [%s:%s] detected %d logical drives" M_RD_CRLFSTR,
+	printk (KERN_NOTICE "megaraid: [%s:%s] detected %d logical drives" M_RD_CRLFSTR,
 		megaCfg->fwVer, megaCfg->biosVer, megaCfg->numldrv);
 	/*
 	 * I hope that I can unmap here, reason DMA transaction is not required any more
@@ -2368,7 +2449,7 @@
  * Returns data to be displayed in /proc/scsi/megaraid/X
  *----------------------------------------------------------*/
 
-static int megaraid_proc_info (char *buffer, char **start, off_t offset,
+int megaraid_proc_info (char *buffer, char **start, off_t offset,
 		    int length, int host_no, int inout)
 {
 	*start = buffer;
@@ -2411,7 +2492,7 @@
 #endif
 
 	while ((pdev = pci_find_device (pciVendor, pciDev, pdev))) {
-		if (pci_enable_device (pdev))
+		if(pci_enable_device (pdev))
 			continue;
 		pciBus = pdev->bus->number;
 		pciDevFun = pdev->devfn;
@@ -2425,11 +2506,16 @@
 				continue;	/* not an AMI board */
 			}
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#if 0
+/*
+ *	This leads to corruption on some HP boards so disable it
+ */
 			pcibios_read_config_dword (pciBus, pciDevFun,
 						   PCI_CONF_AMISIG64, &magic64);
 
 			if (magic64 == AMI_64BIT_SIGNATURE)
 				flag |= BOARD_64BIT;
+#endif				
 #endif
 		}
 
@@ -2451,9 +2537,7 @@
 			pci_read_config_word (pdev,
 					      PCI_SUBSYSTEM_ID, &subsysid);
 #endif
-			if ((subsysid == 0x1111) && (subsysvid == 0x1111) &&
-			    (!strcmp (megaCfg->fwVer, "3.00")
-			     || !strcmp (megaCfg->fwVer, "3.01"))) {
+			if ((subsysid == 0x1111) && (subsysvid == 0x1111)) {
 				printk (KERN_WARNING
 					"megaraid: Your card is a Dell PERC 2/SC RAID controller with firmware\n"
 					"megaraid: 3.00 or 3.01.  This driver is known to have corruption issues\n"
@@ -2476,7 +2560,7 @@
 				continue;
 		}
 
-		printk (KERN_INFO
+		printk (KERN_NOTICE
 			"megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:func %d\n",
 			pciVendor, pciDev, pciIdx, pciBus, PCI_SLOT (pciDevFun),
 			PCI_FUNC (pciDevFun));
@@ -2499,11 +2583,14 @@
 		pciIdx++;
 
 		if (flag & BOARD_QUARTZ) {
+			megaBase &= PCI_BASE_ADDRESS_MEM_MASK;
 			megaBase = (long) ioremap (megaBase, 128);
 			if (!megaBase)
 				continue;
-		} else
+		} else {
+			megaBase &= PCI_BASE_ADDRESS_IO_MASK;
 			megaBase += 0x10;
+		}
 
 		/* Initialize SCSI Host structure */
 		host = scsi_register (pHostTmpl, sizeof (mega_host_config));
@@ -2514,11 +2601,11 @@
 		megaCfg = (mega_host_config *) host->hostdata;
 		memset (megaCfg, 0, sizeof (mega_host_config));
 
-		printk (KERN_INFO "scsi%d : Found a MegaRAID controller at 0x%x, IRQ: %d"
+		printk (KERN_NOTICE "scsi%d : Found a MegaRAID controller at 0x%x, IRQ: %d"
 			M_RD_CRLFSTR, host->host_no, (u_int) megaBase, megaIrq);
 
 		if (flag & BOARD_64BIT)
-			printk (KERN_INFO "scsi%d : Enabling 64 bit support\n",
+			printk (KERN_NOTICE "scsi%d : Enabling 64 bit support\n",
 				host->host_no);
 
 		/* Copy resource info into structure */
@@ -2549,10 +2636,11 @@
 
 		if (!(flag & BOARD_QUARTZ)) {
 			/* Request our IO Range */
-			if (!request_region(megaBase, 16, "megaraid")) {
-				printk (KERN_WARNING "megaraid: Couldn't register I/O range!" M_RD_CRLFSTR);
+			if (check_region (megaBase, 16)) {
+				printk(KERN_WARNING "megaraid: Couldn't register I/O range!\n");
 				goto err_unregister;
 			}
+			request_region(megaBase, 16, "megaraid");
 		}
 
 		/* Request our IRQ */
@@ -2678,7 +2766,7 @@
 		skip_id = (skip_id > 15) ? -1 : skip_id;
 	}
 
-	printk (KERN_INFO "megaraid: " MEGARAID_VERSION M_RD_CRLFSTR);
+	printk (KERN_NOTICE "megaraid: " MEGARAID_VERSION M_RD_CRLFSTR);
 
 	memset (mega_hbas, 0, sizeof (mega_hbas));
 
@@ -2736,7 +2824,7 @@
 /*---------------------------------------------------------------------
  * Release the controller's resources
  *---------------------------------------------------------------------*/
-static int megaraid_release (struct Scsi_Host *pSHost)
+int megaraid_release (struct Scsi_Host *pSHost)
 {
 	mega_host_config *megaCfg;
 	mega_mailbox *mbox;
@@ -3022,7 +3110,7 @@
 /*----------------------------------------------
  * Get information about the card/driver
  *----------------------------------------------*/
-static const char *megaraid_info (struct Scsi_Host *pSHost)
+const char *megaraid_info (struct Scsi_Host *pSHost)
 {
 	static char buffer[512];
 	mega_host_config *megaCfg;
@@ -3052,7 +3140,7 @@
  *   10 01 numstatus byte
  *   11 01 status byte
  *-----------------------------------------------------------------*/
-static int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *))
+int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *))
 {
 	DRIVER_LOCK_T mega_host_config * megaCfg;
 	mega_scb *pScb;
@@ -3063,11 +3151,11 @@
 
 	if (!(megaCfg->flag & (1L << SCpnt->channel))) {
 		if (SCpnt->channel < SCpnt->host->max_channel)
-			printk ( /*KERN_INFO */
+			printk ( KERN_NOTICE
 				"scsi%d: scanning channel %c for devices.\n",
 				megaCfg->host->host_no, SCpnt->channel + '1');
 		else
-			printk ( /*KERN_INFO */
+			printk ( KERN_NOTICE
 				"scsi%d: scanning virtual channel for logical drives.\n",
 				megaCfg->host->host_no);
 
@@ -3136,7 +3224,7 @@
 			init_MUTEX_LOCKED (&pScb->ioctl_sem);
 			spin_unlock_irq (&io_request_lock);
 			down (&pScb->ioctl_sem);
-			user_area = *((char **) &pScb->SCpnt->cmnd[4]);
+    		user_area = (char *)*((u32*)&pScb->SCpnt->cmnd[4]);
 			if (copy_to_user
 			    (user_area, pScb->buff_ptr, pScb->iDataSize)) {
 				printk
@@ -3178,7 +3266,7 @@
 
 /* shouldn't be used, but included for completeness */
 
-static int megaraid_command (Scsi_Cmnd * SCpnt)
+int megaraid_command (Scsi_Cmnd * SCpnt)
 {
 	internal_done_flag = 0;
 
@@ -3195,7 +3283,7 @@
 /*---------------------------------------------------------------------
  * Abort a previous SCSI request
  *---------------------------------------------------------------------*/
-static int megaraid_abort (Scsi_Cmnd * SCpnt)
+int megaraid_abort (Scsi_Cmnd * SCpnt)
 {
 	mega_host_config *megaCfg;
 	int rc;			/*, idx; */
@@ -3293,7 +3381,7 @@
  * Reset a previous SCSI request
  *---------------------------------------------------------------------*/
 
-static int megaraid_reset (Scsi_Cmnd * SCpnt, unsigned int rstflags)
+int megaraid_reset (Scsi_Cmnd * SCpnt, unsigned int rstflags)
 {
 	mega_host_config *megaCfg;
 	int idx;
@@ -3404,7 +3492,7 @@
 	*start = page;
 
 	proc_printf (megaCfg, "Statistical Information for this controller\n");
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/* 0x020100 */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/* 0x020400 */
 	proc_printf (megaCfg, "Interrupts Collected = %Lu\n",
 		     megaCfg->nInterrupts);
 #else
@@ -3574,7 +3662,7 @@
  *     geom[1] = sectors
  *     geom[2] = cylinders
  *-------------------------------------------------------------*/
-static int megaraid_biosparam (Disk * disk, kdev_t dev, int *geom)
+int megaraid_biosparam (Disk * disk, kdev_t dev, int *geom)
 {
 	int heads, sectors, cylinders;
 	mega_host_config *megaCfg;
@@ -3788,11 +3876,9 @@
 	kdev_t dev;
 	u32 inlen;
 	struct uioctl_t ioc;
-	char *kphysaddr = NULL;
+	char *kvaddr = NULL;
 	int nadap = numCtlrs;
-	int npages;
 	u8 opcode;
-	int order = 0;
 	u32 outlen;
 	int ret;
 	u8 subopcode;
@@ -3800,6 +3886,15 @@
 	struct Scsi_Host *shpnt;
 	char *uaddr;
 	struct uioctl_t *uioc;
+	dma_addr_t	dma_addr;
+	u32		length;
+	mega_host_config *megacfg;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/* 0x020400 */
+	struct pci_dev pdev;
+	struct pci_dev *pdevp = &pdev;
+#else
+	char *pdevp = NULL;
+#endif
 	IO_LOCK_T;
 
 	if (!inode || !(dev = inode->i_rdev))
@@ -3809,12 +3904,6 @@
 		return (-EINVAL);
 
 	/*
-	 * We do not transfer more than IOCTL_MAX_DATALEN (see megaraid.h) with
-	 * this interface.If the user needs to transfer more than this,he should
-	 * use 0x81 command op-code.
-	 */
-
-	/*
 	 * Get the user ioctl structure
 	 */
 	ret = verify_area (VERIFY_WRITE, (char *) arg, sizeof (struct uioctl_t));
@@ -3826,10 +3915,10 @@
 		return -EFAULT;
 
 	/*
-	 * The first call the applications should make is to find out the number
-	 * of controllers in the system. The next logical call should be for
-	 * getting the list of controllers in the system as detected by the
-	 * driver.
+	 * The first call the applications should make is to find out the
+	 * number of controllers in the system. The next logical call should
+	 * be for getting the list of controllers in the system as detected
+	 * by the driver.
 	 */
 
 	/*
@@ -3892,173 +3981,135 @@
 		adapno = ioc.ui.fcs.adapno;
 
 		/* See comment above: MEGAIOC_QADAPINFO */
-		adapno = GETADAP (adapno);
+		adapno = GETADAP(adapno);
 
 		if (adapno >= numCtlrs)
-			return (-ENODEV);
+			return(-ENODEV);
 
-		/* Check for zero length buffer. */
-		if (!ioc.ui.fcs.length)
+		length = ioc.ui.fcs.length;
+
+		/* Check for zero length buffer or very large buffers */
+		if( !length || length > 32*1024 )
 			return -EINVAL;
 
 		/* save the user address */
 		uaddr = ioc.ui.fcs.buffer;
 
-/*
-* For M_RD_IOCTL_CMD_NEW commands, the fields outlen and inlen of uioctl_t
-* structure are treated as flags. If outlen is 1, the data is
-* transferred from the device and if inlen is 1, the data is
-* transferred to the device.
-*/
+		/*
+		 * For M_RD_IOCTL_CMD_NEW commands, the fields outlen and inlen of
+		 * uioctl_t structure are treated as flags. If outlen is 1, the
+		 * data is transferred from the device and if inlen is 1, the data
+		 * is transferred to the device.
+		 */
 		outlen = ioc.outlen;
 		inlen = ioc.inlen;
-#if 0
-		if (inlen && outlen)
-			return -EINVAL;
-#endif
-		if (outlen) {
-			ret = verify_area (VERIFY_WRITE,
-					   (char *) ioc.ui.fcs.buffer,
-					   ioc.ui.fcs.length);
-			if (ret)
-				return ret;
-		} else if (inlen) {
-			ret = verify_area (VERIFY_READ,
-					   (char *) ioc.ui.fcs.buffer,
-					   ioc.ui.fcs.length);
 
-			if (ret)
-				return ret;
+		if(outlen) {
+			ret = verify_area(VERIFY_WRITE, (char *)ioc.ui.fcs.buffer, length);
+			if (ret) return ret;
+		}
+		if(inlen) {
+			ret = verify_area(VERIFY_READ, (char *) ioc.ui.fcs.buffer, length);
+			if (ret) return ret;
 		}
 
-		/* How many pages required of size PAGE_SIZE */
-		npages = ioc.ui.fcs.length / PAGE_SIZE;
-		/* Do we need one more? */
-
-		if (ioc.ui.fcs.length % PAGE_SIZE)
-			npages++;
-
-		/* ioctl does not support data xfer > 32KB */
-		if (npages == 1)
-			order = 0;
-		else if (npages == 2)
-			order = 1;
-		else if (npages <= 4)
-			order = 2;
-		else if (npages <= 8)
-			order = 3;
-		else
-			return -EINVAL;
-
-		if (outlen || inlen) {
-			/*
-			 * Allocate kernel space for npages.
-			 *
-			 * Since we need the memory for DMA, it needs to be physically
-			 * contiguous. __get_free_pags() return consecutive free pages
-			 * in kernel space.
-			 * Note: We don't do __get_dma_pages(), since for PCI devices,
-			 * the DMA memory is not restriceted to 16M, which is ensured
-			 * by __get_dma_pages()
-			 */
-
-			if ((kphysaddr = (char *) __get_free_pages (GFP_KERNEL,
-								    order)) ==
-			    0) {
-				printk (KERN_INFO
-					"megaraid:allocation failed\n");
-				return -ENOMEM;
-			}
-
-			memset (kphysaddr, 0, npages * PAGE_SIZE);
-			ioc.ui.fcs.buffer = kphysaddr;
-
-			if (inlen) {
-				/* copyin the user data */
-				copy_from_user (kphysaddr,
-						(char *) uaddr,
-						ioc.ui.fcs.length);
+		/*
+		 * Find this host
+		 */
+		for( shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next ) {
+			if( shpnt->hostdata == (unsigned long *)megaCtlrs[adapno] ) {
+				megacfg = (mega_host_config *)shpnt->hostdata;
+				break;
 			}
 		}
+		if(shpnt == NULL)  return -ENODEV;
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-		scsicmd = (Scsi_Cmnd *) kmalloc (sizeof (Scsi_Cmnd),
-						 GFP_KERNEL | GFP_DMA);
-		memset (scsicmd, 0, sizeof (Scsi_Cmnd));
+		scsicmd = (Scsi_Cmnd *)kmalloc(sizeof(Scsi_Cmnd), GFP_KERNEL|GFP_DMA);
 #else
-		scsicmd = (Scsi_Cmnd *) scsi_init_malloc (sizeof (Scsi_Cmnd),
+		scsicmd = (Scsi_Cmnd *)scsi_init_malloc(sizeof(Scsi_Cmnd),
 							  GFP_ATOMIC | GFP_DMA);
 #endif
-		if (!scsicmd) {
-			if (kphysaddr)
-				free_pages ((unsigned long) kphysaddr, order);
-			return -ENOMEM;
-		}
+		if(scsicmd == NULL) return -ENOMEM;
 
-		scsicmd->host = NULL;
+		memset(scsicmd, 0, sizeof(Scsi_Cmnd));
+		scsicmd->host = shpnt;
 
-		/*
-		 * Find this host
-		 */
-		for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) {
-			if (shpnt->hostdata ==
-			    (unsigned long *) megaCtlrs[adapno])
-				scsicmd->host = shpnt;
-		}
-
-		if (scsicmd->host == NULL) {
+		if( outlen || inlen ) {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-			kfree (scsicmd);
+			pdevp = &pdev;
+			memcpy(pdevp, megacfg->dev, sizeof(struct pci_dev));
+			pdevp->dma_mask = 0xffffffff;
+#else
+			pdevp = NULL;
+#endif
+			kvaddr = dma_alloc_consistent(pdevp, length, &dma_addr);
+
+			if( kvaddr == NULL ) {
+				printk(KERN_WARNING "megaraid:allocation failed\n");
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/*0x20400 */
+				kfree(scsicmd);
 #else
-			scsi_init_free ((char *) scsicmd, sizeof (Scsi_Cmnd));
+				scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
 #endif
-			if (kphysaddr)
-				free_pages ((unsigned long) kphysaddr, order);
-			return -ENODEV;
+				return -ENOMEM;
+			}
+
+			ioc.ui.fcs.buffer = kvaddr;
+
+			if (inlen) {
+				/* copyin the user data */
+				copy_from_user(kvaddr, (char *)uaddr, length );
+			}
 		}
 
 		scsicmd->cmnd[0] = MEGADEVIOC;
-		scsicmd->request_buffer = (void *) &ioc;
+		scsicmd->request_buffer = (void *)&ioc;
 
-		init_MUTEX_LOCKED (&mimd_ioctl_sem);
+		init_MUTEX_LOCKED(&mimd_ioctl_sem);
 
 		IO_LOCK;
-		megaraid_queue (scsicmd, megadev_ioctl_done);
+		megaraid_queue(scsicmd, megadev_ioctl_done);
 
 		IO_UNLOCK;
 
-		down (&mimd_ioctl_sem);
+		down(&mimd_ioctl_sem);
 
-		if (!scsicmd->result && outlen) {
-			copy_to_user (uaddr, kphysaddr, ioc.ui.fcs.length);
+		if( !scsicmd->result && outlen ) {
+			copy_to_user(uaddr, kvaddr, length);
 		}
 
 		/*
 		 * copyout the result
 		 */
-		uioc = (struct uioctl_t *) arg;
+		uioc = (struct uioctl_t *)arg;
 
-		if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) {
-			put_user (scsicmd->result, &uioc->pthru.scsistatus);
+		if( ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU ) {
+			put_user( scsicmd->result, &uioc->pthru.scsistatus );
 		} else {
-			put_user (1, &uioc->mbox[16]);	/* numstatus */
+			put_user(1, &uioc->mbox[16]);	/* numstatus */
 			/* status */
 			put_user (scsicmd->result, &uioc->mbox[17]);
 		}
 
-		if (kphysaddr) {
-			free_pages ((ulong) kphysaddr, order);
+		if (kvaddr) {
+			dma_free_consistent(pdevp, length, kvaddr, dma_addr);
 		}
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/*0x20400 */
 		kfree (scsicmd);
 #else
-		scsi_init_free ((char *) scsicmd, sizeof (Scsi_Cmnd));
+		scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
 #endif
 
+		/* restore the user address */
+		ioc.ui.fcs.buffer = uaddr;
+
 		return ret;
 
 	case M_RD_IOCTL_CMD:
 		/* which adapter?  */
 		adapno = ioc.ui.fcs.adapno;
+
 		/* See comment above: MEGAIOC_QADAPINFO */
 		adapno = GETADAP (adapno);
 
@@ -4070,85 +4121,74 @@
 		outlen = ioc.outlen;
 		inlen = ioc.inlen;
 
-		if ((outlen >= IOCTL_MAX_DATALEN)
-		    || (inlen >= IOCTL_MAX_DATALEN))
+		if ((outlen >= IOCTL_MAX_DATALEN) || (inlen >= IOCTL_MAX_DATALEN))
 			return (-EINVAL);
 
 		if (outlen) {
 			ret = verify_area (VERIFY_WRITE, ioc.data, outlen);
-			if (ret)
-				return ret;
-		} else if (inlen) {
+			if (ret) return ret;
+		}
+		if (inlen) {
 			ret = verify_area (VERIFY_READ, ioc.data, inlen);
+			if (ret) return ret;
+		}
 
-			if (ret)
-				return ret;
+		/*
+		 * Find this host
+		 */
+		for( shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next ) {
+			if( shpnt->hostdata == (unsigned long *)megaCtlrs[adapno] ) {
+				megacfg = (mega_host_config *)shpnt->hostdata;
+				break;
+			}
 		}
+		if(shpnt == NULL)  return -ENODEV;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+		scsicmd = (Scsi_Cmnd *)kmalloc(sizeof(Scsi_Cmnd), GFP_KERNEL|GFP_DMA);
+#else
+		scsicmd = (Scsi_Cmnd *)scsi_init_malloc(sizeof(Scsi_Cmnd),
+							  GFP_ATOMIC | GFP_DMA);
+#endif
+		if(scsicmd == NULL) return -ENOMEM;
+
+		memset(scsicmd, 0, sizeof(Scsi_Cmnd));
+		scsicmd->host = shpnt;
 
 		if (outlen || inlen) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+			pdevp = &pdev;
+			memcpy(pdevp, megacfg->dev, sizeof(struct pci_dev));
+			pdevp->dma_mask = 0xffffffff;
+#else
+			pdevp = NULL;
+#endif
 			/*
 			 * Allocate a page of kernel space.
 			 */
-			if ((kphysaddr =
-			     (char *) __get_free_pages (GFP_KERNEL, 0)) == 0) {
+			kvaddr = dma_alloc_consistent(pdevp, PAGE_SIZE, &dma_addr);
 
-				printk (KERN_INFO
-					"megaraid:allocation failed\n");
+			if( kvaddr == NULL ) {
+				printk (KERN_WARNING "megaraid:allocation failed\n");
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/*0x20400 */
+				kfree(scsicmd);
+#else
+				scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
+#endif
 				return -ENOMEM;
 			}
 
-			memset (kphysaddr, 0, PAGE_SIZE);
-			ioc.data = kphysaddr;
+			ioc.data = kvaddr;
 
 			if (inlen) {
 				if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) {
 					/* copyin the user data */
-					copy_from_user (kphysaddr,
-							uaddr,
-							ioc.pthru.dataxferlen);
+					copy_from_user (kvaddr, uaddr, ioc.pthru.dataxferlen);
 				} else {
-					copy_from_user (kphysaddr,
-							uaddr, inlen);
+					copy_from_user (kvaddr, uaddr, inlen);
 				}
 			}
 		}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/* 0x020400 */
-		scsicmd = (Scsi_Cmnd *) kmalloc (sizeof (Scsi_Cmnd),
-						 GFP_KERNEL | GFP_DMA);
-		memset (scsicmd, 0, sizeof (Scsi_Cmnd));
-#else
-		scsicmd = (Scsi_Cmnd *) scsi_init_malloc (sizeof (Scsi_Cmnd),
-							  GFP_ATOMIC | GFP_DMA);
-#endif
-
-		if (!scsicmd) {
-			if (kphysaddr)
-				free_pages ((unsigned long) kphysaddr, 0);
-			return -ENOMEM;
-		}
-
-		scsicmd->host = NULL;
-
-		/*
-		 * Find this host in the hostlist
-		 */
-		for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) {
-			if (shpnt->hostdata ==
-			    (unsigned long *) megaCtlrs[adapno])
-				scsicmd->host = shpnt;
-		}
-
-		if (scsicmd->host == NULL) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-			kfree (scsicmd);
-#else
-			scsi_init_free ((char *) scsicmd, sizeof (Scsi_Cmnd));
-#endif
-			if (kphysaddr)
-				free_pages ((unsigned long) kphysaddr, 0);
-
-			return -ENODEV;
-		}
 
 		scsicmd->cmnd[0] = MEGADEVIOC;
 		scsicmd->request_buffer = (void *) &ioc;
@@ -4163,10 +4203,9 @@
 
 		if (!scsicmd->result && outlen) {
 			if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) {
-				copy_to_user (uaddr,
-					      kphysaddr, ioc.pthru.dataxferlen);
+				copy_to_user (uaddr, kvaddr, ioc.pthru.dataxferlen);
 			} else {
-				copy_to_user (uaddr, kphysaddr, outlen);
+				copy_to_user (uaddr, kvaddr, outlen);
 			}
 		}
 
@@ -4183,26 +4222,31 @@
 			put_user (scsicmd->result, &uioc->mbox[17]);
 		}
 
-		if (kphysaddr)
-			free_pages ((unsigned long) kphysaddr, 0);
+		if (kvaddr) {
+			dma_free_consistent(pdevp, PAGE_SIZE, kvaddr, dma_addr );
+		}
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 		kfree (scsicmd);
 #else
-		scsi_init_free ((char *) scsicmd, sizeof (Scsi_Cmnd));
+		scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
 #endif
+
+		/* restore user pointer */
+		ioc.data = uaddr;
+
 		return ret;
 
 	default:
 		return (-EINVAL);
 
-	}			/* Outer switch */
+	}/* Outer switch */
 
 	return 0;
 }
 
 static void
-megadev_ioctl_done (Scsi_Cmnd * sc)
+megadev_ioctl_done(Scsi_Cmnd *sc)
 {
 	up (&mimd_ioctl_sem);
 }
@@ -4309,6 +4353,94 @@
 #endif
 	return 0;
 }
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+void *
+dma_alloc_consistent(void *dev, size_t size, dma_addr_t *dma_addr)
+{
+	void	*_tv;
+	int		npages;
+	int		order = 0;
+
+	/*
+	 * How many pages application needs
+	 */
+	npages = size / PAGE_SIZE;
+
+	/* Do we need one more page */
+	if(size % PAGE_SIZE)
+		npages++;
+
+	order = mega_get_order(npages);
+
+	_tv = (void *)__get_free_pages(GFP_DMA, order);
+
+	if( _tv != NULL ) {
+		memset(_tv, 0, size);
+		*(dma_addr) = virt_to_bus(_tv);
+	}
+
+	return _tv;
+}
+
+/*
+ * int mega_get_order(int)
+ *
+ * returns the order to be used as 2nd argument to __get_free_pages() - which
+ * return pages equal to pow(2, order) - AM
+ */
+int
+mega_get_order(int n)
+{
+	int		i = 0;
+
+	while( pow_2(i++) < n )
+		; /* null statement */
+
+	return i-1;
+}
+
+/*
+ * int pow_2(int)
+ *
+ * calculates pow(2, i)
+ */
+int
+pow_2(int i)
+{
+	unsigned int	v = 1;
+	
+	while(i--)
+		v <<= 1;
+
+	return v;
+}
+
+void
+dma_free_consistent(void *dev, size_t size, void *vaddr, dma_addr_t dma_addr)
+{
+	int		npages;
+	int		order = 0;
+
+	npages = size / PAGE_SIZE;
+
+	if(size % PAGE_SIZE)
+		npages++;
+
+	if (npages == 1)
+		order = 0;
+	else if (npages == 2)
+		order = 1;
+	else if (npages <= 4)
+		order = 2;
+	else
+		order = 3;
+
+	free_pages((unsigned long)vaddr, order);
+
+}
+#endif
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 static
diff -u --recursive --new-file v2.4.6/linux/drivers/scsi/megaraid.h linux/drivers/scsi/megaraid.h
--- v2.4.6/linux/drivers/scsi/megaraid.h	Fri Apr 13 20:26:07 2001
+++ linux/drivers/scsi/megaraid.h	Wed Jul  4 11:50:39 2001
@@ -27,7 +27,8 @@
 #define M_RD_IOCTL_CMD_NEW		0x81
 #define M_RD_DRIVER_IOCTL_INTERFACE	0x82
 
-#define MEGARAID_VERSION "v1.14g-ac2 (Release Date: Mar 22, 2001; 19:34:02)"
+#define MEGARAID_VERSION "v1.15d (Release Date: Wed May 30 17:30:41 EDT 2001)"
+
 #define MEGARAID_IOCTL_VERSION 	114
 
 /* Methods */
@@ -115,6 +116,23 @@
 #define ENABLE_INTR(base)	WRITE_PORT(base,I_TOGGLE_PORT,ENABLE_INTR_BYTE)
 #define DISABLE_INTR(base)	WRITE_PORT(base,I_TOGGLE_PORT,DISABLE_INTR_BYTE)
 
+/* Define AMI's PCI codes */
+#ifndef PCI_VENDOR_ID_AMI
+#define PCI_VENDOR_ID_AMI		0x101E
+#endif
+
+#ifndef PCI_DEVICE_ID_AMI_MEGARAID
+#define PCI_DEVICE_ID_AMI_MEGARAID	0x9010
+#endif
+
+#ifndef PCI_DEVICE_ID_AMI_MEGARAID2
+#define PCI_DEVICE_ID_AMI_MEGARAID2	0x9060
+#endif
+
+#ifndef PCI_DEVICE_ID_AMI_MEGARAID3
+#define PCI_DEVICE_ID_AMI_MEGARAID3	0x1960
+#endif
+
 /* Special Adapter Commands */
 #define FW_FIRE_WRITE   	0x2C
 #define FW_FIRE_FLASH   	0x2D
@@ -829,15 +847,15 @@
  *
  *================================================================
  */
-static const char *megaraid_info (struct Scsi_Host *);
+const char *megaraid_info (struct Scsi_Host *);
 int megaraid_detect (Scsi_Host_Template *);
-static int megaraid_release (struct Scsi_Host *);
-static int megaraid_command (Scsi_Cmnd *);
-static int megaraid_abort (Scsi_Cmnd *);
-static int megaraid_reset (Scsi_Cmnd *, unsigned int);
-static int megaraid_queue (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
-static int megaraid_biosparam (Disk *, kdev_t, int *);
-static int megaraid_proc_info (char *buffer, char **start, off_t offset,
+int megaraid_release (struct Scsi_Host *);
+int megaraid_command (Scsi_Cmnd *);
+int megaraid_abort (Scsi_Cmnd *);
+int megaraid_reset (Scsi_Cmnd *, unsigned int);
+int megaraid_queue (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
+int megaraid_biosparam (Disk *, kdev_t, int *);
+int megaraid_proc_info (char *buffer, char **start, off_t offset,
 			int length, int hostno, int inout);
 
 static int megaIssueCmd (mega_host_config * megaCfg, u_char * mboxData,
@@ -855,7 +873,7 @@
 
 static int megaraid_reboot_notify (struct notifier_block *,
 				   unsigned long, void *);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)  
 static mega_scb *mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt);
 static void mega_build_kernel_sg (char *barea, ulong xfersize, mega_scb * pScb,
 			   mega_ioctl_mbox * mbox);
diff -u --recursive --new-file v2.4.6/linux/drivers/scsi/pcmcia/Config.in linux/drivers/scsi/pcmcia/Config.in
--- v2.4.6/linux/drivers/scsi/pcmcia/Config.in	Sun Mar  4 14:30:19 2001
+++ linux/drivers/scsi/pcmcia/Config.in	Wed Jul  4 11:50:38 2001
@@ -8,12 +8,13 @@
 bool 'PCMCIA SCSI adapter support' CONFIG_SCSI_PCMCIA
 if [ "$CONFIG_SCSI_PCMCIA" = "y" ]; then
    dep_tristate '  Adaptec AHA152X PCMCIA support' CONFIG_PCMCIA_AHA152X m
-   dep_tristate '  Qlogic PCMCIA support' CONFIG_PCMCIA_QLOGIC m
    dep_tristate '  Future Domain PCMCIA support' CONFIG_PCMCIA_FDOMAIN m
+   dep_tristate	'  NinjaSCSI-3 / NinjaSCSI-32Bi (16bit) PCMCIA support' CONFIG_PCMCIA_NINJA_SCSI m
+   dep_tristate '  Qlogic PCMCIA support' CONFIG_PCMCIA_QLOGIC m
 fi
 
 if [ "$CONFIG_PCMCIA_QLOGIC" = "y" -o "$CONFIG_PCMCIA_AHA152X" = "y" -o \
-     "$CONFIG_PCMCIA_FDOMAIN" = "y" ]; then
+     "$CONFIG_PCMCIA_FDOMAIN" = "y" -o "$CONFIG_PCMCIA_NINJA_SCSI" = "y" ]; then
    define_bool CONFIG_PCMCIA_SCSICARD y
 fi
 
diff -u --recursive --new-file v2.4.6/linux/drivers/scsi/pcmcia/Makefile linux/drivers/scsi/pcmcia/Makefile
--- v2.4.6/linux/drivers/scsi/pcmcia/Makefile	Mon Mar 26 15:36:30 2001
+++ linux/drivers/scsi/pcmcia/Makefile	Wed Jul  4 11:50:38 2001
@@ -19,6 +19,7 @@
 obj-$(CONFIG_PCMCIA_QLOGIC)	+= qlogic_cs.o
 obj-$(CONFIG_PCMCIA_FDOMAIN)	+= fdomain_cs.o
 obj-$(CONFIG_PCMCIA_AHA152X)	+= aha152x_cs.o
+obj-$(CONFIG_PCMCIA_NINJA_SCSI)	+= nsp_cs.o
 
 list-multi	:= qlogic_cs.o fdomain_cs.o aha152x_cs.o
 aha152x_cs-objs	:= aha152x_stub.o aha152x.o
diff -u --recursive --new-file v2.4.6/linux/drivers/scsi/pcmcia/nsp_cs.c linux/drivers/scsi/pcmcia/nsp_cs.c
--- v2.4.6/linux/drivers/scsi/pcmcia/nsp_cs.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/pcmcia/nsp_cs.c	Wed Jul  4 11:50:38 2001
@@ -0,0 +1,1714 @@
+/*======================================================================
+
+    NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI hostadapter card driver
+      By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
+
+    Ver.2.0   Support 32bit PIO mode
+    Ver.1.1.2 Fix for scatter list buffer exceeds
+    Ver.1.1   Support scatter list
+    Ver.0.1   Initial version
+
+    This software may be used and distributed according to the terms of
+    the GNU General Public License.
+
+======================================================================*/
+
+/***********************************************************************
+    This driver is for these PCcards.
+
+	I-O DATA PCSC-F	 (Workbit NinjaSCSI-3)
+			"WBT", "NinjaSCSI-3", "R1.0"
+	I-O DATA CBSC-II (Workbit NinjaSCSI-32Bi in 16bit mode)
+			"IO DATA", "CBSC16	 ", "1"
+
+***********************************************************************/
+
+/* $Id: nsp_cs.c,v 1.28 2001/02/15 02:56:32 elca Exp $ */
+
+#ifdef NSP_KERNEL_2_2
+#include <pcmcia/config.h>
+#include <pcmcia/k_compat.h>
+#endif
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/tqueue.h>
+#include <linux/interrupt.h>
+#include <linux/major.h>
+#include <linux/blk.h>
+#include <linux/stat.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <../drivers/scsi/scsi.h>
+#include <../drivers/scsi/hosts.h>
+#include <../drivers/scsi/sd.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_ioctl.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+#include "nsp_cs.h"
+
+MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
+MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
+MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+MODULE_PARM(pc_debug, "i");
+MODULE_PARM_DESC(pc_debug, "set debug level");
+static char *version = "$Id: nsp_cs.c,v 1.28 2001/02/15 02:56:32 elca Exp $";
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+#else
+#define DEBUG(n, args...) /* */
+#endif
+
+#include "nsp_io.h"
+
+/*====================================================================*/
+
+typedef struct scsi_info_t {
+	dev_link_t             link;
+	struct Scsi_Host      *host;
+	int	               ndev;
+	dev_node_t             node[8];
+	int                    stop;
+	struct bus_operations *bus;
+} scsi_info_t;
+
+static void nsp_release(u_long arg);
+static int nsp_event(event_t event, int priority,
+		     event_callback_args_t *args);
+static dev_link_t *nsp_attach(void);
+static void nsp_detach(dev_link_t *);
+static int nsp_detect(Scsi_Host_Template * );
+static const char * nsp_info(struct Scsi_Host *);
+static int nsp_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
+static int nsp_abort(Scsi_Cmnd *);
+static int nsp_reset(Scsi_Cmnd *, unsigned int);
+
+
+/*----------------------------------------------------------------*/
+
+#if (KERNEL_VERSION(2,4,0) > LINUX_VERSION_CODE)
+#define PROC_SCSI_NSP PROC_SCSI_IBMMCA /* bad hack... */
+static struct proc_dir_entry proc_scsi_nsp = {
+	PROC_SCSI_NSP, 6, "nsp_cs",
+	S_IFDIR | S_IRUGO | S_IXUGO, 2
+};
+#endif
+
+/*====================================================================*/
+/* Parameters that can be set with 'insmod' */
+
+static unsigned int irq_mask = 0xffff;
+MODULE_PARM(irq_mask, "i");
+MODULE_PARM_DESC(irq_mask, "IRQ mask bits");
+
+static int irq_list[4] = { -1 };
+MODULE_PARM(irq_list, "1-4i");
+MODULE_PARM_DESC(irq_list, "IRQ number list");
+
+/*----------------------------------------------------------------*/
+/* driver state info, local to driver */
+static char nspinfo[100];     /* description */
+
+/* /usr/src/linux/drivers/scsi/hosts.h */
+static Scsi_Host_Template driver_template = {
+/*	next:			NULL,*/
+/*	proc_dir:		NULL,*/
+/*	proc_info:		NULL,*/
+	name:			"WorkBit NinjaSCSI-3/32Bi",
+	detect:			nsp_detect,
+/*	release:		NULL,*/
+	info:			nsp_info,
+/*	command:		NULL,*/
+	queuecommand:		nsp_queuecommand,
+/*	eh_strategy_handler:	nsp_eh_strategy,*/
+/*	eh_abort_handler:	nsp_eh_abort,*/
+/*	eh_device_reset_handler: nsp_eh_device_reset,*/
+	eh_bus_reset_handler:	nsp_eh_bus_reset,
+/*	eh_host_reset_handler:	nsp_eh_host_reset,*/
+	abort:			nsp_abort,
+	reset:			nsp_reset,
+/*	slave_attach:		NULL,*/
+/*	bios_param:		nsp_biosparam,*/
+	can_queue:		1,
+	this_id:		-1,
+	sg_tablesize:		SG_ALL,
+	cmd_per_lun:		1,
+/*	present:		0,*/
+/*	unchecked_isa_dma:	0,*/
+	use_clustering:		DISABLE_CLUSTERING,
+	use_new_eh_code:	0,
+/*	emulated:		0,*/
+};
+
+static dev_link_t *dev_list = NULL;
+static dev_info_t dev_info  = {"nsp_cs"};
+
+static nsp_hw_data nsp_data;
+
+/***********************************************************/
+
+static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+{
+#ifdef PCMCIA_DEBUG
+	//unsigned int host_id = SCpnt->host->this_id;
+	//unsigned int base    = SCpnt->host->io_port;
+	unsigned char target = SCpnt->target;
+#endif
+
+	DEBUG(0, __FUNCTION__ "() SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d\n",
+	      SCpnt, target, SCpnt->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
+	//DEBUG(0, " before CurrentSC=0x%p\n", nsp_data.CurrentSC);
+
+	if(nsp_data.CurrentSC != NULL) {
+		printk(KERN_DEBUG " " __FUNCTION__ "() CurrentSC!=NULL this can't be happen\n");
+		nsp_data.CurrentSC = NULL;
+		SCpnt->result	   = DID_BAD_TARGET << 16;
+		done(SCpnt);
+		return FAILED;
+	}
+
+#ifdef PCMCIA_DEBUG
+	show_command(SCpnt);
+#endif
+
+	SCpnt->scsi_done	= done;
+	nsp_data.CurrentSC	= SCpnt;
+	RESID		        = SCpnt->request_bufflen;
+
+	SCpnt->SCp.Status	= -1;
+	SCpnt->SCp.Message	= -1;
+	SCpnt->SCp.have_data_in = IO_UNKNOWN;
+	SCpnt->SCp.sent_command = 0;
+	SCpnt->SCp.phase	= PH_UNDETERMINED;
+
+	/* setup scratch area
+	   SCp.ptr		: buffer pointer
+	   SCp.this_residual	: buffer length
+	   SCp.buffer		: next buffer
+	   SCp.buffers_residual : left buffers in list
+	   SCp.phase		: current state of the command */
+	if (SCpnt->use_sg) {
+		SCpnt->SCp.buffer	    = (struct scatterlist *) SCpnt->request_buffer;
+		SCpnt->SCp.ptr		    = SCpnt->SCp.buffer->address;
+		SCpnt->SCp.this_residual    = SCpnt->SCp.buffer->length;
+		SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
+	} else {
+		SCpnt->SCp.ptr		    = (char *) SCpnt->request_buffer;
+		SCpnt->SCp.this_residual    = SCpnt->request_bufflen;
+		SCpnt->SCp.buffer	    = NULL;
+		SCpnt->SCp.buffers_residual = 0;
+	}
+
+	if(nsphw_start_selection(SCpnt) == FALSE) {
+		DEBUG(0, " selection fail\n");
+		nsp_data.CurrentSC = NULL;
+		SCpnt->result	   = DID_NO_CONNECT << 16;
+		done(SCpnt);
+		return FAILED;
+	}
+
+
+	//DEBUG(0, __FUNCTION__ "() out\n");
+	return SUCCESS;
+}
+
+/*
+ * setup PIO FIFO transfer mode and enable/disable to data out
+ */
+static void nsp_setup_fifo(unsigned int base, int enabled)
+{
+	unsigned char transfer_mode;
+
+	//DEBUG(0, __FUNCTION__ "() enabled=%d\n", enabled);
+
+	if (enabled != FALSE) {
+		transfer_mode = TRANSFER_GO | BRAIND;
+	} else {
+		transfer_mode = 0;
+	}
+
+	transfer_mode |= nsp_data.TransferMode;
+
+	nsp_index_write(base, TRANSFERMODE, transfer_mode);
+}
+
+/*
+ * Initialize Ninja hardware
+ */
+static int nsphw_init(void)
+{
+	unsigned int base     = nsp_data.BaseAddress;
+	int	     i, j;
+	sync_data    tmp_sync = { SyncNegotiation: SYNC_NOT_YET,
+				  SyncPeriod:	   0,
+				  SyncOffset:	   0
+	};
+
+	//DEBUG(0, __FUNCTION__ "() in\n");
+
+	nsp_data.ScsiClockDiv = CLOCK_40M;
+	nsp_data.CurrentSC    = NULL;
+	nsp_data.FifoCount    = 0;
+	nsp_data.TransferMode = MODE_IO8;
+
+	/* setup sync data */
+	for ( i = 0; i < N_TARGET; i++ ) {
+		for ( j = 0; j < N_LUN; j++ ) {
+			nsp_data.Sync[i][j] = tmp_sync;
+		}
+	}
+
+	/* block all interrupts */
+	nsp_write(base,	      IRQCONTROL,   IRQCONTROL_ALLMASK);
+
+	/* setup SCSI interface */
+	nsp_write(base,	      IFSELECT,	    IF_IFSEL);
+
+	nsp_index_write(base, SCSIIRQMODE,  0);
+
+	nsp_index_write(base, TRANSFERMODE, MODE_IO8);
+	nsp_index_write(base, CLOCKDIV,	    nsp_data.ScsiClockDiv);
+
+	nsp_index_write(base, PARITYCTRL,   0);
+	nsp_index_write(base, POINTERCLR,   POINTER_CLEAR     |
+					    ACK_COUNTER_CLEAR |
+					    REQ_COUNTER_CLEAR |
+					    HOST_COUNTER_CLEAR);
+
+	/* setup fifo asic */
+	nsp_write(base,	      IFSELECT,	    IF_REGSEL);
+	nsp_index_write(base, TERMPWRCTRL,  0);
+	if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
+		printk(KERN_INFO "nsp_cs: terminator power on\n");
+		nsp_index_write(base, TERMPWRCTRL, POWER_ON);
+	}
+
+	nsp_index_write(base, TIMERCOUNT,   0);
+	nsp_index_write(base, TIMERCOUNT,   0); /* requires 2 times!! */
+
+	nsp_index_write(base, SYNCREG,	    0);
+	nsp_index_write(base, ACKWIDTH,	    0);
+
+	/* enable interrupts and ack them */
+	nsp_index_write(base, SCSIIRQMODE,  SCSI_PHASE_CHANGE_EI |
+					    RESELECT_EI		 |
+					    SCSI_RESET_IRQ_EI	 );
+	nsp_write(base,	      IRQCONTROL,   IRQCONTROL_ALLCLEAR);
+
+	nsp_setup_fifo(base, FALSE);
+
+	return TRUE;
+}
+
+/*
+ * Start selection phase
+ */
+static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt)
+{
+	unsigned int  host_id	 = SCpnt->host->this_id;
+	unsigned int  base	 = SCpnt->host->io_port;
+	unsigned char target	 = SCpnt->target;
+	int	      wait_count;
+	unsigned char phase, arbit;
+
+	//DEBUG(0, __FUNCTION__ "()in\n");
+
+
+	phase = nsp_index_read(base, SCSIBUSMON);
+	if(phase != BUSMON_BUS_FREE) {
+		//DEBUG(0, " bus busy\n");
+		return FALSE;
+	}
+
+	/* start arbitration */
+	//DEBUG(0, " start arbit\n");
+	SCpnt->SCp.phase = PH_ARBSTART;
+	nsp_index_write(base, SETARBIT, ARBIT_GO);
+
+	wait_count = jiffies + 10 * HZ;
+	do {
+		/* XXX: what a stupid chip! */
+		arbit = nsp_index_read(base, ARBITSTATUS);
+		//DEBUG(0, " arbit=%d, wait_count=%d\n", arbit, wait_count);
+		udelay(1); /* hold 1.2us */
+	} while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
+		time_before(jiffies, wait_count));
+
+	if((arbit & ARBIT_WIN) == 0) {
+		//DEBUG(0, " arbit fail\n");
+		nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
+		return FALSE;
+	}
+
+	/* assert select line */
+	//DEBUG(0, " assert SEL line\n");
+	SCpnt->SCp.phase = PH_SELSTART;
+	udelay(3);
+	nsp_index_write(base, SCSIDATALATCH, (1 << host_id) | (1 << target));
+	nsp_index_write(base, SCSIBUSCTRL,   SCSI_SEL | SCSI_BSY | SCSI_ATN);
+	udelay(3);
+	nsp_index_write(base, SCSIBUSCTRL,   SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
+	nsp_index_write(base, SETARBIT,	     ARBIT_FLAG_CLEAR);
+	udelay(3);
+	nsp_index_write(base, SCSIBUSCTRL,   SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
+
+	/* check selection timeout */
+	nsp_start_timer(SCpnt, 1000/51);
+	nsp_data.SelectionTimeOut = 1;
+
+	return TRUE;
+}
+
+struct nsp_sync_table {
+	unsigned int min_period;
+	unsigned int max_period;
+	unsigned int chip_period;
+	unsigned int ack_width;
+};
+
+static struct nsp_sync_table nsp_sync_table_40M[] = {
+	{0x0c,0x0c,0x1,0},	/* 20MB	 50ns*/
+	{0x19,0x19,0x3,1},	/* 10MB	 100ns*/ 
+	{0x1a,0x25,0x5,2},	/* 7.5MB 150ns*/ 
+	{0x26,0x32,0x7,3},	/* 5MB	 200ns*/
+	{0x0, 0,   0,  0}
+};
+
+static struct nsp_sync_table nsp_sync_table_20M[] = {
+	{0x19,0x19,0x1,0},	/* 10MB	 100ns*/ 
+	{0x1a,0x25,0x2,0},	/* 7.5MB 150ns*/ 
+	{0x26,0x32,0x3,1},	/* 5MB	 200ns*/
+	{0x0, 0,   0,  0}
+};
+
+/*
+ * setup synchronous data transfer mode
+ */
+static int nsp_msg(Scsi_Cmnd *SCpnt)
+{
+	unsigned char	       target = SCpnt->target;
+	unsigned char	       lun    = SCpnt->lun;
+	sync_data	      *sync   = &(nsp_data.Sync[target][lun]);
+	struct nsp_sync_table *sync_table;
+	unsigned int	       period, offset;
+	int		       i;
+
+
+	DEBUG(0, __FUNCTION__ "()\n");
+
+/**!**/
+
+	period = sync->SyncPeriod;
+	offset = sync->SyncOffset;
+
+	DEBUG(0, " period=0x%x, offset=0x%x\n", period, offset);
+
+	if (nsp_data.ScsiClockDiv == CLOCK_20M) {
+		sync_table = &nsp_sync_table_20M[0];
+	} else {
+		sync_table = &nsp_sync_table_40M[0];
+	}
+
+	for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
+		if ( period >= sync_table->min_period &&
+		     period <= sync_table->max_period	 ) {
+			break;
+		}
+	}
+
+	if (period != 0 && sync_table->max_period == 0) {
+		/*
+		 * No proper period/offset found
+		 */
+		DEBUG(0, " no proper period/offset\n");
+
+		sync->SyncPeriod   = 0;
+		sync->SyncOffset   = 0;
+		sync->SyncRegister = 0;
+		sync->AckWidth	   = 0;
+
+		return FALSE;
+	}
+
+	sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
+			     (offset & SYNCREG_OFFSET_MASK);
+	sync->AckWidth	   = sync_table->ack_width;
+
+	DEBUG(0, " sync_reg=0x%x, ack_width=0x%x\n", sync->SyncRegister, sync->AckWidth);
+
+	return TRUE;
+}
+
+
+/*
+ * start ninja hardware timer
+ */
+static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time)
+{
+	unsigned int base = SCpnt->host->io_port;
+
+	//DEBUG(0, __FUNCTION__ "() in SCpnt=0x%p, time=%d\n", SCpnt, time);
+	nsp_data.TimerCount = time;
+	nsp_index_write(base, TIMERCOUNT, time);
+}
+
+/*
+ * wait for bus phase change
+ */
+static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
+{
+	unsigned int  base = SCpnt->host->io_port;
+	unsigned char reg;
+	int	      count, i = TRUE;
+
+	//DEBUG(0, __FUNCTION__ "()\n");
+
+	count = jiffies + HZ;
+
+	do {
+		reg = nsp_index_read(base, SCSIBUSMON);
+		if (reg == 0xff) {
+			break;
+		}
+	} while ((i = time_before(jiffies, count)) && (reg & mask) != 0);
+
+	if (!i) {
+		printk(KERN_DEBUG __FUNCTION__ " %s signal off timeut\n", str);
+	}
+
+	return 0;
+}
+
+/*
+ * expect Ninja Irq
+ */
+static int nsp_expect_signal(Scsi_Cmnd	   *SCpnt,
+			     unsigned char  current_phase,
+			     unsigned char  mask)
+{
+	unsigned int  base	 = SCpnt->host->io_port;
+	int	      wait_count;
+	unsigned char phase, i_src;
+
+	//DEBUG(0, __FUNCTION__ "() current_phase=0x%x, mask=0x%x\n", current_phase, mask);
+
+	wait_count = jiffies + HZ;
+	do {
+		phase = nsp_index_read(base, SCSIBUSMON);
+		if (phase == 0xff) {
+			//DEBUG(0, " ret -1\n");
+			return -1;
+		}
+		i_src = nsp_read(base, IRQSTATUS);
+		if (i_src & IRQSTATUS_SCSI) {
+			//DEBUG(0, " ret 0 found scsi signal\n");
+			return 0;
+		}
+		if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
+			//DEBUG(0, " ret 1 phase=0x%x\n", phase);
+			return 1;
+		}
+	} while(time_before(jiffies, wait_count));
+
+	//DEBUG(0, __FUNCTION__ " : " __FUNCTION__ " timeout\n");
+	return -1;
+}
+
+/*
+ * transfer SCSI message
+ */
+static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase)
+{
+	unsigned int  base = SCpnt->host->io_port;
+	char	     *buf  = nsp_data.MsgBuffer;
+	int	      len  = MIN(MSGBUF_SIZE, nsp_data.MsgLen);
+	int	      ptr;
+	int	      ret;
+
+	//DEBUG(0, __FUNCTION__ "()\n");
+/**!**/
+	for (ptr = 0; len > 0; len --, ptr ++) {
+
+		ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
+		if (ret <= 0) {
+			DEBUG(0, " xfer quit\n");
+			return 0;
+		}
+
+		/* if last byte, negate ATN */
+		if (len == 1) {
+			nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
+		}
+
+		/* read & write message */
+		if (phase & BUSMON_IO) {
+			//DEBUG(0, " read msg\n");
+			buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
+		} else {
+			//DEBUG(0, " write msg\n");
+			nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
+		}
+		nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
+
+	}
+	return len;
+}
+
+/*
+ * get extra SCSI data from fifo
+ */
+static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt)
+{
+	unsigned int base = SCpnt->host->io_port;
+	unsigned int count;
+
+	//DEBUG(0, __FUNCTION__ "()\n");
+
+	if (SCpnt->SCp.have_data_in != IO_IN) {
+		return 0;
+	}
+
+	count = nsp_fifo_count(SCpnt);
+	if (nsp_data.FifoCount == count) {
+		//DEBUG(0, " not use bypass quirk\n");
+		return 0;
+	}
+
+	/*
+	 * XXX: NSP_QUIRK
+	 * data phase skip only occures in case of SCSI_LOW_READ
+	 */
+	SCpnt->SCp.phase = PH_DATA;
+	nsp_pio_read(SCpnt);
+	nsp_setup_fifo(base, FALSE);
+
+	DEBUG(0, " use bypass quirk\n");
+	return 0;
+}
+
+/*
+ * accept reselection
+ */
+static int nsp_reselected(Scsi_Cmnd *SCpnt)
+{
+	unsigned int  base = SCpnt->host->io_port;
+	unsigned char reg;
+
+	//DEBUG(0, __FUNCTION__ "()\n");
+
+	nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
+
+	nsp_nexus(SCpnt);
+	reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
+	nsp_index_write(base, SCSIBUSCTRL, reg);
+	nsp_index_write(base, SCSIBUSCTRL, reg | AUTODIRECTION | ACKENB);
+
+	return TRUE;
+}
+
+/*
+ * count how many data transferd
+ */
+static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
+{
+	unsigned int base = SCpnt->host->io_port;
+	unsigned int count;
+	unsigned int l, m, h;
+
+	nsp_index_write(base, POINTERCLR, POINTER_CLEAR);
+
+        l = (unsigned int)nsp_read(base, DATAREG);
+        m = (unsigned int)nsp_read(base, DATAREG);
+        h = (unsigned int)nsp_read(base, DATAREG);
+
+	count = (h << 16) | (m << 8) | (l << 0);
+
+	//DEBUG(0, __FUNCTION__ "() =0x%x\n", count);
+
+	return count;
+}
+
+/* fifo size */
+#define RFIFO_CRIT 64
+#define WFIFO_CRIT 64
+
+/*
+ * read data in DATA IN phase
+ */
+static void nsp_pio_read(Scsi_Cmnd *SCpnt)
+{
+	unsigned int  base     = SCpnt->host->io_port;
+	int	      time_out, i;
+	int	      ocount, res;
+	unsigned char stat, fifo_stat;
+
+	ocount = nsp_data.FifoCount;
+
+	DEBUG(0, __FUNCTION__ "() in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d\n", SCpnt, RESID, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
+
+	time_out = jiffies + 10 * HZ;
+
+	while ((i = time_before(jiffies,time_out)) &&
+	       (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
+
+		stat = nsp_index_read(base, SCSIBUSMON);
+		stat &= BUSMON_PHASE_MASK;
+
+		res = nsp_fifo_count(SCpnt) - ocount;
+
+		//DEBUG(0, " ptr=0x%p this=0x%x ocount=0x%x res=0x%x\n", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount, res);
+		if (res == 0) { /* if some data avilable ? */
+			if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
+				//DEBUG(0, " wait for data this=%d\n", SCpnt->SCp.this_residual);
+				continue;
+			} else {
+				DEBUG(0, " phase changed stat=0x%x\n", stat);
+				break;
+			}
+		}
+
+		fifo_stat = nsp_read(base, FIFOSTATUS);
+		if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
+		    stat                                == BUSPHASE_DATA_IN) {
+			continue;
+		}
+
+		res = MIN(res, SCpnt->SCp.this_residual);
+
+		switch (nsp_data.TransferMode) {
+		case MODE_IO32:
+			res &= ~(BIT(1)|BIT(0)); /* align 4 */
+			nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
+			break;
+		case MODE_IO8:
+			nsp_fifo8_read (base, SCpnt->SCp.ptr, res     );
+			break;
+		default:
+			DEBUG(0, "unknown read mode\n");
+			break;
+		}
+
+		RESID			 -= res;
+		SCpnt->SCp.ptr		 += res;
+		SCpnt->SCp.this_residual -= res;
+		ocount			 += res;
+		//DEBUG(0, " ptr=0x%p this_residual=0x%x ocount=0x%x\n", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
+
+		/* go to next scatter list if availavle */
+		if (SCpnt->SCp.this_residual	== 0 &&
+		    SCpnt->SCp.buffers_residual != 0 ) {
+			//DEBUG(0, " scatterlist next timeout=%d\n", time_out);
+			SCpnt->SCp.buffers_residual--;
+			SCpnt->SCp.buffer++;
+			SCpnt->SCp.ptr		 = SCpnt->SCp.buffer->address;
+			SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
+		}
+
+		time_out = jiffies + 10 * HZ;
+	}
+
+	nsp_data.FifoCount = ocount;
+
+	if (!i) {
+		printk(KERN_DEBUG __FUNCTION__ "() pio read timeout resid=%d this_residual=%d buffers_residual=%d\n", RESID, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
+	}
+	DEBUG(0, " read ocount=0x%x\n", ocount);
+}
+
+/*
+ * write data in DATA OUT phase
+ */
+static void nsp_pio_write(Scsi_Cmnd *SCpnt)
+{
+	unsigned int  base     = SCpnt->host->io_port;
+	int	      time_out, i;
+	unsigned int  ocount, res;
+	unsigned char stat;
+
+	ocount	 = nsp_data.FifoCount;
+
+	DEBUG(0, __FUNCTION__ "() in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x\n", nsp_data.FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, SCpnt->resid);
+
+	time_out = jiffies + 10 * HZ;
+
+	while ((i = time_before(jiffies, time_out))                             &&
+	       (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
+		stat = nsp_index_read(base, SCSIBUSMON);
+		stat &= BUSMON_PHASE_MASK;
+		if (stat != BUSPHASE_DATA_OUT) {
+			DEBUG(0, " phase changed stat=0x%x\n", stat);
+			break;
+		}
+
+		res = ocount - nsp_fifo_count(SCpnt);
+		if (res > 0) { /* write all data? */
+			DEBUG(0, " wait for all data out. ocount=0x%x res=%d\n", ocount, res);
+			continue;
+		}
+
+		res = MIN(SCpnt->SCp.this_residual, WFIFO_CRIT);
+
+		//DEBUG(0, " ptr=0x%p this=0x%x res=0x%x\n", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
+		switch (nsp_data.TransferMode) {
+		case MODE_IO32:
+			res &= ~(BIT(1)|BIT(0)); /* align 4 */
+			nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
+			break;
+		case MODE_IO8:
+			nsp_fifo8_write (base, SCpnt->SCp.ptr, res     );
+			break;
+		default:
+			DEBUG(0, "unknown write mode\n");
+			break;
+		}
+
+		RESID			 -= res;
+		SCpnt->SCp.ptr		 += res;
+		SCpnt->SCp.this_residual -= res;
+		ocount			 += res;
+
+		/* go to next scatter list if availavle */
+		if (SCpnt->SCp.this_residual	== 0 &&
+		    SCpnt->SCp.buffers_residual != 0 ) {
+			//DEBUG(0, " scatterlist next\n");
+			SCpnt->SCp.buffers_residual--;
+			SCpnt->SCp.buffer++;
+			SCpnt->SCp.ptr		 = SCpnt->SCp.buffer->address;
+			SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
+		}
+
+		time_out = jiffies + 10 * HZ;
+	}
+
+	nsp_data.FifoCount = ocount;
+
+	if (!i) {
+		printk(KERN_DEBUG __FUNCTION__ "() pio write timeout resid=%d\n", RESID);
+	}
+	//DEBUG(0, " write ocount=%d\n", ocount);
+}
+
+#undef RFIFO_CRIT
+#undef WFIFO_CRIT
+
+/*
+ * setup synchronous/asynchronous data transfer mode
+ */
+static int nsp_nexus(Scsi_Cmnd *SCpnt)
+{
+	unsigned int  base   = SCpnt->host->io_port;
+	unsigned char target = SCpnt->target;
+	unsigned char lun    = SCpnt->lun;
+	sync_data *sync = &(nsp_data.Sync[target][lun]);
+
+	//DEBUG(0, __FUNCTION__ "() in SCpnt=0x%p\n", SCpnt);
+
+	/* setup synch transfer registers */
+	nsp_index_write(base, SYNCREG,	sync->SyncRegister);
+	nsp_index_write(base, ACKWIDTH, sync->AckWidth);
+
+	if (RESID % 4 != 0   ||
+	    RESID     <= 256 ) {
+		nsp_data.TransferMode = MODE_IO8;
+	} else {
+		nsp_data.TransferMode = MODE_IO32;
+	}
+
+	/* setup pdma fifo */
+	nsp_setup_fifo(base, TRUE);
+
+	/* clear ack counter */
+	nsp_data.FifoCount = 0;
+	nsp_index_write(base, POINTERCLR, POINTER_CLEAR	    |
+					  ACK_COUNTER_CLEAR |
+					  REQ_COUNTER_CLEAR |
+					  HOST_COUNTER_CLEAR);
+
+	return 0;
+}
+
+/*
+ * interrupt handler
+ */
+static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int   base;
+	unsigned char  i_src, irq_phase, phase;
+	Scsi_Cmnd     *tmpSC;
+	int	       ret, len;
+	unsigned char  data_reg, control_reg;
+
+
+	//DEBUG(0, __FUNCTION__ "(%d) CurrentSC=0x%p\n", irq, nsp_data.CurrentSC);
+
+	base = nsp_data.BaseAddress;
+	//DEBUG(0, " base=0x%x\n", base);
+
+	/*
+	 * interrupt check
+	 */
+	nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
+	i_src = nsp_read(base, IRQSTATUS);
+	if (i_src == 0xff || (i_src & IRQSTATUS_MASK) == 0) {
+		nsp_write(base, IRQCONTROL, 0);
+		//DEBUG(0, " no irq\n");
+		return;
+	}
+
+	//DEBUG(0, " i_src=0x%x\n", i_src);
+
+	/* XXX: IMPORTANT
+	 * Do not read an irq_phase register if no scsi phase interrupt.
+	 * Unless, you should lose a scsi phase interrupt.
+	 */
+	phase = nsp_index_read(base, SCSIBUSMON);
+	if((i_src & IRQSTATUS_SCSI) != 0) {
+		irq_phase = nsp_index_read(base, IRQPHASESENCE);
+	} else {
+		irq_phase = 0;
+	}
+
+	//DEBUG(0, " irq_phase=0x%x\n", irq_phase);
+
+	/*
+	 * timer interrupt handler (scsi vs timer interrupts)
+	 */
+	//DEBUG(0, " timercount=%d\n", nsp_data.TimerCount);
+	if (nsp_data.TimerCount != 0) {
+		//DEBUG(0, " stop timer\n");
+		nsp_index_write(base, TIMERCOUNT, 0);
+		nsp_index_write(base, TIMERCOUNT, 0);
+		nsp_data.TimerCount = 0;
+	}
+
+	if ((i_src & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
+	    nsp_data.SelectionTimeOut == 0) {
+		//DEBUG(0, " timer start\n");
+		nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
+		return;
+	}
+
+	nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
+
+	if (nsp_data.CurrentSC == NULL) {
+		printk(KERN_DEBUG __FUNCTION__ " CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x this can't be happen\n", i_src, phase, irq_phase);
+		return;
+	} else {
+		tmpSC = nsp_data.CurrentSC;
+	}
+
+	/*
+	 * parse hardware SCSI irq reasons register
+	 */
+	if ((i_src & IRQSTATUS_SCSI) != 0) {
+		if ((irq_phase & SCSI_RESET_IRQ) != 0) {
+			printk(KERN_DEBUG " " __FUNCTION__ "() bus reset (power off?)\n");
+
+			nsp_data.CurrentSC = NULL;
+			tmpSC->result	   = DID_RESET << 16;
+			tmpSC->scsi_done(tmpSC);
+			return;
+		}
+
+		if ((irq_phase & RESELECT_IRQ) != 0) {
+			DEBUG(0, " reselect\n");
+			nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
+			if (nsp_reselected(tmpSC) != FALSE) {
+				return;
+			}
+		}
+
+		if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
+			return; 
+		}
+	}
+
+	//show_phase(tmpSC);
+
+	switch(tmpSC->SCp.phase) {
+	case PH_SELSTART:
+		if ((phase & BUSMON_BSY) == 0) {
+			//DEBUG(0, " selection count=%d\n", nsp_data.SelectionTimeOut);
+			if (nsp_data.SelectionTimeOut >= NSP_SELTIMEOUT) {
+				DEBUG(0, " selection time out\n");
+				nsp_data.SelectionTimeOut = 0;
+				nsp_index_write(base, SCSIBUSCTRL, 0);
+
+				nsp_data.CurrentSC = NULL;
+				tmpSC->result	   = DID_NO_CONNECT << 16;
+				tmpSC->scsi_done(tmpSC);
+
+				return;
+			}
+			nsp_data.SelectionTimeOut += 1;
+			nsp_start_timer(tmpSC, 1000/51);
+			return;
+		}
+
+		/* attention assert */
+		//DEBUG(0, " attention assert\n");
+		nsp_data.SelectionTimeOut = 0;
+		tmpSC->SCp.phase	  = PH_SELECTED;
+		nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
+		udelay(1);
+		nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
+		return;
+
+		break;
+
+	case PH_RESELECT:
+		//DEBUG(0, " phase reselect\n");
+		if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
+
+			nsp_data.CurrentSC = NULL;
+			tmpSC->result	   = DID_ABORT << 16;
+			tmpSC->scsi_done(tmpSC);
+			return;
+		}
+		/* fall thru */
+	default:
+		if (( i_src & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
+			return;
+		}
+		break;
+	}
+
+	/*
+	 * SCSI sequencer
+	 */
+	//DEBUG(0, " start scsi seq\n");
+
+	/* normal disconnect */
+	if ((irq_phase & LATCHED_BUS_FREE) != 0) {
+		//DEBUG(0, " normal disconnect i_src=0x%x, phase=0x%x, irq_phase=0x%x\n", i_src, phase, irq_phase);
+		if ((tmpSC->SCp.Message == 0)) {     /* all command complete and return status */
+			nsp_data.CurrentSC = NULL;
+			tmpSC->result = (DID_OK		    << 16) |
+					(tmpSC->SCp.Message <<	8) |
+					(tmpSC->SCp.Status  <<	0);
+			DEBUG(0, " command complete result=0x%x\n", tmpSC->result);
+			tmpSC->scsi_done(tmpSC);
+			return;
+		}
+
+		return;
+	}
+
+
+	/* check unexpected bus free state */
+	if (phase == 0) {
+		printk(KERN_DEBUG " " __FUNCTION__ " unexpected bus free. i_src=0x%x, phase=0x%x, irq_phase=0x%x\n", i_src, phase, irq_phase);
+
+		nsp_data.CurrentSC = NULL;
+		tmpSC->result	   = DID_ERROR << 16;
+		tmpSC->scsi_done(tmpSC);
+		return;
+	}
+
+	switch (phase & BUSMON_PHASE_MASK) {
+	case BUSPHASE_COMMAND:
+		DEBUG(0, " BUSPHASE_COMMAND\n");
+		if ((phase & BUSMON_REQ) == 0) {
+			DEBUG(0, " REQ == 0\n");
+			return;
+		}
+
+		tmpSC->SCp.phase = PH_COMMAND;
+
+		nsp_nexus(tmpSC);
+
+		/* write scsi command */
+		nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
+		for (len = 0; len < COMMAND_SIZE(tmpSC->cmnd[0]); len++) {
+			nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[len]);
+		}
+		nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
+		break;
+
+	case BUSPHASE_DATA_OUT:
+		DEBUG(0, " BUSPHASE_DATA_OUT\n");
+
+		tmpSC->SCp.phase = PH_DATA;
+		tmpSC->SCp.have_data_in = IO_OUT;
+
+		nsp_pio_write(tmpSC);
+
+		break;
+
+	case BUSPHASE_DATA_IN:
+		DEBUG(0, " BUSPHASE_DATA_IN\n");
+
+		tmpSC->SCp.phase = PH_DATA;
+		tmpSC->SCp.have_data_in = IO_IN;
+
+		nsp_pio_read(tmpSC);
+
+		break;
+
+	case BUSPHASE_STATUS:
+		nsp_dataphase_bypass(tmpSC);
+		DEBUG(0, " BUSPHASE_STATUS\n");
+
+		tmpSC->SCp.phase = PH_STATUS;
+
+		tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
+		//DEBUG(0, " message=0x%x status=0x%x\n", tmpSC->SCp.Message, tmpSC->SCp.Status);
+
+		break;
+
+	case BUSPHASE_MESSAGE_OUT:
+		DEBUG(0, " BUSPHASE_MESSAGE_OUT\n");
+		if ((phase & BUSMON_REQ) == 0) {
+			goto timer_out;
+		}
+
+		tmpSC->SCp.phase = PH_MSG_OUT;
+
+		/*
+		 * XXX: NSP QUIRK
+		 * NSP invoke interrupts only in the case of scsi phase changes,
+		 * therefore we should poll the scsi phase here to catch 
+		 * the next "msg out" if exists (no scsi phase changes).
+		 */
+		ret = 16;
+		len = 0;
+
+		nsp_msg(tmpSC);
+
+		nsp_data.MsgBuffer[len] = IDENTIFY(TRUE, tmpSC->lun); len++;
+		nsp_data.MsgLen		= len;
+
+		do {
+			DEBUG(0, " msgout loop\n");
+
+			if (nsp_xfer(tmpSC, BUSPHASE_MESSAGE_OUT)) {
+				printk(KERN_DEBUG " " __FUNCTION__ " msgout: xfer short\n");
+			}
+
+			/* catch a next signal */
+			ret = nsp_expect_signal(tmpSC, BUSPHASE_MESSAGE_OUT, BUSMON_REQ);
+		} while (ret > 0 && len-- > 0);
+
+		break;
+
+	case BUSPHASE_MESSAGE_IN:
+		nsp_dataphase_bypass(tmpSC);
+		DEBUG(0, " BUSPHASE_MESSAGE_IN\n");
+		if ((phase & BUSMON_REQ) == 0) {
+			goto timer_out;
+		}
+
+		tmpSC->SCp.phase = PH_MSG_IN;
+
+		/*
+		 * XXX: NSP QUIRK
+		 * NSP invoke interrupts only in the case of scsi phase changes,
+		 * therefore we should poll the scsi phase here to catch 
+		 * the next "msg in" if exists (no scsi phase changes).
+		 */
+		ret = 16;
+		len = 0;
+
+		do {
+			//DEBUG(0, " msgin loop\n");
+			/* read data */
+			data_reg = nsp_index_read(base, SCSIDATAIN);
+
+			/* assert ACK */
+			control_reg = nsp_index_read(base, SCSIBUSCTRL);
+			control_reg |= SCSI_ACK;
+			nsp_index_write(base, SCSIBUSCTRL, control_reg);
+			nsp_negate_signal(tmpSC, BUSMON_REQ, "msgin<REQ>");
+
+			nsp_data.MsgBuffer[len] = data_reg; len++;
+			DEBUG(0, " msg=0x%x\n", data_reg);
+
+			/* deassert ACK */
+			control_reg =  nsp_index_read(base, SCSIBUSCTRL);
+			control_reg &= ~SCSI_ACK;
+			nsp_index_write(base, SCSIBUSCTRL, control_reg);
+
+			/* catch a next signal */
+			ret = nsp_expect_signal(tmpSC, BUSPHASE_MESSAGE_IN, BUSMON_REQ);
+		} while (ret > 0 && MSGBUF_SIZE > len);
+
+		nsp_data.MsgLen	   = len;
+		tmpSC->SCp.Message = nsp_data.MsgBuffer[len-1];
+
+		//DEBUG(0, " message=0x%x len=%d\n", tmpSC->SCp.Message, nsp_data.MsgLen);
+		break;
+
+	case BUSPHASE_SELECT:
+	default:
+		DEBUG(0, " BUSPHASE other\n");
+
+		break;
+	}
+
+	//DEBUG(0, __FUNCTION__ "() out\n");
+	return;	
+
+timer_out:
+	nsp_start_timer(tmpSC, 1000/102);
+	return;
+}
+
+#ifdef DBG_SHOWCOMMAND
+#include "nsp_debug.c"
+#endif	/* DBG_SHOWCOMMAND */
+
+/*====================================================================*/
+static void cs_error(client_handle_t handle, int func, int ret)
+{
+	error_info_t err = { func, ret };
+	CardServices(ReportError, handle, &err);
+}
+
+/*======================================================================
+    nsp_attach() creates an "instance" of the driver, allocating
+    local data structures for one device.  The device is registered
+    with Card Services.
+
+    The dev_link structure is initialized, but we don't actually
+    configure the card at this point -- we wait until we receive a
+    card insertion event.
+======================================================================*/
+static dev_link_t *nsp_attach(void)
+{
+	scsi_info_t  *info;
+	client_reg_t  client_reg;
+	dev_link_t   *link;
+	int	      ret, i;
+
+	DEBUG(0, __FUNCTION__ "()\n");
+
+	/* Create new SCSI device */
+	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	if (!info) return NULL;
+	memset(info, 0, sizeof(*info));
+	link = &info->link;
+	link->priv = info;
+
+	/* Initialize the dev_link_t structure */
+	link->release.function	 = &nsp_release;
+	link->release.data	 = (u_long)link;
+
+	/* The io structure describes IO port mapping */
+	link->io.NumPorts1	 = 0x10;
+	link->io.Attributes1	 = IO_DATA_PATH_WIDTH_AUTO;
+	link->io.IOAddrLines	 = 10;	/* not used */
+
+	/* Interrupt setup */
+	link->irq.Attributes	 = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+	link->irq.IRQInfo1	 = IRQ_INFO2_VALID    | IRQ_LEVEL_ID;
+	if (irq_list[0] == -1) {
+		link->irq.IRQInfo2 = irq_mask;
+	} else {
+		for (i = 0; i < 4; i++) {
+			link->irq.IRQInfo2 |= 1 << irq_list[i];
+		}
+	}
+	link->irq.Handler	 = &nspintr;
+
+	/* General socket configuration */
+	link->conf.Attributes	 = CONF_ENABLE_IRQ;
+	link->conf.Vcc		 = 50;
+	link->conf.IntType	 = INT_MEMORY_AND_IO;
+	link->conf.Present	 = PRESENT_OPTION;
+
+
+	/* Register with Card Services */
+	link->next               = dev_list;
+	dev_list                 = link;
+	client_reg.dev_info	 = &dev_info;
+	client_reg.Attributes	 = INFO_IO_CLIENT | INFO_CARD_SHARE;
+	client_reg.EventMask	 =
+		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET	|
+		CS_EVENT_PM_SUSPEND	| CS_EVENT_PM_RESUME	 ;
+	client_reg.event_handler = &nsp_event;
+	client_reg.Version	 = 0x0210;
+	client_reg.event_callback_args.client_data = link;
+	ret = CardServices(RegisterClient, &link->handle, &client_reg);
+	if (ret != CS_SUCCESS) {
+		cs_error(link->handle, RegisterClient, ret);
+		nsp_detach(link);
+		return NULL;
+	}
+
+	return link;
+} /* nsp_attach */
+
+
+/*======================================================================
+    This deletes a driver "instance".  The device is de-registered
+    with Card Services.	 If it has been released, all local data
+    structures are freed.  Otherwise, the structures will be freed
+    when the device is released.
+======================================================================*/
+static void nsp_detach(dev_link_t *link)
+{
+	dev_link_t **linkp;
+
+	DEBUG(0, __FUNCTION__ "(0x%p)\n", link);
+    
+	/* Locate device structure */
+	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
+		if (*linkp == link) {
+			break;
+		}
+	}
+	if (*linkp == NULL) {
+		return;
+	}
+
+	del_timer(&link->release);
+	if (link->state & DEV_CONFIG) {
+		nsp_release((u_long)link);
+		if (link->state & DEV_STALE_CONFIG) {
+			link->state |= DEV_STALE_LINK;
+			return;
+		}
+	}
+
+	/* Break the link with Card Services */
+	if (link->handle) {
+		CardServices(DeregisterClient, link->handle);
+	}
+
+	/* Unlink device structure, free bits */
+	*linkp = link->next;
+	kfree(link->priv);
+
+} /* nsp_detach */
+
+
+/*======================================================================
+    nsp_config() is scheduled to run after a CARD_INSERTION event
+    is received, to configure the PCMCIA socket, and to make the
+    ethernet device available to the system.
+======================================================================*/
+#define CS_CHECK(fn, args...) \
+while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed
+#define CFG_CHECK(fn, args...) \
+if (CardServices(fn, args) != 0) goto next_entry
+/*====================================================================*/
+
+static void nsp_config(dev_link_t *link)
+{
+	client_handle_t	  handle = link->handle;
+	scsi_info_t	 *info	 = link->priv;
+	tuple_t		  tuple;
+	cisparse_t	  parse;
+	int		  i, last_ret, last_fn;
+	u_char		  tuple_data[64];
+	config_info_t	  conf;
+	Scsi_Device	 *dev;
+	dev_node_t	**tail, *node;
+	struct Scsi_Host *host;
+
+	DEBUG(0, __FUNCTION__ "() in\n");
+
+	tuple.DesiredTuple    = CISTPL_CONFIG;
+	tuple.Attributes      = 0;
+	tuple.TupleData	      = tuple_data;
+	tuple.TupleDataMax    = sizeof(tuple_data);
+	tuple.TupleOffset     = 0;
+	CS_CHECK(GetFirstTuple, handle, &tuple);
+	CS_CHECK(GetTupleData,	handle, &tuple);
+	CS_CHECK(ParseTuple,	handle, &tuple, &parse);
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present    = parse.config.rmask[0];
+
+	/* Configure card */
+	driver_template.module = &__this_module;
+	link->state	      |= DEV_CONFIG;
+
+	/* Look up the current Vcc */
+	CS_CHECK(GetConfigurationInfo, handle, &conf);
+	link->conf.Vcc = conf.Vcc;
+
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	CS_CHECK(GetFirstTuple, handle, &tuple);
+	while (1) {
+		CFG_CHECK(GetTupleData, handle, &tuple);
+		CFG_CHECK(ParseTuple,	handle, &tuple, &parse);
+		link->conf.ConfigIndex = parse.cftable_entry.index;
+		link->io.BasePort1     = parse.cftable_entry.io.win[0].base;
+		i = CardServices(RequestIO, handle, &link->io);
+		if (i == CS_SUCCESS) {
+			break;
+		}
+	next_entry:
+		DEBUG(0, __FUNCTION__ " next\n");
+		CS_CHECK(GetNextTuple, handle, &tuple);
+	}
+
+	CS_CHECK(RequestIRQ,	       handle, &link->irq);
+	CS_CHECK(RequestConfiguration, handle, &link->conf);
+
+	/* A bad hack... */
+	release_region(link->io.BasePort1, link->io.NumPorts1);
+
+	/* Set port and IRQ */
+	nsp_data.BaseAddress = link->io.BasePort1;
+	nsp_data.NumAddress  = link->io.NumPorts1;
+	nsp_data.IrqNumber   = link->irq.AssignedIRQ;
+
+	DEBUG(0, __FUNCTION__ " I/O[0x%x+0x%x] IRQ %d\n",
+	      nsp_data.BaseAddress, nsp_data.NumAddress, nsp_data.IrqNumber);
+
+	if(nsphw_init() == FALSE) {
+		goto cs_failed;
+	}
+
+	scsi_register_module(MODULE_SCSI_HA, &driver_template);
+
+	DEBUG(0, "GET_SCSI_INFO\n");
+	tail = &link->dev;
+	info->ndev = 0;
+	for (host = scsi_hostlist; host != NULL; host = host->next) {
+		if (host->hostt == &driver_template) {
+			for (dev = host->host_queue; dev != NULL; dev = dev->next) {
+				u_long arg[2], id;
+				kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
+				id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) +
+					((arg[0]>>8)&0xf00) + ((arg[0]>>12)&0xf000);
+				node = &info->node[info->ndev];
+				node->minor = 0;
+				switch (dev->type) {
+				case TYPE_TAPE:
+					node->major = SCSI_TAPE_MAJOR;
+					sprintf(node->dev_name, "st#%04lx", id);
+					break;
+				case TYPE_DISK:
+				case TYPE_MOD:
+					node->major = SCSI_DISK0_MAJOR;
+					sprintf(node->dev_name, "sd#%04lx", id);
+					break;
+				case TYPE_ROM:
+				case TYPE_WORM:
+					node->major = SCSI_CDROM_MAJOR;
+					sprintf(node->dev_name, "sr#%04lx", id);
+					break;
+				default:
+					node->major = SCSI_GENERIC_MAJOR;
+					sprintf(node->dev_name, "sg#%04lx", id);
+					break;
+				}
+				*tail = node; tail = &node->next;
+				info->ndev++;
+				info->host = dev->host;
+			}
+		}
+	}
+	*tail = NULL;
+	if (info->ndev == 0) {
+		printk(KERN_INFO "nsp_cs: no SCSI devices found\n");
+	}
+
+	/* Finally, report what we've done */
+	printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d",
+	       link->conf.ConfigIndex,
+	       link->conf.Vcc/10, link->conf.Vcc%10);
+	if (link->conf.Vpp1) {
+		printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
+	}
+	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+		printk(", irq %d", link->irq.AssignedIRQ);
+	}
+	if (link->io.NumPorts1) {
+		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+		       link->io.BasePort1+link->io.NumPorts1-1);
+	}
+	printk("\n");
+
+	link->state &= ~DEV_CONFIG_PENDING;
+	return;
+
+cs_failed:
+	cs_error(link->handle, last_fn, last_ret);
+	nsp_release((u_long)link);
+	return;
+
+} /* nsp_config */
+#undef CS_CHECK
+#undef CFG_CHECK
+
+/*======================================================================
+    After a card is removed, nsp_release() will unregister the net
+    device, and release the PCMCIA configuration.  If the device is
+    still open, this will be postponed until it is closed.
+======================================================================*/
+static void nsp_release(u_long arg)
+{
+	dev_link_t *link = (dev_link_t *)arg;
+
+	DEBUG(0, __FUNCTION__ "(0x%p)\n", link);
+
+	/*
+	 * If the device is currently in use, we won't release until it
+	 * is actually closed.
+	 */
+	if (link->open) {
+		DEBUG(1, "nsp_cs: release postponed, '%s' still open\n",
+		      link->dev->dev_name);
+		link->state |= DEV_STALE_CONFIG;
+		return;
+	}
+
+	/* Unlink the device chain */
+	scsi_unregister_module(MODULE_SCSI_HA, &driver_template);
+	link->dev = NULL;
+
+	if (link->win) {
+		CardServices(ReleaseWindow, link->win);
+	}
+	CardServices(ReleaseConfiguration,  link->handle);
+	if (link->io.NumPorts1) {
+		CardServices(ReleaseIO,     link->handle, &link->io);
+	}
+	if (link->irq.AssignedIRQ) {
+		CardServices(ReleaseIRQ,    link->handle, &link->irq);
+	}
+	link->state &= ~DEV_CONFIG;
+
+	if (link->state & DEV_STALE_LINK) {
+		nsp_detach(link);
+	}
+} /* nsp_release */
+
+/*======================================================================
+
+    The card status event handler.  Mostly, this schedules other
+    stuff to run after an event is received.  A CARD_REMOVAL event
+    also sets some flags to discourage the net drivers from trying
+    to talk to the card any more.
+
+    When a CARD_REMOVAL event is received, we immediately set a flag
+    to block future accesses to this device.  All the functions that
+    actually access the device should check this flag to make sure
+    the card is still present.
+    
+======================================================================*/
+static int nsp_event(event_t		    event,
+		     int		    priority,
+		     event_callback_args_t *args)
+{
+	dev_link_t  *link = args->client_data;
+	scsi_info_t *info = link->priv;
+
+	DEBUG(1, __FUNCTION__ "(0x%06x)\n", event);
+
+	switch (event) {
+	case CS_EVENT_CARD_REMOVAL:
+		DEBUG(0, " event: remove\n");
+		link->state &= ~DEV_PRESENT;
+		if (link->state & DEV_CONFIG) {
+			((scsi_info_t *)link->priv)->stop = 1;
+			mod_timer(&link->release, jiffies + HZ/20);
+		}
+		break;
+
+	case CS_EVENT_CARD_INSERTION:
+		DEBUG(0, " event: insert\n");
+		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+		info->bus    =  args->bus;
+		nsp_config(link);
+		break;
+
+	case CS_EVENT_PM_SUSPEND:
+		link->state |= DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_RESET_PHYSICAL:
+		/* Mark the device as stopped, to block IO until later */
+		info->stop = 1;
+		if (link->state & DEV_CONFIG) {
+			CardServices(ReleaseConfiguration, link->handle);
+		}
+		break;
+
+	case CS_EVENT_PM_RESUME:
+		link->state &= ~DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_CARD_RESET:
+		DEBUG(0, " event: reset\n");
+		if (link->state & DEV_CONFIG) {
+			Scsi_Cmnd tmp;
+
+			CardServices(RequestConfiguration, link->handle, &link->conf);
+			tmp.host = info->host;
+			nsp_reset(&tmp, 0);
+		}
+		info->stop = 0;
+		/* restart IO */
+		nsphw_init();
+		break;
+
+	default:
+		DEBUG(0, " event: unknown\n");
+		break;
+	}
+	DEBUG(0, __FUNCTION__ " end\n");
+	return 0;
+} /* nsp_event */
+
+/*----------------------------------------------------------------*/
+/* look for ninja3 card and init if found			  */
+/*----------------------------------------------------------------*/
+static int nsp_detect(Scsi_Host_Template *sht)
+{
+	struct Scsi_Host *host;	/* registered host structure */
+
+	DEBUG(0, __FUNCTION__ " this_id=%d\n", sht->this_id);
+
+#if (KERNEL_VERSION(2,3,99) > LINUX_VERSION_CODE)
+	sht->proc_dir	  = &proc_scsi_nsp; /* kernel 2.2 */
+#else
+	sht->proc_name	  = "nsp_cs";	    /* kernel 2.4 */
+#endif
+
+	sht->this_id	  = SCSI_INITIATOR_ID;
+
+	request_region(nsp_data.BaseAddress, nsp_data.NumAddress,"nsp_cs");
+	host		  = scsi_register(sht, 0);
+	host->io_port	  = nsp_data.BaseAddress;
+	host->unique_id	  = nsp_data.BaseAddress;
+	host->n_io_port	  = nsp_data.NumAddress;
+	host->irq	  = nsp_data.IrqNumber;
+	host->dma_channel = -1;
+
+	sprintf(nspinfo,
+/* Buffer size is 100 bytes */
+/*  0         1         2         3         4         5         6         7         8         9         0*/
+/*  01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890*/
+   "NinjaSCSI-3/32Bi Driver version 2.0, I/O 0x%04lx-0x%04lx IRQ %2d",
+		host->io_port, host->io_port + host->n_io_port,
+		host->irq);
+	sht->name	  = nspinfo;
+
+	DEBUG(0, __FUNCTION__ " end\n");
+
+	return 1; /* detect done. */
+}
+
+
+/*----------------------------------------------------------------*/
+/* return info string						  */
+/*----------------------------------------------------------------*/
+static const char *nsp_info(struct Scsi_Host *host)
+{
+	return nspinfo;
+}
+
+static int nsp_reset(Scsi_Cmnd *SCpnt, unsigned int why)
+{
+	DEBUG(0, __FUNCTION__ "() SCpnt=0x%p why=%d\n", SCpnt, why);
+
+	return nsp_eh_bus_reset(SCpnt);
+}
+
+static int nsp_abort(Scsi_Cmnd *SCpnt)
+{
+	DEBUG(0, __FUNCTION__ "() SCpnt=0x%p\n", SCpnt);
+	return FAILED;
+}
+
+/*static int nsp_eh_strategy(struct Scsi_Host *Shost)
+{
+}
+static int nsp_eh_abort(Scsi_Cmnd * cmd)
+{
+	DEBUG(0, __FUNCTION__"() SCpnt\n");
+}
+
+static nsp_eh_device_reset(Scsi_Cmnd *)
+{
+}
+*/
+static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
+{
+	unsigned int base = SCpnt->host->io_port;
+	int	     i;
+
+	DEBUG(0, __FUNCTION__ "() SCpnt=0x%p\n", SCpnt);
+
+	nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
+
+	nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
+	mdelay(100); /* 100ms */
+	nsp_index_write(base, SCSIBUSCTRL, 0);
+	for(i = 0; i < 5; i++) {
+		(void) nsp_index_read(base, IRQPHASESENCE); /* dummy read */
+	}
+
+	nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
+
+	return 0;
+}
+/*
+static nsp_eh_host_reset(Scsi_Cmnd *)
+{
+}*/
+
+/*======================================================================*
+ *	module entry point
+ *====================================================================*/
+static int __init nsp_init(void)
+{
+	servinfo_t serv;
+
+	DEBUG(0, __FUNCTION__ "() in\n");
+	DEBUG(0, "%s\n", version);
+	CardServices(GetCardServicesInfo, &serv);
+	if (serv.Revision != CS_RELEASE_CODE) {
+		printk(KERN_DEBUG "nsp_cs: Card Services release "
+		       "does not match!\n");
+		return -1;
+	}
+	register_pcmcia_driver(&dev_info, &nsp_attach, &nsp_detach);
+
+	DEBUG(0, __FUNCTION__ "() out\n");
+	return 0;
+}
+
+
+static void __exit nsp_cleanup(void)
+{
+	DEBUG(0, "nsp_cs: unloading\n");
+	unregister_pcmcia_driver(&dev_info);
+	while (dev_list != NULL) {
+		if (dev_list->state & DEV_CONFIG) {
+			nsp_release((u_long)dev_list);
+		}
+		nsp_detach(dev_list);
+	}
+}
+
+module_init(nsp_init);
+module_exit(nsp_cleanup);
+
+/*
+ *
+ *
+ */
+
+/* end */
diff -u --recursive --new-file v2.4.6/linux/drivers/scsi/pcmcia/nsp_cs.h linux/drivers/scsi/pcmcia/nsp_cs.h
--- v2.4.6/linux/drivers/scsi/pcmcia/nsp_cs.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/pcmcia/nsp_cs.h	Wed Jul  4 11:50:38 2001
@@ -0,0 +1,302 @@
+/*=======================================================/
+  Header file for nsp_cs.c
+      By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
+
+    Ver.1.0 : Cut unused lines.
+    Ver 0.1 : Initial version.
+
+    This software may be used and distributed according to the terms of
+    the GNU General Public License.
+
+=========================================================*/
+
+/* $Id: nsp_cs.h,v 1.18 2001/02/09 04:42:19 elca Exp $ */
+
+#ifndef  __nsp_cs__
+#define  __nsp_cs__
+
+/* for debugging */
+/*
+#define DBG
+#define DBG_PRINT
+#define DBG_SHOWCOMMAND
+#define PCMCIA_DEBUG 9
+*/
+
+/*
+#define static
+#define inline
+*/
+
+/************************************
+ * Some useful macros...
+ */
+#define Number(arr) ((int) (sizeof(arr) / sizeof(arr[0])))
+#define BIT(x)      (1<<(x))
+#define MIN(a,b)    ((a) > (b) ? (b) : (a))
+
+/* SCSI initiator must be 7 */
+#define SCSI_INITIATOR_ID  7
+
+/* base register */
+#define	IRQCONTROL	0x00
+#  define IRQCONTROL_RESELECT_CLEAR     BIT(0)
+#  define IRQCONTROL_PHASE_CHANGE_CLEAR BIT(1)
+#  define IRQCONTROL_TIMER_CLEAR        BIT(2)
+#  define IRQCONTROL_FIFO_CLEAR         BIT(3)
+#  define IRQCONTROL_ALLMASK            0xff
+#  define IRQCONTROL_ALLCLEAR           0x0f
+#  define IRQCONTROL_IRQDISABLE         0xf0
+
+#define	IRQSTATUS	0x00
+#  define IRQSTATUS_SCSI  BIT(0)
+#  define IRQSTATUS_TIMER BIT(2)
+#  define IRQSTATUS_FIFO  BIT(3)
+#  define IRQSTATUS_MASK  0x0f
+
+#define	IFSELECT	0x01
+#  define IF_IFSEL    BIT(0)
+#  define IF_REGSEL   BIT(2)
+
+#define	FIFOSTATUS	0x01
+#  define FIFOSTATUS_CHIP_REVISION 0x0f
+#  define FIFOSTATUS_CHIP_ID       0x70
+#  define FIFOSTATUS_FULL_EMPTY    0x80
+
+#define	INDEXREG	0x02
+#define	DATAREG		0x03
+#define	FIFODATA	0x04
+#define	FIFODATA1	0x05
+#define	FIFODATA2	0x06
+#define	FIFODATA3	0x07
+
+/* indexed register */
+#define EXTBUSCTRL	0x10
+
+#define CLOCKDIV	0x11
+#  define CLOCK_40M 0x02
+#  define CLOCK_20M 0x01
+
+#define TERMPWRCTRL	0x13
+#  define POWER_ON BIT(0)
+
+#define SCSIIRQMODE	0x15
+#  define SCSI_PHASE_CHANGE_EI BIT(0)
+#  define RESELECT_EI          BIT(4)
+#  define FIFO_IRQ_EI          BIT(5)
+#  define SCSI_RESET_IRQ_EI    BIT(6)
+
+#define IRQPHASESENCE	0x16
+#  define LATCHED_MSG      BIT(0)
+#  define LATCHED_IO       BIT(1)
+#  define LATCHED_CD       BIT(2)
+#  define LATCHED_BUS_FREE BIT(3)
+#  define PHASE_CHANGE_IRQ BIT(4)
+#  define RESELECT_IRQ     BIT(5)
+#  define FIFO_IRQ         BIT(6)
+#  define SCSI_RESET_IRQ   BIT(7)
+
+#define TIMERCOUNT	0x17
+
+#define SCSIBUSCTRL	0x18
+#  define SCSI_SEL         BIT(0)
+#  define SCSI_RST         BIT(1)
+#  define SCSI_DATAOUT_ENB BIT(2)
+#  define SCSI_ATN         BIT(3)
+#  define SCSI_ACK         BIT(4)
+#  define SCSI_BSY         BIT(5)
+#  define AUTODIRECTION    BIT(6)
+#  define ACKENB           BIT(7)
+
+#define SCSIBUSMON	0x19
+
+#define SETARBIT	0x1A
+#  define ARBIT_GO         BIT(0)
+#  define ARBIT_FLAG_CLEAR BIT(1)
+
+#define ARBITSTATUS	0x1A
+/*#  define ARBIT_GO        BIT(0)*/
+#  define ARBIT_WIN        BIT(1)
+#  define ARBIT_FAIL       BIT(2)
+#  define RESELECT_FLAG    BIT(3)
+
+#define PARITYCTRL	0x1B  /* W */
+#define PARITYSTATUS	0x1B  /* R */
+
+#define COMMANDCTRL	0x1C  /* W */
+#  define CLEAR_COMMAND_POINTER BIT(0)
+#  define AUTO_COMMAND_GO       BIT(1)
+
+#define RESELECTID	0x1C  /* R */
+#define COMMANDDATA	0x1D
+
+#define POINTERCLR	0x1E  /* W */
+#  define POINTER_CLEAR      BIT(0)
+#  define ACK_COUNTER_CLEAR  BIT(1)
+#  define REQ_COUNTER_CLEAR  BIT(2)
+#  define HOST_COUNTER_CLEAR BIT(3)
+#  define READ_SOURCE        0x30
+
+#define TRANSFERCOUNT	0x1E  /* R */
+
+#define TRANSFERMODE	0x20
+#   define MODE_MEM8   BIT(0)
+#   define MODE_MEM32  BIT(1)
+#   define MODE_ADR24  BIT(2)
+#   define MODE_ADR32  BIT(3)
+#   define MODE_IO8    BIT(4)
+#   define MODE_IO32   BIT(5)
+#   define TRANSFER_GO BIT(6)
+#   define BRAIND      BIT(7)
+
+#define SYNCREG		0x21
+#  define SYNCREG_OFFSET_MASK  0x0f
+#  define SYNCREG_PERIOD_MASK  0xf0
+#  define SYNCREG_PERIOD_SHIFT 4
+
+#define SCSIDATALATCH	0x22
+#define SCSIDATAIN	0x22
+#define SCSIDATAWITHACK	0x23
+#define SCAMCONTROL	0x24
+#define SCAMSTATUS	0x24
+#define SCAMDATA	0x25
+
+#define OTHERCONTROL	0x26
+#  define TPL_ROM_WRITE_EN BIT(0)
+#  define TPWR_OUT         BIT(1)
+#  define TPWR_SENSE       BIT(2)
+#  define RA8_CONTROL      BIT(3)
+
+#define ACKWIDTH	0x27
+#define CLRTESTPNT	0x28
+#define ACKCNTLD	0x29
+#define REQCNTLD	0x2A
+#define HSTCNTLD	0x2B
+#define CHECKSUM	0x2C
+
+/*
+ * Input status bit definitions.
+ */
+#define S_ATN		0x80	/**/
+#define S_SELECT	0x40	/**/
+#define S_REQUEST	0x20    /* Request line from SCSI bus*/
+#define S_ACK		0x10    /* Acknowlege line from SCSI bus*/
+#define S_BUSY		0x08    /* Busy line from SCSI bus*/
+#define S_CD		0x04    /* Command/Data line from SCSI bus*/
+#define S_IO		0x02    /* Input/Output line from SCSI bus*/
+#define S_MESSAGE	0x01    /* Message line from SCSI bus*/
+
+/*
+ * Useful Bus Monitor status combinations.
+ */
+#define BUSMON_SEL         S_SELECT
+#define BUSMON_BSY         S_BUSY
+#define BUSMON_REQ         S_REQUEST
+#define BUSMON_IO          S_IO
+#define BUSMON_ACK         S_ACK
+#define BUSMON_BUS_FREE    0
+#define BUSMON_COMMAND     ( S_BUSY | S_CD | S_REQUEST )
+#define BUSMON_MESSAGE_IN  ( S_BUSY | S_MESSAGE | S_IO | S_CD | S_REQUEST )
+#define BUSMON_MESSAGE_OUT ( S_BUSY | S_MESSAGE | S_CD | S_REQUEST )
+#define BUSMON_DATA_IN     ( S_BUSY | S_IO | S_REQUEST )
+#define BUSMON_DATA_OUT    ( S_BUSY | S_REQUEST )
+#define BUSMON_STATUS      ( S_BUSY | S_IO | S_CD | S_REQUEST )
+#define BUSMON_RESELECT    ( S_SELECT | S_IO )
+#define BUSMON_PHASE_MASK  ( S_SELECT | S_CD | S_MESSAGE | S_IO )
+
+#define BUSPHASE_COMMAND     ( BUSMON_COMMAND     & BUSMON_PHASE_MASK )
+#define BUSPHASE_MESSAGE_IN  ( BUSMON_MESSAGE_IN  & BUSMON_PHASE_MASK )
+#define BUSPHASE_MESSAGE_OUT ( BUSMON_MESSAGE_OUT & BUSMON_PHASE_MASK )
+#define BUSPHASE_DATA_IN     ( BUSMON_DATA_IN     & BUSMON_PHASE_MASK )
+#define BUSPHASE_DATA_OUT    ( BUSMON_DATA_OUT    & BUSMON_PHASE_MASK )
+#define BUSPHASE_STATUS      ( BUSMON_STATUS      & BUSMON_PHASE_MASK )
+#define BUSPHASE_SELECT      ( S_SELECT | S_IO )
+
+/* synchronous transfer negotiation data */
+typedef struct _sync_data {
+	unsigned int SyncNegotiation;
+#define SYNC_NOT_YET 0
+#define SYNC_OK      1
+#define SYNC_NG      2
+
+	unsigned int  SyncPeriod;
+	unsigned int  SyncOffset;
+	unsigned char SyncRegister;
+	unsigned char AckWidth;
+} sync_data;
+
+typedef struct _nsp_data {
+	unsigned int  BaseAddress;
+	unsigned int  NumAddress;
+	unsigned int  IrqNumber;
+
+	unsigned char ScsiClockDiv;
+
+	unsigned char TransferMode;
+
+	int           TimerCount;
+	int           SelectionTimeOut;
+	Scsi_Cmnd    *CurrentSC;
+
+	int           FifoCount;
+#if (KERNEL_VERSION(2,4,0) > LINUX_VERSION_CODE)
+	int           Residual;
+#define RESID nsp_data.Residual
+#else
+#define RESID SCpnt->resid
+#endif
+
+#define MSGBUF_SIZE 20
+	unsigned char MsgBuffer[MSGBUF_SIZE];
+	int MsgLen;
+
+#define N_TARGET 8
+#define N_LUN    8
+	sync_data     Sync[N_TARGET][N_LUN];
+} nsp_hw_data;
+
+
+static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt);
+static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time);
+
+static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt);
+
+static int nsp_fifo_count(Scsi_Cmnd *SCpnt);
+static void nsp_pio_read(Scsi_Cmnd *SCpnt);
+static int nsp_nexus(Scsi_Cmnd *SCpnt);
+
+#ifdef PCMCIA_DEBUG
+# ifdef DBG_SHOWCOMMAND
+static void show_command(Scsi_Cmnd *ptr);
+static void show_phase(Scsi_Cmnd *SCpnt);
+static void show_busphase(unsigned char stat);
+# endif /* DBG_SHOWCOMMAND */
+#endif
+
+/*
+ * SCSI phase
+ */
+enum _scsi_phase {
+	PH_UNDETERMINED,
+	PH_ARBSTART,
+	PH_SELSTART,
+	PH_SELECTED,
+	PH_COMMAND,
+	PH_DATA,
+	PH_STATUS,
+	PH_MSG_IN,
+	PH_MSG_OUT,
+	PH_DISCONNECT,
+	PH_RESELECT
+};
+
+enum _data_in_out {
+	IO_UNKNOWN,
+	IO_IN,
+	IO_OUT
+};
+
+
+#define NSP_SELTIMEOUT 200
+
+#endif  /*__nsp_cs__*/
diff -u --recursive --new-file v2.4.6/linux/drivers/scsi/pcmcia/nsp_debug.c linux/drivers/scsi/pcmcia/nsp_debug.c
--- v2.4.6/linux/drivers/scsi/pcmcia/nsp_debug.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/pcmcia/nsp_debug.c	Wed Jul  4 11:50:38 2001
@@ -0,0 +1,195 @@
+/*========================================================================
+    Debug routines for nsp_cs
+      By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
+
+    This software may be used and distributed according to the terms of
+    the GNU General Public License.
+=========================================================================*/
+
+/* $Id: nsp_debug.c,v 1.5 2001/02/08 08:08:58 elca Exp $ */
+
+/*
+ * Show the command data of a command
+ */
+static const char unknown[] = "UNKNOWN";
+
+static const char * group_0_commands[] = {
+/* 00-03 */ "Test Unit Ready", "Rezero Unit", unknown, "Request Sense",
+/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reasssign Blocks",
+/* 08-0d */ "Read (6)", unknown, "Write (6)", "Seek (6)", unknown, unknown,
+/* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", "Inquiry",  
+/* 13-16 */ unknown, "Recover Buffered Data", "Mode Select", "Reserve",
+/* 17-1b */ "Release", "Copy", "Erase", "Mode Sense", "Start/Stop Unit",
+/* 1c-1d */ "Receive Diagnostic", "Send Diagnostic", 
+/* 1e-1f */ "Prevent/Allow Medium Removal", unknown,
+};
+
+
+static const char *group_1_commands[] = {
+/* 20-22 */  unknown, unknown, unknown,
+/* 23-28 */ unknown, unknown, "Read Capacity", unknown, unknown, "Read (10)",
+/* 29-2d */ unknown, "Write (10)", "Seek (10)", unknown, unknown,
+/* 2e-31 */ "Write Verify","Verify", "Search High", "Search Equal",
+/* 32-34 */ "Search Low", "Set Limits", "Prefetch or Read Position", 
+/* 35-37 */ "Synchronize Cache","Lock/Unlock Cache", "Read Defect Data",
+/* 38-3c */ "Medium Scan", "Compare","Copy Verify", "Write Buffer", "Read Buffer",
+/* 3d-3f */ "Update Block", "Read Long",  "Write Long",
+};
+
+
+static const char *group_2_commands[] = {
+/* 40-41 */ "Change Definition", "Write Same", 
+/* 42-48 */ "Read Sub-Ch(cd)", "Read TOC", "Read Header(cd)", "Play Audio(cd)", unknown, "Play Audio MSF(cd)", "Play Audio Track/Index(cd)", 
+/* 49-4f */ "Play Track Relative(10)(cd)", unknown, "Pause/Resume(cd)", "Log Select", "Log Sense", unknown, unknown,
+/* 50-55 */ unknown, unknown, unknown, unknown, unknown, "Mode Select (10)",
+/* 56-5b */ unknown, unknown, unknown, unknown, "Mode Sense (10)", unknown,
+/* 5c-5f */ unknown, unknown, unknown,
+};
+
+#define group(opcode) (((opcode) >> 5) & 7)
+
+#define RESERVED_GROUP  0
+#define VENDOR_GROUP    1
+#define NOTEXT_GROUP    2
+
+static const char **commands[] = {
+    group_0_commands, group_1_commands, group_2_commands, 
+    (const char **) RESERVED_GROUP, (const char **) RESERVED_GROUP, 
+    (const char **) NOTEXT_GROUP, (const char **) VENDOR_GROUP, 
+    (const char **) VENDOR_GROUP
+};
+
+static const char reserved[] = "RESERVED";
+static const char vendor[] = "VENDOR SPECIFIC";
+
+static void print_opcodek(unsigned char opcode)
+{
+	const char **table = commands[ group(opcode) ];
+
+	switch ((unsigned long) table) {
+	case RESERVED_GROUP:
+		printk("%s[%02x] ", reserved, opcode); 
+		break;
+	case NOTEXT_GROUP:
+		printk("%s(notext)[%02x] ", unknown, opcode); 
+		break;
+	case VENDOR_GROUP:
+		printk("%s[%02x] ", vendor, opcode); 
+		break;
+	default:
+		if (table[opcode & 0x1f] != unknown)
+			printk("%s[%02x] ", table[opcode & 0x1f], opcode);
+		else
+			printk("%s[%02x] ", unknown, opcode);
+		break;
+	}
+}
+
+void print_commandk (unsigned char *command)
+{
+	int i,s;
+	printk(KERN_DEBUG);
+	print_opcodek(command[0]);
+	/*printk(KERN_DEBUG __FUNCTION__ " ");*/
+	for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) {
+		printk("%02x ", command[i]);
+	}
+	switch (COMMAND_SIZE(command[0])) {
+	case 6:
+		printk("LBA=%d len=%d",
+		       (((unsigned int)command[1] & 0x0f) << 16) |
+		       ( (unsigned int)command[2]         <<  8) |
+		       ( (unsigned int)command[3]              ),
+		       (unsigned int)command[4]
+			);
+		break;
+	case 10:
+		printk("LBA=%d len=%d",
+		       ((unsigned int)command[2] << 24) |
+		       ((unsigned int)command[3] << 16) |
+		       ((unsigned int)command[4] <<  8) |
+		       ((unsigned int)command[5]      ),
+		       ((unsigned int)command[7] <<  8) |
+		       ((unsigned int)command[8]      )
+		       );
+		break;
+	case 12:
+		printk("LBA=%d len=%d",
+		       ((unsigned int)command[2] << 24) |
+		       ((unsigned int)command[3] << 16) |
+		       ((unsigned int)command[4] <<  8) |
+		       ((unsigned int)command[5]      ),
+		       ((unsigned int)command[6] << 24) |
+		       ((unsigned int)command[7] << 16) |
+		       ((unsigned int)command[8] <<  8) |
+		       ((unsigned int)command[9]      )
+		       );
+		break;
+	default:
+		break;
+	}
+	printk("\n");
+}
+
+static void show_command(Scsi_Cmnd *ptr)
+{
+	print_commandk(ptr->cmnd);
+}
+
+static void show_phase(Scsi_Cmnd *SCpnt)
+{
+	int i = SCpnt->SCp.phase;
+
+	char *ph[] = {
+		"PH_UNDETERMINED",
+		"PH_ARBSTART",
+		"PH_SELSTART",
+		"PH_SELECTED",
+		"PH_COMMAND",
+		"PH_DATA",
+		"PH_STATUS",
+		"PH_MSG_IN",
+		"PH_MSG_OUT",
+		"PH_DISCONNECT",
+		"PH_RESELECT"
+	};
+
+	if ( i < PH_UNDETERMINED || i > PH_RESELECT ) {
+		printk(KERN_DEBUG "scsi phase: unknown(%d)\n", i);
+		return;
+	}
+
+	printk(KERN_DEBUG "scsi phase: %s\n", ph[i]);
+
+	return;
+}
+
+static void show_busphase(unsigned char stat)
+{
+	switch(stat) {
+	case BUSPHASE_COMMAND:
+		printk(KERN_DEBUG "BUSPHASE_COMMAND\n");
+		break;
+	case BUSPHASE_MESSAGE_IN:
+		printk(KERN_DEBUG "BUSPHASE_MESSAGE_IN\n");
+		break;
+	case BUSPHASE_MESSAGE_OUT:
+		printk(KERN_DEBUG "BUSPHASE_MESSAGE_OUT\n");
+		break;
+	case BUSPHASE_DATA_IN:
+		printk(KERN_DEBUG "BUSPHASE_DATA_IN\n");
+		break;
+	case BUSPHASE_DATA_OUT:
+		printk(KERN_DEBUG "BUSPHASE_DATA_OUT\n");
+		break;
+	case BUSPHASE_STATUS:
+		printk(KERN_DEBUG "BUSPHASE_STATUS\n");
+		break;
+	case BUSPHASE_SELECT:
+		printk(KERN_DEBUG "BUSPHASE_SELECT\n");
+		break;
+	default:
+		printk(KERN_DEBUG "BUSPHASE_other\n");
+		break;
+	}
+}
diff -u --recursive --new-file v2.4.6/linux/drivers/scsi/pcmcia/nsp_io.h linux/drivers/scsi/pcmcia/nsp_io.h
--- v2.4.6/linux/drivers/scsi/pcmcia/nsp_io.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/pcmcia/nsp_io.h	Wed Jul  4 11:50:38 2001
@@ -0,0 +1,176 @@
+/*
+  NinjaSCSI I/O funtions 
+      By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
+ 
+  This software may be used and distributed according to the terms of
+  the GNU General Public License.
+
+  */
+
+/* $Id: nsp_io.h,v 1.8 2001/01/30 05:16:02 elca Exp $ */
+
+#ifndef __NSP_IO_H__
+#define __NSP_IO_H__
+
+static inline          void nsp_write(unsigned int base,
+				      unsigned int index,
+				      unsigned char val);
+static inline unsigned char nsp_read(unsigned int base,
+				     unsigned int index);
+static inline          void nsp_index_write(unsigned int BaseAddr,
+					    unsigned int Register,
+					    unsigned char Value);
+static inline unsigned char nsp_index_read(unsigned int BaseAddr,
+					   unsigned int Register);
+
+/*******************************************************************
+ * Basic IO
+ */
+
+static inline void nsp_write(unsigned int  base,
+			     unsigned int  index,
+			     unsigned char val)
+{
+	outb(val, (base + index));
+}
+
+static inline unsigned char nsp_read(unsigned int base,
+				     unsigned int index)
+{
+	return inb(base + index);
+}
+
+
+/**********************************************************************
+ * Indexed IO
+ */
+static inline unsigned char nsp_index_read(unsigned int BaseAddr,
+					   unsigned int Register)
+{
+	outb(Register, BaseAddr + INDEXREG);
+	return inb(BaseAddr + DATAREG);
+}
+
+static inline void nsp_index_write(unsigned int  BaseAddr,
+				   unsigned int  Register,
+				   unsigned char Value)
+{
+	outb(Register, BaseAddr + INDEXREG);
+	outb(Value, BaseAddr + DATAREG);
+}
+
+/*********************************************************************
+ * fifo func
+ */
+
+/* read 8 bit FIFO */
+static inline void nsp_multi_read_1(unsigned int   BaseAddr,
+				    unsigned int   Register,
+				    void          *buf,
+				    unsigned long  count)
+{
+	insb(BaseAddr + Register, buf, count);
+}
+
+static inline void nsp_fifo8_read(unsigned int   base,
+				  void          *buf,
+				  unsigned long  count)
+{
+	//DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx\n", buf, count);
+	nsp_multi_read_1(base, FIFODATA, buf, count);
+}
+
+/*--------------------------------------------------------------*/
+
+/* read 16 bit FIFO */
+static inline void nsp_multi_read_2(unsigned int   BaseAddr,
+				    unsigned int   Register,
+				    void          *buf,
+				    unsigned long  count)
+{
+	insw(BaseAddr + Register, buf, count);
+}
+
+static inline void nsp_fifo16_read(unsigned int   base,
+				   void          *buf,
+				   unsigned long  count)
+{
+	//DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx*2\n", buf, count);
+	nsp_multi_read_2(base, FIFODATA, buf, count);
+}
+
+/*--------------------------------------------------------------*/
+
+/* read 32bit FIFO */
+static inline void nsp_multi_read_4(unsigned int   BaseAddr,
+				    unsigned int   Register,
+				    void          *buf,
+				    unsigned long  count)
+{
+	insl(BaseAddr + Register, buf, count);
+}
+
+static inline void nsp_fifo32_read(unsigned int   base,
+				   void          *buf,
+				   unsigned long  count)
+{
+	//DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx*4\n", buf, count);
+	nsp_multi_read_4(base, FIFODATA, buf, count);
+}
+
+/*----------------------------------------------------------*/
+
+/* write 8bit FIFO */
+static inline void nsp_multi_write_1(unsigned int   BaseAddr,
+				     unsigned int   Register,
+				     void          *buf,
+				     unsigned long  count)
+{
+	outsb(BaseAddr + Register, buf, count);
+}
+
+static inline void nsp_fifo8_write(unsigned int   base,
+				   void          *buf,
+				   unsigned long  count)
+{
+	nsp_multi_write_1(base, FIFODATA, buf, count);
+}
+
+/*---------------------------------------------------------*/
+
+/* write 16bit FIFO */
+static inline void nsp_multi_write_2(unsigned int   BaseAddr,
+				     unsigned int   Register,
+				     void          *buf,
+				     unsigned long  count)
+{
+	outsw(BaseAddr + Register, buf, count);
+}
+
+static inline void nsp_fifo16_write(unsigned int   base,
+				    void          *buf,
+				    unsigned long  count)
+{
+	nsp_multi_write_2(base, FIFODATA, buf, count);
+}
+
+/*---------------------------------------------------------*/
+
+/* write 32bit FIFO */
+static inline void nsp_multi_write_4(unsigned int   BaseAddr,
+				     unsigned int   Register,
+				     void          *buf,
+				     unsigned long  count)
+{
+	outsl(BaseAddr + Register, buf, count);
+}
+
+static inline void nsp_fifo32_write(unsigned int   base,
+				    void          *buf,
+				    unsigned long  count)
+{
+	nsp_multi_write_4(base, FIFODATA, buf, count);
+}
+
+#endif
+/* end */
diff -u --recursive --new-file v2.4.6/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
--- v2.4.6/linux/drivers/scsi/sr_ioctl.c	Fri Dec 29 14:07:22 2000
+++ linux/drivers/scsi/sr_ioctl.c	Wed Jul  4 11:50:39 2001
@@ -85,6 +85,10 @@
 
 	SDev = scsi_CDs[target].device;
 	SRpnt = scsi_allocate_request(scsi_CDs[target].device);
+        if (!SRpnt) {
+                printk("Unable to allocate SCSI request in sr_do_ioctl");
+                return -ENOMEM;
+        }
 	SRpnt->sr_data_direction = readwrite;
 
 	/* use ISA DMA buffer if necessary */
diff -u --recursive --new-file v2.4.6/linux/drivers/scsi/ultrastor.c linux/drivers/scsi/ultrastor.c
--- v2.4.6/linux/drivers/scsi/ultrastor.c	Sat Feb  3 11:32:54 2001
+++ linux/drivers/scsi/ultrastor.c	Wed Jul  4 11:50:39 2001
@@ -259,7 +259,7 @@
 } config = {0};
 
 /* Set this to 1 to reset the SCSI bus on error.  */
-int ultrastor_bus_reset = 0;
+int ultrastor_bus_reset;
 
 
 /* Allowed BIOS base addresses (NULL indicates reserved) */
diff -u --recursive --new-file v2.4.6/linux/drivers/sound/Config.in linux/drivers/sound/Config.in
--- v2.4.6/linux/drivers/sound/Config.in	Tue Jul  3 17:08:21 2001
+++ linux/drivers/sound/Config.in	Wed Jul  4 11:50:38 2001
@@ -6,12 +6,27 @@
 
 # Prompt user for primary drivers.
 
-dep_tristate '  C-Media PCI (CMI8338/8378)' CONFIG_SOUND_CMPCI $CONFIG_SOUND $CONFIG_PCI
+dep_tristate '  C-Media PCI (CMI8338/8738)' CONFIG_SOUND_CMPCI $CONFIG_SOUND $CONFIG_PCI
 if [ "$CONFIG_SOUND_CMPCI" = "y" -o "$CONFIG_SOUND_CMPCI" = "m" ]; then
-    bool '    Enable S/PDIF loop for CMI8738' CONFIG_SOUND_CMPCI_SPDIFLOOP
-    bool '    Enable 4 channel mode for CMI8738' CONFIG_SOUND_CMPCI_4CH
-    if [ "$CONFIG_SOUND_CMPCI_4CH" = "y" ]; then
-        bool '    Separate rear out jack' CONFIG_SOUND_CMPCI_REAR
+    bool '    Enable legacy FM' CONFIG_SOUND_CMPCI_FM
+    if [ "$CONFIG_SOUND_CMPCI_FM" = "y" ]; then
+	define_hex CONFIG_SOUND_CMPCI_FMIO 388
+        hex '    FM I/O 388, 3C8, 3E0, 3E8' CONFIG_SOUND_CMPCI_FMIO 388
+    fi
+    bool '    Enable legacy MPU-401' CONFIG_SOUND_CMPCI_MIDI
+    if [ "$CONFIG_SOUND_CMPCI_MIDI" = "y" ]; then
+        hex '    MPU-401 I/O 330, 320, 310, 300' CONFIG_SOUND_CMPCI_MPUIO 330
+    fi
+    bool '    Enable joystick' CONFIG_SOUND_CMPCI_JOYSTICK
+    bool '    Support CMI8738 based audio cards' CONFIG_SOUND_CMPCI_CM8738
+    if [ "$CONFIG_SOUND_CMPCI_CM8738" = "y" ]; then
+	bool '      Inverse S/PDIF in for CMI8738' CONFIG_SOUND_CMPCI_SPDIFINVERSE
+	bool '      Enable S/PDIF loop for CMI8738' CONFIG_SOUND_CMPCI_SPDIFLOOP
+	int  '      Number of speakers 2, 4, 5, 6' CONFIG_SOUND_CMPCI_SPEAKERS 2
+	if [ "$CONFIG_SOUND_CMPCI_SPEAKERS" != "2" ]; then
+	    bool '        Use Line-in as Read-out' CONFIG_SOUND_CMPCI_LINE_REAR
+	    bool '        Use Line-in as Bass' CONFIG_SOUND_CMPCI_LINE_BASS
+	fi
     fi
 fi
 dep_tristate '  Creative SBLive! (EMU10K1)' CONFIG_SOUND_EMU10K1 $CONFIG_SOUND $CONFIG_PCI
diff -u --recursive --new-file v2.4.6/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c
--- v2.4.6/linux/drivers/sound/ad1848.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/sound/ad1848.c	Wed Jul  4 11:50:39 2001
@@ -106,11 +106,11 @@
 ad1848_port_info;
 
 static struct address_info cfg;
-static int nr_ad1848_devs = 0;
+static int nr_ad1848_devs;
 
-int deskpro_xl = 0;
-int deskpro_m = 0;
-int soundpro = 0;
+int deskpro_xl;
+int deskpro_m;
+int soundpro;
 
 static volatile signed char irq2dev[17] = {
 	-1, -1, -1, -1, -1, -1, -1, -1,
@@ -121,7 +121,7 @@
 static int timer_installed = -1;
 #endif
 
-static int loaded = 0;
+static int loaded;
 
 static int ad_format_mask[10 /*devc->model */ ] =
 {
diff -u --recursive --new-file v2.4.6/linux/drivers/sound/dev_table.h linux/drivers/sound/dev_table.h
--- v2.4.6/linux/drivers/sound/dev_table.h	Sun Feb  4 10:05:29 2001
+++ linux/drivers/sound/dev_table.h	Wed Jul  4 11:50:39 2001
@@ -350,14 +350,14 @@
 };
 
 #ifdef _DEV_TABLE_C_   
-struct audio_operations *audio_devs[MAX_AUDIO_DEV] = {NULL};
-int num_audiodevs = 0;
-struct mixer_operations *mixer_devs[MAX_MIXER_DEV] = {NULL};
-int num_mixers = 0;
-struct synth_operations *synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV] = {NULL};
-int num_synths = 0;
-struct midi_operations *midi_devs[MAX_MIDI_DEV] = {NULL};
-int num_midis = 0;
+struct audio_operations *audio_devs[MAX_AUDIO_DEV];
+int num_audiodevs;
+struct mixer_operations *mixer_devs[MAX_MIXER_DEV];
+int num_mixers;
+struct synth_operations *synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV];
+int num_synths;
+struct midi_operations *midi_devs[MAX_MIDI_DEV];
+int num_midis;
 
 extern struct sound_timer_operations default_sound_timer;
 struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] = {
diff -u --recursive --new-file v2.4.6/linux/drivers/sound/maestro.c linux/drivers/sound/maestro.c
--- v2.4.6/linux/drivers/sound/maestro.c	Fri Mar  2 11:12:11 2001
+++ linux/drivers/sound/maestro.c	Wed Jul  4 11:50:39 2001
@@ -115,6 +115,12 @@
  *	themselves, but we'll see.  
  *	
  * History
+ *  v0.15 - May 21 2001 - Marcus Meissner <mm@caldera.de>
+ *      Ported to Linux 2.4 PCI API. Some clean ups, global devs list
+ *      removed (now using pci device driver data).
+ *      PM needs to be polished still. Bumped version.
+ *  (still kind of v0.14) May 13 2001 - Ben Pfaff <pfaffben@msu.edu>
+ *      Add support for 978 docking and basic hardware volume control
  *  (still kind of v0.14) Nov 23 - Alan Cox <alan@redhat.com>
  *	Add clocking= for people with seriously warped hardware
  *  (still v0.14) Nov 10 2000 - Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
@@ -189,7 +195,7 @@
  *	fix bob frequency
  *	endianness
  *	do smart things with ac97 2.0 bits.
- *	docking and dual codecs and 978?
+ *	dual codecs
  *	leave 54->61 open
  *
  *	it also would be fun to have a mode that would not use pci dma at all
@@ -204,28 +210,6 @@
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
 #include <linux/wrapper.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-
- #define DECLARE_WAITQUEUE(QUEUE,INIT) struct wait_queue QUEUE = {INIT, NULL}
- #define wait_queue_head_t struct wait_queue *
- #define SILLY_PCI_BASE_ADDRESS(PCIDEV) (PCIDEV->base_address[0] & PCI_BASE_ADDRESS_IO_MASK)
- #define SILLY_INIT_SEM(SEM) SEM=MUTEX;
- #define init_waitqueue_head init_waitqueue
- #define SILLY_MAKE_INIT(FUNC) __initfunc(FUNC)
- #define SILLY_OFFSET(VMA) ((VMA)->vm_offset)
-
-
-#else
-
- #define SILLY_PCI_BASE_ADDRESS(PCIDEV) (PCIDEV->resource[0].start)
- #define SILLY_INIT_SEM(SEM) init_MUTEX(&SEM)
- #define SILLY_MAKE_INIT(FUNC) __init FUNC
- #define SILLY_OFFSET(VMA) ((VMA)->vm_pgoff)
-
-
-#endif
-
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/ioport.h>
@@ -249,6 +233,8 @@
 
 #include "maestro.h"
 
+static struct pci_driver maestro_pci_driver;
+
 /* --------------------------------------------------------------------- */
 
 #define M_DEBUG 1
@@ -269,8 +255,17 @@
 	
 static int clocking=48000;
 
+MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Alan Cox <alan@redhat.com>");
+MODULE_DESCRIPTION("ESS Maestro Driver");
+#ifdef M_DEBUG
+MODULE_PARM(debug,"i");
+#endif
+MODULE_PARM(dsps_order,"i");
+MODULE_PARM(use_pm,"i");
+MODULE_PARM(clocking, "i");
+
 /* --------------------------------------------------------------------- */
-#define DRIVER_VERSION "0.14"
+#define DRIVER_VERSION "0.15"
 
 #ifndef PCI_VENDOR_ESS
 #define PCI_VENDOR_ESS			0x125D
@@ -352,6 +347,11 @@
 	[ACPI_D3] = ACPI_NONE
 };
 
+static char version[] __devinitdata =
+KERN_INFO "maestro: version " DRIVER_VERSION " time " __TIME__ " " __DATE__ "\n";
+
+
+
 static const unsigned sample_size[] = { 1, 2, 2, 4 };
 static const unsigned sample_shift[] = { 0, 1, 1, 2 };
 
@@ -483,8 +483,12 @@
 
 	int bob_freq;
 	char dsps_open;
+
+	int dock_mute_vol;
 };
 
+static void set_mixer(struct ess_card *card,unsigned int mixer, unsigned int val );
+
 static unsigned 
 ld2(unsigned int x)
 {
@@ -516,8 +520,6 @@
 
 static void check_suspend(struct ess_card *card);
 
-static struct ess_card *devs = NULL;
-
 /* --------------------------------------------------------------------- */
 
 
@@ -983,6 +985,17 @@
 		outw(inw(ioaddr+0x68) | 0x600, ioaddr + 0x68);
 		outw(0x0209, ioaddr + 0x60);
 	}
+
+	/* Turn on the 978 docking chip.
+	   First frob the "master output enable" bit,
+	   then set most of the playback volume control registers to max. */
+	outb(inb(ioaddr+0xc0)|(1<<5), ioaddr+0xc0);
+	outb(0xff, ioaddr+0xc3);
+	outb(0xff, ioaddr+0xc4);
+	outb(0xff, ioaddr+0xc6);
+	outb(0xff, ioaddr+0xc8);
+	outb(0x3f, ioaddr+0xcf);
+	outb(0x3f, ioaddr+0xd0);
 }
 /*
  *	Indirect register access. Not all registers are readable so we
@@ -1895,19 +1908,52 @@
 	outw(inw(c->iobase+4)&1, c->iobase+4);
 
 /*	M_printk("maestro int: %x\n",event);*/
-
 	if(event&(1<<6))
 	{
-		/* XXX if we have a hw volume control int enable
-			all the ints?  doesn't make sense.. */
-		event = inw(c->iobase+0x18);
-		outb(0xFF, c->iobase+0x1A);
-	}
-	else
-	{
-		/* else ack 'em all, i imagine */
-		outb(0xFF, c->iobase+0x1A);
+		int x;
+		enum {UP_EVT, DOWN_EVT, MUTE_EVT} vol_evt;
+		int volume;
+
+		/* Figure out which volume control button was pushed,
+		   based on differences from the default register
+		   values. */
+		x = inb(c->iobase+0x1c);
+		if (x&1) vol_evt = MUTE_EVT;
+		else if (((x>>1)&7) > 4) vol_evt = UP_EVT;
+		else vol_evt = DOWN_EVT;
+
+		/* Reset the volume control registers. */
+		outb(0x88, c->iobase+0x1c);
+		outb(0x88, c->iobase+0x1d);
+		outb(0x88, c->iobase+0x1e);
+		outb(0x88, c->iobase+0x1f);
+
+		/* Deal with the button press in a hammer-handed
+		   manner by adjusting the master mixer volume. */
+		volume = c->mix.mixer_state[0] & 0xff;
+		if (vol_evt == UP_EVT) {
+			volume += 10;
+			if (volume > 100)
+				volume = 100;
+		}
+		else if (vol_evt == DOWN_EVT) {
+			volume -= 10;
+			if (volume < 0)
+				volume = 0;
+		} else {
+			/* vol_evt == MUTE_EVT */
+			if (volume == 0)
+				volume = c->dock_mute_vol;
+			else {
+				c->dock_mute_vol = volume;
+				volume = 0;
+			}
+		}
+		set_mixer (c, 0, (volume << 8) | volume);
 	}
+
+	/* Ack all the interrupts. */
+	outb(0xFF, c->iobase+0x1A);
 		
 	/*
 	 *	Update the pointers for all APU's we are running.
@@ -2083,17 +2129,25 @@
 }
 
 /* --------------------------------------------------------------------- */
-
 static int ess_open_mixdev(struct inode *inode, struct file *file)
 {
 	int minor = MINOR(inode->i_rdev);
-	struct ess_card *card = devs;
-
-	while (card && card->dev_mixer != minor)
-		card = card->next;
+	struct ess_card *card = NULL;
+	struct pci_dev *pdev;
+	struct pci_driver *drvr;
+
+	pci_for_each_dev(pdev) {
+		drvr = pci_dev_driver (pdev);
+		if (drvr == &maestro_pci_driver) {
+			card = (struct ess_card*)pci_get_drvdata (pdev);
+			if (!card)
+				continue;
+			if (card->dev_mixer == minor)
+				break;
+		}
+	}
 	if (!card)
 		return -ENODEV;
-
 	file->private_data = card;
 	return 0;
 }
@@ -2455,7 +2509,7 @@
 #endif
 		goto out;
 	ret = -EINVAL;
-	if (SILLY_OFFSET(vma) != 0)
+	if (vma->vm_pgoff != 0)
 		goto out;
 	size = vma->vm_end - vma->vm_start;
 	if (size > (PAGE_SIZE << db->buforder))
@@ -2919,33 +2973,40 @@
 ess_open(struct inode *inode, struct file *file)
 {
 	int minor = MINOR(inode->i_rdev);
-	struct ess_card *c = devs;
-	struct ess_state *s = NULL, *sp;
-	int i;
+	struct ess_state *s = NULL;
 	unsigned char fmtm = ~0, fmts = 0;
-
+	struct pci_dev *pdev;
 	/*
 	 *	Scan the cards and find the channel. We only
 	 *	do this at open time so it is ok
 	 */
-	 
-	while (c!=NULL)
-	{
-		for(i=0;i<NR_DSPS;i++)
-		{
-			sp=&c->channels[i];
-			if(sp->dev_audio < 0)
-				continue;
-			if((sp->dev_audio ^ minor) & ~0xf)
+
+	pci_for_each_dev(pdev) {
+		struct ess_card *c;
+		struct pci_driver *drvr;
+
+		drvr = pci_dev_driver (pdev);
+		if (drvr == &maestro_pci_driver) {
+			int i;
+			struct ess_state *sp;
+
+			c = (struct ess_card*)pci_get_drvdata (pdev);
+			if (!c)
 				continue;
-			s=sp;
+			for(i=0;i<NR_DSPS;i++)
+			{
+				sp=&c->channels[i];
+				if(sp->dev_audio < 0)
+					continue;
+				if((sp->dev_audio ^ minor) & ~0xf)
+					continue;
+				s=sp;
+			}
 		}
-		c=c->next;
 	}
-		
 	if (!s)
 		return -ENODEV;
-		
+
        	VALIDATE_STATE(s);
 	file->private_data = s;
 	/* wait for device to become free */
@@ -3087,8 +3148,8 @@
 	/* XXX how do we know which to use? */
 	w&=~(1<<14);		/* External clock */
 	
-	w&=~(1<<7);		/* HWV off */
-	w&=~(1<<6);		/* Debounce off */
+	w|= (1<<7);		/* Hardware volume control on */
+	w|= (1<<6);		/* Debounce off: easier to push the HWV buttons. */
 	w&=~(1<<5);		/* GPIO 4:5 */
 	w|= (1<<4);             /* Disconnect from the CHI.  Enabling this made a dell 7500 work. */
 	w&=~(1<<2);		/* MIDI fix off (undoc) */
@@ -3106,6 +3167,12 @@
 	 
 	pci_write_config_word(pcidev, 0x40, w);
 
+	/* Set up 978 docking control chip. */
+	pci_read_config_word(pcidev, 0x58, &w);
+	w|=1<<2;	/* Enable 978. */
+	w|=1<<3;	/* Turn on 978 hardware volume control. */
+	w&=~(1<<11);	/* Turn on 978 mixer volume control. */
+	pci_write_config_word(pcidev, 0x58, w);
 	
 	sound_reset(iobase);
 
@@ -3170,7 +3237,7 @@
 	outw(w, iobase+0x18);
 
 	w=inw(iobase+0x18);
-	w&=~(1<<6);		/* Harpo off */
+	w&=~(1<<6);		/* Hardware volume control interrupt off... for now. */
 	outw(w, iobase+0x18);
 	
 	w=inw(iobase+0x18);
@@ -3193,6 +3260,13 @@
 	w|=(1<<0);		/* SB IRQ on */
 	outw(w, iobase+0x18);
 
+	/* Set hardware volume control registers to midpoints.
+	   We can tell which button was pushed based on how they change. */
+	outb(0x88, iobase+0x1c);
+	outb(0x88, iobase+0x1d);
+	outb(0x88, iobase+0x1e);
+	outb(0x88, iobase+0x1f);
+
 	/* it appears some maestros (dell 7500) only work if these are set,
 		regardless of wether we use the assp or not. */
 
@@ -3308,32 +3382,44 @@
 }
 
 static int __init
-maestro_install(struct pci_dev *pcidev, int card_type)
+maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid)
 {
+	int card_type = pdid->driver_data;
 	u32 n;
 	int iobase;
-	int i;
+	int i, ret;
 	struct ess_card *card;
 	struct ess_state *ess;
 	struct pm_dev *pmdev;
 	int num = 0;
 
+/* when built into the kernel, we only print version if device is found */
+#ifndef MODULE
+	static int printed_version;
+	if (!printed_version++)
+		printk(version);
+#endif
+
 	/* don't pick up weird modem maestros */
 	if(((pcidev->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO)
-		return 0;
+		return -ENODEV;
+
+
+	if ((ret=pci_enable_device(pcidev)))
+		return ret;
 			
-	iobase = SILLY_PCI_BASE_ADDRESS(pcidev); 
+	iobase = pci_resource_start(pcidev,0);
+	if (!iobase || !(pci_resource_flags(pcidev, 0 ) & IORESOURCE_IO))
+		return -ENODEV;
+
+	if(pcidev->irq == 0)
+		return -ENODEV;
 
 	/* stake our claim on the iospace */
 	if( request_region(iobase, 256, card_names[card_type]) == NULL )
 	{
 		printk(KERN_WARNING "maestro: can't allocate 256 bytes I/O at 0x%4.4x\n", iobase);
-		return 0;
-	}
-
-	/* this was tripping up some machines */
-	if(pcidev->irq == 0) {
-		printk(KERN_WARNING "maestro: pci subsystem reports irq 0, this might not be correct.\n");
+		return -EBUSY;
 	}
 
 	/* just to be sure */
@@ -3343,7 +3429,8 @@
 	if(card == NULL)
 	{
 		printk(KERN_WARNING "maestro: out of memory\n");
-		return 0;
+		release_region(iobase, 256);
+		return -ENOMEM;
 	}
 	
 	memset(card, 0, sizeof(*card));
@@ -3354,18 +3441,14 @@
 	if (pmdev)
 		pmdev->data = card;
 
-	if (register_reboot_notifier(&maestro_nb)) {
-		printk(KERN_WARNING "maestro: reboot notifier registration failed; may not reboot properly.\n");
-	}
-
 	card->iobase = iobase;
 	card->card_type = card_type;
 	card->irq = pcidev->irq;
-	card->next = devs;
 	card->magic = ESS_CARD_MAGIC;
 	spin_lock_init(&card->lock);
 	init_waitqueue_head(&card->suspend_queue);
-	devs = card;
+
+	card->dock_mute_vol = 50;
 	
 	/* init our groups of 6 apus */
 	for(i=0;i<NR_DSPS;i++)
@@ -3379,7 +3462,7 @@
 		init_waitqueue_head(&s->dma_dac.wait);
 		init_waitqueue_head(&s->open_wait);
 		spin_lock_init(&s->lock);
-		SILLY_INIT_SEM(s->open_sem);
+		init_MUTEX(&s->open_sem);
 		s->magic = ESS_STATE_MAGIC;
 		
 		s->apu[0] = 6*i;
@@ -3407,19 +3490,6 @@
 	
 	ess = &card->channels[0];
 
-	if (pci_enable_device(pcidev)) {
-		printk (KERN_ERR "maestro: pci_enable_device() failed\n");
-		for (i = 0; i < NR_DSPS; i++) {
-			struct ess_state *s = &card->channels[i];
-			if (s->dev_audio != -1)
-				unregister_sound_dsp(s->dev_audio);
-		}
-		release_region(card->iobase, 256);
-		unregister_reboot_notifier(&maestro_nb);
-		kfree(card);
-		return 0;
-	}
-
 	/*
 	 *	Ok card ready. Begin setup proper
 	 */
@@ -3469,7 +3539,7 @@
 		mixer_push_state(card);
 	}
 	
-	if(request_irq(card->irq, ess_interrupt, SA_SHIRQ, card_names[card_type], card))
+	if((ret=request_irq(card->irq, ess_interrupt, SA_SHIRQ, card_names[card_type], card)))
 	{
 		printk(KERN_ERR "maestro: unable to allocate irq %d,\n", card->irq);
 		unregister_sound_mixer(card->dev_mixer);
@@ -3482,26 +3552,69 @@
 		release_region(card->iobase, 256);		
 		unregister_reboot_notifier(&maestro_nb);
 		kfree(card);
-		return 0;
+		return ret;
 	}
+
+	/* Turn on hardware volume control interrupt.
+	   This has to come after we grab the IRQ above,
+	   or a crash will result on installation if a button has been pressed,
+	   because in that case we'll get an immediate interrupt. */
+	n = inw(iobase+0x18);
+	n|=(1<<6);
+	outw(n, iobase+0x18);
+
+	pci_set_drvdata(pcidev,card);
 	/* now go to sleep 'till something interesting happens */
 	maestro_power(card,ACPI_D2);
 
 	printk(KERN_INFO "maestro: %d channels configured.\n", num);
-	return 1; 
+	return 0;
 }
 
-int __init init_maestro(void)
-{
-	struct pci_dev *pcidev = NULL;
-	int foundone = 0;
-
-	if (!pci_present())   /* No PCI bus in this machine! */
-		return -ENODEV;
-	printk(KERN_INFO "maestro: version " DRIVER_VERSION " time " __TIME__ " " __DATE__ "\n");
+static void maestro_remove(struct pci_dev *pcidev) {
+	struct ess_card *card = pci_get_drvdata(pcidev);
+	int i;
+	
+	/* XXX maybe should force stop bob, but should be all 
+		stopped by _release by now */
+	free_irq(card->irq, card);
+	unregister_sound_mixer(card->dev_mixer);
+	for(i=0;i<NR_DSPS;i++)
+	{
+		struct ess_state *ess = &card->channels[i];
+		if(ess->dev_audio != -1)
+			unregister_sound_dsp(ess->dev_audio);
+	}
+	/* Goodbye, Mr. Bond. */
+	maestro_power(card,ACPI_D3);
+ 	release_region(card->iobase, 256);
+	kfree(card);
+	pci_set_drvdata(pcidev,NULL);
+}
+
+static struct pci_device_id maestro_pci_tbl[] __devinitdata = {
+	{PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO2},
+	{PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1978, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO2E},
+	{PCI_VENDOR_ESS_OLD, PCI_DEVICE_ID_ESS_ESS0100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO},
+	{0,}
+};
+MODULE_DEVICE_TABLE(pci, maestro_pci_tbl);
 
-	pcidev = NULL;
+static struct pci_driver maestro_pci_driver = {
+	name:"maestro",
+	id_table:maestro_pci_tbl,
+	probe:maestro_probe,
+	remove:maestro_remove,
+};
 
+int __init init_maestro(void)
+{
+	pci_module_init(&maestro_pci_driver);
+	if (register_reboot_notifier(&maestro_nb))
+		printk(KERN_WARNING "maestro: reboot notifier registration failed; may not reboot properly.\n");
+#ifdef MODULE
+	printk(version);
+#endif
 	if (dsps_order < 0)   {
 		dsps_order = 1;
 		printk(KERN_WARNING "maestro: clipping dsps_order to %d\n",dsps_order);
@@ -3510,97 +3623,29 @@
 		dsps_order = MAX_DSP_ORDER;
 		printk(KERN_WARNING "maestro: clipping dsps_order to %d\n",dsps_order);
 	}
-
-	/*
-	 *	Find the ESS Maestro 2.
-	 */
-
-	while( (pcidev = pci_find_device(PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1968, pcidev))!=NULL ) {
-		if (maestro_install(pcidev, TYPE_MAESTRO2))
-			foundone=1;
-	}
-
-	/*
-	 *	Find the ESS Maestro 2E
-	 */
-
-	while( (pcidev = pci_find_device(PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1978, pcidev))!=NULL) {
-		if (maestro_install(pcidev, TYPE_MAESTRO2E))
-			foundone=1;
-	}
-
-	/*
-	 *	ESS Maestro 1
-	 */
-
-	while((pcidev = pci_find_device(PCI_VENDOR_ESS_OLD, PCI_DEVICE_ID_ESS_ESS0100, pcidev))!=NULL) {
-		if (maestro_install(pcidev, TYPE_MAESTRO))
-			foundone=1;
-	}
-	if( ! foundone ) {
-		printk("maestro: no devices found.\n");
-		return -ENODEV;
-	}
 	return 0;
 }
 
-static void nuke_maestros(void)
-{
-	struct ess_card *card;
-
-	/* we do these unconditionally, which is probably wrong */
-	pm_unregister_all(maestro_pm_callback);
-	unregister_reboot_notifier(&maestro_nb);
-
-	while ((card = devs)) {
-		int i;
-		devs = devs->next;
-	
-		/* XXX maybe should force stop bob, but should be all 
-			stopped by _release by now */
-		free_irq(card->irq, card);
-		unregister_sound_mixer(card->dev_mixer);
-		for(i=0;i<NR_DSPS;i++)
-		{
-			struct ess_state *ess = &card->channels[i];
-			if(ess->dev_audio != -1)
-				unregister_sound_dsp(ess->dev_audio);
-		}
-		/* Goodbye, Mr. Bond. */
-		maestro_power(card,ACPI_D3);
-		release_region(card->iobase, 256);
-		kfree(card);
-	}
-	devs = NULL;
-}
-
 static int maestro_notifier(struct notifier_block *nb, unsigned long event, void *buf)
 {
 	/* this notifier is called when the kernel is really shut down. */
 	M_printk("maestro: shutting down\n");
-	nuke_maestros();
+	/* this will remove all card instances too */
+	pci_unregister_driver(&maestro_pci_driver);
+	/* XXX dunno about power management */
 	return NOTIFY_OK;
 }
 
 /* --------------------------------------------------------------------- */
 
-#ifdef MODULE
-MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Alan Cox <alan@redhat.com>");
-MODULE_DESCRIPTION("ESS Maestro Driver");
-#ifdef M_DEBUG
-MODULE_PARM(debug,"i");
-#endif
-MODULE_PARM(dsps_order,"i");
-MODULE_PARM(use_pm,"i");
-MODULE_PARM(clocking, "i");
 
-void cleanup_module(void) {
+void cleanup_maestro(void) {
 	M_printk("maestro: unloading\n");
-	nuke_maestros();
+	pci_unregister_driver(&maestro_pci_driver);
+	pm_unregister_all(maestro_pm_callback);
+	unregister_reboot_notifier(&maestro_nb);
 }
 
-#endif
-
 /* --------------------------------------------------------------------- */
 
 void
@@ -3759,3 +3804,4 @@
 }
 
 module_init(init_maestro);
+module_exit(cleanup_maestro);
diff -u --recursive --new-file v2.4.6/linux/drivers/sound/nm256_audio.c linux/drivers/sound/nm256_audio.c
--- v2.4.6/linux/drivers/sound/nm256_audio.c	Tue May  1 16:05:00 2001
+++ linux/drivers/sound/nm256_audio.c	Wed Jul  4 11:50:39 2001
@@ -29,8 +29,8 @@
 #include "nm256.h"
 #include "nm256_coeff.h"
 
-int nm256_debug = 0;
-static int force_load = 0;
+int nm256_debug;
+static int force_load;
 
 /* 
  * The size of the playback reserve.  When the playback buffer has less
@@ -131,8 +131,8 @@
     return NULL;
 }
 
-static int usecache = 0;
-static int buffertop = 0;
+static int usecache;
+static int buffertop;
 
 /* Check to see if we're using the bank of cached coefficients. */
 int
diff -u --recursive --new-file v2.4.6/linux/drivers/sound/sb_common.c linux/drivers/sound/sb_common.c
--- v2.4.6/linux/drivers/sound/sb_common.c	Wed Apr 18 11:49:12 2001
+++ linux/drivers/sound/sb_common.c	Wed Jul  4 11:50:39 2001
@@ -45,10 +45,10 @@
  * global module flag
  */
 
-int sb_be_quiet = 0;
+int sb_be_quiet;
 
-static sb_devc *detected_devc = NULL;	/* For communication from probe to init */
-static sb_devc *last_devc = NULL;	/* For MPU401 initialization */
+static sb_devc *detected_devc;	/* For communication from probe to init */
+static sb_devc *last_devc;	/* For MPU401 initialization */
 
 static unsigned char jazz_irq_bits[] = {
 	0, 0, 2, 3, 0, 1, 0, 4, 0, 2, 5, 0, 0, 0, 0, 6
@@ -58,14 +58,14 @@
 	0, 1, 0, 2, 0, 3, 0, 4
 };
 
-void *smw_free = NULL;
+void *smw_free;
 
 /*
  * Jazz16 chipset specific control variables
  */
 
-static int jazz16_base = 0;		/* Not detected */
-static unsigned char jazz16_bits = 0;	/* I/O relocation bits */
+static int jazz16_base;			/* Not detected */
+static unsigned char jazz16_bits;	/* I/O relocation bits */
 static spinlock_t jazz16_lock = SPIN_LOCK_UNLOCKED;
 
 /*
@@ -75,12 +75,12 @@
 #ifdef SMW_MIDI0001_INCLUDED
 #include "smw-midi0001.h"
 #else
-static unsigned char *smw_ucode = NULL;
-static int      smw_ucodeLen = 0;
+static unsigned char *smw_ucode;
+static int      smw_ucodeLen;
 
 #endif
 
-sb_devc *last_sb = NULL;		/* Last sb loaded */
+sb_devc *last_sb;		/* Last sb loaded */
 
 int sb_dsp_command(sb_devc * devc, unsigned char val)
 {
diff -u --recursive --new-file v2.4.6/linux/drivers/sound/ymfpci.c linux/drivers/sound/ymfpci.c
--- v2.4.6/linux/drivers/sound/ymfpci.c	Tue Jul  3 17:08:21 2001
+++ linux/drivers/sound/ymfpci.c	Wed Jul  4 11:50:39 2001
@@ -23,14 +23,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * TODO:
- *  - Use P44Slot for 44.1 playback.
+ *  - Use P44Slot for 44.1 playback (beware of idle buzzing in P44Slot).
  *  - 96KHz playback for DVD - use pitch of 2.0.
- *  - uLaw for Sun apps.
- *     : Alan says firmly "no software format conversion in kernel".
  *  - Retain DMA buffer on close, do not wait the end of frame.
- *  - Cleanup
- *      ? underused structure members
- *      - Remove remaining P3 tags (debug messages).
  *  - Resolve XXX tagged questions.
  *  - Cannot play 5133Hz.
  *  - 2001/01/07 Consider if we can remove voice_lock, like so:
@@ -66,14 +61,28 @@
 #endif
 #include "ymfpci.h"
 
-static int ymf_playback_trigger(ymfpci_t *codec, struct ymf_pcm *ypcm, int cmd);
+/*
+ * I do not believe in debug levels as I never can guess what
+ * part of the code is going to be problematic in the future.
+ * Don't forget to run your klogd with -c 8.
+ */
+/* #define YMFDBG(fmt, arg...)  do{ printk(KERN_DEBUG fmt, ##arg); }while(0) */
+#define YMFDBGW(fmt, arg...)  /* */
+#define YMFDBGI(fmt, arg...)  /* */
+
+static int ymf_playback_trigger(ymfpci_t *unit, struct ymf_pcm *ypcm, int cmd);
 static void ymf_capture_trigger(ymfpci_t *unit, struct ymf_pcm *ypcm, int cmd);
-static void ymfpci_voice_free(ymfpci_t *codec, ymfpci_voice_t *pvoice);
+static void ymfpci_voice_free(ymfpci_t *unit, ymfpci_voice_t *pvoice);
 static int ymf_capture_alloc(struct ymf_unit *unit, int *pbank);
 static int ymf_playback_prepare(struct ymf_state *state);
 static int ymf_capture_prepare(struct ymf_state *state);
 static struct ymf_state *ymf_state_alloc(ymfpci_t *unit);
 
+static void ymfpci_aclink_reset(struct pci_dev * pci);
+static void ymfpci_disable_dsp(ymfpci_t *unit);
+static void ymfpci_download_image(ymfpci_t *codec);
+static void ymf_memload(ymfpci_t *unit);
+
 static LIST_HEAD(ymf_devs);
 
 /*
@@ -237,8 +246,7 @@
 }
 
 /*
- * XXX Find if this function exists in the OSS framework.
- * XXX Make sure we do no panic when ADPCM is selected.
+ * We ever allow only a few formats, but let's be generic, for smaller surprise.
  */
 static int ymf_pcm_format_width(int format)
 {
@@ -330,7 +338,7 @@
 	spin_lock_irqsave(&state->unit->reg_lock, flags);
 	dmabuf->hwptr = dmabuf->swptr = 0;
 	dmabuf->total_bytes = 0;
-	dmabuf->count = dmabuf->error = 0;
+	dmabuf->count = 0;
 	spin_unlock_irqrestore(&state->unit->reg_lock, flags);
 
 	/* allocate DMA buffer if not allocated yet */
@@ -579,9 +587,9 @@
 	dmabuf = &ypcm->dmabuf;
 	spin_lock(&codec->reg_lock);
 	if (ypcm->running) {
-/* P3 */ /** printk("ymfpci: %d, intr bank %d count %d start 0x%x:%x\n",
-  voice->number, codec->active_bank, dmabuf->count,
-  voice->bank[0].start, voice->bank[1].start); **/
+		YMFDBGI("ymfpci: %d, intr bank %d count %d start 0x%x:%x\n",
+		   voice->number, codec->active_bank, dmabuf->count,
+		   voice->bank[0].start, voice->bank[1].start);
 		silence = (ymf_pcm_format_width(state->format.format) == 16) ?
 		    0 : 0x80;
 		/* We need actual left-hand-side redzone size here. */
@@ -810,8 +818,6 @@
 		end >>= 1;
 	if (w_16)
 		end >>= 1;
-/* P3 */ // printk("ymf_pcm_init_voice: %d: Rate %d Format 0x%08x Delta 0x%x End 0x%x\n",
-//  voice->number, rate, format, delta, end);
 	for (nbank = 0; nbank < 2; nbank++) {
 		bank = &voice->bank[nbank];
 		bank->format = format;
@@ -907,7 +913,7 @@
 
 	if ((err = ymfpci_pcm_voice_alloc(ypcm, state->format.voices)) < 0) {
 		/* Somebody started 32 mpg123's in parallel? */
-		/* P3 */ printk("ymfpci%d: cannot allocate voice\n",
+		printk(KERN_INFO "ymfpci%d: cannot allocate voice\n",
 		    state->unit->dev_audio);
 		return err;
 	}
@@ -1178,6 +1184,7 @@
 {
 	struct ymf_state *state = (struct ymf_state *)file->private_data;
 	struct ymf_dmabuf *dmabuf = &state->rpcm.dmabuf;
+	struct ymf_unit *unit = state->unit;
 	DECLARE_WAITQUEUE(waita, current);
 	ssize_t ret;
 	unsigned long flags;
@@ -1190,18 +1197,26 @@
 		return -ENXIO;
 	if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
 		return ret;
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
 	ret = 0;
 
 	add_wait_queue(&dmabuf->wait, &waita);
 	while (count > 0) {
-		spin_lock_irqsave(&state->unit->reg_lock, flags);
+		spin_lock_irqsave(&unit->reg_lock, flags);
+		if (unit->suspended) {
+			spin_unlock_irqrestore(&unit->reg_lock, flags);
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule();
+			if (signal_pending(current)) {
+				if (!ret) ret = -EAGAIN;
+				break;
+			}
+			continue;
+		}
 		swptr = dmabuf->swptr;
 		cnt = dmabuf->dmasize - swptr;
 		if (dmabuf->count < cnt)
 			cnt = dmabuf->count;
-		spin_unlock_irqrestore(&state->unit->reg_lock, flags);
+		spin_unlock_irqrestore(&unit->reg_lock, flags);
 
 		if (cnt > count)
 			cnt = count;
@@ -1240,7 +1255,7 @@
 			}
 			spin_unlock_irqrestore(&state->unit->reg_lock, flags);
 			if (signal_pending(current)) {
-				ret = ret ? ret : -ERESTARTSYS;
+				if (!ret) ret = -ERESTARTSYS;
 				break;
 			}
 			continue;
@@ -1253,19 +1268,24 @@
 
 		swptr = (swptr + cnt) % dmabuf->dmasize;
 
-		spin_lock_irqsave(&state->unit->reg_lock, flags);
+		spin_lock_irqsave(&unit->reg_lock, flags);
+		if (unit->suspended) {
+			spin_unlock_irqrestore(&unit->reg_lock, flags);
+			continue;
+		}
+
 		dmabuf->swptr = swptr;
 		dmabuf->count -= cnt;
-		// spin_unlock_irqrestore(&state->unit->reg_lock, flags);
+		// spin_unlock_irqrestore(&unit->reg_lock, flags);
 
 		count -= cnt;
 		buffer += cnt;
 		ret += cnt;
-		// spin_lock_irqsave(&state->unit->reg_lock, flags);
+		// spin_lock_irqsave(&unit->reg_lock, flags);
 		if (!state->rpcm.running) {
-			ymf_capture_trigger(state->unit, &state->rpcm, 1);
+			ymf_capture_trigger(unit, &state->rpcm, 1);
 		}
-		spin_unlock_irqrestore(&state->unit->reg_lock, flags);
+		spin_unlock_irqrestore(&unit->reg_lock, flags);
 	}
 	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&dmabuf->wait, &waita);
@@ -1278,6 +1298,7 @@
 {
 	struct ymf_state *state = (struct ymf_state *)file->private_data;
 	struct ymf_dmabuf *dmabuf = &state->wpcm.dmabuf;
+	struct ymf_unit *unit = state->unit;
 	DECLARE_WAITQUEUE(waita, current);
 	ssize_t ret;
 	unsigned long flags;
@@ -1286,7 +1307,7 @@
 	int redzone;
 	int delay;
 
-/* P3 */ /* printk("ymf_write: count %d\n", count); */
+	YMFDBGW("ymf_write: count %d\n", count);
 
 	if (ppos != &file->f_pos)
 		return -ESPIPE;
@@ -1294,8 +1315,6 @@
 		return -ENXIO;
 	if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
 		return ret;
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
 	ret = 0;
 
 	/*
@@ -1310,7 +1329,17 @@
 
 	add_wait_queue(&dmabuf->wait, &waita);
 	while (count > 0) {
-		spin_lock_irqsave(&state->unit->reg_lock, flags);
+		spin_lock_irqsave(&unit->reg_lock, flags);
+		if (unit->suspended) {
+			spin_unlock_irqrestore(&unit->reg_lock, flags);
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule();
+			if (signal_pending(current)) {
+				if (!ret) ret = -EAGAIN;
+				break;
+			}
+			continue;
+		}
 		if (dmabuf->count < 0) {
 			printk(KERN_ERR
 			   "ymf_write: count %d, was legal in cs46xx\n",
@@ -1342,22 +1371,22 @@
 		cnt = dmabuf->dmasize - swptr;
 		if (dmabuf->count + cnt > dmabuf->dmasize - redzone)
 			cnt = (dmabuf->dmasize - redzone) - dmabuf->count;
-		spin_unlock_irqrestore(&state->unit->reg_lock, flags);
+		spin_unlock_irqrestore(&unit->reg_lock, flags);
 
 		if (cnt > count)
 			cnt = count;
 		if (cnt <= 0) {
-/* P3 */ /* printk("ymf_write: full, count %d swptr %d\n",
-  dmabuf->count, dmabuf->swptr); */
+			YMFDBGW("ymf_write: full, count %d swptr %d\n",
+			   dmabuf->count, dmabuf->swptr);
 			/*
 			 * buffer is full, start the dma machine and
 			 * wait for data to be played
 			 */
-			spin_lock_irqsave(&state->unit->reg_lock, flags);
+			spin_lock_irqsave(&unit->reg_lock, flags);
 			if (!state->wpcm.running) {
-				ymf_playback_trigger(state->unit, &state->wpcm, 1);
+				ymf_playback_trigger(unit, &state->wpcm, 1);
 			}
-			spin_unlock_irqrestore(&state->unit->reg_lock, flags);
+			spin_unlock_irqrestore(&unit->reg_lock, flags);
 			if (file->f_flags & O_NONBLOCK) {
 				if (!ret) ret = -EAGAIN;
 				break;
@@ -1379,7 +1408,11 @@
 			swptr -= dmabuf->dmasize;
 		}
 
-		spin_lock_irqsave(&state->unit->reg_lock, flags);
+		spin_lock_irqsave(&unit->reg_lock, flags);
+		if (unit->suspended) {
+			spin_unlock_irqrestore(&unit->reg_lock, flags);
+			continue;
+		}
 		dmabuf->swptr = swptr;
 		dmabuf->count += cnt;
 
@@ -1393,10 +1426,10 @@
 		delay = state->format.rate / 20;	/* 50ms */
 		delay <<= state->format.shift;
 		if (dmabuf->count >= delay && !state->wpcm.running) {
-			ymf_playback_trigger(state->unit, &state->wpcm, 1);
+			ymf_playback_trigger(unit, &state->wpcm, 1);
 		}
 
-		spin_unlock_irqrestore(&state->unit->reg_lock, flags);
+		spin_unlock_irqrestore(&unit->reg_lock, flags);
 
 		count -= cnt;
 		buffer += cnt;
@@ -1406,7 +1439,7 @@
 	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&dmabuf->wait, &waita);
 
-/* P3 */ /* printk("ymf_write: dmabuf.count %d\n", dmabuf->count); */
+	YMFDBGW("ymf_write: dmabuf.count %d\n", dmabuf->count);
 	return ret;
 }
 
@@ -1621,7 +1654,6 @@
 	case SNDCTL_DSP_CHANNELS:
 		if (get_user(val, (int *)arg))
 			return -EFAULT;
-	/* P3 */ /* printk("ymfpci: ioctl SNDCTL_DSP_CHANNELS 0x%x\n", val); */
 		if (val != 0) {
 			if (file->f_mode & FMODE_WRITE) {
 				ymf_wait_dac(state);
@@ -1667,19 +1699,6 @@
 		spin_unlock_irqrestore(&state->unit->reg_lock, flags);
 		return 0;
 
-#if 0 /* XXX Was dummy implementation anyways. Make sense of this. */
-	case SNDCTL_DSP_SUBDIVIDE:
-		dmabuf = &state->wpcm.dmabuf;
-		if (dmabuf->subdivision)
-			return -EINVAL;
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		if (val != 1 && val != 2)
-			return -EINVAL;
-		dmabuf->subdivision = val;
-		return 0;
-#endif
-
 	case SNDCTL_DSP_SETFRAGMENT:
 		if (get_user(val, (int *)arg))
 			return -EFAULT;
@@ -1729,40 +1748,6 @@
 			    (int *)arg); */
 		return put_user(0, (int *)arg);
 
-#if 0 /* not implememnted, yet? */
-	case SNDCTL_DSP_GETTRIGGER:
-		val = 0;
-		dmabuf = &state->wpcm.dmabuf;
-		if (file->f_mode & FMODE_READ && dmabuf->enable)
-			val |= PCM_ENABLE_INPUT;
-		if (file->f_mode & FMODE_WRITE && dmabuf->enable)
-			val |= PCM_ENABLE_OUTPUT;
-		return put_user(val, (int *)arg);
-
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			dmabuf = &state->rpcm.dmabuf;
-			if (val & PCM_ENABLE_INPUT) {
-				if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
-					return ret;
-				start_adc(state);
-			} else
-				stop_adc(state);
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			dmabuf = &state->wpcm.dmabuf;
-			if (val & PCM_ENABLE_OUTPUT) {
-				if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
-					return ret;
-				start_dac(state);  // sure?
-			} else
-				stop_dac(state);
-		}
-		return 0;
-#endif
-
 	case SNDCTL_DSP_GETIPTR:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
@@ -1794,18 +1779,6 @@
 	case SNDCTL_DSP_SETDUPLEX:	/* XXX TODO */
 		return -EINVAL;
 
-#if 0 /* XXX implement when an app found that uses it. */
-	case SNDCTL_DSP_GETODELAY:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		spin_lock_irqsave(&state->unit->reg_lock, flags);
-		cs_update_ptr(state);
-		dmabuf = &state->wpcm.dmabuf;
-		val = dmabuf->count;
-		spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-		return put_user(val, (int *)arg);
-#endif
-
 	case SOUND_PCM_READ_RATE:
 		return put_user(state->format.rate, (int *)arg);
 
@@ -1827,7 +1800,6 @@
 		 * Some programs mix up audio devices and ioctls
 		 * or perhaps they expect "universal" ioctls,
 		 * for instance we get SNDCTL_TMR_CONTINUE here.
-		 * XXX Is there sound_generic_ioctl() around?
 		 */
 		 break;
 	}
@@ -2017,6 +1989,79 @@
 };
 
 /*
+ */
+
+static int ymf_suspend(struct pci_dev *pcidev, u32 unused)
+{
+	struct ymf_unit *unit = pci_get_drvdata(pcidev);
+	unsigned long flags;
+	struct ymf_dmabuf *dmabuf;
+	struct list_head *p;
+	struct ymf_state *state;
+
+	spin_lock_irqsave(&unit->reg_lock, flags);
+
+	unit->suspended = 1;
+
+	list_for_each(p, &unit->states) {
+		state = list_entry(p, struct ymf_state, chain);
+
+		dmabuf = &state->wpcm.dmabuf;
+		dmabuf->hwptr = dmabuf->swptr = 0;
+		dmabuf->total_bytes = 0;
+		dmabuf->count = 0;
+
+		dmabuf = &state->rpcm.dmabuf;
+		dmabuf->hwptr = dmabuf->swptr = 0;
+		dmabuf->total_bytes = 0;
+		dmabuf->count = 0;
+	}
+
+	ymfpci_writel(unit, YDSXGR_NATIVEDACOUTVOL, 0);
+	ymfpci_disable_dsp(unit);
+
+	spin_unlock_irqrestore(&unit->reg_lock, flags);
+	
+	return 0;
+}
+
+static int ymf_resume(struct pci_dev *pcidev)
+{
+	struct ymf_unit *unit = pci_get_drvdata(pcidev);
+	unsigned long flags;
+	struct list_head *p;
+	struct ymf_state *state;
+
+	ymfpci_aclink_reset(unit->pci);
+	ymfpci_codec_ready(unit, 0, 1);		/* prints diag if not ready. */
+
+#ifdef CONFIG_SOUND_YMFPCI_LEGACY
+	/* XXX At this time the legacy registers are probably deprogrammed. */
+#endif
+
+	ymfpci_download_image(unit);
+
+	ymf_memload(unit);
+
+	spin_lock_irqsave(&unit->reg_lock, flags);
+
+	if (unit->start_count) {
+		ymfpci_writel(unit, YDSXGR_MODE, 3);
+		unit->active_bank = ymfpci_readl(unit, YDSXGR_CTRLSELECT) & 1;
+	}
+
+	unit->suspended = 0;
+	list_for_each(p, &unit->states) {
+		state = list_entry(p, struct ymf_state, chain);
+		wake_up(&state->wpcm.dmabuf.wait);
+		wake_up(&state->rpcm.dmabuf.wait);
+	}
+
+	spin_unlock_irqrestore(&unit->reg_lock, flags);
+	return 0;
+}
+
+/*
  *  initialization routines
  */
 
@@ -2176,6 +2221,9 @@
 	}
 
 	ymfpci_enable_dsp(codec);
+
+	/* 0.02s sounds not too bad, we may do schedule_timeout() later. */
+	mdelay(20); /* seems we need some delay after downloading image.. */
 }
 
 static int ymfpci_memalloc(ymfpci_t *codec)
@@ -2239,28 +2287,6 @@
 	ptr += (codec->bank_size_effect + 0x00ff) & ~0x00ff;
 	codec->work_base = ptr;
 
-	ymfpci_writel(codec, YDSXGR_PLAYCTRLBASE, virt_to_bus(codec->bank_base_playback));
-	ymfpci_writel(codec, YDSXGR_RECCTRLBASE, virt_to_bus(codec->bank_base_capture));
-	ymfpci_writel(codec, YDSXGR_EFFCTRLBASE, virt_to_bus(codec->bank_base_effect));
-	ymfpci_writel(codec, YDSXGR_WORKBASE, virt_to_bus(codec->work_base));
-	ymfpci_writel(codec, YDSXGR_WORKSIZE, codec->work_size >> 2);
-
-	/* S/PDIF output initialization */
-	ymfpci_writew(codec, YDSXGR_SPDIFOUTCTRL, 0);
-	ymfpci_writew(codec, YDSXGR_SPDIFOUTSTATUS,
-		SND_PCM_AES0_CON_EMPHASIS_NONE |
-		(SND_PCM_AES1_CON_ORIGINAL << 8) |
-		(SND_PCM_AES1_CON_PCM_CODER << 8));
-
-	/* S/PDIF input initialization */
-	ymfpci_writew(codec, YDSXGR_SPDIFINCTRL, 0);
-
-	/* move this volume setup to mixer */
-	ymfpci_writel(codec, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff);
-	ymfpci_writel(codec, YDSXGR_BUF441OUTVOL, 0);
-	ymfpci_writel(codec, YDSXGR_NATIVEADCINVOL, 0x3fff3fff);
-	ymfpci_writel(codec, YDSXGR_NATIVEDACINVOL, 0x3fff3fff);
-
 	return 0;
 }
 
@@ -2274,6 +2300,32 @@
 	kfree(codec->work_ptr);
 }
 
+static void ymf_memload(ymfpci_t *unit)
+{
+
+	ymfpci_writel(unit, YDSXGR_PLAYCTRLBASE, virt_to_bus(unit->bank_base_playback));
+	ymfpci_writel(unit, YDSXGR_RECCTRLBASE, virt_to_bus(unit->bank_base_capture));
+	ymfpci_writel(unit, YDSXGR_EFFCTRLBASE, virt_to_bus(unit->bank_base_effect));
+	ymfpci_writel(unit, YDSXGR_WORKBASE, virt_to_bus(unit->work_base));
+	ymfpci_writel(unit, YDSXGR_WORKSIZE, unit->work_size >> 2);
+
+	/* S/PDIF output initialization */
+	ymfpci_writew(unit, YDSXGR_SPDIFOUTCTRL, 0);
+	ymfpci_writew(unit, YDSXGR_SPDIFOUTSTATUS,
+		SND_PCM_AES0_CON_EMPHASIS_NONE |
+		(SND_PCM_AES1_CON_ORIGINAL << 8) |
+		(SND_PCM_AES1_CON_PCM_CODER << 8));
+
+	/* S/PDIF input initialization */
+	ymfpci_writew(unit, YDSXGR_SPDIFINCTRL, 0);
+
+	/* move this volume setup to mixer */
+	ymfpci_writel(unit, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff);
+	ymfpci_writel(unit, YDSXGR_BUF441OUTVOL, 0);
+	ymfpci_writel(unit, YDSXGR_NATIVEADCINVOL, 0x3fff3fff);
+	ymfpci_writel(unit, YDSXGR_NATIVEDACINVOL, 0x3fff3fff);
+}
+
 static int ymf_ac97_init(ymfpci_t *unit, int num_ac97)
 {
 	struct ac97_codec *codec;
@@ -2380,12 +2432,9 @@
 
 	ymfpci_download_image(codec);
 
-	udelay(100); /* seems we need some delay after downloading image.. */
-
 	if (ymfpci_memalloc(codec) < 0)
 		goto out_disable_dsp;
-
-	/* ymfpci_proc_init(unit, codec); */
+	ymf_memload(codec);
 
 	if (request_irq(pcidev->irq, ymf_interrupt, SA_SHIRQ, "ymfpci", codec) != 0) {
 		printk(KERN_ERR "ymfpci: unable to request IRQ %d\n",
@@ -2481,6 +2530,8 @@
 	id_table:	ymf_id_tbl,
 	probe:		ymf_probe_one,
 	remove:         ymf_remove_one,
+	suspend:	ymf_suspend,
+	resume:		ymf_resume
 };
 
 static int __init ymf_init_module(void)
diff -u --recursive --new-file v2.4.6/linux/drivers/sound/ymfpci.h linux/drivers/sound/ymfpci.h
--- v2.4.6/linux/drivers/sound/ymfpci.h	Tue May 15 11:16:26 2001
+++ linux/drivers/sound/ymfpci.h	Wed Jul  4 11:50:39 2001
@@ -257,6 +257,7 @@
 	ymfpci_effect_bank_t *bank_effect[YDSXG_EFFECT_VOICES][2];
 
 	int start_count;
+	int suspended;
 
 	u32 active_bank;
 	struct ymf_voice voices[64];
@@ -282,8 +283,6 @@
 
 	struct list_head ymf_devs;
 	struct list_head states;	/* List of states for this unit */
-	/* For the moment we do not traverse list of states so it is
-	 * entirely useless. Will be used (PM) or killed. XXX */
 };
 
 struct ymf_dmabuf {
@@ -300,7 +299,6 @@
 	int count;		/* fill count */
 	unsigned total_bytes;	/* total bytes dmaed by hardware */
 
-	unsigned error;		/* number of over/underruns */
 	wait_queue_head_t wait;	/* put process on wait queue when no more space in buffer */
 
 	/* redundant, but makes calculations easier */
diff -u --recursive --new-file v2.4.6/linux/drivers/video/cyber2000fb.c linux/drivers/video/cyber2000fb.c
--- v2.4.6/linux/drivers/video/cyber2000fb.c	Tue Jul  3 17:08:21 2001
+++ linux/drivers/video/cyber2000fb.c	Wed Jul  4 11:50:39 2001
@@ -367,6 +367,7 @@
 	 * Other
 	 */
 	u_char	palette_ctrl;
+	u_int	vmode;
 };
 
 static const u_char crtc_idx[] = {
@@ -427,6 +428,16 @@
 	cyber2000_attrw(0x13, 0x00);
 	cyber2000_attrw(0x14, 0x00);
 
+	/* woody: set the interlaced bit... */
+	/* FIXME: what about doublescan? */
+	cyber2000_outb(0x11, 0x3ce);
+	i = cyber2000_inb(0x3cf);
+	if (hw->vmode == FB_VMODE_INTERLACED)
+		i |= 0x20;
+	else
+		i &= ~0x20;
+	cyber2000_outb(i, 0x3cf);
+
 	/* PLL registers */
 	cyber2000_grphw(DCLK_MULT, hw->clock_mult);
 	cyber2000_grphw(DCLK_DIV,  hw->clock_div);
@@ -711,6 +722,7 @@
 
 	hw->width = var->xres_virtual;
 	hw->palette_ctrl = 0x06;
+	hw->vmode = var->vmode;
 
 	switch (var->bits_per_pixel) {
 #ifdef FBCON_HAS_CFB8
@@ -1570,7 +1582,7 @@
 	/*
 	 * Our driver data
 	 */
-	dev->driver_data = cfb;
+	pci_set_drvdata(dev, cfb);
 	if (int_cfb_info == NULL)
 		int_cfb_info = cfb;
 
@@ -1586,7 +1598,7 @@
 
 static void __devexit cyberpro_remove(struct pci_dev *dev)
 {
-	struct cfb_info *cfb = (struct cfb_info *)dev->driver_data;
+	struct cfb_info *cfb = pci_get_drvdata(dev);
 
 	if (cfb) {
 		/*
@@ -1606,7 +1618,7 @@
 		 * Ensure that the driver data is no longer
 		 * valid.
 		 */
-		dev->driver_data = NULL;
+		pci_set_drvdata(dev, NULL);
 		if (cfb == int_cfb_info)
 			int_cfb_info = NULL;
 	}
@@ -1622,7 +1634,7 @@
  */
 static int cyberpro_resume(struct pci_dev *dev)
 {
-	struct cfb_info *cfb = (struct cfb_info *)dev->driver_data;
+	struct cfb_info *cfb = pci_get_drvdata(dev);
 
 	if (cfb) {
 		cyberpro_init_hw(cfb, 0);
diff -u --recursive --new-file v2.4.6/linux/drivers/video/fbcon.c linux/drivers/video/fbcon.c
--- v2.4.6/linux/drivers/video/fbcon.c	Tue Jul  3 17:08:21 2001
+++ linux/drivers/video/fbcon.c	Wed Jul  4 11:50:39 2001
@@ -31,6 +31,8 @@
  *
  *  Random hacking by Martin Mares <mj@ucw.cz>
  *
+ *	2001 - Documented with DocBook
+ *	- Brad Douglas <brad@neruo.com>
  *
  *  The low level operations for the various display memory organizations are
  *  now in separate source files.
@@ -239,6 +241,20 @@
       add_timer(&cursor_timer);
 }
 
+
+/**
+ *	PROC_CONSOLE - find the attached tty or visible console
+ *	@info: frame buffer info structure
+ *
+ *	Finds the tty attached to the process or visible console if
+ *	the process is not directly attached to a tty (e.g. remote
+ *	user) for device @info.
+ *
+ *	Returns -1 errno on error, or tty/visible console number
+ *	on success.
+ *
+ */
+
 int PROC_CONSOLE(const struct fb_info *info)
 {
         int fgc;
@@ -261,6 +277,21 @@
         return MINOR(current->tty->device) - 1;
 }
 
+
+/**
+ *	set_all_vcs - set all virtual consoles to match
+ *	@fbidx: frame buffer index (e.g. fb0, fb1, ...)
+ *	@fb: frame buffer ops structure
+ *	@var: frame buffer screen structure to set
+ *	@info: frame buffer info structure
+ *
+ *	Set all virtual consoles to match screen info set in @var
+ *	for device @info.
+ *
+ *	Returns negative errno on error, or zero on success.
+ *
+ */
+
 int set_all_vcs(int fbidx, struct fb_ops *fb, struct fb_var_screeninfo *var,
                 struct fb_info *info)
 {
@@ -277,6 +308,17 @@
     return 0;
 }
 
+
+/**
+ *	set_con2fb_map - map console to frame buffer device
+ *	@unit: virtual console number to map
+ *	@newidx: frame buffer index to map virtual console to
+ *
+ *	Maps a virtual console @unit to a frame buffer device
+ *	@newidx.
+ *
+ */
+
 void set_con2fb_map(int unit, int newidx)
 {
     int oldidx = con2fb_map[unit];
@@ -1108,11 +1150,13 @@
 	    	}
 	    }
 	    scr_writew(c, d);
+	    console_conditional_schedule();
 	    s++;
 	    d++;
 	} while (s < le);
 	if (s > start)
 	    p->dispsw->putcs(conp, p, start, s - start, real_y(p, line), x);
+	console_conditional_schedule();
 	if (offset > 0)
 		line++;
 	else {
@@ -1124,6 +1168,20 @@
     }
 }
 
+/**
+ *	fbcon_redraw_clear - clear area of the screen
+ *	@conp: stucture pointing to current active virtual console
+ *	@p: display structure
+ *	@sy: starting Y coordinate
+ *	@sx: starting X coordinate
+ *	@height: height of area to clear
+ *	@width: width of area to clear
+ *
+ *	Clears a specified area of the screen.  All dimensions are in
+ *	pixels.
+ *
+ */
+
 void fbcon_redraw_clear(struct vc_data *conp, struct display *p, int sy, int sx,
 		     int height, int width)
 {
@@ -1133,7 +1191,25 @@
 	    fbcon_putc(conp, ' ', sy+y, sx+x);
 }
 
-/* This cannot be used together with ypan or ywrap */
+
+/**
+ *	fbcon_redraw_bmove - copy area of screen to another area
+ *	@p: display structure
+ *	@sy: origin Y coordinate
+ *	@sx: origin X coordinate
+ *	@dy: destination Y coordinate
+ *	@dx: destination X coordinate
+ *	@h: height of area to copy
+ *	@w: width of area to copy
+ *
+ *	Copies an area of the screen to another area of the same screen.
+ *	All dimensions are in pixels.
+ *
+ *	Note that this function cannot be used together with ypan or
+ *	ywrap.
+ *
+ */
+
 void fbcon_redraw_bmove(struct display *p, int sy, int sx, int dy, int dx, int h, int w)
 {
     if (sy != dy)
diff -u --recursive --new-file v2.4.6/linux/drivers/video/imsttfb.c linux/drivers/video/imsttfb.c
--- v2.4.6/linux/drivers/video/imsttfb.c	Tue Jul  3 17:08:21 2001
+++ linux/drivers/video/imsttfb.c	Wed Jul  4 11:50:39 2001
@@ -386,7 +386,6 @@
 #if defined(CONFIG_PPC)
 static signed char init_vmode __initdata = -1, init_cmode __initdata = -1;
 #endif
-static struct fb_info_imstt *fb_info_imstt_p[FB_MAX] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 
 static struct imstt_regvals tvp_reg_init_2 = {
 	512,
@@ -444,6 +443,12 @@
 	{ 0x38, 0x38, 0x38 }, { 0xf3, 0xf2, 0xf1 }
 };
 
+/*
+ * PCI driver prototypes
+ */
+static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+static void imsttfb_remove(struct pci_dev *pdev);
+
 static __u32
 getclkMHz (struct fb_info_imstt *p)
 {
@@ -1623,6 +1628,23 @@
 	}
 }
 
+static struct pci_device_id imsttfb_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_IMS, PCI_DEVICE_ID_IMS_TT128,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, IBM },
+	{ PCI_VENDOR_ID_IMS, PCI_DEVICE_ID_IMS_TT3D,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TVP },
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, imsttfb_pci_tbl);
+
+static struct pci_driver imsttfb_pci_driver = {
+	name:		"imsttfb",
+	id_table:	imsttfb_pci_tbl,
+	probe:		imsttfb_probe,
+	remove:		imsttfb_remove,
+};
+
 static struct fb_ops imsttfb_ops = {
 	owner:		THIS_MODULE,
 	fb_get_fix:	imsttfb_get_fix,
@@ -1869,7 +1891,6 @@
 	printk("fb%u: %s frame buffer; %uMB vram; chip version %u\n",
 		i, p->fix.id, p->total_vram >> 20, tmp);
 
-	fb_info_imstt_p[i] = p;
 #ifdef CONFIG_FB_COMPAT_XPMAC
 	strncpy(display_info.name, "IMS,tt128mb", sizeof(display_info.name));
 	display_info.fb_address = p->frame_buffer_phys;
@@ -1881,61 +1902,69 @@
 #endif /* CONFIG_FB_COMPAT_XPMAC */
 }
 
-int __init 
-imsttfb_init(void)
+static int __devinit
+imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	int i;
-	struct pci_dev *pdev = NULL;
 	struct fb_info_imstt *p;
 	unsigned long addr, size;
 
-	while ((pdev = pci_find_device(PCI_VENDOR_ID_IMS, PCI_ANY_ID, pdev))) {
-		if ((pdev->class >> 16) != PCI_BASE_CLASS_DISPLAY)
-			continue;
-		if (pci_enable_device(pdev))
-			continue;
-
-		addr = pci_resource_start (pdev, 0);
-		size = pci_resource_len (pdev, 0);
-		if (!addr)
-			continue;
-
-		p = kmalloc(sizeof(struct fb_info_imstt), GFP_ATOMIC);
-		if (!p)
-			continue;
-		memset(p, 0, sizeof(struct fb_info_imstt));
-
-		if (!request_mem_region(addr, size, "imsttfb")) {
-			kfree(p);
-			continue;
-		}
-		printk("imsttfb: device=%04x\n", pdev->device);
-
-		switch (pdev->device) {
-			case 0x9128:	/* IMS,tt128mbA */
-				p->ramdac = IBM;
-				break;
-			case 0x9135:	/* IMS,tt3d */
-			default:
-				p->ramdac = TVP;
-				break;
-		}
+	addr = pci_resource_start (pdev, 0);
+	size = pci_resource_len (pdev, 0);
 
-		p->frame_buffer_phys = addr;
-		p->board_size = size;
-		p->frame_buffer = (__u8 *)ioremap(addr, p->ramdac == IBM ? 0x400000 : 0x800000);
-		p->dc_regs_phys = addr + 0x800000;
-		p->dc_regs = (__u32 *)ioremap(addr + 0x800000, 0x1000);
-		p->cmap_regs_phys = addr + 0x840000;
-		p->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000);
+	p = kmalloc(sizeof(struct fb_info_imstt), GFP_KERNEL);
 
-		init_imstt(p);
+	if (!p) {
+		printk(KERN_ERR "imsttfb: Can't allocate memory\n");
+		return -ENOMEM;
 	}
-	for (i = 0; i < FB_MAX; i++) {
-		if (fb_info_imstt_p[i])
-			return 0;
+
+	memset(p, 0, sizeof(struct fb_info_imstt));
+
+	if (!request_mem_region(addr, size, "imsttfb")) {
+		printk(KERN_ERR "imsttfb: Can't reserve memory region\n");
+		kfree(p);
+		return -ENODEV;
 	}
-	return -ENXIO;
+
+	switch (pdev->device) {
+		case PCI_DEVICE_ID_IMS_TT128: /* IMS,tt128mbA */
+			p->ramdac = IBM;
+			break;
+		case PCI_DEVICE_ID_IMS_TT3D:  /* IMS,tt3d */
+			p->ramdac = TVP;
+			break;
+		default:
+			printk(KERN_INFO "imsttfb: Device 0x%lx unknown, "
+					 "contact maintainer.\n", pdev->device);
+			return -ENODEV;
+	}
+
+	p->frame_buffer_phys = addr;
+	p->board_size = size;
+	p->frame_buffer = (__u8 *)ioremap(addr, p->ramdac == IBM ? 0x400000 : 0x800000);
+	p->dc_regs_phys = addr + 0x800000;
+	p->dc_regs = (__u32 *)ioremap(addr + 0x800000, 0x1000);
+	p->cmap_regs_phys = addr + 0x840000;
+	p->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000);
+
+	init_imstt(p);
+
+	pdev->driver_data = p;
+
+	return 0;
+}
+
+static void __devexit
+imsttfb_remove(struct pci_dev *pdev)
+{
+	struct fb_info_imstt *p = (struct fb_info_imstt *)pdev->driver_data;
+
+	unregister_framebuffer(&p->info);
+	iounmap(p->cmap_regs);
+	iounmap(p->dc_regs);
+	iounmap(p->frame_buffer);
+	release_mem_region(p->frame_buffer_phys, p->board_size);
+	kfree(p);
 }
 
 #ifndef MODULE
@@ -1996,29 +2025,20 @@
 	return 0;
 }
 
-#else /* MODULE */
-static void __exit
-imsttfb_exit(void)
-{
-	struct fb_info_imstt *p;
-	__u32 i;
+#endif /* MODULE */
 
-	for (i = 0; i < FB_MAX; i++) {
-		p = fb_info_imstt_p[i];
-		if (!p)
-			continue;
-		unregister_framebuffer(&p->info);
-		iounmap(p->cmap_regs);
-		iounmap(p->dc_regs);
-		iounmap(p->frame_buffer);
-		release_mem_region(p->frame_buffer_phys, p->board_size);
-		kfree(p);
-	}
+int __init imsttfb_init(void)
+{
+	return pci_module_init(&imsttfb_pci_driver);
+}
+ 
+static void __exit imsttfb_exit(void)
+{
+	pci_unregister_driver(&imsttfb_pci_driver);
 }
 
-#include "macmodes.c"
-
+#ifdef MODULE
 module_init(imsttfb_init);
+#endif
 module_exit(imsttfb_exit);
-#endif /* MODULE */
 
diff -u --recursive --new-file v2.4.6/linux/drivers/video/maxinefb.c linux/drivers/video/maxinefb.c
--- v2.4.6/linux/drivers/video/maxinefb.c	Wed Apr 18 11:49:12 2001
+++ linux/drivers/video/maxinefb.c	Wed Jul  4 11:50:39 2001
@@ -272,14 +272,6 @@
 	return 0;
 }
 
-
-static int maxinefb_ioctl(struct inode *inode, struct file *file,
-			  unsigned int cmd, unsigned long arg, int con,
-			  struct fb_info *info)
-{
-	return -EINVAL;
-}
-
 static int maxinefb_switch(int con, struct fb_info *info)
 {
 	maxinefb_do_fb_set_var(&fb_display[con].var, 1);
@@ -287,22 +279,6 @@
 	return 0;
 }
 
-/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
-
-static void maxinefb_blank(int blank, struct fb_info *info)
-{
-	/* Not supported */
-}
-
-static int maxinefb_open(struct fb_info *info, int user)
-{
-	/*
-	 * Nothing, only a usage count for the moment
-	 */
-	MOD_INC_USE_COUNT;
-	return (0);
-}
-
 static void maxinefb_set_disp(int con)
 {
 	struct fb_fix_screeninfo fix;
@@ -329,31 +305,28 @@
 	display->dispsw = &fbcon_cfb8;
 }
 
-static int maxinefb_release(struct fb_info *info, int user)
-{
-	MOD_DEC_USE_COUNT;
-	return (0);
-}
-
 static struct fb_ops maxinefb_ops = {
-	owner:THIS_MODULE,
-	fb_open:maxinefb_open,
-	fb_release:maxinefb_release,
-	fb_get_fix:maxinefb_get_fix,
-	fb_get_var:maxinefb_get_var,
-	fb_set_var:maxinefb_set_var,
-	fb_get_cmap:maxinefb_get_cmap,
-	fb_set_cmap:maxinefb_set_cmap,
-	fb_ioctl:maxinefb_ioctl,
-	fb_mmap:0,
-	fb_rasterimg:0
+	owner:		THIS_MODULE,
+	fb_get_fix:	maxinefb_get_fix,
+	fb_get_var:	maxinefb_get_var,
+	fb_set_var:	maxinefb_set_var,
+	fb_get_cmap:	maxinefb_get_cmap,
+	fb_set_cmap:	maxinefb_set_cmap,
 };
 
-int __init maxinefb_init_one()
+int __init maxinefb_init(void)
 {
 	volatile unsigned char *fboff;
 	int i;
 
+	/* Validate we're on the proper machine type */
+	if (mips_machtype != MACH_DS5000_XX) {
+		return -EINVAL;
+	}
+
+	printk(KERN_INFO "Maxinefb: Personal DECstation detected\n");
+	printk(KERN_INFO "Maxinefb: initializing onboard framebuffer\n");
+
 	/* Framebuffer display memory base address */
 	fb_start = DS5000_xx_ONBOARD_FBMEM_START;
 
@@ -390,7 +363,7 @@
 	fb_info.disp = &disp;
 	fb_info.switch_con = &maxinefb_switch;
 	fb_info.updatevar = &maxinefb_fb_update_var;
-	fb_info.blank = &maxinefb_blank;
+	fb_info.blank = NULL;
 	fb_info.flags = FBINFO_FLAG_DEFAULT;
 	maxinefb_do_fb_set_var(&maxinefb_defined, 1);
 
@@ -403,23 +376,13 @@
 	return 0;
 }
 
-
-/* Initialise the framebuffer */
-
-void __init maxinefb_init()
+static void __exit maxinefb_exit(void)
 {
-	unsigned int sid;
-
-	if (mips_machtype == MACH_DS5000_XX) {
-		printk("Maxinefb: Personal DECstation detected\n");
-		printk("Maxinefb: initializing onboard framebuffer\n");
-
-		maxinefb_init_one();
-
-	}
-
+	unregister_framebuffer(&fb_info);
 }
 
-void __init maxinefb_setup(char *options, int *ints)
-{
-}
+#ifdef MODULE
+module_init(maxinefb_init);
+#endif
+module_exit(maxinefb_exit);
+
diff -u --recursive --new-file v2.4.6/linux/drivers/video/tdfxfb.c linux/drivers/video/tdfxfb.c
--- v2.4.6/linux/drivers/video/tdfxfb.c	Wed Apr 18 11:49:12 2001
+++ linux/drivers/video/tdfxfb.c	Wed Jul  4 11:50:39 2001
@@ -1207,7 +1207,7 @@
    revc:		tdfx_cfbX_revc,   
    cursor:		tdfx_cfbX_cursor, 
    clear_margins:	tdfx_cfbX_clear_margins,
-   fontwidthmask:	FONTWIDTH(8)
+   fontwidthmask:	FONTWIDTHRANGE(8, 12)
 };
 #endif
 #ifdef FBCON_HAS_CFB16
@@ -1220,7 +1220,7 @@
    revc:		tdfx_cfbX_revc, 
    cursor:		tdfx_cfbX_cursor, 
    clear_margins:	tdfx_cfbX_clear_margins,
-   fontwidthmask:	FONTWIDTH(8)
+   fontwidthmask:	FONTWIDTHRANGE(8, 12)
 };
 #endif
 #ifdef FBCON_HAS_CFB24
@@ -1233,7 +1233,7 @@
    revc:		tdfx_cfbX_revc, 
    cursor:		tdfx_cfbX_cursor, 
    clear_margins:	tdfx_cfbX_clear_margins,
-   fontwidthmask:	FONTWIDTH(8)
+   fontwidthmask:	FONTWIDTHRANGE(8, 12)
 };
 #endif
 #ifdef FBCON_HAS_CFB32
@@ -1246,7 +1246,7 @@
    revc:		tdfx_cfbX_revc, 
    cursor:		tdfx_cfbX_cursor, 
    clear_margins:	tdfx_cfbX_clear_margins,
-   fontwidthmask:	FONTWIDTH(8)
+   fontwidthmask:	FONTWIDTHRANGE(8, 12)
 };
 #endif
 
@@ -1892,7 +1892,7 @@
        ((pdev->device == PCI_DEVICE_ID_3DFX_BANSHEE) ||
 	(pdev->device == PCI_DEVICE_ID_3DFX_VOODOO3) ||
 	(pdev->device == PCI_DEVICE_ID_3DFX_VOODOO5))) {
-      char *name;
+      char *name = NULL;
 
       fb_info.dev   = pdev->device;
       switch (pdev->device) {
@@ -2314,7 +2314,12 @@
    unsigned int h,to;
 
    tdfxfb_createcursorshape(p);
-   xline = (1 << fb_info.cursor.w)-1;
+   xline = ~((1 << (32 - fb_info.cursor.w)) - 1);
+
+#ifdef __LITTLE_ENDIAN
+   xline = swab32(xline);
+#endif
+
    cursorbase=(u8*)fb_info.bufbase_virt;
    h=fb_info.cursor.cursorimage;     
    
diff -u --recursive --new-file v2.4.6/linux/fs/jffs/jffs_fm.c linux/fs/jffs/jffs_fm.c
--- v2.4.6/linux/fs/jffs/jffs_fm.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/jffs/jffs_fm.c	Wed Jul  4 11:50:39 2001
@@ -47,7 +47,10 @@
 	mtd = get_mtd_device(NULL, MINOR(dev));
 
 	if (!mtd)
+	{
+		kfree(fmc);
 		return NULL;
+	}
 	
 	/* Retrieve the size of the flash memory.  */
 	fmc->flash_start = 0;
diff -u --recursive --new-file v2.4.6/linux/include/asm-cris/axisflashmap.h linux/include/asm-cris/axisflashmap.h
--- v2.4.6/linux/include/asm-cris/axisflashmap.h	Tue May  1 16:05:00 2001
+++ linux/include/asm-cris/axisflashmap.h	Wed Jul  4 11:50:39 2001
@@ -50,6 +50,7 @@
 };
 /* ended by an end marker: */
 #define PARTITIONTABLE_END_MARKER 0xFFFFFFFF
+#define PARTITIONTABLE_END_MARKER_SIZE 4
 
 /*#define PARTITION_TYPE_RESCUE 0x0000?*/  /* Not used, maybe it should? */
 #define PARTITION_TYPE_PARAM  0x0001 /* Hmm.. */
diff -u --recursive --new-file v2.4.6/linux/include/asm-cris/bitops.h linux/include/asm-cris/bitops.h
--- v2.4.6/linux/include/asm-cris/bitops.h	Fri Apr  6 10:51:19 2001
+++ linux/include/asm-cris/bitops.h	Wed Jul  4 11:50:39 2001
@@ -1,5 +1,15 @@
-/* $Id: bitops.h,v 1.4 2001/02/28 04:26:11 hp Exp $ */
-/* all of these should probably be rewritten in assembler for speed. */
+/* asm/bitops.h for Linux/CRIS
+ *
+ * TODO: asm versions if speed is needed
+ *       set_bit, clear_bit and change_bit wastes cycles being only
+ *       macros into test_and_set_bit etc.
+ *       kernel-doc things (**) for macros are disabled
+ *
+ * All bit operations return 0 if the bit was cleared before the
+ * operation and != 0 if it was not.
+ *
+ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ */
 
 #ifndef _CRIS_BITOPS_H
 #define _CRIS_BITOPS_H
@@ -10,25 +20,72 @@
 #include <asm/system.h>
 
 /*
- * These have to be done with inline assembly: that way the bit-setting
- * is guaranteed to be atomic. All bit operations return 0 if the bit
- * was cleared before the operation and != 0 if it was not.
- *
- * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
- */
-
-/*
  * Some hacks to defeat gcc over-optimizations..
  */
 struct __dummy { unsigned long a[100]; };
 #define ADDR (*(struct __dummy *) addr)
 #define CONST_ADDR (*(const struct __dummy *) addr)
 
+/*
+ * set_bit - Atomically set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This function is atomic and may not be reordered.  See __set_bit()
+ * if you do not require the atomic guarantees.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+
 #define set_bit(nr, addr)    (void)test_and_set_bit(nr, addr)
+
+/*
+ * clear_bit - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * clear_bit() is atomic and may not be reordered.  However, it does
+ * not contain a memory barrier, so if it is used for locking purposes,
+ * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
+ * in order to ensure changes are visible on other processors.
+ */
+
 #define clear_bit(nr, addr)  (void)test_and_clear_bit(nr, addr)
+
+/*
+ * change_bit - Toggle a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * change_bit() is atomic and may not be reordered.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+
 #define change_bit(nr, addr) (void)test_and_change_bit(nr, addr)
 
-extern __inline__ int test_and_set_bit(int nr, void *addr)
+/*
+ * __change_bit - Toggle a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * Unlike change_bit(), this function is non-atomic and may be reordered.
+ * If it's called on the same region of memory simultaneously, the effect
+ * may be that only one operation succeeds.
+ */
+
+#define __change_bit(nr, addr) (void)__test_and_change_bit(nr, addr)
+
+/**
+ * test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.  
+ * It also implies a memory barrier.
+ */
+
+static __inline__ int test_and_set_bit(int nr, void *addr)
 {
 	unsigned int mask, retval;
 	unsigned long flags;
@@ -50,7 +107,16 @@
 #define smp_mb__before_clear_bit()      barrier()
 #define smp_mb__after_clear_bit()       barrier()
 
-extern __inline__ int test_and_clear_bit(int nr, void *addr)
+/**
+ * test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.  
+ * It also implies a memory barrier.
+ */
+
+static __inline__ int test_and_clear_bit(int nr, void *addr)
 {
 	unsigned int mask, retval;
 	unsigned long flags;
@@ -66,7 +132,37 @@
 	return retval;
 }
 
-extern __inline__ int test_and_change_bit(int nr, void *addr)
+/**
+ * __test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic and can be reordered.  
+ * If two examples of this operation race, one can appear to succeed
+ * but actually fail.  You must protect multiple accesses with a lock.
+ */
+
+static __inline__ int __test_and_clear_bit(int nr, void *addr)
+{
+	unsigned int mask, retval;
+	unsigned int *adr = (unsigned int *)addr;
+	
+	adr += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *adr) != 0;
+	*adr &= ~mask;
+	return retval;
+}
+/**
+ * test_and_change_bit - Change a bit and return its new value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.  
+ * It also implies a memory barrier.
+ */
+
+static __inline__ int test_and_change_bit(int nr, void *addr)
 {
 	unsigned int mask, retval;
 	unsigned long flags;
@@ -81,10 +177,30 @@
 	return retval;
 }
 
-/*
+/* WARNING: non atomic and it can be reordered! */
+
+static __inline__ int __test_and_change_bit(int nr, void *addr)
+{
+	unsigned int mask, retval;
+	unsigned int *adr = (unsigned int *)addr;
+
+	adr += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *adr) != 0;
+	*adr ^= mask;
+
+	return retval;
+}
+
+/**
+ * test_bit - Determine whether a bit is set
+ * @nr: bit number to test
+ * @addr: Address to start counting from
+ *
  * This routine doesn't need to be atomic.
  */
-extern __inline__ int test_bit(int nr, const void *addr)
+
+static __inline__ int test_bit(int nr, const void *addr)
 {
 	unsigned int mask;
 	unsigned int *adr = (unsigned int *)addr;
@@ -102,7 +218,7 @@
  * ffz = Find First Zero in word. Undefined if no zero exists,
  * so code should check against ~0UL first..
  */
-extern __inline__ unsigned long ffz(unsigned long word)
+static __inline__ unsigned long ffz(unsigned long word)
 {
 	unsigned long result = 0;
 	
@@ -117,7 +233,7 @@
  * Find first one in word. Undefined if no one exists,
  * so code should check against 0UL first..
  */
-extern __inline__ unsigned long find_first_one(unsigned long word)
+static __inline__ unsigned long find_first_one(unsigned long word)
 {
 	unsigned long result = 0;
 	
@@ -128,7 +244,13 @@
 	return result;
 }
 
-extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+/**
+ * find_next_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ */
+static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
 {
 	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
 	unsigned long result = offset & ~31UL;
@@ -163,6 +285,15 @@
  found_middle:
 	return result + ffz(tmp);
 }
+
+/**
+ * find_first_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit-number of the first zero bit, not the number of the byte
+ * containing a bit.
+ */
 
 #define find_first_zero_bit(addr, size) \
         find_next_zero_bit((addr), (size), 0)
diff -u --recursive --new-file v2.4.6/linux/include/asm-cris/delay.h linux/include/asm-cris/delay.h
--- v2.4.6/linux/include/asm-cris/delay.h	Fri Apr  6 10:51:19 2001
+++ linux/include/asm-cris/delay.h	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: delay.h,v 1.3 2001/02/23 13:47:33 bjornw Exp $ */
+/* $Id: delay.h,v 1.4 2001/05/31 06:40:53 markusl Exp $ */
 
 #ifndef _CRIS_DELAY_H
 #define _CRIS_DELAY_H
@@ -20,23 +20,17 @@
 
 extern __inline__ void __delay(int loops)
 {
-	/* need to be a great deal of nops, because Etrax shuts off IRQ's during a branch
-	   and we depend on the irq's to measure the time! */
-	
 	__asm__ __volatile__ (
-			      "move.d %0,r0\n"
+			      "move.d %0,r0\n\t"
 			      "1:\n\t"
-			      "nop\n\t"
-			      "nop\n\t"
-			      "nop\n\t"
-			      "nop\n\t"
-			      "nop\n\t"
-			      "nop\n\t"
+			      "cmpq 0,r0\n\t"
+			      "beq 2f\n\t"
 			      "nop\n\t"
 			      "subq 1,r0\n\t"
-			      "bne 1b\n\t"
+			      "ba 1b\n\t"
 			      "nop\n\t"
-			      : : "r" (loops) : "r0", "cc");
+			      "2:\n\t"
+			      : : "r" (loops) : "r0");
 }
 
 
@@ -55,13 +49,7 @@
 	__delay(usecs * loops_per_usec);
 }
 
-extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
-{
-	printk("muldiv called!\n");
-	return 0;
-}
-
-#endif /* defined(_ETRAX_DELAY_H) */
+#endif /* defined(_CRIS_DELAY_H) */
 
 
 
diff -u --recursive --new-file v2.4.6/linux/include/asm-cris/dma.h linux/include/asm-cris/dma.h
--- v2.4.6/linux/include/asm-cris/dma.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/dma.h	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: dma.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $
+/* $Id: dma.h,v 1.2 2001/05/09 12:17:42 johana Exp $
  * linux/include/asm/dma.h: Defines for using and allocating dma channels.
  */
 
@@ -13,6 +13,44 @@
 /* TODO: check nbr of channels on Etrax-100LX */
 
 #define MAX_DMA_CHANNELS	10
+
+/* dma0 and dma1 used for network (ethernet) */
+#define NETWORK_TX_DMA_NBR 0
+#define NETWORK_RX_DMA_NBR 1
+
+/* dma2 and dma3 shared by par0, scsi0, ser2 and ata */
+#define PAR0_TX_DMA_NBR 2
+#define PAR0_RX_DMA_NBR 3
+#define SCSI0_TX_DMA_NBR 2
+#define SCSI0_RX_DMA_NBR 3
+#define SER2_TX_DMA_NBR 2
+#define SER2_RX_DMA_NBR 3
+#define ATA_TX_DMA_NBR 2
+#define ATA_RX_DMA_NBR 3
+
+/* dma4 and dma5 shared by par1, scsi1, ser3 and extdma0 */
+#define PAR1_TX_DMA_NBR 4
+#define PAR1_RX_DMA_NBR 5
+#define SCSI1_TX_DMA_NBR 4
+#define SCSI1_RX_DMA_NBR 5
+#define SER3_TX_DMA_NBR 4
+#define SER3_RX_DMA_NBR 5
+#define EXTDMA0_TX_DMA_NBR 4
+#define EXTDMA0_RX_DMA_NBR 5
+
+/* dma6 and dma7 shared by ser0, extdma1 and mem2mem */
+#define SER0_TX_DMA_NBR 6
+#define SER0_RX_DMA_NBR 7
+#define EXTDMA1_TX_DMA_NBR 6
+#define EXTDMA1_RX_DMA_NBR 7
+#define MEM2MEM_TX_DMA_NBR 6
+#define MEM2MEM_RX_DMA_NBR 7
+
+/* dma8 and dma9 shared by ser1 and usb */
+#define SER1_TX_DMA_NBR 8
+#define SER1_RX_DMA_NBR 9
+#define USB_TX_DMA_NBR 8
+#define USB_RX_DMA_NBR 9
 
 /* These are in kernel/dma.c: */
 extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
diff -u --recursive --new-file v2.4.6/linux/include/asm-cris/etraxgpio.h linux/include/asm-cris/etraxgpio.h
--- v2.4.6/linux/include/asm-cris/etraxgpio.h	Tue May  1 16:05:00 2001
+++ linux/include/asm-cris/etraxgpio.h	Wed Jul  4 11:50:39 2001
@@ -31,4 +31,8 @@
 /* LED ioctl extended */
 #define IO_LED_SETBIT 0xB
 #define IO_LED_CLRBIT 0xC
+
+/* SHUTDOWN ioctl */
+#define IO_SHUTDOWN   0xD
+#define IO_GET_PWR_BT 0xE
 #endif
diff -u --recursive --new-file v2.4.6/linux/include/asm-cris/io.h linux/include/asm-cris/io.h
--- v2.4.6/linux/include/asm-cris/io.h	Tue May  1 16:05:00 2001
+++ linux/include/asm-cris/io.h	Wed Jul  4 11:50:39 2001
@@ -128,12 +128,24 @@
 #define LED_ACTIVE_SET_R(x) \
          REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED2R, !(x))
 #define LED_DISK_WRITE(x) \
-         REG_SHADOW_SET(R_PORT_PB_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED3R, !(x))
+         REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED3R, !(x))
 #define LED_DISK_READ(x) \
-         REG_SHADOW_SET(R_PORT_PB_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED3G, !(x))     
+         REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED3G, !(x))     
 #endif
 
 #ifdef CONFIG_ETRAX_CSP0_LEDS
+#define CONFIGURABLE_LEDS\
+        ((1 << CONFIG_ETRAX_LED1G ) | (1 << CONFIG_ETRAX_LED1R ) |\
+         (1 << CONFIG_ETRAX_LED2G ) | (1 << CONFIG_ETRAX_LED2R ) |\
+         (1 << CONFIG_ETRAX_LED3G ) | (1 << CONFIG_ETRAX_LED3R ) |\
+         (1 << CONFIG_ETRAX_LED4G ) | (1 << CONFIG_ETRAX_LED4R ) |\
+         (1 << CONFIG_ETRAX_LED5G ) | (1 << CONFIG_ETRAX_LED5R ) |\
+         (1 << CONFIG_ETRAX_LED6G ) | (1 << CONFIG_ETRAX_LED6R ) |\
+         (1 << CONFIG_ETRAX_LED7G ) | (1 << CONFIG_ETRAX_LED7R ) |\
+         (1 << CONFIG_ETRAX_LED8Y ) | (1 << CONFIG_ETRAX_LED9Y ) |\
+         (1 << CONFIG_ETRAX_LED10Y ) |(1 << CONFIG_ETRAX_LED11Y )|\
+         (1 << CONFIG_ETRAX_LED12R ))
+
 #define LED_NETWORK_SET_G(x) \
          REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED1G, !(x))
 #define LED_NETWORK_SET_R(x) \
@@ -146,10 +158,24 @@
          REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED3R, !(x))
 #define LED_DISK_READ(x) \
          REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_LED3G, !(x))
-#define LED_BIT_SET(x) \
-         REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, x, 1)
-#define LED_BIT_CLR(x) \
-          REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, x, 0)        
+#define LED_BIT_SET(x)\
+        do{\
+                if((( 1 << x) & CONFIGURABLE_LEDS)  != 0)\
+                       REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, x, 1);\
+        }while(0)
+#define LED_BIT_CLR(x)\
+        do{\
+                if((( 1 << x) & CONFIGURABLE_LEDS)  != 0)\
+                       REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, x, 0);\
+        }while(0)
+#endif
+
+#
+#ifdef CONFIG_ETRAX_SOFT_SHUTDOWN
+#define SOFT_SHUTDOWN() \
+          REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, CONFIG_ETRAX_SHUTDOWN_BIT, 1)
+#else
+#define SOFT_SHUTDOWN()
 #endif
 
 /*
diff -u --recursive --new-file v2.4.6/linux/include/asm-cris/irq.h linux/include/asm-cris/irq.h
--- v2.4.6/linux/include/asm-cris/irq.h	Tue May  1 16:05:00 2001
+++ linux/include/asm-cris/irq.h	Wed Jul  4 11:50:39 2001
@@ -1,10 +1,11 @@
 /*
- * Interrupt handling assembler for Linux/CRIS
+ * Interrupt handling assembler and defines for Linux/CRIS
  *
  * Copyright (c) 2000 Axis Communications AB
  *
  * Authors:   Bjorn Wesen (bjornw@axis.com)
  *
+ * $Id: irq.h,v 1.11 2001/06/01 14:57:17 starvik Exp $
  */
 
 #ifndef _ASM_IRQ_H
@@ -20,6 +21,61 @@
 #include <asm/sv_addr_ag.h>
 
 #define NR_IRQS 32
+#define SOME_IRQ_NBR        IO_BITNR(R_VECT_MASK_RD, some)   /* 0 ? */
+#define NMI_IRQ_NBR         IO_BITNR(R_VECT_MASK_RD, nmi)    /* 1 */
+#define TIMER0_IRQ_NBR      IO_BITNR(R_VECT_MASK_RD, timer0) /* 2 */
+#define TIMER1_IRQ_NBR      IO_BITNR(R_VECT_MASK_RD, timer1) /* 3 */
+/* mio, ata, par0, scsi0 on 4 */
+/* par1, scsi1 on 5 */
+#define NETWORK_STATUS_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, network) /* 6 */
+
+#define SERIAL_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, network) /* 8 */
+#define PA_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, pa) /* 11 */
+/* extdma0 and extdma1 is at irq 12 and 13 and/or same as dma5 and dma6 ? */
+#define EXTDMA0_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, ext_dma0)
+#define EXTDMA1_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, ext_dma1)
+
+/* dma0-9 is irq 16..25 */
+/* 16,17: network */
+#define DMA0_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma0)
+#define DMA1_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma1)
+#define NETWORK_DMA_TX_IRQ_NBR DMA0_TX_IRQ_NBR
+#define NETWORK_DMA_RX_IRQ_NBR DMA1_RX_IRQ_NBR
+
+/* 18,19: dma2 and dma3 shared by par0, scsi0, ser2 and ata */
+#define DMA2_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma2)
+#define DMA3_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma3)
+#define SER2_DMA_TX_IRQ_NBR DMA2_TX_IRQ_NBR
+#define SER2_DMA_RX_IRQ_NBR DMA3_RX_IRQ_NBR
+
+/* 20,21: dma4 and dma5 shared by par1, scsi1, ser3 and extdma0 */
+#define DMA4_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma4)
+#define DMA5_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma5)
+#define SER3_DMA_TX_IRQ_NBR DMA4_TX_IRQ_NBR
+#define SER3_DMA_RX_IRQ_NBR DMA5_RX_IRQ_NBR
+
+/* 22,23: dma6 and dma7 shared by ser0, extdma1 and mem2mem */
+#define DMA6_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma6)
+#define DMA7_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma7)
+#define SER0_DMA_TX_IRQ_NBR DMA6_TX_IRQ_NBR
+#define SER0_DMA_RX_IRQ_NBR DMA7_RX_IRQ_NBR
+#define MEM2MEM_DMA_TX_IRQ_NBR DMA6_TX_IRQ_NBR
+#define MEM2MEM_DMA_RX_IRQ_NBR DMA7_RX_IRQ_NBR
+
+/* 24,25: dma8 and dma9 shared by ser1 and usb */
+#define DMA8_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma8)
+#define DMA9_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma9)
+#define SER1_DMA_TX_IRQ_NBR DMA8_TX_IRQ_NBR
+#define SER1_DMA_RX_IRQ_NBR DMA9_RX_IRQ_NBR
+#define USB_DMA_TX_IRQ_NBR DMA8_TX_IRQ_NBR
+#define USB_DMA_RX_IRQ_NBR DMA9_RX_IRQ_NBR
+
+/* usb: controller at irq 31 + uses DMA8 and DMA9 */
+#define USB_HC_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, usb)
+
+
+
+
 
 extern void disable_irq(unsigned int);
 extern void enable_irq(unsigned int);
diff -u --recursive --new-file v2.4.6/linux/include/asm-cris/mmu_context.h linux/include/asm-cris/mmu_context.h
--- v2.4.6/linux/include/asm-cris/mmu_context.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/mmu_context.h	Wed Jul  4 11:50:39 2001
@@ -9,6 +9,12 @@
 
 #define activate_mm(prev,next) switch_mm((prev),(next),NULL,smp_processor_id())
 
+/* current active pgd - this is similar to other processors pgd 
+ * registers like cr3 on the i386
+ */
+
+extern volatile pgd_t *current_pgd;   /* defined in arch/cris/mm/fault.c */
+
 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
 {
 }
diff -u --recursive --new-file v2.4.6/linux/include/asm-cris/ptrace.h linux/include/asm-cris/ptrace.h
--- v2.4.6/linux/include/asm-cris/ptrace.h	Tue May  1 16:05:00 2001
+++ linux/include/asm-cris/ptrace.h	Wed Jul  4 11:50:39 2001
@@ -22,8 +22,9 @@
 #define PT_MOF       16
 #define PT_DCCR      17
 #define PT_SRP       18
-#define PT_IRP       19
-#define PT_CSRINSTR  20    /* CPU Status record remnants - valid if frametype == busfault */
+#define PT_IRP       19    /* This is actually the debugged process' PC */
+#define PT_CSRINSTR  20    /* CPU Status record remnants -
+			      valid if frametype == busfault */
 #define PT_CSRADDR   21
 #define PT_CSRDATA   22
 #define PT_USP       23    /* special case - USP is not in the pt_regs */
@@ -31,12 +32,9 @@
 
 /* Frame types */
 
-#define CRIS_FRAME_NORMAL   0  /* normal frame without SBFS stacking */
-#define CRIS_FRAME_BUSFAULT 1  /* frame stacked using SBFS, need RBF return path */
-
-/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-#define PTRACE_GETREGS            12
-#define PTRACE_SETREGS            13
+#define CRIS_FRAME_NORMAL   0 /* normal frame without SBFS stacking */
+#define CRIS_FRAME_BUSFAULT 1 /* frame stacked using SBFS, need RBF return
+				 path */
 
 /* pt_regs not only specifices the format in the user-struct during
  * ptrace but is also the frame format used in the kernel prologue/epilogues 
@@ -47,10 +45,10 @@
 	unsigned long frametype;  /* type of stackframe */
 	unsigned long orig_r10;
 	/* pushed by movem r13, [sp] in SAVE_ALL, movem pushes backwards */
-	unsigned long r13; /* 8 */
-	unsigned long r12; /* 12 */
-	unsigned long r11; /* 16 */
-	unsigned long r10; /* 20 */
+	unsigned long r13;
+	unsigned long r12;
+	unsigned long r11;
+	unsigned long r10;
 	unsigned long r9;
 	unsigned long r8;
 	unsigned long r7;
@@ -64,20 +62,21 @@
 	unsigned long mof;
 	unsigned long dccr;
 	unsigned long srp;
-	unsigned long irp;
+	unsigned long irp; /* This is actually the debugged process' PC */
 	unsigned long csrinstr;
 	unsigned long csraddr;
 	unsigned long csrdata;
 };
 
-/* switch_stack is the extra stuff pushed onto the stack in _resume (entry.S) when
-   doing a context-switch. it is used (apart from in resume) when a new thread is made 
-   and we need to make _resume (which is starting it for the first time) realise what
-   is going on. 
-
-   actually, the use is very close to the thread struct (TSS) in that both the switch_stack
-   and the TSS are used to keep thread stuff when switching in _resume.
-*/
+/* switch_stack is the extra stuff pushed onto the stack in _resume (entry.S)
+ * when doing a context-switch. it is used (apart from in resume) when a new
+ * thread is made and we need to make _resume (which is starting it for the
+ * first time) realise what is going on.
+ *
+ * Actually, the use is very close to the thread struct (TSS) in that both the
+ * switch_stack and the TSS are used to keep thread stuff when switching in
+ * _resume.
+ */
 
 struct switch_stack {
 	unsigned long r9;
@@ -94,6 +93,10 @@
 };
 
 #ifdef __KERNEL__
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+
 /* bit 8 is user-mode flag */
 #define user_mode(regs) ((regs)->dccr & 0x100)
 #define instruction_pointer(regs) ((regs)->irp)
diff -u --recursive --new-file v2.4.6/linux/include/asm-cris/semaphore.h linux/include/asm-cris/semaphore.h
--- v2.4.6/linux/include/asm-cris/semaphore.h	Tue Apr 17 17:19:30 2001
+++ linux/include/asm-cris/semaphore.h	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: semaphore.h,v 1.2 2000/07/13 16:52:46 bjornw Exp $ */
+/* $Id: semaphore.h,v 1.3 2001/05/08 13:54:09 bjornw Exp $ */
 
 /* On the i386 these are coded in asm, perhaps we should as well. Later.. */
 
diff -u --recursive --new-file v2.4.6/linux/include/asm-cris/svinto.h linux/include/asm-cris/svinto.h
--- v2.4.6/linux/include/asm-cris/svinto.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/svinto.h	Wed Jul  4 11:50:39 2001
@@ -33,14 +33,29 @@
 	unsigned long  next;                  /* 4-7 */
 	unsigned long  buf;                   /* 8-11 */
 	unsigned short hw_len;                /* 12-13 */
-	unsigned short status;                /* 14-15 */
+	unsigned char  status;                /* 14 */
+	unsigned char  fifo_len;              /* 15 */
 } etrax_dma_descr;
 
-#define RESET_DMA( n ) \
+
+/* Use this for constant numbers only */
+#define RESET_DMA_NUM( n ) \
   *R_DMA_CH##n##_CMD = IO_STATE( R_DMA_CH0_CMD, cmd, reset )
 
-#define WAIT_DMA( n ) \
+/* Use this for constant numbers or symbols, 
+ * having two macros makes it possible to use constant expressions. 
+ */
+#define RESET_DMA( n ) RESET_DMA_NUM( n )
+
+
+/* Use this for constant numbers only */
+#define WAIT_DMA_NUM( n ) \
   while( (*R_DMA_CH##n##_CMD & IO_MASK( R_DMA_CH0_CMD, cmd )) != \
          IO_STATE( R_DMA_CH0_CMD, cmd, hold ) )
+
+/* Use this for constant numbers or symbols 
+ * having two macros makes it possible to use constant expressions. 
+ */
+#define WAIT_DMA( n ) WAIT_DMA_NUM( n )
 
 #endif
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/atomic.h linux/include/asm-mips64/atomic.h
--- v2.4.6/linux/include/asm-mips64/atomic.h	Tue Nov 28 21:42:04 2000
+++ linux/include/asm-mips64/atomic.h	Wed Jul  4 11:50:39 2001
@@ -21,7 +21,23 @@
 #ifdef __KERNEL__
 #define ATOMIC_INIT(i)    { (i) }
 
+/*
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically reads the value of @v.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
 #define atomic_read(v)	((v)->counter)
+
+/*
+ * atomic_set - set atomic variable
+ * @v: pointer of type atomic_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
 #define atomic_set(v,i)	((v)->counter = (i))
 
 extern __inline__ void atomic_add(int i, volatile atomic_t * v)
@@ -37,6 +53,14 @@
 		: "Ir" (i), "m" (v->counter));
 }
 
+/*
+ * atomic_sub - subtract the atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
 extern __inline__ void atomic_sub(int i, volatile atomic_t * v)
 {
 	unsigned long temp;
@@ -94,11 +118,71 @@
 #define atomic_dec_return(v) atomic_sub_return(1,(v))
 #define atomic_inc_return(v) atomic_add_return(1,(v))
 
+/*
+ * atomic_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v and returns
+ * true if the result is zero, or false for all
+ * other cases.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
 #define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+
+/*
+ * atomic_inc_and_test - increment and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ * atomic_inc_and_test is currently not implemented for mips64.
+ */
+
+/*
+ * atomic_dec_and_test - decrement by 1 and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
 #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
 
+/*
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
 #define atomic_inc(v) atomic_add(1,(v))
+
+/*
+ * atomic_dec - decrement and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
 #define atomic_dec(v) atomic_sub(1,(v))
+
+/*
+ * atomic_add_negative - add and test if negative
+ * @v: pointer of type atomic_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @v and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ *
+ * atomic_add_negative is currently not implemented for mips64.
+ */
+
 #endif /* defined(__KERNEL__) */
 
 #endif /* _ASM_ATOMIC_H */
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/bitops.h linux/include/asm-mips64/bitops.h
--- v2.4.6/linux/include/asm-mips64/bitops.h	Tue Nov 28 21:42:04 2000
+++ linux/include/asm-mips64/bitops.h	Wed Jul  4 11:50:39 2001
@@ -21,16 +21,15 @@
 #include <asm/mipsregs.h>
 
 /*
- * clear_bit() doesn't provide any barrier for the compiler.
+ * set_bit - Atomically set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This function is atomic and may not be reordered.  See __set_bit()
+ * if you do not require the atomic guarantees.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
  */
-#define smp_mb__before_clear_bit()	barrier()
-#define smp_mb__after_clear_bit()	barrier()
-
-/*
- * These functions for MIPS ISA > 1 are interrupt and SMP proof and
- * interrupt friendly
- */
-
 extern __inline__ void
 set_bit(unsigned long nr, volatile void *addr)
 {
@@ -47,7 +46,15 @@
 		: "memory");
 }
 
-/* WARNING: non atomic and it can be reordered! */
+/*
+ * __set_bit - Set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * Unlike set_bit(), this function is non-atomic and may be reordered.
+ * If it's called on the same region of memory simultaneously, the effect
+ * may be that only one operation succeeds.
+ */
 extern __inline__ void __set_bit(int nr, volatile void * addr)
 {
 	unsigned long * m = ((unsigned long *) addr) + (nr >> 6);
@@ -55,6 +62,16 @@
 	*m |= 1UL << (nr & 0x3f);
 }
 
+/*
+ * clear_bit - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * clear_bit() is atomic and may not be reordered.  However, it does
+ * not contain a memory barrier, so if it is used for locking purposes,
+ * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
+ * in order to ensure changes are visible on other processors.
+ */
 extern __inline__ void
 clear_bit(unsigned long nr, volatile void *addr)
 {
@@ -70,7 +87,18 @@
 		: "ir" (~(1UL << (nr & 0x3f))), "m" (*m));
 }
 
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
 
+/*
+ * change_bit - Toggle a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * change_bit() is atomic and may not be reordered.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
 extern __inline__ void
 change_bit(unsigned long nr, volatile void *addr)
 {
@@ -86,6 +114,30 @@
 		:"ir" (1UL << (nr & 0x3f)), "m" (*m));
 }
 
+/*
+ * __change_bit - Toggle a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * Unlike change_bit(), this function is non-atomic and may be reordered.
+ * If it's called on the same region of memory simultaneously, the effect
+ * may be that only one operation succeeds.
+ */
+extern __inline__ void __change_bit(int nr, volatile void * addr)
+{
+	unsigned long * m = ((unsigned long *) addr) + (nr >> 6);
+
+	*m ^= 1UL << (nr & 0x3f);
+}
+
+/*
+ * test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.  
+ * It also implies a memory barrier.
+ */
 extern __inline__ unsigned long
 test_and_set_bit(unsigned long nr, volatile void *addr)
 {
@@ -107,19 +159,37 @@
 	return res != 0;
 }
 
-extern __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+/*
+ * __test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic and can be reordered.  
+ * If two examples of this operation race, one can appear to succeed
+ * but actually fail.  You must protect multiple accesses with a lock.
+ */
+extern __inline__ int
+__test_and_set_bit(int nr, volatile void * addr)
 {
-	int mask, retval;
-	volatile long *a = addr;
+	unsigned long mask, retval;
+	long *a = (unsigned long *) addr;
 
-	a += nr >> 6;
-	mask = 1 << (nr & 0x3f);
-	retval = (mask & *a) != 0;
+	a += (nr >> 6);
+	mask = 1UL << (nr & 0x3f);
+	retval = ((mask & *a) != 0);
 	*a |= mask;
 
 	return retval;
 }
 
+/*
+ * test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.  
+ * It also implies a memory barrier.
+ */
 extern __inline__ unsigned long
 test_and_clear_bit(unsigned long nr, volatile void *addr)
 {
@@ -142,19 +212,37 @@
 	return res != 0;
 }
 
-extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+/*
+ * __test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic and can be reordered.  
+ * If two examples of this operation race, one can appear to succeed
+ * but actually fail.  You must protect multiple accesses with a lock.
+ */
+extern __inline__ int
+__test_and_clear_bit(int nr, volatile void * addr)
 {
-	int     mask, retval;
-	volatile long    *a = addr;
+	unsigned long mask, retval;
+	unsigned long *a = (unsigned long *) addr;
 
-	a += nr >> 6;
-	mask = 1 << (nr & 0x3f);
-	retval = (mask & *a) != 0;
+	a += (nr >> 6);
+	mask = 1UL << (nr & 0x3f);
+	retval = ((mask & *a) != 0);
 	*a &= ~mask;
 
 	return retval;
 }
 
+/*
+ * test_and_change_bit - Change a bit and return its new value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.  
+ * It also implies a memory barrier.
+ */
 extern __inline__ unsigned long
 test_and_change_bit(unsigned long nr, volatile void *addr)
 {
@@ -176,16 +264,51 @@
 	return res != 0;
 }
 
+/*
+ * __test_and_change_bit - Change a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic and can be reordered.  
+ * If two examples of this operation race, one can appear to succeed
+ * but actually fail.  You must protect multiple accesses with a lock.
+ */
+extern __inline__ int
+__test_and_change_bit(int nr, volatile void * addr)
+{
+	unsigned long mask, retval;
+	unsigned long *a = (unsigned long *) addr;
+
+	a += (nr >> 6);
+	mask = 1UL << (nr & 0x3f);
+	retval = ((mask & *a) != 0);
+	*a ^= mask;
+
+	return retval;
+}
+/*
+ * test_bit - Determine whether a bit is set
+ * @nr: bit number to test
+ * @addr: Address to start counting from
+ */
 extern __inline__ unsigned long
 test_bit(int nr, volatile void * addr)
 {
-	return 1UL & (((const long *) addr)[nr >> 6] >> (nr & 0x3f));
+	return 1UL & (((volatile unsigned long *) addr)[nr >> 6] >> (nr & 0x3f));
 }
 
 #ifndef __MIPSEB__
 
 /* Little endian versions. */
 
+/*
+ * find_first_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit-number of the first zero bit, not the number of the byte
+ * containing a bit.
+ */
 extern __inline__ int
 find_first_zero_bit (void *addr, unsigned size)
 {
@@ -228,6 +351,12 @@
 	return res;
 }
 
+/*
+ * find_next_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ */
 extern __inline__ int
 find_next_zero_bit (void * addr, int size, int offset)
 {
@@ -267,8 +396,10 @@
 #endif /* !(__MIPSEB__) */
 
 /*
- * ffz = Find First Zero in word. Undefined if no zero exists,
- * so code should check against ~0UL first..
+ * ffz - find first zero in word.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
  */
 extern __inline__ unsigned long ffz(unsigned long word)
 {
@@ -288,8 +419,12 @@
 
 #ifdef __KERNEL__
 
+
 /*
- * ffs: find first bit set. This is defined the same way as
+ * ffs - find first bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as
  * the libc and compiler builtin ffs routines, therefore
  * differs in spirit from the above ffz (man ffs).
  */
@@ -297,8 +432,10 @@
 #define ffs(x) generic_ffs(x)
 
 /*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
  */
 
 #define hweight32(x) generic_hweight32(x)
@@ -310,11 +447,11 @@
 #ifdef __MIPSEB__
 
 /*
- * find_next_zero_bit() finds the first zero bit in a bit string of length
- * 'size' bits, starting the search at bit 'offset'. This is largely based
- * on Linus's ALPHA routines, which are pretty portable BTW.
+ * find_next_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
  */
-
 extern __inline__ unsigned long
 find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
 {
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/bootinfo.h linux/include/asm-mips64/bootinfo.h
--- v2.4.6/linux/include/asm-mips64/bootinfo.h	Tue Nov 28 21:42:04 2000
+++ linux/include/asm-mips64/bootinfo.h	Wed Jul  4 11:50:39 2001
@@ -88,7 +88,7 @@
 /*
  * Valid machtype for group SGI
  */
-#define MACH_SGI_INDY		0	/* R4?K and R5K Indy workstaions */
+#define MACH_SGI_INDY		0	/* R4?K and R5K Indy workstations */
 #define MACH_SGI_CHALLENGE_S	1       /* The Challenge S server */
 #define MACH_SGI_INDIGO2	2	/* The Indigo2 system */
 #define MACH_SGI_IP27		3	/* Origin 200, Origin 2000, Onyx 2 */
@@ -144,6 +144,11 @@
 
 #define CL_SIZE      (80)
 
+#define BOOT_MEM_MAP_MAX        32
+#define BOOT_MEM_RAM            1
+#define BOOT_MEM_ROM_DATA       2
+#define BOOT_MEM_RESERVED       3
+
 #ifndef _LANGUAGE_ASSEMBLY
 
 /*
@@ -159,6 +164,24 @@
 extern unsigned long mips_machtype;
 extern unsigned long mips_machgroup;
 extern unsigned long mips_tlb_entries;
+
+/*
+ * A memory map that's built upon what was determined
+ * or specified on the command line.
+ */
+struct boot_mem_map {
+        int nr_map;
+        struct {
+                unsigned long addr;     /* start of memory segment */
+                unsigned long size;     /* size of memory segment */
+                long type;              /* type of memory segment */
+        } map[BOOT_MEM_MAP_MAX];
+};
+
+extern struct boot_mem_map boot_mem_map;
+
+extern void add_memory_region(unsigned long start, unsigned long size,
+                              long type);
 
 #endif /* _LANGUAGE_ASSEMBLY */
 
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/cache.h linux/include/asm-mips64/cache.h
--- v2.4.6/linux/include/asm-mips64/cache.h	Sat May 13 08:31:25 2000
+++ linux/include/asm-mips64/cache.h	Wed Jul  4 11:50:39 2001
@@ -1,5 +1,4 @@
-/* $Id: cache.h,v 1.3 2000/02/04 07:40:53 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -11,7 +10,6 @@
 #define _ASM_CACHE_H
 
 /* bytes per L1 cache line */
-#define L1_CACHE_BYTES		32	/* A guess */
-#define SMP_CACHE_BYTES		L1_CACHE_BYTES
+#define L1_CACHE_BYTES		(1 << CONFIG_L1_CACHE_SHIFT)
 
 #endif /* _ASM_CACHE_H */
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/checksum.h linux/include/asm-mips64/checksum.h
--- v2.4.6/linux/include/asm-mips64/checksum.h	Sat May 13 08:31:25 2000
+++ linux/include/asm-mips64/checksum.h	Wed Jul  4 11:50:39 2001
@@ -1,15 +1,17 @@
-/* $Id: checksum.h,v 1.6 2000/02/18 22:06:19 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
  * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2001 Thiemo Seufer.
  */
 #ifndef _ASM_CHECKSUM_H
 #define _ASM_CHECKSUM_H
 
+#include <asm/uaccess.h>
+
 /*
  * computes the checksum of a memory block at buff, length len,
  * and adds in "sum" (32-bit)
@@ -22,7 +24,7 @@
  *
  * it's best to have buff aligned on a 32-bit boundary
  */
-unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum);
 
 /*
  * this is a new version of the above that records errors it finds in *errp,
@@ -41,9 +43,9 @@
  * Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-extern inline unsigned int
-csum_and_copy_to_user (const char *src, char *dst,
-                       int len, int sum, int *err_ptr)
+extern inline unsigned int csum_and_copy_to_user (const char *src, char *dst,
+						  int len, int sum,
+						  int *err_ptr)
 {
 	sum = csum_partial(src, len, sum);
 
@@ -62,23 +64,23 @@
  * this is obsolete and will go away.
  */
 #define csum_partial_copy_fromuser csum_partial_copy
-unsigned int csum_partial_copy(const char *src, char *dst, int len, unsigned int sum);
-  
+unsigned int csum_partial_copy(const char *src, char *dst, int len,
+			       unsigned int sum);
+
 /*
  *	Fold a partial checksum without adding pseudo headers
  */
-static inline unsigned short int
-csum_fold(unsigned int sum)
+static inline unsigned short int csum_fold(unsigned int sum)
 {
-	__asm__("
-	.set	noat            
-	sll	$1, %0, 16
-	addu	%0, $1
-	sltu	$1, %0, $1
-	srl	%0, %0, 16
-	addu	%0, $1
-	xori	%0, 0xffff
-	.set	at"
+	__asm__(
+	".set\tnoat\t\t\t# csum_fold\n\t"
+	"sll\t$1,%0,16\n\t"
+	"addu\t%0,$1\n\t"
+	"sltu\t$1,%0,$1\n\t"
+	"srl\t%0,%0,16\n\t"
+	"addu\t%0,$1\n\t"
+	"xori\t%0,0xffff\n\t"
+	".set\tat"
 	: "=r" (sum)
 	: "0" (sum)
 	: "$1");
@@ -93,8 +95,8 @@
  *	By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
  *	Arnt Gulbrandsen.
  */
-static inline unsigned short
-ip_fast_csum(unsigned char * iph, unsigned int ihl)
+static inline unsigned short ip_fast_csum(unsigned char *iph,
+					  unsigned int ihl)
 {
 	unsigned int sum;
 	unsigned long dummy;
@@ -103,36 +105,35 @@
 	 * This is for 32-bit processors ...  but works just fine for 64-bit
 	 * processors for now ...  XXX
 	 */
-	__asm__ __volatile__("
-	.set	noreorder
-	.set	noat
-	lw	%0, (%1)
-	subu	%2, 4
-	dsll	%2, 2
-
-	lw	%3, 4(%1)
-	daddu	%2, %1
-	addu	%0, %3
-	sltu	$1, %0, %3
-	lw	%3, 8(%1)
-	addu	%0, $1
-	addu	%0, %3
-	sltu	$1, %0, %3
-	lw	%3, 12(%1)
-	addu	%0, $1
-	addu	%0, %3
-	sltu	$1, %0, %3
-	addu	%0, $1
-
-1:	lw	%3, 16(%1)
-	daddiu	%1, 4
-	addu	%0, %3
-	sltu	$1, %0, %3
-	bne	%2, %1, 1b
-	 addu	%0, $1
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# ip_fast_csum\n\t"
+	".set\tnoat\n\t"
+	"lw\t%0, (%1)\n\t"
+	"subu\t%2, 4\n\t"
+	"dsll\t%2, 2\n\t"
+	"lw\t%3, 4(%1)\n\t"
+	"daddu\t%2, %1\n\t"
+	"addu\t%0, %3\n\t"
+	"sltu\t$1, %0, %3\n\t"
+	"lw\t%3, 8(%1)\n\t"
+	"addu\t%0, $1\n\t"
+	"addu\t%0, %3\n\t"
+	"sltu\t$1, %0, %3\n\t"
+	"lw\t%3, 12(%1)\n\t"
+	"addu\t%0, $1\n\t"
+	"addu\t%0, %3\n\t"
+	"sltu\t$1, %0, %3\n\t"
+	"addu\t%0, $1\n"
+
+	"1:\tlw\t%3, 16(%1)\n\t"
+	"daddiu\t%1, 4\n"
+	"addu\t%0, %3\n\t"
+	"sltu\t$1, %0, %3\n\t"
+	"bne\t%2, %1, 1b\n\t"
+	" addu\t%0, $1\n"
 
-2:	.set	at
-	.set	reorder"
+	"2:\t.set\tat\n\t"
+	".set\treorder"
 	: "=&r" (sum), "=&r" (iph), "=&r" (ihl), "=&r" (dummy)
 	: "1" (iph), "2" (ihl)
 	: "$1");
@@ -144,26 +145,29 @@
  * computes the checksum of the TCP/UDP pseudo-header
  * returns a 16-bit checksum, already complemented
  */
-static inline unsigned long
-csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
-                   unsigned short len, unsigned short proto, unsigned int sum)
-{
-    __asm__("
-	.set	noat
-	daddu	%0, %2
-	daddu	%0, %3
-	daddu	%0, %4
-	dsll32	$1, %0, 0
-	daddu	%0, $1		# never results in an overflow
-	dsrl32	%0, %0, 0
-	.set	at"
+static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
+					       unsigned long daddr,
+					       unsigned short len,
+					       unsigned short proto,
+					       unsigned int sum)
+{
+	__asm__(
+	".set\tnoat\t\t\t# csum_tcpudp_nofold\n\t"
+	"daddu\t%0, %2\n\t"
+	"daddu\t%0, %3\n\t"
+	"daddu\t%0, %4\n\t"
+	"dsll32\t$1, %0, 0\n\t"
+	"daddu\t%0, $1\n\t"
+	"dsrl32\t%0, %0, 0\n\t"
+	".set\tat"
 	: "=r" (sum)
-	: "0" (sum), "r"(saddr), "r" (daddr),
+	: "0" (daddr), "r"(saddr),
 #ifdef __MIPSEL__
-	    "r" ((ntohs(len)<<16)+proto*256)
+	  "r" ((ntohs(len)<<16)+proto*256),
 #else
-	    "r" (((proto)<<16)+len)
+	  "r" (((proto)<<16)+len),
 #endif
+	  "r" (sum)
 	: "$1");
 
 	return sum;
@@ -173,82 +177,85 @@
  * computes the checksum of the TCP/UDP pseudo-header
  * returns a 16-bit checksum, already complemented
  */
-static inline unsigned short int
-csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
-                  unsigned short proto, unsigned int sum)
+static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
+						   unsigned long daddr,
+						   unsigned short len,
+						   unsigned short proto,
+						   unsigned int sum)
 {
-	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+	return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
 }
 
 /*
  * this routine is used for miscellaneous IP-like checksums, mainly
  * in icmp.c
  */
-static inline unsigned short
-ip_compute_csum(unsigned char * buff, int len)
+static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
 {
 	return csum_fold(csum_partial(buff, len, 0));
 }
 
 #define _HAVE_ARCH_IPV6_CSUM
-static inline unsigned short int
-csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len,
-                unsigned short proto, unsigned int sum) 
-{
-	__asm__("
-		.set	noreorder
-		.set	noat
-		addu	%0, %5		# proto (long in network byte order)
-		sltu	$1, %0, %5
-		addu	%0, $1
-
-		addu	%0, %6		# csum
-		sltu	$1, %0, %6
-		lw	%1, 0(%2)	# four words source address
-		addu	%0, $1
-		addu	%0, %1
-		sltu	$1, %0, $1
-
-		lw	%1, 4(%2)
-		addu	%0, $1
-		addu	%0, %1
-		sltu	$1, %0, $1
-
-		lw	%1, 8(%2)
-		addu	%0, $1
-		addu	%0, %1
-		sltu	$1, %0, $1
-
-		lw	%1, 12(%2)
-		addu	%0, $1
-		addu	%0, %1
-		sltu	$1, %0, $1
-
-		lw	%1, 0(%3)
-		addu	%0, $1
-		addu	%0, %1
-		sltu	$1, %0, $1
-
-		lw	%1, 4(%3)
-		addu	%0, $1
-		addu	%0, %1
-		sltu	$1, %0, $1
-
-		lw	%1, 8(%3)
-		addu	%0, $1
-		addu	%0, %1
-		sltu	$1, %0, $1
-
-		lw	%1, 12(%3)
-		addu	%0, $1
-		addu	%0, %1
-		sltu	$1, %0, $1
-		.set	noat
-		.set	noreorder"
-		: "=r" (sum), "=r" (proto)
-		: "r" (saddr), "r" (daddr),
-		  "0" (htonl(len)), "1" (htonl(proto)), "r"(sum)
-		: "$1");
+static inline unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
+						 struct in6_addr *daddr,
+						 __u32 len,
+						 unsigned short proto,
+						 unsigned int sum) 
+{
+	__asm__(
+	".set\tnoreorder\t\t\t# csum_ipv6_magic\n\t"
+	".set\tnoat\n\t"
+	"addu\t%0, %5\t\t\t# proto (long in network byte order)\n\t"
+	"sltu\t$1, %0, %5\n\t"
+	"addu\t%0, $1\n\t"
+
+	"addu\t%0, %6\t\t\t# csum\n\t"
+	"sltu\t$1, %0, %6\n\t"
+	"lw\t%1, 0(%2)\t\t\t# four words source address\n\t"
+	"addu\t%0, $1\n\t"
+	"addu\t%0, %1\n\t"
+	"sltu\t$1, %0, $1\n\t"
+
+	"lw\t%1, 4(%2)\n\t"
+	"addu\t%0, $1\n\t"
+	"addu\t%0, %1\n\t"
+	"sltu\t$1, %0, $1\n\t"
+
+	"lw\t%1, 8(%2)\n\t"
+	"addu\t%0, $1\n\t"
+	"addu\t%0, %1\n\t"
+	"sltu\t$1, %0, $1\n\t"
+
+	"lw\t%1, 12(%2)\n\t"
+	"addu\t%0, $1\n\t"
+	"addu\t%0, %1\n\t"
+	"sltu\t$1, %0, $1\n\t"
+
+	"lw\t%1, 0(%3)\n\t"
+	"addu\t%0, $1\n\t"
+	"addu\t%0, %1\n\t"
+	"sltu\t$1, %0, $1\n\t"
+
+	"lw\t%1, 4(%3)\n\t"
+	"addu\t%0, $1\n\t"
+	"addu\t%0, %1\n\t"
+	"sltu\t$1, %0, $1\n\t"
+
+	"lw\t%1, 8(%3)\n\t"
+	"addu\t%0, $1\n\t"
+	"addu\t%0, %1\n\t"
+	"sltu\t$1, %0, $1\n\t"
+
+	"lw\t%1, 12(%3)\n\t"
+	"addu\t%0, $1\n\t"
+	"addu\t%0, %1\n\t"
+	"sltu\t$1, %0, $1\n\t"
+	".set\tnoat\n\t"
+	".set\tnoreorder"
+	: "=r" (sum), "=r" (proto)
+	: "r" (saddr), "r" (daddr),
+	  "0" (htonl(len)), "1" (htonl(proto)), "r" (sum)
+	: "$1");
 
 	return csum_fold(sum);
 }
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/cpu.h linux/include/asm-mips64/cpu.h
--- v2.4.6/linux/include/asm-mips64/cpu.h	Sat May 13 08:31:25 2000
+++ linux/include/asm-mips64/cpu.h	Wed Jul  4 11:50:39 2001
@@ -1,5 +1,4 @@
-/* $Id: cpu.h,v 1.1 1999/10/19 20:51:53 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -18,17 +17,18 @@
  * be examined.
  */
 #define PRID_IMP_R2000    0x0100
-#define PRID_IMP_R3000    0x0200
-#define PRID_IMP_R6000    0x0300
+#define PRID_IMP_R3000    0x0200	/* Same as R2000A  */
+#define PRID_IMP_R6000    0x0300	/* Same as R3000A  */
 #define PRID_IMP_R4000    0x0400
 #define PRID_IMP_R6000A   0x0600
 #define PRID_IMP_R10000   0x0900
 #define PRID_IMP_R4300    0x0b00
+#define PRID_IMP_R12000   0x0e00
 #define PRID_IMP_R8000    0x1000
 #define PRID_IMP_R4600    0x2000
 #define PRID_IMP_R4700    0x2100
 #define PRID_IMP_R4640    0x2200
-#define PRID_IMP_R4650    0x2200		/* Same as R4640 */
+#define PRID_IMP_R4650    0x2200	/* Same as R4640 */
 #define PRID_IMP_R5000    0x2300
 #define PRID_IMP_SONIC    0x2400
 #define PRID_IMP_MAGIC    0x2500
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/delay.h linux/include/asm-mips64/delay.h
--- v2.4.6/linux/include/asm-mips64/delay.h	Sun Feb  4 21:48:46 2001
+++ linux/include/asm-mips64/delay.h	Wed Jul  4 11:50:39 2001
@@ -12,7 +12,7 @@
 
 #include <linux/config.h>
 
-extern unsigned long loops_per_sec;
+extern unsigned long loops_per_jiffy;
 
 extern __inline__ void
 __delay(unsigned long loops)
@@ -36,21 +36,21 @@
  * first constant multiplications gets optimized away if the delay is
  * a constant)
  */
-extern __inline__ void __udelay(unsigned long usecs, unsigned long lps)
+extern __inline__ void __udelay(unsigned long usecs, unsigned long lpj)
 {
 	unsigned long lo;
 
-	usecs *= 0x000010c6f7a0b5edUL;		/* 2**64 / 1000000 */
+	usecs *= 0x00068db8bac710cbUL;		/* 2**64 / (1000000 / HZ) */
 	__asm__("dmultu\t%2,%3"
 		:"=h" (usecs), "=l" (lo)
-		:"r" (usecs),"r" (lps));
+		:"r" (usecs),"r" (lpj));
 	__delay(usecs);
 }
 
 #ifdef CONFIG_SMP
 #define __udelay_val cpu_data[smp_processor_id()].udelay_val
 #else
-#define __udelay_val loops_per_sec
+#define __udelay_val loops_per_jiffy
 #endif
 
 #define udelay(usecs) __udelay((usecs),__udelay_val)
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/elf.h linux/include/asm-mips64/elf.h
--- v2.4.6/linux/include/asm-mips64/elf.h	Thu Jul 27 18:36:54 2000
+++ linux/include/asm-mips64/elf.h	Wed Jul  4 11:50:39 2001
@@ -29,8 +29,7 @@
 	int __res = 1;							\
 	struct elfhdr *__h = (hdr);					\
 									\
-	if ((__h->e_machine != EM_MIPS) &&				\
-	    (__h->e_machine != EM_MIPS_RS4_BE))				\
+	if (__h->e_machine != EM_MIPS)					\
 		__res = 0;						\
 	if (sizeof(elf_caddr_t) == 8 &&					\
 	    __h->e_ident[EI_CLASS] == ELFCLASS32)			\
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/gcc/sgidefs.h linux/include/asm-mips64/gcc/sgidefs.h
--- v2.4.6/linux/include/asm-mips64/gcc/sgidefs.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/gcc/sgidefs.h	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,17 @@
+/*
+ * include/sgidefs.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ *
+ * This file is here to satisfy GCC's expectations.
+ */
+#ifndef __SGIDEFS_H
+#define __SGIDEFS_H
+
+#include <asm/sgidefs.h>
+
+#endif /* __SGIDEFS_H */
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/hdreg.h linux/include/asm-mips64/hdreg.h
--- v2.4.6/linux/include/asm-mips64/hdreg.h	Sat May 13 08:31:25 2000
+++ linux/include/asm-mips64/hdreg.h	Wed Jul  4 11:50:39 2001
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -7,12 +6,13 @@
  *  This file contains the MIPS architecture specific IDE code.
  *
  *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ *  Copyright (C) 2001 Ralf Baechle
  */
 
 #ifndef _ASM_HDREG_H
 #define _ASM_HDREG_H
 
-typedef unsigned short ide_ioreg_t;
+typedef unsigned long ide_ioreg_t;
 
 #endif /* _ASM_HDREG_H */
 
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/ide.h linux/include/asm-mips64/ide.h
--- v2.4.6/linux/include/asm-mips64/ide.h	Sun Jul  9 22:18:15 2000
+++ linux/include/asm-mips64/ide.h	Wed Jul  4 11:50:39 2001
@@ -8,10 +8,6 @@
  * Copyright (C) 1994-1996  Linus Torvalds & authors
  */
 
-/*
- *  This file contains the MIPS architecture specific IDE code.
- */
-
 #ifndef __ASM_IDE_H
 #define __ASM_IDE_H
 
@@ -128,6 +124,52 @@
 {
 	ide_ops->ide_release_region(from, extent);
 }
+
+
+#if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)
+
+#ifdef insl
+#undef insl
+#endif
+#ifdef outsl
+#undef outsl
+#endif
+#ifdef insw
+#undef insw
+#endif
+#ifdef outsw
+#undef outsw
+#endif
+
+#define insw(p,a,c)							\
+do {									\
+	unsigned short *ptr = (unsigned short *)(a);			\
+	unsigned int i = (c);						\
+	while (i--)							\
+		*ptr++ = inw(p);					\
+} while (0)
+#define insl(p,a,c)							\
+do {									\
+	unsigned long *ptr = (unsigned long *)(a);			\
+	unsigned int i = (c);						\
+	while (i--)							\
+		*ptr++ = inl(p);					\
+} while (0)
+#define outsw(p,a,c)							\
+do {									\
+	unsigned short *ptr = (unsigned short *)(a);			\
+	unsigned int i = (c);						\
+	while (i--)							\
+		outw(*ptr++, (p));					\
+} while (0)
+#define outsl(p,a,c) {							\
+	unsigned long *ptr = (unsigned long *)(a);			\
+	unsigned int i = (c);						\
+	while (i--)							\
+		outl(*ptr++, (p));					\
+} while (0)
+
+#endif /* defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)  */
 
 /*
  * The following are not needed for the non-m68k ports
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/io.h linux/include/asm-mips64/io.h
--- v2.4.6/linux/include/asm-mips64/io.h	Tue Nov 28 21:42:04 2000
+++ linux/include/asm-mips64/io.h	Wed Jul  4 11:50:39 2001
@@ -185,7 +185,7 @@
 	".set\tnoreorder\n\t" \
 	".set\tnoat\n" \
 	"1:\tl" #m "\t$1, %4(%5)\n\t" \
-	"dsubiu\t%1, 1\n\t" \
+	"dsubu\t%1, 1\n\t" \
 	"s" #m "\t$1,(%0)\n\t" \
 	"bnez\t%1, 1b\n\t" \
 	"daddiu\t%0, %6\n\t" \
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/ioctl.h linux/include/asm-mips64/ioctl.h
--- v2.4.6/linux/include/asm-mips64/ioctl.h	Sat May 13 08:31:25 2000
+++ linux/include/asm-mips64/ioctl.h	Wed Jul  4 11:50:39 2001
@@ -1,10 +1,9 @@
-/* $Id$
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996, 1999 by Ralf Baechle
+ * Copyright (C) 1995, 1996, 1999, 2001 by Ralf Baechle
  */
 #ifndef _ASM_IOCTL_H
 #define _ASM_IOCTL_H
@@ -39,11 +38,6 @@
 #define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
 
 /*
- * We to additionally limit parameters to a maximum 255 bytes.
- */
-#define _IOC_SLMASK	0xff
-
-/*
  * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit.
  * And this turns out useful to catch old ioctl numbers in header
  * files for us.
@@ -64,7 +58,7 @@
 	(((dir)  << _IOC_DIRSHIFT) | \
 	 ((type) << _IOC_TYPESHIFT) | \
 	 ((nr)   << _IOC_NRSHIFT) | \
-	 (((size) & _IOC_SLMASK) << _IOC_SIZESHIFT))
+	 ((size) << _IOC_SIZESHIFT))
 
 /* used to create numbers */
 #define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/ioctls.h linux/include/asm-mips64/ioctls.h
--- v2.4.6/linux/include/asm-mips64/ioctls.h	Sat May 13 08:31:25 2000
+++ linux/include/asm-mips64/ioctls.h	Wed Jul  4 11:50:39 2001
@@ -58,6 +58,7 @@
 #define FIONCLEX	0x6602		/* these numbers need to be adjusted. */
 #define FIOASYNC	0x667d
 #define FIONBIO		0x667e
+#define FIOQSIZE	0x667f
 
 #if defined(__USE_MISC) || defined (__KERNEL__)
 #define TIOCGLTC	(tIOC | 116)		/* get special local chars */
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/irq.h linux/include/asm-mips64/irq.h
--- v2.4.6/linux/include/asm-mips64/irq.h	Tue Nov 28 21:42:04 2000
+++ linux/include/asm-mips64/irq.h	Wed Jul  4 11:50:39 2001
@@ -6,15 +6,32 @@
  * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle
  * Copyright (C) 1995, 96, 97, 98, 1999, 2000 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 Kanoj Sarcar
  */
 #ifndef _ASM_IRQ_H
 #define _ASM_IRQ_H
 
 #include <linux/config.h>
+#include <asm/sn/arch.h>
 
 #define NR_IRQS 256
 
-#define TIMER_IRQ 0
+/*
+ * Number of levels in INT_PEND0. Can be set to 128 if we also
+ * consider INT_PEND1.
+ */
+#define PERNODE_LEVELS	64
+
+extern int node_level_to_irq[MAX_COMPACT_NODES][PERNODE_LEVELS];
+
+/*
+ * we need to map irq's up to at least bit 7 of the INT_MASK0_A register
+ * since bits 0-6 are pre-allocated for other purposes.
+ */
+#define LEAST_LEVEL	7
+#define FAST_IRQ_TO_LEVEL(i)	((i) + LEAST_LEVEL)
+#define LEVEL_TO_IRQ(c, l) \
+			(node_level_to_irq[CPUID_TO_COMPACT_NODEID(c)][(l)])
 
 #ifdef CONFIG_I8259
 static inline int irq_cannonicalize(int irq)
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/mipsregs.h linux/include/asm-mips64/mipsregs.h
--- v2.4.6/linux/include/asm-mips64/mipsregs.h	Fri Apr 13 20:26:07 2001
+++ linux/include/asm-mips64/mipsregs.h	Wed Jul  4 11:50:39 2001
@@ -246,7 +246,7 @@
 #define  CAUSEF_BD		(1   << 31)
 
 /*
- * Bits in the coprozessor 0 config register.
+ * Bits in the coprocessor 0 config register.
  */
 #define CONF_CM_CACHABLE_NO_WA		0
 #define CONF_CM_CACHABLE_WA		1
@@ -265,7 +265,7 @@
  * R10000 performance counter definitions.
  *
  * FIXME: The R10000 performance counter opens a nice way to implement CPU
- *        time accounting with a precission of one cycle.  I don't have
+ *        time accounting with a precision of one cycle.  I don't have
  *        R10000 silicon but just a manual, so ...
  */
 
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/pci.h linux/include/asm-mips64/pci.h
--- v2.4.6/linux/include/asm-mips64/pci.h	Wed May 16 10:31:27 2001
+++ linux/include/asm-mips64/pci.h	Wed Jul  4 11:50:39 2001
@@ -1,5 +1,4 @@
-/* $Id: pci.h,v 1.4 2000/02/24 00:13:20 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -196,8 +195,21 @@
 #endif
 }
 
-/* Return the index of the PCI controller for device PDEV. */
-#define pci_controller_num(PDEV)	(0)
+extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
+{
+	/*
+	 * we fall back to GFP_DMA when the mask isn't all 1s,
+	 * so we can't guarantee allocations that must be
+	 * within a tighter range than GFP_DMA..
+	 */
+	if (mask < 0x00ffffff)
+		return 0;
+
+	return 1;
+}
+
+/* Return the index of the PCI controller for device. */
+#define pci_controller_num(pdev)	(0)
 
 /*
  * These macros should be used after a pci_map_sg call has been done
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/pgalloc.h linux/include/asm-mips64/pgalloc.h
--- v2.4.6/linux/include/asm-mips64/pgalloc.h	Mon Apr 23 15:28:07 2001
+++ linux/include/asm-mips64/pgalloc.h	Wed Jul  4 11:50:39 2001
@@ -3,8 +3,8 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994 - 2000 by Ralf Baechle at alii
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1994 - 2001 by Ralf Baechle at alii
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_PGALLOC_H
 #define _ASM_PGALLOC_H
@@ -49,9 +49,7 @@
 
 
 /*
- * Allocate and free page tables. The xxx_kernel() versions are
- * used to allocate a kernel page table - this turns on ASN bits
- * if any.
+ * Allocate and free page tables.
  */
 
 #define pgd_quicklist (current_cpu_data.pgd_quick)
@@ -59,6 +57,9 @@
 #define pte_quicklist (current_cpu_data.pte_quick)
 #define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
 
+#define pmd_populate(mm, pmd, pte)	pmd_set(pmd, pte)
+#define pgd_populate(mm, pgd, pmd)	pgd_set(pgd, pmd)
+
 extern pgd_t *get_pgd_slow(void);
 
 extern inline pgd_t *get_pgd_fast(void)
@@ -88,8 +89,29 @@
 	free_pages((unsigned long)pgd, 1);
 }
 
+static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+	pte_t *pte;
+
+	pte = (pte_t *) __get_free_page(GFP_KERNEL);
+	if (pte)
+		clear_page(pte);
+	return pte;
+}
+
+static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
+{
+	unsigned long *ret;
+
+	if ((ret = (unsigned long *)pte_quicklist) != NULL) {
+		pte_quicklist = (unsigned long *)(*ret);
+		ret[0] = ret[1];
+		pgtable_cache_size--;
+	}
+	return (pte_t *)ret;
+}
+
 extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
-extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long address_preadjusted);
 
 extern inline pte_t *get_pte_fast(void)
 {
@@ -115,8 +137,29 @@
 	free_pages((unsigned long)pte, 0);
 }
 
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+	pmd_t *pmd;
+
+	pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, 1);
+	if (pmd)
+		pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table);
+	return pmd;
+}
+
+static inline pmd_t *pmd_alloc_one_fast(struct mm_struct *mm, unsigned long address)
+{
+	unsigned long *ret;
+
+	if ((ret = (unsigned long *)pmd_quicklist) != NULL) {
+		pmd_quicklist = (unsigned long *)(*ret);
+		ret[0] = ret[1];
+		pgtable_cache_size--;
+	}
+	return (pmd_t *)ret;
+}
+
 extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long address_preadjusted);
-extern pmd_t *get_pmd_kernel_slow(pgd_t *pgd, unsigned long address_preadjusted);
 
 extern inline pmd_t *get_pmd_fast(void)
 {
@@ -144,61 +187,13 @@
 	free_pages((unsigned long)pmd, 1);
 }
 
-extern void __bad_pte(pmd_t *pmd);
-extern void __bad_pte_kernel(pmd_t *pmd);
-extern void __bad_pmd(pgd_t *pgd);
-
 #define pte_free(pte)           free_pte_fast(pte)
 #define pmd_free(pte)           free_pmd_fast(pte)
 #define pgd_free(pgd)           free_pgd_fast(pgd)
 #define pgd_alloc(mm)           get_pgd_fast()
 
-extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
-{
-	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
-
-	if (pmd_none(*pmd)) {
-		pte_t *page = get_pte_fast();
-		if (page) {
-			pmd_val(*pmd) = (unsigned long) page;
-			return page + address;
-		}
-		return get_pte_slow(pmd, address);
-	}
-	if (pmd_bad(*pmd)) {
-		__bad_pte(pmd);
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + address;
-}
-
-extern inline pmd_t *pmd_alloc(pgd_t * pgd, unsigned long address)
-{
-	address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
-	if (pgd_none(*pgd)) {
-		pmd_t *page = get_pmd_fast();
-
-		if (!page)
-			return get_pmd_slow(pgd, address);
-		pgd_set(pgd, page);
-		return page + address;
-	}
-	if (pgd_bad(*pgd)) {
-		__bad_pmd(pgd);
-		return NULL;
-	}
-	return (pmd_t *) pgd_page(*pgd) + address;
-}
-
 extern pte_t kptbl[(PAGE_SIZE<<KPTBL_PAGE_ORDER)/sizeof(pte_t)];
 extern pmd_t kpmdtbl[PTRS_PER_PMD];
-
-#define pmd_alloc_kernel(d,a)	(pmd_t *)kpmdtbl
-
-extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
-{
-	return (kptbl + (address >> PAGE_SHIFT));
-}
 
 extern int do_check_pgt_cache(int, int);
 
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/pgtable.h linux/include/asm-mips64/pgtable.h
--- v2.4.6/linux/include/asm-mips64/pgtable.h	Tue Nov 28 21:42:04 2000
+++ linux/include/asm-mips64/pgtable.h	Wed Jul  4 11:50:39 2001
@@ -3,8 +3,8 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994 - 2000 by Ralf Baechle at alii
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1994 - 2001 by Ralf Baechle at alii
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_PGTABLE_H
 #define _ASM_PGTABLE_H
@@ -177,15 +177,25 @@
 
 #define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK)
 
-#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_COW)
+#ifdef CONFIG_MIPS_UNCACHED
+#define PAGE_CACHABLE_DEFAULT _CACHE_UNCACHED
+#else /* ! UNCACHED */
+#ifdef CONFIG_SGI_IP22
+#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_NONCOHERENT
+#else /* ! IP22 */
+#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW
+#endif /* IP22 */
+#endif /* UNCACHED */
+
+#define PAGE_NONE	__pgprot(_PAGE_PRESENT | PAGE_CACHABLE_DEFAULT)
 #define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
-			_CACHE_CACHABLE_COW)
+			PAGE_CACHABLE_DEFAULT)
 #define PAGE_COPY       __pgprot(_PAGE_PRESENT | _PAGE_READ | \
-			_CACHE_CACHABLE_COW)
+			PAGE_CACHABLE_DEFAULT)
 #define PAGE_READONLY   __pgprot(_PAGE_PRESENT | _PAGE_READ | \
-			_CACHE_CACHABLE_COW)
+			PAGE_CACHABLE_DEFAULT)
 #define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
-			_CACHE_CACHABLE_COW)
+			PAGE_CACHABLE_DEFAULT)
 #define PAGE_USERIO     __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
 			_CACHE_UNCACHED)
 #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
@@ -224,22 +234,13 @@
 	printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
 
 /*
- * BAD_PAGETABLE is used when we need a bogus page-table, while
- * BAD_PAGE is used for a bogus page.
- *
  * ZERO_PAGE is a global shared page that is always zero: used
  * for zero-mapped memory areas etc..
  */
-extern pte_t __bad_page(void);
-extern pte_t *__bad_pagetable(void);
-extern pmd_t *__bad_pmd_table(void);
 
 extern unsigned long empty_zero_page;
 extern unsigned long zero_page_mask;
 
-#define BAD_PAGETABLE __bad_pagetable()
-#define BAD_PMDTABLE __bad_pmd_table()
-#define BAD_PAGE __bad_page()
 #define ZERO_PAGE(vaddr) \
 	(virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask)))
 
@@ -297,7 +298,8 @@
 	return pte_val(pte) & _PAGE_PRESENT;
 }
 
-/* Certain architectures need to do special things when pte's
+/*
+ * Certain architectures need to do special things when pte's
  * within a page table are directly modified.  Thus, the following
  * hook is made available.
  */
@@ -312,6 +314,13 @@
 }
 
 /*
+ * (pmds are folded into pgds so this doesnt get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
+#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
+
+/*
  * Empty pmd entries point to the invalid_pte_table.
  */
 extern inline int pmd_none(pmd_t pmd)
@@ -321,7 +330,12 @@
 
 extern inline int pmd_bad(pmd_t pmd)
 {
-	return pmd_val(pmd) == (unsigned long) empty_bad_page_table;
+	return pmd_val(pmd) &~ PAGE_MASK;
+}
+
+extern inline int pmd_present(pmd_t pmd)
+{
+	return pmd_val(pmd) != (unsigned long) invalid_pte_table;
 }
 
 extern inline void pmd_clear(pmd_t *pmdp)
@@ -339,7 +353,12 @@
 
 extern inline int pgd_bad(pgd_t pgd)
 {
-	return pgd_val(pgd) == (unsigned long) empty_bad_pmd_table;
+	return pgd_val(pgd) &~ PAGE_MASK;
+}
+
+extern inline int pgd_present(pgd_t pgd)
+{
+	return pgd_val(pgd) != (unsigned long) invalid_pmd_table;
 }
 
 extern inline void pgd_clear(pgd_t *pgdp)
@@ -350,7 +369,6 @@
 /*
  * Permanent address of a page.  On MIPS64 we never have highmem, so this
  * is simple.
- * called on a highmem page.
  */
 #define page_address(page)	((page)->virtual)
 #ifndef CONFIG_DISCONTIGMEM
@@ -761,7 +779,7 @@
 
 	__asm__ __volatile__(
 		".set noreorder\n\t"
-		"mfc0 %0, $4\n\t"
+		"dmfc0 %0, $4\n\t"
 		".set reorder"
 		: "=r" (val));
 
@@ -772,7 +790,7 @@
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
-		"mtc0 %0, $4\n\t"
+		"dmtc0 %0, $4\n\t"
 		".set reorder"
 		: : "r" (val));
 }
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/processor.h linux/include/asm-mips64/processor.h
--- v2.4.6/linux/include/asm-mips64/processor.h	Sat Dec 30 09:35:40 2000
+++ linux/include/asm-mips64/processor.h	Wed Jul  4 11:50:39 2001
@@ -26,7 +26,7 @@
 ({									\
 	void *_a;							\
 									\
-	__asm__ ("jal\t1f, 1f\n\t"					\
+	__asm__ ("jal\t1f, %0\n\t"					\
 		"1:"							\
 		: "=r" (_a));						\
 									\
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/rrm.h linux/include/asm-mips64/rrm.h
--- v2.4.6/linux/include/asm-mips64/rrm.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/rrm.h	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,88 @@
+/*
+ * SGI Rendering Resource Manager API (?).
+ *
+ * written by Miguel de Icaza (miguel@nuclecu.unam.mx)
+ *
+ * Ok, even if SGI choosed to do mmap trough ioctls, their
+ * kernel support for virtualizing the graphics card is nice.
+ *
+ * We should be able to make graphic applications on Linux
+ * fly.
+ *
+ * This header file should be included from GNU libc as well.
+ */
+
+
+/* Why like this you say?  Well, gdb can print enums */
+#define RRM_BASE 1000
+#define RRM_CMD_LIMIT (RRM_BASE + 100)
+
+enum {
+	RRM_OPENRN = RRM_BASE,	/* open rendering node */
+	RRM_CLOSERN,
+	RRM_BINDPROCTORN,	/* set current rendering region for node */
+	RRM_BINDRNTOCLIP,
+	RRM_UNBINDRNFROMCLIP,
+	RRM_SWAPBUF,
+	RRM_SETSWAPINTERVAL,
+	RRM_WAITFORRETRACE,
+	RRM_SETDISPLAYMODE,
+	RRM_MESSAGE,
+	RRM_INVALIDATERN,
+	RRM_VALIDATECLIP,
+	RRM_VALIDATESWAPBUF,
+	RRM_SWAPGROUP,
+	RRM_SWAPUNGROUP,
+	RRM_VALIDATEMESSAGE,
+	RRM_GETDISPLAYMODES,
+	RRM_LOADDISPLAYMODE,
+	RRM_CUSHIONBUFFER,
+	RRM_SWAPREADY,
+	RRM_MGR_SWAPBUF,
+	RRM_SETVSYNC,
+	RRM_GETVSYNC,
+	RRM_WAITVSYNC,
+	RRM_BINDRNTOREADANDCLIP,
+	RRM_MAPCLIPTOSWPBUFID
+};
+
+/* Parameters for the above ioctls
+ *
+ * All of the ioctls take as their first argument the rendering node id.
+ *
+ */
+
+/*
+ * RRM_OPENRN:
+ *
+ * This is called by the IRIX X server with:
+ * rnid = 0xffffffff rmask = 0
+ *
+ * Returns a number like this: 0x10001.
+ * If you run the X server over and over, you get a value
+ * that is of the form (n * 0x10000) + 1.
+ *
+ * The return value seems to be the RNID.
+ */
+struct RRM_OpenRN {
+	int      rnid;
+	unsigned int rmask;
+};
+
+struct RRM_CloseRN {
+	int rnid;
+};
+
+/*
+ * RRM_BINDPROCTORN:
+ *
+ * Return value when the X server calls it: 0
+ */ 
+struct RRM_BindProcToRN {
+	int      rnid;
+};
+
+#ifdef __KERNEL__
+int rrm_command (unsigned int cmd, void *arg);
+int rrm_close (struct inode *inode, struct file *file);
+#endif
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/semaphore-helper.h linux/include/asm-mips64/semaphore-helper.h
--- v2.4.6/linux/include/asm-mips64/semaphore-helper.h	Tue Nov 28 21:42:04 2000
+++ linux/include/asm-mips64/semaphore-helper.h	Wed Jul  4 11:50:39 2001
@@ -3,8 +3,8 @@
  *
  * (C) Copyright 1996 Linus Torvalds
  * (C) Copyright 1999 Andrea Arcangeli
- * (C) Copyright 1999 Ralf Baechle
- * (C) Copyright 1999 Silicon Graphics, Inc.
+ * (C) Copyright 1999, 2001 Ralf Baechle
+ * (C) Copyright 1999, 2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_SEMAPHORE_HELPER_H
 #define _ASM_SEMAPHORE_HELPER_H
@@ -68,63 +68,56 @@
 
 #ifdef __MIPSEB__
 
-        __asm__ __volatile__("
-	.set	push
-	.set	noat
-0:	lld	%1, %2
-	li	%0, 0
-	sll	$1, %1, 0
-	blez	$1, 1f
-	daddiu	%1, %1, -1
-	li	%0, 1
-	b 	2f
-1:
-	beqz	%3, 2f
-	li	%0, %4
-	dli	$1, 0x0000000100000000
-	daddu	%1, %1, $1
-2:
-	scd	%1, %2
-	beqz	%1, 0b
-	.set	pop"
+        __asm__ __volatile__(
+	".set\tpush\t\t\t# waking_non_zero_interruptible\n\t"
+	".set\tnoat\n\t"
+	"0:\tlld\t%1, %2\n\t"
+	"li\t%0, 0\n\t"
+	"sll\t$1, %1, 0\n\t"
+	"blez\t$1, 1f\n\t"
+	"daddiu\t%1, %1, -1\n\t"
+	"li\t%0, 1\n\t"
+	"b\t2f\n\t"
+	"1:\tbeqz\t%3, 2f\n\t"
+	"li\t%0, %4\n\t"
+	"dli\t$1, 0x0000000100000000\n\t"
+	"daddu\t%1, %1, $1\n\t"
+	"2:\tscd\t%1, %2\n\t"
+	"beqz\t%1, 0b\n\t"
+	".set\tpop"
 	: "=&r" (ret), "=&r" (tmp), "=m" (*sem)
 	: "r" (signal_pending(tsk)), "i" (-EINTR));
 
 #elif defined(__MIPSEL__)
 
-	__asm__ __volatile__("
-	.set	push
-	.set	noat
-0:
-	lld	%1, %2
-	li	%0, 0
-	blez	%1, 1f
-	dli	$1, 0x0000000100000000
-	dsubu	%1, %1, $1
-	li	%0, 1
-	b	2f
-1:
-	beqz	%3, 2f
-	li	%0, %4
+	__asm__ __volatile__(
+	".set\tpush\t\t\t# waking_non_zero_interruptible\n\t"
+	".set\t	noat\n"
+	"0:\tlld\t%1, %2\n\t"
+	"li\t%0, 0\n\t"
+	"blez\t%1, 1f\n\t"
+	"dli\t$1, 0x0000000100000000\n\t"
+	"dsubu\t%1, %1, $1\n\t"
+	"li\t%0, 1\n\t"
+	"b\t2f\n"
+	"1:\tbeqz\t%3, 2f\n\t"
+	"li\t%0, %4\n\t"
 	/* 
 	 * It would be nice to assume that sem->count
 	 * is != -1, but we will guard against that case
 	 */
-	daddiu	$1, %1, 1
-	dsll32	$1, $1, 0
-	dsrl32	$1, $1, 0
-	dsrl32	%1, %1, 0
-	dsll32	%1, %1, 0
-	or	%1, %1, $1
-2:
-	scd	%1, %2
-	beqz	%1, 0b
-	.set	pop"
+	"daddiu\t$1, %1, 1\n\t"
+	"dsll32\t$1, $1, 0\n\t"
+	"dsrl32\t$1, $1, 0\n\t"
+	"dsrl32\t%1, %1, 0\n\t"
+	"dsll32\t%1, %1, 0\n\t"
+	"or\t%1, %1, $1\n"
+	"2:\tscd\t%1, %2\n\t"
+	"beqz\t	%1, 0b\n\t"
+	".set\tpop"
 	: "=&r" (ret), "=&r" (tmp), "=m" (*sem)
 	: "r" (signal_pending(tsk)), "i" (-EINTR));
 
-#else
-#error "MIPS but neither __MIPSEL__ nor __MIPSEB__?"
 #endif
 
 	return ret;
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/semaphore.h linux/include/asm-mips64/semaphore.h
--- v2.4.6/linux/include/asm-mips64/semaphore.h	Tue Apr 17 17:19:31 2001
+++ linux/include/asm-mips64/semaphore.h	Wed Jul  4 11:50:39 2001
@@ -3,8 +3,8 @@
  * for more details.
  *
  * Copyright (C) 1996  Linus Torvalds
- * Copyright (C) 1998, 1999, 2000  Ralf Baechle
- * Copyright (C) 1999, 2000  Silicon Graphics, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001  Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001  Silicon Graphics, Inc.
  */
 #ifndef _ASM_SEMAPHORE_H
 #define _ASM_SEMAPHORE_H
@@ -130,29 +130,25 @@
 	CHECK_MAGIC(sem->__magic);
 #endif
 
-	__asm__ __volatile__("
-			.set	mips3
-
-		0:	lld	%1, %4
-			dli	%3, 0x0000000100000000
-			dsubu	%1, %3
-			li	%0, 0
-			bgez	%1, 2f
-			sll	%2, %1, 0
-			blez	%2, 1f
-			daddiu	%1, %1, -1
-			b	2f
-		1:
-			daddu	%1, %1, %3
-			li	%0, 1
-		2:
-			scd	%1, %4
-			beqz	%1, 0b
-
-			.set	mips0"
-		: "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub)
-		: "m"(*sem)
-		: "memory");
+	__asm__ __volatile__(
+	".set\tmips3\t\t\t# down_trylock\n"
+	"0:\tlld\t%1, %4\n\t"
+	"\tdli\t%3, 0x0000000100000000\n\t"
+	"\tdsubu\t%1, %3\n\t"
+	"\tli\t%0, 0\n\t"
+	"\tbgez\t%1, 2f\n\t"
+	"\tsll\t%2, %1, 0\n\t"
+	"\tblez\t%2, 1f\n\t"
+	"\tdaddiu\t%1, %1, -1\n\t"
+	"\tb\t2f\n"
+	"1:\tdaddu\t%1, %1, %3\n\t"
+	"\tli\t%0, 1\n"
+	"2:\tscd\t%1, %4\n\t"
+	"\tbeqz\t%1, 0b\n\t"
+	"\t.set\tmips0"
+	: "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub)
+	: "m"(*sem)
+	: "memory");
 
 	return ret;
 }
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/sgi/sgint23.h linux/include/asm-mips64/sgi/sgint23.h
--- v2.4.6/linux/include/asm-mips64/sgi/sgint23.h	Tue Nov 28 21:42:04 2000
+++ linux/include/asm-mips64/sgi/sgint23.h	Wed Jul  4 11:50:39 2001
@@ -170,7 +170,7 @@
 #endif
 #define INT2_TCLEAR_T0CLR      0x1        /* Clear timer0 IRQ */
 #define INT2_TCLEAR_T1CLR      0x2        /* Clear timer1 IRQ */
-/* I am guesing there are only two unused registers here 
+/* I am guessing there are only two unused registers here 
  * but I could be wrong...			- andrewb
  */
 /*	u32 _unused[3]; */
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/sgialib.h linux/include/asm-mips64/sgialib.h
--- v2.4.6/linux/include/asm-mips64/sgialib.h	Sat May 13 08:31:25 2000
+++ linux/include/asm-mips64/sgialib.h	Wed Jul  4 11:50:39 2001
@@ -1,5 +1,4 @@
-/* $Id: sgialib.h,v 1.3 1999/12/04 03:59:12 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -7,6 +6,7 @@
  * SGI ARCS firmware interface library for the Linux kernel.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org)
  */
 #ifndef _ASM_SGIALIB_H
 #define _ASM_SGIALIB_H
@@ -90,9 +90,9 @@
  */
 extern void prom_identify_arch(void);
 
-/* Environemt variable routines. */
+/* Environment variable routines. */
 extern PCHAR ArcGetEnvironmentVariable(PCHAR name);
-extern LONG SetEnvironmentVariable(PCHAR name, PCHAR value);
+extern LONG ArcSetEnvironmentVariable(PCHAR name, PCHAR value);
 
 /* ARCS command line acquisition and parsing. */
 extern char *prom_getcmdline(void);
@@ -120,11 +120,11 @@
 extern long prom_exec(char *name, long argc, char **argv, char **envp);
 
 /* Misc. routines. */
-extern void prom_halt(VOID) __attribute__((noreturn));
-extern void prom_powerdown(VOID) __attribute__((noreturn));
-extern void prom_restart(VOID) __attribute__((noreturn));
+extern VOID prom_halt(VOID) __attribute__((noreturn));
+extern VOID prom_powerdown(VOID) __attribute__((noreturn));
+extern VOID prom_restart(VOID) __attribute__((noreturn));
 extern VOID ArcReboot(VOID) __attribute__((noreturn));
-extern VOID ArcEnterInteractiveMode(void) __attribute__((noreturn));
+extern VOID ArcEnterInteractiveMode(VOID) __attribute__((noreturn));
 extern long prom_cfgsave(VOID);
 extern struct linux_sysid *prom_getsysid(VOID);
 extern VOID ArcFlushAllCaches(VOID);
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/sgiarcs.h linux/include/asm-mips64/sgiarcs.h
--- v2.4.6/linux/include/asm-mips64/sgiarcs.h	Sat May 13 08:31:25 2000
+++ linux/include/asm-mips64/sgiarcs.h	Wed Jul  4 11:50:39 2001
@@ -143,7 +143,7 @@
 
 /* ARCS virtual dirents. */
 struct linux_vdirent {
-	unsigned long namelen;
+	ULONG namelen;
 	unsigned char attr;
 	char fname[32]; /* XXX imperical, should be a define */
 };
@@ -177,38 +177,38 @@
 	struct linux_bigint   begin;
 	struct linux_bigint   end;
 	struct linux_bigint   cur;
-	enum linux_devtypes dtype;
+	enum linux_devtypes   dtype;
 	unsigned long         namelen;
 	unsigned char         attr;
 	char                  name[32]; /* XXX imperical, should be define */
 };
 
-/* This describes the vector containing fuction pointers to the ARC
+/* This describes the vector containing function pointers to the ARC
    firmware functions.  */
 struct linux_romvec {
-	LONG load;			/* Load an executable image. */
-	LONG invoke;			/* Invoke a standalong image. */
-	LONG exec;			/* Load and begin execution of a
+	LONG	load;			/* Load an executable image. */
+	LONG	invoke;			/* Invoke a standalong image. */
+	LONG	exec;			/* Load and begin execution of a
 					   standalone image. */
-	LONG halt;			/* Halt the machine. */
-	LONG pdown;			/* Power down the machine. */
-	LONG restart;			/* XXX soft reset??? */
-	LONG reboot;			/* Reboot the machine. */
-	LONG imode;			/* Enter PROM interactive mode. */
-	LONG _unused1;			/* Was ReturnFromMain(). */
+	LONG	halt;			/* Halt the machine. */
+	LONG	pdown;			/* Power down the machine. */
+	LONG	restart;		/* XXX soft reset??? */
+	LONG	reboot;			/* Reboot the machine. */
+	LONG	imode;			/* Enter PROM interactive mode. */
+	LONG	_unused1;		/* Was ReturnFromMain(). */
 
 	/* PROM device tree interface. */
-	LONG next_component;
-	LONG child_component;
-	LONG parent_component;
-	LONG component_data;
-	LONG child_add;
-	LONG comp_del;
-	LONG component_by_path;
+	LONG	next_component;
+	LONG	child_component;
+	LONG	parent_component;
+	LONG	component_data;
+	LONG	child_add;
+	LONG	comp_del;
+	LONG	component_by_path;
 
 	/* Misc. stuff. */
-	LONG cfg_save;
-	LONG get_sysid;
+	LONG	cfg_save;
+	LONG	get_sysid;
 
 	/* Probing for memory. */
 	LONG	get_mdesc;
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/siginfo.h linux/include/asm-mips64/siginfo.h
--- v2.4.6/linux/include/asm-mips64/siginfo.h	Wed May 24 18:38:26 2000
+++ linux/include/asm-mips64/siginfo.h	Wed Jul  4 11:50:39 2001
@@ -1,10 +1,10 @@
-/* $Id: siginfo.h,v 1.2 2000/01/27 01:05:37 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1998, 1999, 2001 Ralf Baechle
+ * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_SIGINFO_H
 #define _ASM_SIGINFO_H
@@ -62,7 +62,7 @@
 
 		/* SIGPOLL, SIGXFSZ (To do ...)  */
 		struct {
-			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			long _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
 			int _fd;
 		} _sigpoll;
 
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/smp.h linux/include/asm-mips64/smp.h
--- v2.4.6/linux/include/asm-mips64/smp.h	Fri Mar  2 11:30:15 2001
+++ linux/include/asm-mips64/smp.h	Wed Jul  4 11:50:39 2001
@@ -1,3 +1,12 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of this
+ * archive for more details.
+ *
+ * Copyright (C) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
+ * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
+ */
+
 #ifndef __ASM_SMP_H
 #define __ASM_SMP_H
 
@@ -38,12 +47,42 @@
 extern int __cpu_logical_map[NR_CPUS];
 #define cpu_logical_map(cpu)  __cpu_logical_map[cpu]
 
-/* Good enough for toy^Wupto 64 CPU Origins.  */
-extern unsigned long cpu_present_mask;
-#define cpu_online_map cpu_present_mask
-
 #endif
 
 #define NO_PROC_ID	(-1)
 
-#endif __ASM_SMP_H
+#if (NR_CPUS <= _MIPS_SZLONG)
+
+typedef unsigned long   cpumask_t;
+
+#define CPUMASK_CLRALL(p)	(p) = 0
+#define CPUMASK_SETB(p, bit)	(p) |= 1 << (bit)
+#define CPUMASK_CLRB(p, bit)	(p) &= ~(1ULL << (bit))
+#define CPUMASK_TSTB(p, bit)	((p) & (1ULL << (bit)))
+
+#elif (NR_CPUS <= 128)
+
+/*
+ * The foll should work till 128 cpus.
+ */
+#define CPUMASK_SIZE		(NR_CPUS/_MIPS_SZLONG)
+#define CPUMASK_INDEX(bit)	((bit) >> 6)
+#define CPUMASK_SHFT(bit)	((bit) & 0x3f)
+
+typedef struct {
+	unsigned long	_bits[CPUMASK_SIZE];
+} cpumask_t;
+
+#define	CPUMASK_CLRALL(p)	(p)._bits[0] = 0, (p)._bits[1] = 0
+#define CPUMASK_SETB(p, bit)	(p)._bits[CPUMASK_INDEX(bit)] |= \
+					(1ULL << CPUMASK_SHFT(bit))
+#define CPUMASK_CLRB(p, bit)	(p)._bits[CPUMASK_INDEX(bit)] &= \
+					~(1ULL << CPUMASK_SHFT(bit))
+#define CPUMASK_TSTB(p, bit)	((p)._bits[CPUMASK_INDEX(bit)] & \
+					(1ULL << CPUMASK_SHFT(bit)))
+
+#else
+#error cpumask macros only defined for 128p kernels
+#endif
+
+#endif /* __ASM_SMP_H */
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/sn/types.h linux/include/asm-mips64/sn/types.h
--- v2.4.6/linux/include/asm-mips64/sn/types.h	Sun Jul  9 22:18:15 2000
+++ linux/include/asm-mips64/sn/types.h	Wed Jul  4 11:50:39 2001
@@ -13,7 +13,6 @@
 #include <linux/types.h>
 
 typedef unsigned long 	cpuid_t;
-typedef unsigned long 	cpumask_t;
 typedef unsigned long	cnodemask_t;
 typedef signed short	nasid_t;	/* node id in numa-as-id space */
 typedef signed short	cnodeid_t;	/* node id in compact-id space */
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/socket.h linux/include/asm-mips64/socket.h
--- v2.4.6/linux/include/asm-mips64/socket.h	Tue Jul  3 17:08:21 2001
+++ linux/include/asm-mips64/socket.h	Wed Jul  4 11:50:39 2001
@@ -3,8 +3,8 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1997, 1999, 2000 Ralf Baechle
- * Copyright (C) 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1997, 1999, 2000, 2001 Ralf Baechle
+ * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_SOCKET_H
 #define _ASM_SOCKET_H
@@ -41,7 +41,7 @@
 #define SO_RCVLOWAT	0x1004	/* receive low-water mark */
 #define SO_SNDTIMEO	0x1005	/* send timeout */
 #define SO_RCVTIMEO 	0x1006	/* receive timeout */
-#define SO_ACCEPTCONN	0x1007
+#define SO_ACCEPTCONN	0x1009
 
 /* linux-specific, might as well be the same as on i386 */
 #define SO_NO_CHECK	11
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/system.h linux/include/asm-mips64/system.h
--- v2.4.6/linux/include/asm-mips64/system.h	Tue Nov 28 21:42:04 2000
+++ linux/include/asm-mips64/system.h	Wed Jul  4 11:50:39 2001
@@ -33,7 +33,7 @@
 }
 
 /*
- * For cli() we have to insert nops to make shure that the new value
+ * For cli() we have to insert nops to make sure that the new value
  * has actually arrived in the status register before the end of this
  * macro.
  * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/termios.h linux/include/asm-mips64/termios.h
--- v2.4.6/linux/include/asm-mips64/termios.h	Tue Jul  3 17:08:21 2001
+++ linux/include/asm-mips64/termios.h	Wed Jul  4 11:50:39 2001
@@ -1,10 +1,10 @@
-/* $Id: termios.h,v 1.2 2000/01/27 23:45:30 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996 by Ralf Baechle
+ * Copyright (C) 1995, 1996, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_TERMIOS_H
 #define _ASM_TERMIOS_H
diff -u --recursive --new-file v2.4.6/linux/include/asm-mips64/unaligned.h linux/include/asm-mips64/unaligned.h
--- v2.4.6/linux/include/asm-mips64/unaligned.h	Tue Nov 28 21:42:04 2000
+++ linux/include/asm-mips64/unaligned.h	Wed Jul  4 11:50:39 2001
@@ -3,8 +3,8 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1999, 2000 by Ralf Baechle
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1996, 1999, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_UNALIGNED_H
 #define _ASM_UNALIGNED_H
@@ -84,8 +84,15 @@
 		: "r" (__val));
 }
 
-/* 
- * The main single-value unaligned transfer routines.
+/*
+ * get_unaligned - get value from possibly mis-aligned location
+ * @ptr: pointer to value
+ *
+ * This macro should be used for accessing values larger in size than 
+ * single bytes at locations that are expected to be improperly aligned, 
+ * e.g. retrieving a u16 value from a location not u16-aligned.
+ *
+ * Note that unaligned accesses can be very expensive on some architectures.
  */
 #define get_unaligned(ptr)						\
 ({									\
@@ -102,7 +109,7 @@
 		__val = __ldl_u((const unsigned int *)(ptr));		\
 		break;							\
 	case 8:								\
-		__val = __ldq_u((const unsigned long long *)(ptr));	\
+		__val = __ldq_u((const unsigned long *)(ptr));		\
 		break;							\
 	default:							\
 		__get_unaligned_bad_length();				\
@@ -112,6 +119,17 @@
 	__val;								\
 })
 
+/*
+ * put_unaligned - put value to a possibly mis-aligned location
+ * @val: value to place
+ * @ptr: pointer to location
+ *
+ * This macro should be used for placing values larger in size than 
+ * single bytes at locations that are expected to be improperly aligned, 
+ * e.g. writing a u16 value to a location not u16-aligned.
+ *
+ * Note that unaligned accesses can be very expensive on some architectures.
+ */
 #define put_unaligned(val,ptr)						\
 do {									\
 	switch (sizeof(*(ptr))) {					\
diff -u --recursive --new-file v2.4.6/linux/include/asm-s390/bitops.h linux/include/asm-s390/bitops.h
--- v2.4.6/linux/include/asm-s390/bitops.h	Wed Apr 11 19:02:28 2001
+++ linux/include/asm-s390/bitops.h	Wed Jul  4 11:50:39 2001
@@ -34,7 +34,14 @@
  * align the address to 4 byte boundary. It seems to work
  * without the alignment. 
  */
+#ifdef __KERNEL__
 #define ALIGN_CS 0
+#else
+#define ALIGN_CS 1
+#ifndef CONFIG_SMP
+#error "bitops won't work without CONFIG_SMP"
+#endif
+#endif
 
 /* bitmap tables from arch/S390/kernel/bitmap.S */
 extern const char _oi_bitmap[];
@@ -487,6 +494,7 @@
              : "cc", "memory", "1", "2" );
         return oldbit;
 }
+#define __test_and_set_bit(X,Y)		test_and_set_bit_simple(X,Y)
 
 /*
  * fast, non-SMP test_and_clear_bit routine
@@ -513,6 +521,7 @@
              : "cc", "memory", "1", "2" );
         return oldbit;
 }
+#define __test_and_clear_bit(X,Y)	test_and_clear_bit_simple(X,Y)
 
 /*
  * fast, non-SMP test_and_change_bit routine
@@ -539,6 +548,7 @@
              : "cc", "memory", "1", "2" );
         return oldbit;
 }
+#define __test_and_change_bit(X,Y)	test_and_change_bit_simple(X,Y)
 
 #ifdef CONFIG_SMP
 #define set_bit             set_bit_cs
diff -u --recursive --new-file v2.4.6/linux/include/asm-s390/ebcdic.h linux/include/asm-s390/ebcdic.h
--- v2.4.6/linux/include/asm-s390/ebcdic.h	Wed Apr 11 19:02:28 2001
+++ linux/include/asm-s390/ebcdic.h	Wed Jul  4 11:50:39 2001
@@ -29,8 +29,8 @@
         __asm__ __volatile__(
 		"   bras 1,1f\n"
 		"   tr   0(1,%0),0(%2)\n"
-		"0: la   %0,256(%0)\n"
-                "   tr   0(256,%0),0(%2)\n"
+                "0: tr   0(256,%0),0(%2)\n"
+		"   la   %0,256(%0)\n"
 		"1: ahi  %1,-256\n"
 		"   jp   0b\n"
 		"   ex   %1,0(1)"
diff -u --recursive --new-file v2.4.6/linux/include/asm-s390/pci.h linux/include/asm-s390/pci.h
--- v2.4.6/linux/include/asm-s390/pci.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-s390/pci.h	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,9 @@
+#ifndef __ASM_S390_PCI_H
+#define __ASM_S390_PCI_H
+
+/* S/390 systems don't have a PCI bus. This file is just here because some stupid .c code
+ * includes it even if CONFIG_PCI is not set.
+ */
+
+#endif /* __ASM_S390_PCI_H */
+
diff -u --recursive --new-file v2.4.6/linux/include/asm-s390x/bitops.h linux/include/asm-s390x/bitops.h
--- v2.4.6/linux/include/asm-s390x/bitops.h	Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390x/bitops.h	Wed Jul  4 11:50:39 2001
@@ -38,7 +38,14 @@
  * align the address to 4 byte boundary. It seems to work
  * without the alignment. 
  */
+#ifdef __KERNEL__
 #define ALIGN_CS 0
+#else
+#define ALIGN_CS 1
+#ifndef CONFIG_SMP
+#error "bitops won't work without CONFIG_SMP"
+#endif
+#endif
 
 /* bitmap tables from arch/S390/kernel/bitmap.S */
 extern const char _oi_bitmap[];
@@ -54,7 +61,7 @@
         unsigned long bits, mask;
         __asm__ __volatile__(
 #if ALIGN_CS == 1
-             "   lghi  %2,3\n"         /* CS must be aligned on 4 byte b. */
+             "   lghi  %2,7\n"         /* CS must be aligned on 4 byte b. */
              "   ngr   %2,%1\n"        /* isolate last 2 bits of address */
              "   xgr   %1,%2\n"        /* make addr % 4 == 0 */
              "   sllg  %2,%2,3\n"
@@ -84,7 +91,7 @@
         unsigned long bits, mask;
         __asm__ __volatile__(
 #if ALIGN_CS == 1
-             "   lghi  %2,3\n"         /* CS must be aligned on 4 byte b. */
+             "   lghi  %2,7\n"         /* CS must be aligned on 4 byte b. */
              "   ngr   %2,%1\n"        /* isolate last 2 bits of address */
              "   xgr   %1,%2\n"        /* make addr % 4 == 0 */
              "   sllg  %2,%2,3\n"
@@ -115,7 +122,7 @@
         unsigned long bits, mask;
         __asm__ __volatile__(
 #if ALIGN_CS == 1
-             "   lghi  %2,3\n"         /* CS must be aligned on 4 byte b. */
+             "   lghi  %2,7\n"         /* CS must be aligned on 4 byte b. */
              "   ngr   %2,%1\n"        /* isolate last 2 bits of address */
              "   xgr   %1,%2\n"        /* make addr % 4 == 0 */
              "   sllg  %2,%2,3\n"
@@ -146,7 +153,7 @@
         unsigned long bits, mask;
         __asm__ __volatile__(
 #if ALIGN_CS == 1
-             "   lghi  %2,3\n"         /* CS must be aligned on 4 byte b. */
+             "   lghi  %2,7\n"         /* CS must be aligned on 4 byte b. */
              "   ngr   %2,%1\n"        /* isolate last 2 bits of address */
              "   xgr   %1,%2\n"        /* make addr % 4 == 0 */
              "   sllg  %2,%2,3\n"
@@ -179,7 +186,7 @@
         unsigned long bits, mask;
         __asm__ __volatile__(
 #if ALIGN_CS == 1
-             "   lghi  %2,3\n"         /* CS must be aligned on 4 byte b. */
+             "   lghi  %2,7\n"         /* CS must be aligned on 4 byte b. */
              "   ngr   %2,%1\n"        /* isolate last 2 bits of address */
              "   xgr   %1,%2\n"        /* make addr % 4 == 0 */
              "   sllg  %2,%2,3\n"
@@ -212,7 +219,7 @@
         unsigned long bits, mask;
         __asm__ __volatile__(
 #if ALIGN_CS == 1
-             "   lghi  %2,3\n"         /* CS must be aligned on 4 byte b. */
+             "   lghi  %2,7\n"         /* CS must be aligned on 4 byte b. */
              "   ngr   %2,%1\n"        /* isolate last 2 bits of address */
              "   xgr   %1,%2\n"        /* make addr % 4 == 0 */
              "   sllg  %2,%2,3\n"
@@ -494,6 +501,7 @@
              : "cc", "memory", "1", "2" );
         return oldbit & 1;
 }
+#define __test_and_set_bit(X,Y)		test_and_set_bit_simple(X,Y)
 
 /*
  * fast, non-SMP test_and_clear_bit routine
@@ -518,6 +526,7 @@
              : "cc", "memory", "1", "2" );
         return oldbit & 1;
 }
+#define __test_and_clear_bit(X,Y)	test_and_clear_bit_simple(X,Y)
 
 /*
  * fast, non-SMP test_and_change_bit routine
@@ -542,6 +551,7 @@
              : "cc", "memory", "1", "2" );
         return oldbit & 1;
 }
+#define __test_and_change_bit(X,Y)	test_and_change_bit_simple(X,Y)
 
 #ifdef CONFIG_SMP
 #define set_bit             set_bit_cs
diff -u --recursive --new-file v2.4.6/linux/include/asm-s390x/byteorder.h linux/include/asm-s390x/byteorder.h
--- v2.4.6/linux/include/asm-s390x/byteorder.h	Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390x/byteorder.h	Wed Jul  4 11:50:39 2001
@@ -36,9 +36,9 @@
 static __inline__ void ___arch__swab64s(__u64 *x)
 {
   __asm__ __volatile__ (
-          "   lrvg %0,%1\n"
-	  "   stg  %0,%1"
-          : : "m" (*x) : "memory");
+          "   lrvg 0,%0\n"
+	  "   stg  0,%0"
+          : "+m" (*x) : : "0");
 }
 
 static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
@@ -64,9 +64,9 @@
 static __inline__ void ___arch__swab32s(__u32 *x)
 {
   __asm__ __volatile__ (
-          "   lrv  %0,%1\n"
-	  "   st   %0,%1"
-          : : "m" (*x) : "memory");
+          "   lrv  0,%0\n"
+	  "   st   0,%0"
+          : "+m" (*x) : : "0" );
 }
 
 static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
@@ -92,15 +92,18 @@
 static __inline__ void ___arch__swab16s(__u16 *x)
 {
   __asm__ __volatile__ (
-          "   lrvh %0,%1\n"
-	  "   sth  %0,%1"
-          : : "m" (*x) : "memory");
+          "   lrvh 0,%0\n"
+	  "   sth  0,%0"
+          : "+m" (*x) : : "0" );
 }
 
+#define __arch__swab64(x) ___arch__swab64(x)
 #define __arch__swab32(x) ___arch__swab32(x)
 #define __arch__swab16(x) ___arch__swab16(x)
+#define __arch__swab64p(x) ___arch__swab64p(x)
 #define __arch__swab32p(x) ___arch__swab32p(x)
 #define __arch__swab16p(x) ___arch__swab16p(x)
+#define __arch__swab64s(x) ___arch__swab64s(x)
 #define __arch__swab32s(x) ___arch__swab32s(x)
 #define __arch__swab16s(x) ___arch__swab16s(x)
 
diff -u --recursive --new-file v2.4.6/linux/include/asm-s390x/ebcdic.h linux/include/asm-s390x/ebcdic.h
--- v2.4.6/linux/include/asm-s390x/ebcdic.h	Wed Apr 11 19:02:29 2001
+++ linux/include/asm-s390x/ebcdic.h	Wed Jul  4 11:50:39 2001
@@ -29,8 +29,8 @@
         __asm__ __volatile__(
 		"   bras  1,1f\n"
 		"   tr    0(1,%0),0(%2)\n"
-		"0: la    %0,256(%0)\n"
-		"   tr    0(256,%0),0(%2)\n"
+		"0: tr    0(256,%0),0(%2)\n"
+		"   la    %0,256(%0)\n"
 		"1: ahi   %1,-256\n"
 		"   jp    0b\n"
 		"   ex    %1,0(1)"
diff -u --recursive --new-file v2.4.6/linux/include/asm-s390x/irq.h linux/include/asm-s390x/irq.h
--- v2.4.6/linux/include/asm-s390x/irq.h	Wed Apr 11 19:02:29 2001
+++ linux/include/asm-s390x/irq.h	Wed Jul  4 11:50:39 2001
@@ -889,9 +889,9 @@
         spin_lock_irqsave(&(ioinfo[irq]->irq_lock), flags)
 #define s390irq_spin_unlock_irqrestore(irq,flags) \
         spin_unlock_irqrestore(&(ioinfo[irq]->irq_lock), flags)
-#endif /* __KERNEL__ */
 
 #define touch_nmi_watchdog() do { } while(0)
 
+#endif /* __KERNEL__ */
 #endif
 
diff -u --recursive --new-file v2.4.6/linux/include/asm-s390x/string.h linux/include/asm-s390x/string.h
--- v2.4.6/linux/include/asm-s390x/string.h	Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390x/string.h	Wed Jul  4 11:50:39 2001
@@ -45,8 +45,6 @@
 extern char *strncpy(char *, const char *, size_t);
 extern int strcmp(const char *,const char *);
 
-#undef __HAVE_ARCH_MEMCHR
-#if 0
 static inline void * memchr(const void * cs,int c,size_t count)
 {
     void *ptr;
@@ -63,7 +61,6 @@
                           : "cc", "0", "1" );
     return ptr;
 }
-#endif
 
 static __inline__ char *strcpy(char *dest, const char *src)
 {
@@ -77,8 +74,6 @@
     return tmp;
 }
 
-#undef __HAVE_ARCH_STRLEN
-#if 0
 static __inline__ size_t strlen(const char *s)
 {
     size_t len;
@@ -93,10 +88,7 @@
                           : "cc", "0" );
     return len;
 }
-#endif
 
-#undef __HAVE_ARCH_STRCAT
-#if 0
 static __inline__ char *strcat(char *dest, const char *src)
 {
     char *tmp = dest;
@@ -112,7 +104,6 @@
                           : "cc", "memory", "0" );
     return tmp;
 }
-#endif
 
 extern void *alloca(size_t);
 #endif /* __KERNEL__ */
diff -u --recursive --new-file v2.4.6/linux/include/linux/apm_bios.h linux/include/linux/apm_bios.h
--- v2.4.6/linux/include/linux/apm_bios.h	Fri Apr  6 10:51:19 2001
+++ linux/include/linux/apm_bios.h	Wed Jul  4 11:50:39 2001
@@ -52,6 +52,9 @@
 	struct apm_bios_info	bios;
 	unsigned short		connection_version;
 	int			get_power_status_broken;
+	int			allow_ints;
+	int			realmode_power_off;
+	int			disabled;
 };
 
 /*
diff -u --recursive --new-file v2.4.6/linux/include/linux/hdreg.h linux/include/linux/hdreg.h
--- v2.4.6/linux/include/linux/hdreg.h	Fri May 25 18:01:27 2001
+++ linux/include/linux/hdreg.h	Wed Jul  4 11:50:39 2001
@@ -98,6 +98,7 @@
 #define SMART_IMMEDIATE_OFFLINE	0xd4
 #define SMART_READ_LOG_SECTOR	0xd5
 #define SMART_WRITE_LOG_SECTOR	0xd6
+#define SMART_WRITE_THRESHOLDS	0xd7
 #define SMART_ENABLE		0xd8
 #define SMART_DISABLE		0xd9
 #define SMART_STATUS		0xda
@@ -159,6 +160,7 @@
 #define ABRT_ERR	0x04	/* Command aborted */
 #define MCR_ERR		0x08	/* media change request */
 #define ID_ERR		0x10	/* ID field not found */
+#define MC_ERR		0x20	/* media changed */
 #define ECC_ERR		0x40	/* Uncorrectable ECC error */
 #define	BBD_ERR		0x80	/* pre-EIDE meaning:  block marked bad */
 #define	ICRC_ERR	0x80	/* new meaning:  CRC error during transfer */
@@ -174,6 +176,7 @@
 #define HDIO_GETGEO		0x0301	/* get device geometry */
 #define HDIO_GET_UNMASKINTR	0x0302	/* get current unmask setting */
 #define HDIO_GET_MULTCOUNT	0x0304	/* get current IDE blockmode setting */
+#define HDIO_GET_QDMA		0x0305	/* get use-qdma flag */
 #define HDIO_OBSOLETE_IDENTITY	0x0307	/* OBSOLETE, DO NOT USE: returns 142 bytes */
 #define HDIO_GET_KEEPSETTINGS	0x0308	/* get keep-settings-on-reset flag */
 #define HDIO_GET_32BIT		0x0309	/* get current io_32bit setting */
@@ -181,9 +184,13 @@
 #define HDIO_GET_DMA		0x030b	/* get use-dma flag */
 #define HDIO_GET_NICE		0x030c	/* get nice flags */
 #define HDIO_GET_IDENTITY	0x030d	/* get IDE identification info */
+#define HDIO_GET_WCACHE		0x030e	/* get write cache mode on|off */
+#define HDIO_GET_ACOUSTIC	0x030f	/* get acoustic value */
 
+#define HDIO_GET_BUSSTATE	0x031a	/* get the bus state of the hwif */
+#define HDIO_TRISTATE_HWIF	0x031b	/* OBSOLETE - use SET_BUSSTATE */
 #define HDIO_DRIVE_RESET	0x031c	/* execute a device reset */
-#define HDIO_TRISTATE_HWIF	0x031d	/* execute a channel tristate */
+#define HDIO_DRIVE_TASKFILE	0x031d	/* execute raw taskfile */
 #define HDIO_DRIVE_TASK		0x031e	/* execute task and special drive command */
 #define HDIO_DRIVE_CMD		0x031f	/* execute a special drive command */
 
@@ -200,6 +207,17 @@
 #define HDIO_SCAN_HWIF		0x0328	/* register and (re)scan interface */
 #define HDIO_SET_NICE		0x0329	/* set nice flags */
 #define HDIO_UNREGISTER_HWIF	0x032a  /* unregister interface */
+#define HDIO_SET_WCACHE		0x032b	/* change write cache enable-disable */
+#define HDIO_SET_ACOUSTIC	0x032c	/* change acoustic behavior */
+#define HDIO_SET_BUSSTATE	0x032d	/* set the bus state of the hwif */
+#define HDIO_SET_QDMA		0x032e	/* change use-qdma flag */
+
+/* bus states */
+enum {
+	BUSSTATE_OFF = 0,
+	BUSSTATE_ON,
+	BUSSTATE_TRISTATE
+};
 
 /* BIG GEOMETRY */
 struct hd_big_geometry {
diff -u --recursive --new-file v2.4.6/linux/include/linux/ibmtr.h linux/include/linux/ibmtr.h
--- v2.4.6/linux/include/linux/ibmtr.h	Tue Jul  3 17:08:21 2001
+++ linux/include/linux/ibmtr.h	Wed Jul  4 11:50:39 2001
@@ -6,26 +6,22 @@
 
 /* ported to the Alpha architecture 02/20/96 (just used the HZ macro) */
 
-#define TR_RETRY_INTERVAL (5*HZ) /* 500 on PC = 5 s */
-#define TR_RESET_INTERVAL (HZ/20) /* 5 on PC = 50 ms */
-#define TR_BUSY_INTERVAL (HZ/5) /* 5 on PC = 200 ms */
-#define TR_SPIN_INTERVAL (3*HZ) /* 3 seconds before init timeout */
-#define TR_RETRIES 6            /* number of open retries */ 
+#define TR_RETRY_INTERVAL	(30*HZ)	/* 500 on PC = 5 s */
+#define TR_RST_TIME		(HZ/20) /* 5 on PC = 50 ms */
+#define TR_BUSY_INTERVAL	(HZ/5)	/* 5 on PC = 200 ms */
+#define TR_SPIN_INTERVAL	(3*HZ)	/* 3 seconds before init timeout */
 
 #define TR_ISA 1
 #define TR_MCA 2
 #define TR_ISAPNP 3
 #define NOTOK 0
-#define TOKDEBUG 1
 
 #define IBMTR_SHARED_RAM_SIZE 0x10000
 #define IBMTR_IO_EXTENT 4
-#define IBMTR_MAX_ADAPTERS 2
+#define IBMTR_MAX_ADAPTERS 4
 
 #define CHANNEL_ID      0X1F30
 #define AIP             0X1F00
-#define AIPCHKSUM1      0X1F60
-#define AIPCHKSUM2      0X1FF0
 #define AIPADAPTYPE     0X1FA0
 #define AIPDATARATE     0X1FA2
 #define AIPEARLYTOKEN   0X1FA4
@@ -35,22 +31,17 @@
 #define AIP16MBDHB      0X1FAC
 #define AIPFID		0X1FBA
 
-/* Note, 0xA20 == 0x220 since motherboard decodes 10 bits.  I left everything
-   the way my documentation had it, ie: 0x0A20.     */
-#define ADAPTINTCNTRL   0x02f0  /* Adapter interrupt control */
 #define ADAPTRESET      0x1     /* Control Adapter reset (add to base) */
 #define ADAPTRESETREL   0x2     /* Release Adapter from reset ( """)  */
 #define ADAPTINTREL	0x3 	/* Adapter interrupt release */
 
-#define MMIOStartLocP   0x0a20  /* Primary adapter's starting MMIO area */
-#define MMIOStartLocA   0x0a24  /* Alternate adapter's starting MMIO area */
-
 #define GLOBAL_INT_ENABLE 0x02f0
 
 /* MMIO bits 0-4 select register */
-#define RRR_EVEN        0x00    /* Shared RAM relocation registers - even and odd */
+#define RRR_EVEN       0x00 /* Shared RAM relocation registers - even and odd */
 /* Used to set the starting address of shared RAM  */
-/* Bits 1 through 7 of this register map to bits 13 through 19 of the shared RAM address.*/
+/* Bits 1 through 7 of this register map to bits 13 through 19 of the shared
+   RAM address.*/
 /* ie: 0x02 sets RAM address to ...ato!  issy su wazzoo !! GODZILLA!!! */
 #define RRR_ODD         0x01
 /* Bits 2 and 3 of this register can be read to determine shared RAM size */
@@ -59,28 +50,26 @@
 #define WRBR_ODD        0x03
 #define WWOR_EVEN       0x04    /* Write window open registers - even and odd */
 #define WWOR_ODD        0x05
-#define WWCR_EVEN       0x06    /* Write window close registers - even and odd */
+#define WWCR_EVEN       0x06   /* Write window close registers - even and odd */
 #define WWCR_ODD        0x07
 
 /* Interrupt status registers - PC system  - even and odd */
 #define ISRP_EVEN       0x08
 
-#define TCR_INT 0x10    /* Bit 4 - Timer interrupt.  The TVR_EVEN timer has
+#define TCR_INT    0x10    /* Bit 4 - Timer interrupt.  The TVR_EVEN timer has
                                                                    expired. */
-#define ERR_INT 0x08    /* Bit 3 - Error interrupt.  The adapter has had an
-                                                                   internal error. */
+#define ERR_INT	   0x08    /* Bit 3 - Error interrupt.  The adapter has had an
+                                                            internal error. */
 #define ACCESS_INT 0x04    /* Bit 2 - Access interrupt.  You have attempted to
-                                                           write to an invalid area of shared RAM or an invalid
-                                                                   register within the MMIO. */
-/*      In addition, the following bits within ISRP_EVEN can be turned on or off by you */
-/*      to control the interrupt processing:   */
-#define INT_IRQ 0x80    /* Bit 7 - If 0 the adapter will issue a CHCK, if 1 and
-                                                              IRQ.  This should normally be set (by you) to 1.  */
+				      write to an invalid area of shared RAM
+				      or an invalid register within the MMIO. */
+/* In addition, the following bits within ISRP_EVEN can be turned on or off   */
+/* by you to control the interrupt processing:   */
 #define INT_ENABLE 0x40 /* Bit 6 - Interrupt enable.  If 0, no interrupts will
-                                                                   occur.  If 1, interrupts will occur normally.
-                                                                   Normally set to 1.  */
-/* Bit 0 - Primary or alternate adapter.  Set to zero if this adapter is the primary adapter,*/
-/*         1 if this adapter is the alternate adapter. */
+                                   occur.  If 1, interrupts will occur normally.
+                                                         Normally set to 1.  */
+/* Bit 0 - Primary or alternate adapter.  Set to zero if this adapter is the
+		primary adapter, 1 if this adapter is the alternate adapter. */
 
 
 #define ISRP_ODD        0x09
@@ -92,21 +81,21 @@
                              an SRB request and set the return code within
                              the SRB. */
 #define ASB_FREE_INT 0x10 /* Bit 4 - ASB free.  The adapter has read the ASB
-                                                                          and this area can be safely reused. This interrupt
-                                                                          is only used if your application has set the ASB
-                                                                          free request bit in ISRA_ODD or if an error was
-                                                                detected in your response. */
+                             and this area can be safely reused. This interrupt
+                             is only used if your application has set the ASB
+                             free request bit in ISRA_ODD or if an error was
+                             detected in your response. */
 #define ARB_CMD_INT  0x08 /* Bit 3 - ARB command.  The adapter has given you a
-                                                                          command for action.  The command is located in the
-                                                                          ARB area of shared memory. */
+                             command for action.  The command is located in the
+                             ARB area of shared memory. */
 #define SSB_RESP_INT 0x04 /* Bit 2 - SSB response.  The adapter has posted a
-                                                                          response to your SRB (the response is located in
-                                                                          the SSB area of shared memory). */
+                             response to your SRB (the response is located in
+                             the SSB area of shared memory). */
 /* Bit 1 - Bridge frame forward complete. */
 
 
 
-#define ISRA_EVEN       0x0A    /* Interrupt status registers - adapter  - even and odd */
+#define ISRA_EVEN 0x0A /*Interrupt status registers - adapter  - even and odd */
 /* Bit 7 - Internal parity error (on adapter's internal bus) */
 /* Bit 6 - Timer interrupt pending */
 /* Bit 5 - Access interrupt (attempt by adapter to access illegal address) */
@@ -114,21 +103,21 @@
 /* Bit 3 - Adapter processor check status */
 /* Bit 2 - Reserved */
 /* Bit 1 - Adapter hardware interrupt mask (prevents internal interrupts) */
-/* Bit 0 - Adapter software interrupt mask (prevents internal software interrupts) */
+/* Bit 0 - Adapter software interrupt mask (prevents internal software ints) */
 
 #define ISRA_ODD        0x0B
-#define CMD_IN_SRB 0x20 /* Bit 5  - Indicates that you have placed a new
+#define CMD_IN_SRB  0x20 /* Bit 5  - Indicates that you have placed a new
                            command in the SRB and are ready for the adapter to
                            process the command. */
 #define RESP_IN_ASB 0x10 /* Bit 4 - Indicates that you have placed a response
-                                                                    (an ASB) in the shared RAM which is available for
-                                                                         the adapter's use. */
-/* Bit 3 - Indicates that you are ready to put an SRB in the shared RAM, but that a previous */
-/*         command is still pending.  The adapter will then interrupt you when the previous */
-/*         command is completed */
-/* Bit 2 - Indicates that you are ready to put an ASB in the shared RAM, but that a previous */
-/*         ASB is still pending.  The adapter will then interrupt you when the previous ASB */
-/*         is copied.  */
+                            (an ASB) in the shared RAM which is available for
+                            the adapter's use. */
+/* Bit 3 - Indicates that you are ready to put an SRB in the shared RAM, but
+	that a previous command is still pending.  The adapter will then
+	interrupt you when the previous command is completed */
+/* Bit 2 - Indicates that you are ready to put an ASB in the shared RAM, but
+	that a previous ASB is still pending.  The adapter will then interrupt
+	you when the previous ASB is copied.  */
 #define ARB_FREE 0x2
 #define SSB_FREE 0x1
 
@@ -138,7 +127,7 @@
 #define TVR_ODD         0x0F
 #define SRPR_EVEN       0x18    /* Shared RAM paging registers - even and odd */
 #define SRPR_ENABLE_PAGING 0xc0
-#define SRPR_ODD        0x19 /* Not used. */
+#define SRPR_ODD        0x19	/* Not used. */
 #define TOKREAD         0x60
 #define TOKOR           0x40
 #define TOKAND          0x20
@@ -153,7 +142,8 @@
 /* MMIO bits 7-8 select area of interest.. see below */
 /* 00 selects attachment control area. */
 /* 01 is reserved. */
-/* 10 selects adapter identification area A containing the adapter encoded address. */
+/* 10 selects adapter identification area A containing the adapter encoded
+	address. */
 /* 11 selects the adapter identification area B containing test patterns. */
 
 #define PCCHANNELID 5049434F3631313039393020
@@ -165,18 +155,18 @@
 #define ACA_RW 0x00
 
 #ifdef ENABLE_PAGING
-#define SET_PAGE(x) (isa_writeb((x), \
-  ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN))
+#define SET_PAGE(x) (writeb((x), ti->mmio + ACA_OFFSET+ ACA_RW + SRPR_EVEN))
 #else
 #define SET_PAGE(x)
 #endif
 
-typedef enum { IN_PROGRESS, SUCCESS, FAILURE, CLOSED } open_state;
-
 /* do_tok_int possible values */
 #define FIRST_INT 1
 #define NOT_FIRST 2
 
+typedef enum {	CLOSED,	OPEN } open_state;
+//staic const char *printstate[] = { "CLOSED","OPEN"};
+
 struct tok_info {
 	unsigned char irq;
 	__u32 mmio;
@@ -186,6 +176,7 @@
 	unsigned char token_release;
 	unsigned char avail_shared_ram;
 	unsigned char shared_ram_paging;
+        unsigned char turbo;
 	unsigned short dhb_size4mb;
 	unsigned short rbuf_len4;
 	unsigned short rbuf_cnt4;
@@ -196,14 +187,13 @@
 	unsigned short maxmtu16;
 	/* Additions by David Morris       */
 	unsigned char do_tok_int;
-	wait_queue_head_t wait_for_tok_int;
 	wait_queue_head_t wait_for_reset;
 	unsigned char sram_base;
 	/* Additions by Peter De Schrijver */
 	unsigned char page_mask;          /* mask to select RAM page to Map*/
 	unsigned char mapped_ram_size;    /* size of RAM page */
-	__u32 sram;                       /* Shared memory base address */
-	__u32 init_srb;                   /* Initial System Request Block address */
+	__u32 sram_virt;                  /* Shared memory base address */
+	__u32 init_srb;               /* Initial System Request Block address */
 	__u32 srb;                        /* System Request Block address */
 	__u32 ssb;                        /* System Status Block address */
 	__u32 arb;                        /* Adapter Request Block address */
@@ -217,14 +207,15 @@
 	unsigned short global_int_enable;
 	struct sk_buff *current_skb;
 	struct net_device_stats tr_stats;
-	unsigned char auto_ringspeedsave;
-	open_state open_status;
+	unsigned char auto_speedsave;
+	open_state			open_status, sap_status;
+	enum {MANUAL, AUTOMATIC}	open_mode;
+	enum {FAIL, RESTART, REOPEN}	open_action;
+	enum {NO, YES}			open_failure;
 	unsigned char readlog_pending;
 	unsigned short adapter_int_enable; /* Adapter-specific int enable */
         struct timer_list tr_timer;
 	unsigned char ring_speed;
-	__u32 func_addr;
-	unsigned int retry_count;
 	spinlock_t lock;		/* SMP protection */
 };
 
@@ -311,18 +302,6 @@
 	unsigned char product_id[18];
 };
 
-struct srb_open_response {
-	unsigned char command;
-	unsigned char reserved1;
-	unsigned char ret_code;
-	unsigned char reserved2[3];
-	__u16 error_code;
-	__u16 asb_addr;
-	__u16 srb_addr;
-	__u16 arb_addr;
-	__u16 ssb_addr;
-};
-
 struct dlc_open_sap {
 	unsigned char command;
 	unsigned char reserved1;
@@ -353,49 +332,6 @@
 	__u16 station_id;
 };
 
-struct srb_interrupt {
-	unsigned char command;
-	unsigned char cmd_corr;
-	unsigned char ret_code;
-};
-
-struct srb_read_log {
-	unsigned char command;
-	unsigned char reserved1;
-	unsigned char ret_code;
-	unsigned char reserved2;
-	unsigned char line_errors;
-	unsigned char internal_errors;
-	unsigned char burst_errors;
-	unsigned char A_C_errors;
-	unsigned char abort_delimiters;
-	unsigned char reserved3;
-	unsigned char lost_frames;
-	unsigned char recv_congest_count;
-	unsigned char frame_copied_errors;
-	unsigned char frequency_errors;
-	unsigned char token_errors;
-};
-
-struct asb_xmit_resp {
-	unsigned char command;
-	unsigned char cmd_corr;
-	unsigned char ret_code;
-	unsigned char reserved;
-	__u16 station_id;
-	__u16 frame_length;
-	unsigned char hdr_length;
-	unsigned char rsap_value;
-};
-
-struct arb_xmit_req {
-	unsigned char command;
-	unsigned char cmd_corr;
-	unsigned char reserved1[2];
-	__u16 station_id;
-	__u16 dhb_address;
-};
-
 struct arb_rec_req {
 	unsigned char command;
 	unsigned char reserved1[3];
@@ -417,36 +353,14 @@
 };
 
 struct rec_buf {
-  /*	unsigned char reserved1[2]; */
+  	unsigned char reserved1[2];
 	__u16 buf_ptr;
 	unsigned char reserved2;
+	unsigned char receive_fs;
 	__u16 buf_len;
 	unsigned char data[0];
 };
 
-struct arb_dlc_status {
-	unsigned char command;
-	unsigned char reserved1[3];
-	__u16 station_id;
-	__u16 status;
-	unsigned char frmr_data[5];
-	unsigned char access_prio;
-	unsigned char rem_addr[TR_ALEN];
-	unsigned char rsap_value;
-};
-
-struct arb_ring_stat_change {
-	unsigned char command;
-	unsigned char reserved1[5];
-	__u16 ring_status;
-};
-
-struct srb_close_adapter {
-	unsigned char command;
-	unsigned char reserved1;
-	unsigned char ret_code;
-};
-
 struct srb_set_funct_addr {
 	unsigned char command;
 	unsigned char reserved1;
@@ -455,4 +369,4 @@
 	unsigned char funct_address[4];
 };
 
-#endif /* __LINUX_IBMTR_H__ */
+#endif
diff -u --recursive --new-file v2.4.6/linux/include/net/irda/ali-ircc.h linux/include/net/irda/ali-ircc.h
--- v2.4.6/linux/include/net/irda/ali-ircc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/net/irda/ali-ircc.h	Wed Jul  4 11:50:38 2001
@@ -0,0 +1,229 @@
+/*********************************************************************
+ *                
+ * Filename:      ali-ircc.h
+ * Version:       0.5
+ * Description:   Driver for the ALI M1535D and M1543C FIR Controller
+ * Status:        Experimental.
+ * Author:        Benjamin Kong <benjamin_kong@ali.com.tw>
+ * Created at:    2000/10/16 03:46PM
+ * Modified at:   2001/1/3 02:56PM
+ * Modified by:   Benjamin Kong <benjamin_kong@ali.com.tw>
+ * 
+ *     Copyright (c) 2000 Benjamin Kong <benjamin_kong@ali.com.tw>
+ *     All Rights Reserved
+ *      
+ *     This program is free software; you can redistribute it and/or 
+ *     modify it under the terms of the GNU General Public License as 
+ *     published by the Free Software Foundation; either version 2 of 
+ *     the License, or (at your option) any later version.
+ *  
+ ********************************************************************/
+
+#ifndef ALI_IRCC_H
+#define ALI_IRCC_H
+
+#include <linux/time.h>
+
+#include <linux/spinlock.h>
+#include <linux/pm.h>
+#include <asm/io.h>
+
+/* SIR Register */
+/* Usr definition of linux/serial_reg.h */
+
+/* FIR Register */
+#define BANK0		0x20
+#define BANK1		0x21
+#define BANK2		0x22
+#define BANK3		0x23
+
+#define FIR_MCR		0x07	/* Master Control Register */
+
+/* Bank 0 */
+#define FIR_DR		0x00	/* Alias 0, FIR Data Register (R/W) */ 
+#define FIR_IER		0x01	/* Alias 1, FIR Interrupt Enable Register (R/W) */
+#define FIR_IIR		0x02	/* Alias 2, FIR Interrupt Identification Register (Read only) */
+#define FIR_LCR_A	0x03	/* Alias 3, FIR Line Control Register A (R/W) */
+#define FIR_LCR_B	0x04	/* Alias 4, FIR Line Control Register B (R/W) */
+#define FIR_LSR		0x05	/* Alias 5, FIR Line Status Register (R/W) */
+#define FIR_BSR		0x06	/* Alias 6, FIR Bus Status Register (Read only) */
+
+
+	/* Alias 1 */
+	#define	IER_FIFO	0x10	/* FIR FIFO Interrupt Enable */	
+	#define	IER_TIMER	0x20 	/* Timer Interrupt Enable */ 
+	#define	IER_EOM		0x40	/* End of Message Interrupt Enable */
+	#define IER_ACT		0x80	/* Active Frame Interrupt Enable */
+	
+	/* Alias 2 */
+	#define IIR_FIFO	0x10	/* FIR FIFO Interrupt */
+	#define IIR_TIMER	0x20	/* Timer Interrupt */
+	#define IIR_EOM		0x40	/* End of Message Interrupt */
+	#define IIR_ACT		0x80	/* Active Frame Interrupt */	
+	
+	/* Alias 3 */
+	#define LCR_A_FIFO_RESET 0x80	/* FIFO Reset */
+
+	/* Alias 4 */
+	#define	LCR_B_BW	0x10	/* Brick Wall */
+	#define LCR_B_SIP	0x20	/* SIP Enable */
+	#define	LCR_B_TX_MODE 	0x40	/* Transmit Mode */
+	#define LCR_B_RX_MODE	0x80	/* Receive Mode */
+	
+	/* Alias 5 */	
+	#define LSR_FIR_LSA	0x00	/* FIR Line Status Address */
+	#define LSR_FRAME_ABORT	0x08	/* Frame Abort */
+	#define LSR_CRC_ERROR	0x10	/* CRC Error */
+	#define LSR_SIZE_ERROR	0x20	/* Size Error */
+	#define LSR_FRAME_ERROR	0x40	/* Frame Error */
+	#define LSR_FIFO_UR	0x80	/* FIFO Underrun */
+	#define LSR_FIFO_OR	0x80	/* FIFO Overrun */
+		
+	/* Alias 6 */
+	#define BSR_FIFO_NOT_EMPTY	0x80	/* FIFO Not Empty */
+	
+/* Bank 1 */
+#define	FIR_CR		0x00 	/* Alias 0, FIR Configuration Register (R/W) */
+#define FIR_FIFO_TR	0x01   	/* Alias 1, FIR FIFO Threshold Register (R/W) */
+#define FIR_DMA_TR	0x02	/* Alias 2, FIR DMA Threshold Register (R/W) */
+#define FIR_TIMER_IIR	0x03	/* Alias 3, FIR Timer interrupt interval register (W/O) */
+#define FIR_FIFO_FR	0x03	/* Alias 3, FIR FIFO Flag register (R/O) */
+#define FIR_FIFO_RAR	0x04 	/* Alias 4, FIR FIFO Read Address register (R/O) */
+#define FIR_FIFO_WAR	0x05	/* Alias 5, FIR FIFO Write Address register (R/O) */
+#define FIR_TR		0x06	/* Alias 6, Test REgister (W/O) */
+
+	/* Alias 0 */
+	#define CR_DMA_EN	0x01	/* DMA Enable */
+	#define CR_DMA_BURST	0x02	/* DMA Burst Mode */
+	#define CR_TIMER_EN 	0x08	/* Timer Enable */
+	
+	/* Alias 3 */
+	#define TIMER_IIR_500	0x00	/* 500 us */
+	#define TIMER_IIR_1ms	0x01	/* 1   ms */
+	#define TIMER_IIR_2ms	0x02	/* 2   ms */
+	#define TIMER_IIR_4ms	0x03	/* 4   ms */
+	
+/* Bank 2 */
+#define FIR_IRDA_CR	0x00	/* Alias 0, IrDA Control Register (R/W) */
+#define FIR_BOF_CR	0x01	/* Alias 1, BOF Count Register (R/W) */
+#define FIR_BW_CR	0x02	/* Alias 2, Brick Wall Count Register (R/W) */
+#define FIR_TX_DSR_HI	0x03	/* Alias 3, TX Data Size Register (high) (R/W) */
+#define FIR_TX_DSR_LO	0x04	/* Alias 4, TX Data Size Register (low) (R/W) */
+#define FIR_RX_DSR_HI	0x05	/* Alias 5, RX Data Size Register (high) (R/W) */
+#define FIR_RX_DSR_LO	0x06	/* Alias 6, RX Data Size Register (low) (R/W) */
+	
+	/* Alias 0 */
+	#define IRDA_CR_HDLC1152 0x80	/* 1.152Mbps HDLC Select */
+	#define IRDA_CR_CRC	0X40	/* CRC Select. */
+	#define IRDA_CR_HDLC	0x20	/* HDLC select. */
+	#define IRDA_CR_HP_MODE 0x10	/* HP mode (read only) */
+	#define IRDA_CR_SD_ST	0x08	/* SD/MODE State.  */
+	#define IRDA_CR_FIR_SIN 0x04	/* FIR SIN Select. */
+	#define IRDA_CR_ITTX_0	0x02	/* SOUT State. IRTX force to 0 */
+	#define IRDA_CR_ITTX_1	0x03	/* SOUT State. IRTX force to 1 */
+	
+/* Bank 3 */
+#define FIR_ID_VR	0x00	/* Alias 0, FIR ID Version Register (R/O) */
+#define FIR_MODULE_CR	0x01	/* Alias 1, FIR Module Control Register (R/W) */
+#define FIR_IO_BASE_HI	0x02	/* Alias 2, FIR Higher I/O Base Address Register (R/O) */
+#define FIR_IO_BASE_LO	0x03	/* Alias 3, FIR Lower I/O Base Address Register (R/O) */
+#define FIR_IRQ_CR	0x04	/* Alias 4, FIR IRQ Channel Register (R/O) */
+#define FIR_DMA_CR	0x05	/* Alias 5, FIR DMA Channel Register (R/O) */
+
+struct ali_chip {
+	char *name;
+	int cfg[2];
+	unsigned char entr1;
+	unsigned char entr2;
+	unsigned char cid_index;
+	unsigned char cid_value;
+	int (*probe)(struct ali_chip *chip, chipio_t *info);
+	int (*init)(struct ali_chip *chip, chipio_t *info); 
+};
+typedef struct ali_chip ali_chip_t;
+
+
+/* DMA modes needed */
+#define DMA_TX_MODE     0x08    /* Mem to I/O, ++, demand. */
+#define DMA_RX_MODE     0x04    /* I/O to mem, ++, demand. */
+
+#define MAX_TX_WINDOW 	7
+#define MAX_RX_WINDOW 	7
+
+#define TX_FIFO_Threshold	8
+#define RX_FIFO_Threshold	1
+#define TX_DMA_Threshold	1
+#define RX_DMA_Threshold	1
+
+/* For storing entries in the status FIFO */
+
+struct st_fifo_entry {
+	int status;
+	int len;
+};
+
+struct st_fifo {
+	struct st_fifo_entry entries[MAX_RX_WINDOW];
+	int pending_bytes;
+	int head;
+	int tail;
+	int len;
+};
+
+struct frame_cb {
+	void *start; /* Start of frame in DMA mem */
+	int len;     /* Lenght of frame in DMA mem */
+};
+
+struct tx_fifo {
+	struct frame_cb queue[MAX_TX_WINDOW]; /* Info about frames in queue */
+	int             ptr;                  /* Currently being sent */
+	int             len;                  /* Lenght of queue */
+	int             free;                 /* Next free slot */
+	void           *tail;                 /* Next free start in DMA mem */
+};
+
+/* Private data for each instance */
+struct ali_ircc_cb {
+
+	struct st_fifo st_fifo;    /* Info about received frames */
+	struct tx_fifo tx_fifo;    /* Info about frames to be transmitted */
+
+	struct net_device *netdev;     /* Yes! we are some kind of netdevice */
+	struct net_device_stats stats;
+	
+	struct irlap_cb *irlap;    /* The link layer we are binded to */
+	struct qos_info qos;       /* QoS capabilities for this device */
+	
+	chipio_t io;               /* IrDA controller information */
+	iobuff_t tx_buff;          /* Transmit buffer */
+	iobuff_t rx_buff;          /* Receive buffer */
+
+	__u8 ier;                  /* Interrupt enable register */
+	
+	__u8 InterruptID;	   /* Interrupt ID */	
+	__u8 BusStatus;		   /* Bus Status */	
+	__u8 LineStatus;	   /* Line Status */	
+	
+	unsigned char rcvFramesOverflow;
+		
+	struct timeval stamp;
+	struct timeval now;
+
+	spinlock_t lock;           /* For serializing operations */
+	
+	__u32 flags;               /* Interface flags */
+	__u32 new_speed;
+	int index;                 /* Instance index */
+	
+	unsigned char fifo_opti_buf;
+
+        struct pm_dev *dev;
+};
+
+static inline void switch_bank(int iobase, int bank)
+{
+		outb(bank, iobase+FIR_MCR);
+}
+
+#endif /* ALI_IRCC_H */
diff -u --recursive --new-file v2.4.6/linux/include/net/irda/irlap.h linux/include/net/irda/irlap.h
--- v2.4.6/linux/include/net/irda/irlap.h	Fri May 25 17:07:20 2001
+++ linux/include/net/irda/irlap.h	Wed Jul  4 11:50:38 2001
@@ -43,15 +43,8 @@
 
 #define LAP_ADDR_HEADER 1  /* IrLAP Address Header */
 #define LAP_CTRL_HEADER 1  /* IrLAP Control Header */
-#define LAP_COMP_HEADER 1  /* IrLAP Compression Header */
 
-#ifdef CONFIG_IRDA_COMPRESSION
-#  define LAP_MAX_HEADER  (LAP_ADDR_HEADER + LAP_CTRL_HEADER + LAP_COMP_HEADER)
-#  define IRDA_COMPRESSED 1
-#  define IRDA_NORMAL     0
-#else
 #define LAP_MAX_HEADER (LAP_ADDR_HEADER + LAP_CTRL_HEADER)
-#endif
 
 #define BROADCAST  0xffffffff /* Broadcast device address */
 #define CBROADCAST 0xfe       /* Connection broadcast address */
@@ -68,26 +61,6 @@
 #define NS_UNEXPECTED   0
 #define NS_INVALID     -1
 
-#ifdef CONFIG_IRDA_COMPRESSION
-
-/*  
- *  Just some shortcuts (may give you strange compiler errors if you change 
- *  them :-)
- */
-#define irda_compress    (*self->compessor.cp->compress)
-#define irda_comp_free   (*self->compressor.cp->comp_free)
-#define irda_decompress  (*self->decompressor.cp->decompress)
-#define irda_decomp_free (*self->decompressor.cp->decomp_free)
-#define irda_incomp      (*self->decompressor.cp->incomp)
-
-struct irda_compressor {
-	irda_queue_t q;
-
-	struct compressor *cp;
-	void *state; /* Not used by IrDA */
-};
-#endif
-
 /* Main structure of IrLAP */
 struct irlap_cb {
 	irda_queue_t q;     /* Must be first */
@@ -180,11 +153,6 @@
 	int    xbofs_delay;   /* Nr of XBOF's used to MTT */
 	int    bofs_count;    /* Negotiated extra BOFs */
 	int    next_bofs;     /* Negotiated extra BOFs after next frame */
-
-#ifdef CONFIG_IRDA_COMPRESSION
-	struct irda_compressor compressor;
-        struct irda_compressor decompressor;
-#endif /* CONFIG_IRDA_COMPRESSION */
 };
 
 extern hashbin_t *irlap;
diff -u --recursive --new-file v2.4.6/linux/include/net/irda/irlap_comp.h linux/include/net/irda/irlap_comp.h
--- v2.4.6/linux/include/net/irda/irlap_comp.h	Mon Dec 11 13:33:20 2000
+++ linux/include/net/irda/irlap_comp.h	Wed Dec 31 16:00:00 1969
@@ -1,47 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      irlap_comp.h
- * Version:       
- * Description:   
- * Status:        Experimental.
- * Author:        Dag Brattli <dagb@cs.uit.no>
- * Created at:    Fri Oct  9 09:21:12 1998
- * Modified at:   Sat Dec 12 12:23:16 1998
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
- *      
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
- *     the License, or (at your option) any later version.
- *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
- *     provided "AS-IS" and at no charge.
- *     
- ********************************************************************/
-
-#ifndef IRLAP_COMP_H
-#define IRLAP_COMP_H
-
-#include <linux/ppp-comp.h>
-
-#define CI_BZIP2  27 /* Random pick */
-
-extern hashbin_t *irlap_compressors;
-
-int irda_register_compressor( struct compressor *cp);
-void irda_unregister_compressor( struct compressor *cp);
-
-int irda_set_compression( struct irlap_cb *self, int proto);
-void irlap_compressor_init( struct irlap_cb *self, int compress);
-void irda_free_compression( struct irlap_cb *self);
-
-struct sk_buff *irlap_compress_frame( struct irlap_cb *self, 
-				      struct sk_buff *skb);
-struct sk_buff *irlap_decompress_frame( struct irlap_cb *self, 
-					struct sk_buff *skb);
-
-#endif
-
diff -u --recursive --new-file v2.4.6/linux/include/net/irda/qos.h linux/include/net/irda/qos.h
--- v2.4.6/linux/include/net/irda/qos.h	Fri May 25 18:02:38 2001
+++ linux/include/net/irda/qos.h	Wed Jul  4 11:50:38 2001
@@ -43,8 +43,6 @@
 #define PI_ADD_BOFS      0x85
 #define PI_MIN_TURN_TIME 0x86
 #define PI_LINK_DISC     0x08
-#define PI_COMPRESSION   0x07 /* Just a random pick */
-
 
 #define IR_115200_MAX 0x3f
 
@@ -80,10 +78,6 @@
 	qos_value_t link_disc_time;
 	
 	qos_value_t power;
-#ifdef CONFIG_IRDA_COMPRESSION
-	/* An experimental non IrDA field */
-	qos_value_t compression;
-#endif
 };
 
 extern int sysctl_max_baud_rate;
diff -u --recursive --new-file v2.4.6/linux/kernel/sys.c linux/kernel/sys.c
--- v2.4.6/linux/kernel/sys.c	Thu Apr 12 12:20:31 2001
+++ linux/kernel/sys.c	Wed Jul  4 11:50:38 2001
@@ -1119,8 +1119,6 @@
 		return -EINVAL;
 	if(copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
 		return -EFAULT;
-	if (new_rlim.rlim_cur < 0 || new_rlim.rlim_max < 0)
-		return -EINVAL;
 	old_rlim = current->rlim + resource;
 	if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
 	     (new_rlim.rlim_max > old_rlim->rlim_max)) &&
diff -u --recursive --new-file v2.4.6/linux/mm/swapfile.c linux/mm/swapfile.c
--- v2.4.6/linux/mm/swapfile.c	Tue Jul  3 17:08:22 2001
+++ linux/mm/swapfile.c	Wed Jul  4 11:50:38 2001
@@ -513,7 +513,7 @@
 
 	len += sprintf(buf, "Filename\t\t\tType\t\tSize\tUsed\tPriority\n");
 	for (i = 0 ; i < nr_swapfiles ; i++, ptr++) {
-		if (ptr->flags & SWP_USED) {
+		if ((ptr->flags & SWP_USED) && ptr->swap_map) {
 			char * path = d_path(ptr->swap_file, ptr->swap_vfsmnt,
 						page, PAGE_SIZE);
 
diff -u --recursive --new-file v2.4.6/linux/net/atm/mpoa_proc.c linux/net/atm/mpoa_proc.c
--- v2.4.6/linux/net/atm/mpoa_proc.c	Tue May 15 01:29:35 2001
+++ linux/net/atm/mpoa_proc.c	Wed Jul  4 11:50:38 2001
@@ -109,8 +109,6 @@
 	eg_cache_entry *eg_entry;
 	struct timeval now;
 	unsigned char ip_string[16];
-	if(count < 0)
-	        return -EINVAL;
 	if(count == 0)
 	        return 0;
 	page = get_free_page(GFP_KERNEL);
@@ -173,7 +171,6 @@
         char *page, c;
         const char *tmp;
 
-        if (nbytes < 0) return -EINVAL;
         if (nbytes == 0) return 0;
         if (nbytes >= PAGE_SIZE) nbytes = PAGE_SIZE-1;
 
diff -u --recursive --new-file v2.4.6/linux/net/atm/proc.c linux/net/atm/proc.c
--- v2.4.6/linux/net/atm/proc.c	Sun Mar 25 18:14:25 2001
+++ linux/net/atm/proc.c	Wed Jul  4 11:50:38 2001
@@ -495,7 +495,7 @@
 	unsigned long page;
 	int length;
 
-	if (count < 0) return -EINVAL;
+	if (count == 0) return 0;
 	page = get_free_page(GFP_KERNEL);
 	if (!page) return -ENOMEM;
 	dev = ((struct proc_dir_entry *) file->f_dentry->d_inode->u.generic_ip)
@@ -524,7 +524,7 @@
 	info = ((struct proc_dir_entry *) file->f_dentry->d_inode->u.generic_ip)
 	    ->data;
 
-	if (count < 0) return -EINVAL;
+	if (count == 0) return 0;
 	page = get_free_page(GFP_KERNEL);
 	if (!page) return -ENOMEM;
 	length = (*info)(*pos,(char *) page);
diff -u --recursive --new-file v2.4.6/linux/net/decnet/sysctl_net_decnet.c linux/net/decnet/sysctl_net_decnet.c
--- v2.4.6/linux/net/decnet/sysctl_net_decnet.c	Fri Feb  9 11:34:13 2001
+++ linux/net/decnet/sysctl_net_decnet.c	Wed Jul  4 11:50:38 2001
@@ -27,7 +27,7 @@
 #include <net/dn_route.h>
 
 
-int decnet_debug_level = 0;
+int decnet_debug_level;
 int decnet_time_wait = 30;
 int decnet_dn_count = 1;
 int decnet_di_count = 3;
diff -u --recursive --new-file v2.4.6/linux/net/irda/Makefile linux/net/irda/Makefile
--- v2.4.6/linux/net/irda/Makefile	Fri Dec 29 14:07:24 2000
+++ linux/net/irda/Makefile	Wed Jul  4 11:50:38 2001
@@ -20,7 +20,6 @@
 obj-m   := $(O_TARGET)
 endif
 
-obj-$(CONFIG_IRDA_COMPRESSION) += irlap_comp.o
 obj-$(CONFIG_PROC_FS) += irproc.o
 obj-$(CONFIG_SYSCTL) += irsysctl.o
 obj-$(CONFIG_IRLAN) += irlan/irlan.o
@@ -28,7 +27,6 @@
 subdir-$(CONFIG_IRLAN) += irlan
 subdir-$(CONFIG_IRNET) += irnet
 subdir-$(CONFIG_IRCOMM) += ircomm
-subdir-$(CONFIG_IRDA_COMPRESSION) += compressors
 
 ifeq ($(CONFIG_IRLAN),y)
 obj-y += irlan/irlan.o
@@ -36,14 +34,6 @@
 
 ifeq ($(CONFIG_IRNET),y)
 obj-y += irnet/irnet.o
-endif
-
-ifeq ($(CONFIG_IRDA_DEFLATE),y)
-obj-y += compressors/irda_deflate.o
-else
-  ifeq ($(CONFIG_IRDA_DEFLATE),m)
-  MOD_TO_LIST += irda_deflate.o
-  endif
 endif
 
 ifeq ($(CONFIG_IRCOMM),y)
diff -u --recursive --new-file v2.4.6/linux/net/irda/af_irda.c linux/net/irda/af_irda.c
--- v2.4.6/linux/net/irda/af_irda.c	Sat May 19 17:47:55 2001
+++ linux/net/irda/af_irda.c	Wed Jul  4 11:50:38 2001
@@ -218,8 +218,7 @@
 		   self->max_data_size);
 
 	memcpy(&self->qos_tx, qos, sizeof(struct qos_info));
-
-	skb_queue_tail(&sk->receive_queue, skb);
+	kfree_skb(skb);
 
 	/* We are now connected! */
 	sk->state = TCP_ESTABLISHED;
@@ -439,7 +438,7 @@
  * We were waiting for a node to be discovered, but nothing has come up
  * so far. Wake up the user and tell him that we failed...
  */
-static void irda_discovery_timeout(u_long	priv)
+static void irda_discovery_timeout(u_long priv)
 {
 	struct irda_sock *self;
 	
@@ -776,7 +775,6 @@
 	struct sock *sk = sock->sk;
 	struct sockaddr_irda *addr = (struct sockaddr_irda *) uaddr;
 	struct irda_sock *self;
-	__u16 hints = 0;
 	int err;
 
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
@@ -821,15 +819,6 @@
 				 self->stsap_sel, IAS_KERNEL_ATTR);
 	irias_insert_object(self->ias_obj);
 	
-#if 1 /* Will be removed in near future */
-
-	/* Fill in some default hint bits values */
-	if (strncmp(addr->sir_name, "OBEX", 4) == 0)
-		hints = irlmp_service_to_hint(S_OBEX);
-	
-	if (hints)
-		self->skey = irlmp_register_service(hints);
-#endif
 	return 0;
 }
 
@@ -1079,8 +1068,10 @@
 		return -ENOMEM;
 	
 	self = kmalloc(sizeof(struct irda_sock), GFP_ATOMIC);
-	if (self == NULL)
+	if (self == NULL) {
+		kfree (sk);
 		return -ENOMEM;
+	}
 	memset(self, 0, sizeof(struct irda_sock));
 
 	init_waitqueue_head(&self->query_wait);
@@ -1633,34 +1624,58 @@
 {
 	struct sock *sk = sock->sk;
 	unsigned int mask;
+	struct irda_sock *self;
 
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
+	self = sk->protinfo.irda;
 	poll_wait(file, sk->sleep, wait);
 	mask = 0;
 
-	/* exceptional events? */
+	/* Exceptional events? */
 	if (sk->err)
 		mask |= POLLERR;
-	if (sk->shutdown & RCV_SHUTDOWN)
+	if (sk->shutdown & RCV_SHUTDOWN) {
+		IRDA_DEBUG(0, __FUNCTION__ "(), POLLHUP\n");
 		mask |= POLLHUP;
+	}
 
-	/* readable? */
+	/* Readable? */
 	if (!skb_queue_empty(&sk->receive_queue)) {
 		IRDA_DEBUG(4, "Socket is readable\n");
 		mask |= POLLIN | POLLRDNORM;
 	}
+
 	/* Connection-based need to check for termination and startup */
-	if (sk->type == SOCK_STREAM && sk->state==TCP_CLOSE)
-		mask |= POLLHUP;
+	switch (sk->type) {
+	case SOCK_STREAM:
+		if (sk->state == TCP_CLOSE) {
+			IRDA_DEBUG(0, __FUNCTION__ "(), POLLHUP\n");
+			mask |= POLLHUP;
+		}
 
-	/*
-	 * we set writable also when the other side has shut down the
-	 * connection. This prevents stuck sockets.
-	 */
-	if (sk->sndbuf - (int)atomic_read(&sk->wmem_alloc) >= SOCK_MIN_WRITE_SPACE)
+		if (sk->state == TCP_ESTABLISHED) {
+			if ((self->tx_flow == FLOW_START) && 
+			    (sk->sndbuf - (int)atomic_read(&sk->wmem_alloc) >= SOCK_MIN_WRITE_SPACE))
+			{
+				mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
+			}
+		}
+		break;
+	case SOCK_SEQPACKET:
+		if ((self->tx_flow == FLOW_START) && 
+		    (sk->sndbuf - (int)atomic_read(&sk->wmem_alloc) >= SOCK_MIN_WRITE_SPACE))
+		{	
 			mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
-
+		}
+		break;
+	case SOCK_DGRAM:
+		if (sk->sndbuf - (int)atomic_read(&sk->wmem_alloc) >= SOCK_MIN_WRITE_SPACE)
+			mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
+		break;
+	default:
+		break;
+	}		
 	return mask;
 }
 
@@ -1740,7 +1755,7 @@
 {
  	struct sock *sk = sock->sk;
 	struct irda_sock *self;
-	struct irda_ias_set	ias_opt;
+	struct irda_ias_set    *ias_opt;
 	struct ias_object      *ias_obj;
 	struct ias_attrib *	ias_attr;	/* Attribute in IAS object */
 	int opt;
@@ -1763,64 +1778,78 @@
 		if (optlen != sizeof(struct irda_ias_set))
 			return -EINVAL;
 	
+		ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
+		if (ias_opt == NULL)
+			return -ENOMEM;
+
 		/* Copy query to the driver. */
-		if (copy_from_user(&ias_opt, (char *)optval, optlen))
+		if (copy_from_user(ias_opt, (char *)optval, optlen)) {
+			kfree(ias_opt);
 		  	return -EFAULT;
+		}
 
 		/* Find the object we target */
-		ias_obj = irias_find_object(ias_opt.irda_class_name);
+		ias_obj = irias_find_object(ias_opt->irda_class_name);
 		if(ias_obj == (struct ias_object *) NULL) {
 			/* Create a new object */
-			ias_obj = irias_new_object(ias_opt.irda_class_name,
+			ias_obj = irias_new_object(ias_opt->irda_class_name,
 						   jiffies);
 		}
 
 		/* Do we have it already ? */
-		if(irias_find_attrib(ias_obj, ias_opt.irda_attrib_name))
+		if(irias_find_attrib(ias_obj, ias_opt->irda_attrib_name)) {
+			kfree(ias_opt);
 			return -EINVAL;
+		}
 
 		/* Look at the type */
-		switch(ias_opt.irda_attrib_type) {
+		switch(ias_opt->irda_attrib_type) {
 		case IAS_INTEGER:
 			/* Add an integer attribute */
 			irias_add_integer_attrib(
 				ias_obj,
-				ias_opt.irda_attrib_name, 
-				ias_opt.attribute.irda_attrib_int,
+				ias_opt->irda_attrib_name, 
+				ias_opt->attribute.irda_attrib_int,
 				IAS_USER_ATTR);
 			break;
 		case IAS_OCT_SEQ:
 			/* Check length */
-			if(ias_opt.attribute.irda_attrib_octet_seq.len >
-			   IAS_MAX_OCTET_STRING)
+			if(ias_opt->attribute.irda_attrib_octet_seq.len >
+			   IAS_MAX_OCTET_STRING) {
+				kfree(ias_opt);
 				return -EINVAL;
+			}
 			/* Add an octet sequence attribute */
 			irias_add_octseq_attrib(
 			      ias_obj,
-			      ias_opt.irda_attrib_name, 
-			      ias_opt.attribute.irda_attrib_octet_seq.octet_seq,
-			      ias_opt.attribute.irda_attrib_octet_seq.len,
+			      ias_opt->irda_attrib_name, 
+			      ias_opt->attribute.irda_attrib_octet_seq.octet_seq,
+			      ias_opt->attribute.irda_attrib_octet_seq.len,
 			      IAS_USER_ATTR);
 			break;
 		case IAS_STRING:
 			/* Should check charset & co */
 			/* Check length */
-			if(ias_opt.attribute.irda_attrib_string.len >
-			   IAS_MAX_STRING)
+			if(ias_opt->attribute.irda_attrib_string.len >
+			   IAS_MAX_STRING) {
+				kfree(ias_opt);
 				return -EINVAL;
+			}
 			/* NULL terminate the string (avoid troubles) */
-			ias_opt.attribute.irda_attrib_string.string[ias_opt.attribute.irda_attrib_string.len] = '\0';
+			ias_opt->attribute.irda_attrib_string.string[ias_opt->attribute.irda_attrib_string.len] = '\0';
 			/* Add a string attribute */
 			irias_add_string_attrib(
 				ias_obj,
-				ias_opt.irda_attrib_name, 
-				ias_opt.attribute.irda_attrib_string.string,
+				ias_opt->irda_attrib_name, 
+				ias_opt->attribute.irda_attrib_string.string,
 				IAS_USER_ATTR);
 			break;
 		default :
+			kfree(ias_opt);
 			return -EINVAL;
 		}
 		irias_insert_object(ias_obj);
+		kfree(ias_opt);
 		break;
 	case IRLMP_IAS_DEL:
 		/* The user want to delete an object from our local IAS
@@ -1831,31 +1860,42 @@
 		if (optlen != sizeof(struct irda_ias_set))
 			return -EINVAL;
 	
+		ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
+		if (ias_opt == NULL)
+			return -ENOMEM;
+	
 		/* Copy query to the driver. */
-		if (copy_from_user(&ias_opt, (char *)optval, optlen))
+		if (copy_from_user(ias_opt, (char *)optval, optlen)) {
+			kfree(ias_opt);
 		  	return -EFAULT;
+		}
 
 		/* Find the object we target */
-		ias_obj = irias_find_object(ias_opt.irda_class_name);
-		if(ias_obj == (struct ias_object *) NULL)
+		ias_obj = irias_find_object(ias_opt->irda_class_name);
+		if(ias_obj == (struct ias_object *) NULL) {
+			kfree(ias_opt);
 			return -EINVAL;
+		}
 
 		/* Find the attribute (in the object) we target */
 		ias_attr = irias_find_attrib(ias_obj,
-					     ias_opt.irda_attrib_name); 
-		if(ias_attr == (struct ias_attrib *) NULL)
+					     ias_opt->irda_attrib_name); 
+		if(ias_attr == (struct ias_attrib *) NULL) {
+			kfree(ias_opt);
 			return -EINVAL;
+		}
 
 		/* Check is the user space own the object */
 		if(ias_attr->value->owner != IAS_USER_ATTR) {
 			IRDA_DEBUG(1, __FUNCTION__ 
 				   "(), attempting to delete a kernel attribute\n");
+			kfree(ias_opt);
 			return -EPERM;
 		}
 
 		/* Remove the attribute (and maybe the object) */
 		irias_delete_attrib(ias_obj, ias_attr);
-
+		kfree(ias_opt);
 		break;
 	case IRLMP_MAX_SDU_SIZE:
 		if (optlen < sizeof(int))
@@ -1978,7 +2018,7 @@
 	struct irda_sock *self;
 	struct irda_device_list list;
 	struct irda_device_info *discoveries;
-	struct irda_ias_set	ias_opt;	/* IAS get/query params */
+	struct irda_ias_set *	ias_opt;	/* IAS get/query params */
 	struct ias_object *	ias_obj;	/* Object in IAS */
 	struct ias_attrib *	ias_attr;	/* Attribute in IAS object */
 	int daddr = DEV_ADDR_ANY;	/* Dest address for IAS queries */
@@ -2048,34 +2088,49 @@
 		 * that we found */
 
 		/* Check that the user has allocated the right space for us */
-		if (len != sizeof(ias_opt))
+		if (len != sizeof(struct irda_ias_set))
 			return -EINVAL;
 
+		ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
+		if (ias_opt == NULL)
+			return -ENOMEM;
+
 		/* Copy query to the driver. */
-		if (copy_from_user((char *) &ias_opt, (char *)optval, len))
+		if (copy_from_user((char *) ias_opt, (char *)optval, len)) {
+			kfree(ias_opt);
 		  	return -EFAULT;
+		}
 
 		/* Find the object we target */
-		ias_obj = irias_find_object(ias_opt.irda_class_name);
-		if(ias_obj == (struct ias_object *) NULL)
+		ias_obj = irias_find_object(ias_opt->irda_class_name);
+		if(ias_obj == (struct ias_object *) NULL) {
+			kfree(ias_opt);
 			return -EINVAL;
+		}
 
 		/* Find the attribute (in the object) we target */
 		ias_attr = irias_find_attrib(ias_obj,
-					     ias_opt.irda_attrib_name); 
-		if(ias_attr == (struct ias_attrib *) NULL)
+					     ias_opt->irda_attrib_name); 
+		if(ias_attr == (struct ias_attrib *) NULL) {
+			kfree(ias_opt);
 			return -EINVAL;
+		}
 
 		/* Translate from internal to user structure */
-		err = irda_extract_ias_value(&ias_opt, ias_attr->value);
-		if(err)
+		err = irda_extract_ias_value(ias_opt, ias_attr->value);
+		if(err) {
+			kfree(ias_opt);
 			return err;
+		}
 
 		/* Copy reply to the user */
-		if (copy_to_user((char *)optval, (char *) &ias_opt,
-				 sizeof(ias_opt)))
+		if (copy_to_user((char *)optval, (char *) ias_opt,
+				 sizeof(struct irda_ias_set))) {
+			kfree(ias_opt);
 		  	return -EFAULT;
+		}
 		/* Note : don't need to put optlen, we checked it */
+		kfree(ias_opt);
 		break;
 	case IRLMP_IAS_QUERY:
 		/* The user want an object from a remote IAS database.
@@ -2083,12 +2138,18 @@
 		 * then wait for the answer to come back. */
 
 		/* Check that the user has allocated the right space for us */
-		if (len != sizeof(ias_opt))
+		if (len != sizeof(struct irda_ias_set))
 			return -EINVAL;
 
+		ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
+		if (ias_opt == NULL)
+			return -ENOMEM;
+
 		/* Copy query to the driver. */
-		if (copy_from_user((char *) &ias_opt, (char *)optval, len))
+		if (copy_from_user((char *) ias_opt, (char *)optval, len)) {
+			kfree(ias_opt);
 		  	return -EFAULT;
+		}
 
 		/* At this point, there are two cases...
 		 * 1) the socket is connected - that's the easy case, we
@@ -2105,15 +2166,18 @@
 		} else {
 			/* We are not connected, we must specify a valid
 			 * destination address */
-			daddr = ias_opt.daddr;
-			if((!daddr) || (daddr == DEV_ADDR_ANY))
+			daddr = ias_opt->daddr;
+			if((!daddr) || (daddr == DEV_ADDR_ANY)) {
+				kfree(ias_opt);
 				return -EINVAL;
+			}
 		}
 
 		/* Check that we can proceed with IAP */
 		if (self->iriap) {
 			WARNING(__FUNCTION__
 				"(), busy with a previous query\n");
+			kfree(ias_opt);
 			return -EBUSY;
 		}
 
@@ -2126,14 +2190,15 @@
 		/* Query remote LM-IAS */
 		iriap_getvaluebyclass_request(self->iriap,
 					      self->saddr, daddr,
-					      ias_opt.irda_class_name,
-					      ias_opt.irda_attrib_name);
+					      ias_opt->irda_class_name,
+					      ias_opt->irda_attrib_name);
 		/* Wait for answer (if not already failed) */
 		if(self->iriap != NULL)
 			interruptible_sleep_on(&self->query_wait);
 		/* Check what happened */
 		if (self->errno)
 		{
+			kfree(ias_opt);
 			/* Requested object/attribute doesn't exist */
 			if((self->errno == IAS_CLASS_UNKNOWN) ||
 			   (self->errno == IAS_ATTRIB_UNKNOWN))
@@ -2143,17 +2208,22 @@
 		}
 
 		/* Translate from internal to user structure */
-		err = irda_extract_ias_value(&ias_opt, self->ias_result);
+		err = irda_extract_ias_value(ias_opt, self->ias_result);
 		if (self->ias_result)
 			irias_delete_value(self->ias_result);
-		if (err)
+		if (err) {
+			kfree(ias_opt);
 			return err;
+		}
 
 		/* Copy reply to the user */
-		if (copy_to_user((char *)optval, (char *) &ias_opt,
-				 sizeof(ias_opt)))
+		if (copy_to_user((char *)optval, (char *) ias_opt,
+				 sizeof(struct irda_ias_set))) {
+			kfree(ias_opt);
 		  	return -EFAULT;
+		}
 		/* Note : don't need to put optlen, we checked it */
+		kfree(ias_opt);
 		break;
 	case IRLMP_WAITDEVICE:
 		/* This function is just another way of seeing life ;-)
@@ -2328,6 +2398,9 @@
 SOCKOPS_WRAP(irda_stream, PF_IRDA);
 SOCKOPS_WRAP(irda_seqpacket, PF_IRDA);
 SOCKOPS_WRAP(irda_dgram, PF_IRDA);
+#ifdef CONFIG_IRDA_ULTRA
+SOCKOPS_WRAP(irda_ultra, PF_IRDA);
+#endif /* CONFIG_IRDA_ULTRA */
 
 /*
  * Function irda_device_event (this, event, ptr)
@@ -2416,7 +2489,9 @@
 #endif
 	return 0;
 }
-module_init(irda_proto_init);
+#ifdef MODULE
+module_init(irda_proto_init);	/* If non-module, called from init/main.c */
+#endif
 
 /*
  * Function irda_proto_cleanup (void)
diff -u --recursive --new-file v2.4.6/linux/net/irda/compressors/Config.in linux/net/irda/compressors/Config.in
--- v2.4.6/linux/net/irda/compressors/Config.in	Wed Sep 29 15:32:14 1999
+++ linux/net/irda/compressors/Config.in	Wed Dec 31 16:00:00 1969
@@ -1,11 +0,0 @@
-
-bool '  IrLAP compression' CONFIG_IRDA_COMPRESSION
-
-if [ "$CONFIG_IRDA_COMPRESSION" != "n" ]; then
-   comment '    IrDA compressors'
-   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      dep_tristate '    Deflate compression (EXPERIMENTAL)' CONFIG_IRDA_DEFLATE $CONFIG_IRDA
-   fi
-#   tristate '    BZIP2 compression' CONFIG_IRDA_BZIP2
-#   tristate '    BSD compression' CONFIG_IRDA_BSD
-fi
diff -u --recursive --new-file v2.4.6/linux/net/irda/compressors/Makefile linux/net/irda/compressors/Makefile
--- v2.4.6/linux/net/irda/compressors/Makefile	Fri Dec 29 14:07:24 2000
+++ linux/net/irda/compressors/Makefile	Wed Dec 31 16:00:00 1969
@@ -1,20 +0,0 @@
-#
-# Makefile for the Linux IRDA compression protocols
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
-
-O_TARGET :=
-
-obj-y := 
-obj-m := 
-
-obj-$(CONFIG_IRDA_DEFLATE) += irda_deflate.o
-
-include $(TOPDIR)/Rules.make
-
-tar:
-		tar -cvf /dev/f1 .
diff -u --recursive --new-file v2.4.6/linux/net/irda/compressors/irda_deflate.c linux/net/irda/compressors/irda_deflate.c
--- v2.4.6/linux/net/irda/compressors/irda_deflate.c	Fri Feb  9 11:29:44 2001
+++ linux/net/irda/compressors/irda_deflate.c	Wed Dec 31 16:00:00 1969
@@ -1,634 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      irda_deflate.c
- * Version:       
- * Description:   
- * Status:        Experimental.
- * Author:        Dag Brattli <dagb@cs.uit.no>
- * Created at:    Fri Oct  9 02:52:08 1998
- * Modified at:   Mon Dec 14 19:48:54 1998
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *  ==FILEVERSION 980319==
- *
- * irda_deflate.c - interface the zlib procedures for Deflate compression
- * and decompression (as used by gzip) to the IrDA code.
- * This version is for use with Linux kernel 2.1.X.
- *
- * Copyright (c) 1994 The Australian National University.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation is hereby granted, provided that the above copyright
- * notice appears in all copies.  This software is provided without any
- * warranty, express or implied. The Australian National University
- * makes no representations about the suitability of this software for
- * any purpose.
- *
- * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
- * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
- * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
- * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
- * OR MODIFICATIONS.
- *
- * From: deflate.c,v 1.1 1996/01/18 03:17:48 paulus Exp
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h> 
-#include <linux/errno.h>
-#include <linux/string.h>	/* used in new tty drivers */
-#include <linux/signal.h>	/* used in new tty drivers */
-
-#include <asm/system.h>
-
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <linux/inet.h>
-#include <linux/ioctl.h>
-
-#include <linux/ppp_defs.h>
-#include <linux/ppp-comp.h>
-
-/*
- * This is not that nice, but what can we do when the code has been placed
- * elsewhere
- */
-
-#include "../../../drivers/net/zlib.c"
-
-/*
- * State for a Deflate (de)compressor.
- */
-struct irda_deflate_state {
-    int		seqno;
-    int		w_size;
-    int		unit;
-    int		mru;
-    int		debug;
-    z_stream	strm;
-    struct compstat stats;
-};
-
-#define DEFLATE_OVHD	2		/* Deflate overhead/packet */
-
-static void	*zalloc __P((void *, unsigned int items, unsigned int size));
-static void	*zalloc_init __P((void *, unsigned int items,
-				  unsigned int size));
-static void	zfree __P((void *, void *ptr));
-static void	*z_comp_alloc __P((unsigned char *options, int opt_len));
-static void	*z_decomp_alloc __P((unsigned char *options, int opt_len));
-static void	z_comp_free __P((void *state));
-static void	z_decomp_free __P((void *state));
-static int	z_comp_init __P((void *state, unsigned char *options,
-				 int opt_len,
-				 int unit, int hdrlen, int debug));
-static int	z_decomp_init __P((void *state, unsigned char *options,
-				   int opt_len,
-				   int unit, int hdrlen, int mru, int debug));
-static int	z_compress __P((void *state, unsigned char *rptr,
-				unsigned char *obuf,
-				int isize, int osize));
-static void	z_incomp __P((void *state, unsigned char *ibuf, int icnt));
-static int	z_decompress __P((void *state, unsigned char *ibuf,
-				int isize, unsigned char *obuf, int osize));
-static void	z_comp_reset __P((void *state));
-static void	z_decomp_reset __P((void *state));
-static void	z_comp_stats __P((void *state, struct compstat *stats));
-
-struct chunk_header {
-	int valloced;		/* allocated with valloc, not kmalloc */
-	int guard;		/* check for overwritten header */
-};
-
-#define GUARD_MAGIC	0x77a8011a
-#define MIN_VMALLOC	2048	/* use kmalloc for blocks < this */
-
-/*
- * Space allocation and freeing routines for use by zlib routines.
- */
-void zfree(void *arg, void *ptr)
-{
-	struct chunk_header *hdr = ((struct chunk_header *)ptr) - 1;
-	
-	if (hdr->guard != GUARD_MAGIC) {
-		printk(KERN_WARNING "zfree: header corrupted (%x %x) at %p\n",
-		       hdr->valloced, hdr->guard, hdr);
-		return;
-	}
-	if (hdr->valloced)
-		vfree(hdr);
-	else
-		kfree(hdr);
-}
-
-void *
-zalloc(arg, items, size)
-    void *arg;
-    unsigned int items, size;
-{
-	struct chunk_header *hdr;
-	unsigned nbytes;
-
-	nbytes = items * size + sizeof(*hdr);
-	hdr = kmalloc(nbytes, GFP_ATOMIC);
-	if (hdr == 0)
-		return 0;
-	hdr->valloced = 0;
-	hdr->guard = GUARD_MAGIC;
-	return (void *) (hdr + 1);
-}
-
-void * zalloc_init(void *arg, unsigned int items, unsigned int size)
-{
-	struct chunk_header *hdr;
-	unsigned nbytes;
-
-	nbytes = items * size + sizeof(*hdr);
-	if (nbytes >= MIN_VMALLOC)
-		hdr = vmalloc(nbytes);
-	else
-		hdr = kmalloc(nbytes, GFP_KERNEL);
-	if (hdr == 0)
-		return 0;
-	hdr->valloced = nbytes >= MIN_VMALLOC;
-	hdr->guard = GUARD_MAGIC;
-	return (void *) (hdr + 1);
-}
-
-static void
-z_comp_free(arg)
-    void *arg;
-{
-	struct irda_deflate_state *state = (struct irda_deflate_state *) arg;
-
-	if (state) {
-		deflateEnd(&state->strm);
-		kfree(state);
-		MOD_DEC_USE_COUNT;
-	}
-}
-
-/*
- * Allocate space for a compressor.
- */
-static void *
-z_comp_alloc(options, opt_len)
-    unsigned char *options;
-    int opt_len;
-{
-	struct irda_deflate_state *state;
-	int w_size;
-
-	if (opt_len != CILEN_DEFLATE
-	    || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
-	    || options[1] != CILEN_DEFLATE
-	    || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
-	    || options[3] != DEFLATE_CHK_SEQUENCE)
-		return NULL;
-	w_size = DEFLATE_SIZE(options[2]);
-	w_size = MAX_WBITS;
-	if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
-		return NULL;
-
-	state = (struct irda_deflate_state *) kmalloc(sizeof(*state), GFP_KERNEL);
-	if (state == NULL)
-		return NULL;
-
-	MOD_INC_USE_COUNT;
-	memset (state, 0, sizeof (struct irda_deflate_state));
-	state->strm.next_in = NULL;
-	state->strm.zalloc  = zalloc_init;
-	state->strm.zfree   = zfree;
-	state->w_size       = w_size;
-
-	if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION,
-			 DEFLATE_METHOD_VAL, -w_size, 8, Z_DEFAULT_STRATEGY)
-	    != Z_OK)
-		goto out_free;
-	state->strm.zalloc = zalloc;
-	return (void *) state;
-
-out_free:
-	z_comp_free(state);
-	MOD_DEC_USE_COUNT;
-	return NULL;
-}
-
-static int
-z_comp_init(arg, options, opt_len, unit, hdrlen, debug)
-    void *arg;
-    unsigned char *options;
-    int opt_len, unit, hdrlen, debug;
-{
-	struct irda_deflate_state *state = (struct irda_deflate_state *) arg;
-
-	if (opt_len < CILEN_DEFLATE
-	    || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
-	    || options[1] != CILEN_DEFLATE
-	    || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
-	    || DEFLATE_SIZE(options[2]) != state->w_size
-	    || options[3] != DEFLATE_CHK_SEQUENCE)
-		return 0;
-
-	state->seqno = 0;
-	state->unit  = unit;
-	state->debug = debug;
-
-	deflateReset(&state->strm);
-
-	return 1;
-}
-
-static void z_comp_reset(void *arg)
-{
-	struct irda_deflate_state *state = (struct irda_deflate_state *) arg;
-
-	state->seqno = 0;
-	deflateReset(&state->strm);
-}
-
-int
-z_compress(arg, rptr, obuf, isize, osize)
-    void *arg;
-    unsigned char *rptr;	/* uncompressed packet (in) */
-    unsigned char *obuf;	/* compressed packet (out) */
-    int isize, osize;
-{
-	struct irda_deflate_state *state = (struct irda_deflate_state *) arg;
-	int r, olen, oavail;
-
-	olen = 0;
-
-	/* Don't generate compressed packets which are larger than
-	   the uncompressed packet. */
-	if (osize > isize)
-		osize = isize;
-
-	state->strm.next_out = obuf;
-	state->strm.avail_out = oavail = osize;
-
-	state->strm.next_in = rptr;
-	state->strm.avail_in = isize;
-
-	for (;;) {
-		r = deflate(&state->strm, Z_PACKET_FLUSH);
-		if (r != Z_OK) {
-			if (state->debug)
-				printk(KERN_ERR
-				       "z_compress: deflate returned %d\n", r);
-			break;
-		}
-		if (state->strm.avail_out == 0) {
-			olen += oavail;
-			state->strm.next_out = NULL;
-			state->strm.avail_out = oavail = 1000000;
-		} else {
-			break;		/* all done */
-		}
-	}
-	olen += oavail - state->strm.avail_out;
-
-	/*
-	 * See if we managed to reduce the size of the packet.
-	 */
-	if (olen < isize) {
-		state->stats.comp_bytes += olen;
-		state->stats.comp_packets++;
-	} else {
-		state->stats.inc_bytes += isize;
-		state->stats.inc_packets++;
-		olen = 0;
-	}
-	state->stats.unc_bytes += isize;
-	state->stats.unc_packets++;
-
-	return olen;
-}
-
-static void
-z_comp_stats(arg, stats)
-    void *arg;
-    struct compstat *stats;
-{
-	struct irda_deflate_state *state = (struct irda_deflate_state *) arg;
-
-	*stats = state->stats;
-}
-
-static void z_decomp_free(void *arg)
-{
-	struct irda_deflate_state *state = (struct irda_deflate_state *) arg;
-
-	if (state) {
-		inflateEnd(&state->strm);
-		kfree(state);
-		MOD_DEC_USE_COUNT;
-	}
-}
-
-/*
- * Allocate space for a decompressor.
- */
-static void *
-z_decomp_alloc(options, opt_len)
-    unsigned char *options;
-    int opt_len;
-{
-	struct irda_deflate_state *state;
-	int w_size;
-
-	if (opt_len != CILEN_DEFLATE
-	    || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
-	    || options[1] != CILEN_DEFLATE
-	    || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
-	    || options[3] != DEFLATE_CHK_SEQUENCE)
-		return NULL;
-	w_size = DEFLATE_SIZE(options[2]);
-	w_size = MAX_WBITS;
-	if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
-		return NULL;
-
-	state = (struct irda_deflate_state *) kmalloc(sizeof(*state), GFP_KERNEL);
-	if (state == NULL)
-		return NULL;
-
-	MOD_INC_USE_COUNT;
-	memset (state, 0, sizeof (struct irda_deflate_state));
-	state->w_size        = w_size;
-	state->strm.next_out = NULL;
-	state->strm.zalloc   = zalloc_init;
-	state->strm.zfree    = zfree;
-
-	if (inflateInit2(&state->strm, -w_size) != Z_OK)
-		goto out_free;
-	state->strm.zalloc = zalloc;
-	return (void *) state;
-
-out_free:
-	z_decomp_free(state);
-	MOD_DEC_USE_COUNT;
-	return NULL;
-}
-
-static int
-z_decomp_init(arg, options, opt_len, unit, hdrlen, mru, debug)
-    void *arg;
-    unsigned char *options;
-    int opt_len, unit, hdrlen, mru, debug;
-{
-	struct irda_deflate_state *state = (struct irda_deflate_state *) arg;
-
-	if (opt_len < CILEN_DEFLATE
-	    || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
-	    || options[1] != CILEN_DEFLATE
-	    || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
-	    || DEFLATE_SIZE(options[2]) != state->w_size
-	    || options[3] != DEFLATE_CHK_SEQUENCE)
-		return 0;
-
-	state->seqno = 0;
-	state->unit  = unit;
-	state->debug = debug;
-	state->mru   = mru;
-
-	inflateReset(&state->strm);
-
-	return 1;
-}
-
-static void z_decomp_reset(void *arg)
-{
-	struct irda_deflate_state *state = (struct irda_deflate_state *) arg;
-
-	state->seqno = 0;
-	inflateReset(&state->strm);
-}
-
-/*
- * Decompress a Deflate-compressed packet.
- *
- * Because of patent problems, we return DECOMP_ERROR for errors
- * found by inspecting the input data and for system problems, but
- * DECOMP_FATALERROR for any errors which could possibly be said to
- * be being detected "after" decompression.  For DECOMP_ERROR,
- * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
- * infringing a patent of Motorola's if we do, so we take CCP down
- * instead.
- *
- * Given that the frame has the correct sequence number and a good FCS,
- * errors such as invalid codes in the input most likely indicate a
- * bug, so we return DECOMP_FATALERROR for them in order to turn off
- * compression, even though they are detected by inspecting the input.
- */
-int
-z_decompress(arg, ibuf, isize, obuf, osize)
-    void *arg;
-    unsigned char *ibuf;
-    int isize;
-    unsigned char *obuf;
-    int osize;
-{
-	struct irda_deflate_state *state = (struct irda_deflate_state *) arg;
-	int olen, r;
-	int overflow;
-	unsigned char overflow_buf[1];
-
-	if (isize <= DEFLATE_OVHD) {
-		if (state->debug)
-			printk(KERN_DEBUG "z_decompress%d: short pkt (%d)\n",
-			       state->unit, isize);
-		return DECOMP_ERROR;
-	}
-
-	/*
-	 * Set up to call inflate.
-	 */
-	state->strm.next_in = ibuf;
-	state->strm.avail_in = isize;
-	state->strm.next_out = obuf;
-	state->strm.avail_out = osize;
-	overflow = 0;
-
-	/*
-	 * Call inflate, supplying more input or output as needed.
-	 */
-	for (;;) {
-		r = inflate(&state->strm, Z_PACKET_FLUSH);
-		if (r != Z_OK) {
-			if (state->debug)
-				printk(KERN_DEBUG "z_decompress%d: inflate returned %d (%s)\n",
-				       state->unit, r, (state->strm.msg? state->strm.msg: ""));
-			return DECOMP_FATALERROR;
-		}
-		if (state->strm.avail_out != 0)
-			break;		/* all done */
-		
-		if (!overflow) {
-			/*
-			 * We've filled up the output buffer; the only way to
-			 * find out whether inflate has any more characters
-			 * left is to give it another byte of output space.
-			 */
-			state->strm.next_out = overflow_buf;
-			state->strm.avail_out = 1;
-			overflow = 1;
-		} else {
-			if (state->debug)
-				printk(KERN_DEBUG "z_decompress%d: ran out of mru\n",
-				       state->unit);
-			return DECOMP_FATALERROR;
-		}
-	}
-
-	olen = osize + overflow - state->strm.avail_out;
-	state->stats.unc_bytes += olen;
-	state->stats.unc_packets++;
-	state->stats.comp_bytes += isize;
-	state->stats.comp_packets++;
-
-	return olen;
-}
-
-/*
- * Incompressible data has arrived - add it to the history.
- */
-static void
-z_incomp(arg, ibuf, icnt)
-    void *arg;
-    unsigned char *ibuf;
-    int icnt;
-{
-	struct irda_deflate_state *state = (struct irda_deflate_state *) arg;
-	int r;
-
-	/*
-	 * Check that the protocol is one we handle.
-	 */
-
-	/*
-	 * We start at the either the 1st or 2nd byte of the protocol field,
-	 * depending on whether the protocol value is compressible.
-	 */
-	state->strm.next_in = ibuf;
-	state->strm.avail_in = icnt;
-
-	r = inflateIncomp(&state->strm);
-	if (r != Z_OK) {
-		/* gak! */
-		if (state->debug) {
-			printk(KERN_DEBUG "z_incomp%d: inflateIncomp returned %d (%s)\n",
-			       state->unit, r, (state->strm.msg? state->strm.msg: ""));
-		}
-		return;
-	}
-
-	/*
-	 * Update stats.
-	 */
-	state->stats.inc_bytes += icnt;
-	state->stats.inc_packets++;
-	state->stats.unc_bytes += icnt;
-	state->stats.unc_packets++;
-}
-
-/*************************************************************
- * Module interface table
- *************************************************************/
-
-/* These are in ppp.c */
-extern int  irda_register_compressor   (struct compressor *cp);
-extern void irda_unregister_compressor (struct compressor *cp);
-
-/*
- * Procedures exported to if_ppp.c.
- */
-static struct compressor irda_deflate = {
-compress_proto:	CI_DEFLATE,
-comp_alloc:	z_comp_alloc,
-comp_free:	z_comp_free,
-comp_init:	z_comp_init,
-comp_reset:	z_comp_reset,
-compress:	z_compress,
-comp_stat:	z_comp_stats,
-decomp_alloc:	z_decomp_alloc,
-decomp_free:	z_decomp_free,
-decomp_init:	z_decomp_init,
-decomp_reset:	z_decomp_reset,
-decompress:	z_decompress,
-incomp:		z_incomp,
-decomp_stat:	z_comp_stats
-};
-
-static struct compressor irda_deflate_draft = {
-compress_proto:	CI_DEFLATE_DRAFT,
-comp_alloc:	z_comp_alloc,
-comp_free:	z_comp_free,
-comp_init:	z_comp_init,
-comp_reset:	z_comp_reset,
-compress:	z_compress,
-comp_stat:	z_comp_stats,
-decomp_alloc:	z_decomp_alloc,
-decomp_free:	z_decomp_free,
-decomp_init:	z_decomp_init,
-decomp_reset:	z_decomp_reset,
-decompress:	z_decompress,
-incomp:		z_incomp,
-decomp_stat:	z_comp_stats
-};
-
-int __init irda_deflate_init(void)
-{
-        int answer = irda_register_compressor ( &irda_deflate);
-        if (answer == 0)
-                printk (KERN_INFO
-			"IrDA Deflate Compression module registered\n");
-	irda_register_compressor( &irda_deflate_draft);
-        return answer;
-}
-
-void irda_deflate_cleanup(void)
-{
-
-	irda_unregister_compressor (&irda_deflate);
-	irda_unregister_compressor (&irda_deflate_draft);
-}
-
-#ifdef MODULE
-/*************************************************************
- * Module support routines
- *************************************************************/
-
-int init_module(void)
-{  
-	return irda_deflate_init();
-}
-     
-void
-cleanup_module(void)
-{
-	if (MOD_IN_USE)
-		printk (KERN_INFO
-			"Deflate Compression module busy, remove delayed\n");
-	else {
-		irda_deflate_cleanup();
-	}
-}
-#endif
diff -u --recursive --new-file v2.4.6/linux/net/irda/ircomm/ircomm_tty_ioctl.c linux/net/irda/ircomm/ircomm_tty_ioctl.c
--- v2.4.6/linux/net/irda/ircomm/ircomm_tty_ioctl.c	Thu Jan  6 14:46:18 2000
+++ linux/net/irda/ircomm/ircomm_tty_ioctl.c	Wed Jul  4 11:50:38 2001
@@ -221,16 +221,14 @@
 { 
 	unsigned int arg;
 	__u8 old_rts, old_dtr;
-	int error;
 
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
-	error = get_user(arg, value);
-	if (error)
-		return error;
+	if (get_user(arg, value))
+		return -EFAULT;
 
 	old_rts = self->settings.dte & IRCOMM_RTS;
 	old_dtr = self->settings.dte & IRCOMM_DTR;
@@ -431,28 +429,18 @@
 		cnow = driver->icount;
 		restore_flags(flags);
 		p_cuser = (struct serial_icounter_struct *) arg;
-		error = put_user(cnow.cts, &p_cuser->cts);
-		if (error) return error;
-		error = put_user(cnow.dsr, &p_cuser->dsr);
-		if (error) return error;
-		error = put_user(cnow.rng, &p_cuser->rng);
-		if (error) return error;
-		error = put_user(cnow.dcd, &p_cuser->dcd);
-		if (error) return error;
-		error = put_user(cnow.rx, &p_cuser->rx);
-		if (error) return error;
-		error = put_user(cnow.tx, &p_cuser->tx);
-		if (error) return error;
-		error = put_user(cnow.frame, &p_cuser->frame);
-		if (error) return error;
-		error = put_user(cnow.overrun, &p_cuser->overrun);
-		if (error) return error;
-		error = put_user(cnow.parity, &p_cuser->parity);
-		if (error) return error;
-		error = put_user(cnow.brk, &p_cuser->brk);
-		if (error) return error;
-		error = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
-		if (error) return error;			
+		if (put_user(cnow.cts, &p_cuser->cts) ||
+		    put_user(cnow.dsr, &p_cuser->dsr) ||
+		    put_user(cnow.rng, &p_cuser->rng) ||
+		    put_user(cnow.dcd, &p_cuser->dcd) ||
+		    put_user(cnow.rx, &p_cuser->rx) ||
+		    put_user(cnow.tx, &p_cuser->tx) ||
+		    put_user(cnow.frame, &p_cuser->frame) ||
+		    put_user(cnow.overrun, &p_cuser->overrun) ||
+		    put_user(cnow.parity, &p_cuser->parity) ||
+		    put_user(cnow.brk, &p_cuser->brk) ||
+		    put_user(cnow.buf_overrun, &p_cuser->buf_overrun))
+			return -EFAULT;
 #endif		
 		return 0;
 	default:
diff -u --recursive --new-file v2.4.6/linux/net/irda/irias_object.c linux/net/irda/irias_object.c
--- v2.4.6/linux/net/irda/irias_object.c	Sat May 19 17:47:55 2001
+++ linux/net/irda/irias_object.c	Wed Jul  4 11:50:38 2001
@@ -34,7 +34,7 @@
 /*
  *  Used when a missing value needs to be returned
  */
-struct ias_value missing = { IAS_MISSING, 0, 0, 0};
+struct ias_value missing = { IAS_MISSING, 0, 0, 0, {0}};
 
 /*
  * Function strdup (str)
diff -u --recursive --new-file v2.4.6/linux/net/irda/irlan/irlan_common.c linux/net/irda/irlan/irlan_common.c
--- v2.4.6/linux/net/irda/irlan/irlan_common.c	Sat Nov 11 18:11:23 2000
+++ linux/net/irda/irlan/irlan_common.c	Wed Jul  4 11:50:38 2001
@@ -209,6 +209,7 @@
 	struct irlan_cb *self;
 
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
+	ASSERT(irlan != NULL, return NULL;);
 
 	/* 
 	 *  Initialize the irlan structure. 
@@ -224,8 +225,6 @@
 	 */
 	self->magic = IRLAN_MAGIC;
 
-	ASSERT(irlan != NULL, return NULL;);
-	
 	sprintf(self->dev.name, "%s", "unknown");
 
 	self->dev.priv = (void *) self;
@@ -1074,19 +1073,18 @@
 {
  	struct irlan_cb *self;
 	unsigned long flags;
+	ASSERT(irlan != NULL, return 0;);
      
 	save_flags(flags);
 	cli();
 
-	ASSERT(irlan != NULL, return 0;);
-	
 	len = 0;
 	
 	len += sprintf(buf+len, "IrLAN instances:\n");
 	
 	self = (struct irlan_cb *) hashbin_get_first(irlan);
 	while (self != NULL) {
-		ASSERT(self->magic == IRLAN_MAGIC, return len;);
+		ASSERT(self->magic == IRLAN_MAGIC, break;);
 		
 		len += sprintf(buf+len, "ifname: %s,\n",
 			       self->dev.name);
diff -u --recursive --new-file v2.4.6/linux/net/irda/irlap.c linux/net/irda/irlap.c
--- v2.4.6/linux/net/irda/irlap.c	Sat May 19 17:47:55 2001
+++ linux/net/irda/irlap.c	Wed Jul  4 11:50:38 2001
@@ -46,7 +46,6 @@
 #include <net/irda/irlap.h>
 #include <net/irda/timer.h>
 #include <net/irda/qos.h>
-#include <net/irda/irlap_comp.h>
 
 hashbin_t *irlap = NULL;
 int sysctl_slot_timeout = SLOT_TIMEOUT * 1000 / HZ;
@@ -79,15 +78,6 @@
 		return -ENOMEM;
 	}
 
-#ifdef CONFIG_IRDA_COMPRESSION
-	irlap_compressors = hashbin_new(HB_LOCAL);
-	if (irlap_compressors == NULL) {
-		WARNING(__FUNCTION__ 
-			"(), can't allocate compressors hashbin!\n");
-		return -ENOMEM;
-	}
-#endif
-
 	return 0;
 }
 
@@ -96,10 +86,6 @@
 	ASSERT(irlap != NULL, return;);
 
 	hashbin_delete(irlap, (FREE_FUNC) __irlap_close);
-
-#ifdef CONFIG_IRDA_COMPRESSION
-	hashbin_delete(irlap_compressors, (FREE_FUNC) kfree);
-#endif
 }
 
 /*
@@ -312,16 +298,6 @@
 	/* Hide LAP header from IrLMP layer */
 	skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
 
-#ifdef CONFIG_IRDA_COMPRESSION
-	if (self->qos_tx.compression.value) {
-		skb_get(skb); /*LEVEL4*/
-		skb = irlap_decompress_frame(self, skb);
-		if (!skb) {
-			IRDA_DEBUG(1, __FUNCTION__ "(), Decompress error!\n");
-			return;
-		}
-	}
-#endif
 	skb_get(skb); /*LEVEL4*/
 	irlmp_link_data_indication(self->notify.instance, skb, unreliable);
 }
@@ -341,15 +317,6 @@
 
 	IRDA_DEBUG(3, __FUNCTION__ "()\n");
 
-#ifdef CONFIG_IRDA_COMPRESSION
-	if (self->qos_tx.compression.value) {
-		skb = irlap_compress_frame(self, skb);
-		if (!skb) {
-			IRDA_DEBUG(1, __FUNCTION__ "(), Compress error!\n");
-			return;
-		}
-	}
-#endif
 	ASSERT(skb_headroom(skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER), 
 	       return;);
 	skb_push(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
@@ -482,9 +449,6 @@
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 
-#ifdef CONFIG_IRDA_COMPRESSION
-	irda_free_compression(self);
-#endif
 	/* Flush queues */
 	irlap_flush_all_queues(self);
 	
@@ -860,13 +824,6 @@
 	/* Free sliding window buffered packets */
 	while ((skb = skb_dequeue(&self->wx_list)) != NULL)
 		dev_kfree_skb(skb);
-
-#ifdef CONFIG_IRDA_RECYCLE_RR
-	if (self->recycle_rr_skb) { 
- 		dev_kfree_skb(self->recycle_rr_skb);
- 		self->recycle_rr_skb = NULL;
- 	}
-#endif
 }
 
 /*
@@ -894,50 +851,6 @@
 	}
 }
 
-#ifdef CONFIG_IRDA_COMPRESSION
-void irlap_init_comp_qos_capabilities(struct irlap_cb *self)
-{
-	struct irda_compressor *comp;
-	__u8 mask; /* Current bit tested */
-	int i;
-
-	ASSERT(self != NULL, return;);
-	ASSERT(self->magic == LAP_MAGIC, return;);
-	
-	/* 
-	 *  Find out which compressors we support. We do this be checking that
-	 *  the corresponding compressor for each bit set in the QoS bits has 
-	 *  actually been loaded. Ths is sort of hairy code but that is what 
-	 *  you get when you do a little bit flicking :-)
-	 */
-	IRDA_DEBUG(4, __FUNCTION__ "(), comp bits 0x%02x\n", 
-		   self->qos_rx.compression.bits); 
-	mask = 0x80; /* Start with testing MSB */
-	for (i=0;i<8;i++) {
-		IRDA_DEBUG(4, __FUNCTION__ "(), testing bit %d\n", 8-i);
-		if (self->qos_rx.compression.bits & mask) {
-			IRDA_DEBUG(4, __FUNCTION__ 
-				   "(), bit %d is set by defalt\n", 8-i);
-			comp = hashbin_find(irlap_compressors, 
-					    compressions[msb_index(mask)], 
-					    NULL);
-			if (!comp) {
-				/* Protocol not supported, so clear the bit */
-				IRDA_DEBUG(4, __FUNCTION__ "(), Compression "
-					   "protocol %d has not been loaded!\n", 
-					   compressions[msb_index(mask)]);
-				self->qos_rx.compression.bits &= ~mask;
-				IRDA_DEBUG(4, __FUNCTION__ 
-					   "(), comp bits 0x%02x\n", 
-					   self->qos_rx.compression.bits); 
-			}
-		}
-		/* Try the next bit */
-		mask >>= 1;
-	}
-}
-#endif	
-
 /*
  * Function irlap_init_qos_capabilities (self, qos)
  *
@@ -956,10 +869,6 @@
 	/* Start out with the maximum QoS support possible */
 	irda_init_max_qos_capabilies(&self->qos_rx);
 
-#ifdef CONFIG_IRDA_COMPRESSION
-	irlap_init_comp_qos_capabilities(self);
-#endif
-
 	/* Apply drivers QoS capabilities */
 	irda_qos_compute_intersection(&self->qos_rx, self->qos_dev);
 
@@ -981,9 +890,6 @@
 
 		if (qos_user->link_disc_time.bits)
 			self->qos_rx.link_disc_time.bits &= qos_user->link_disc_time.bits;
-#ifdef CONFIG_IRDA_COMPRESSION
-		self->qos_rx.compression.bits &= qos_user->compression.bits;
-#endif
 	}
 
 	/* Use 500ms in IrLAP for now */
@@ -1076,7 +982,7 @@
 
 	/* Set the negociated xbofs value */
 	self->next_bofs   = self->qos_tx.additional_bofs.value;
-	if(now)
+	if (now)
 		self->bofs_count = self->next_bofs;
 
 	/* Set the negociated link speed (may need the new xbofs value) */
@@ -1092,51 +998,62 @@
 	self->line_capacity = 
 		irlap_max_line_capacity(self->qos_tx.baud_rate.value,
 					self->qos_tx.max_turn_time.value);
+
+	
+	/* 
+	 *  Initialize timeout values, some of the rules are listed on 
+	 *  page 92 in IrLAP.
+	 */
+	ASSERT(self->qos_tx.max_turn_time.value != 0, return;);
+	ASSERT(self->qos_rx.max_turn_time.value != 0, return;);
+	/* The poll timeout applies only to the primary station.
+	 * It defines the maximum time the primary stay in XMIT mode
+	 * before timeout and turning the link around (sending a RR).
+	 * Or, this is how much we can keep the pf bit in primary mode.
+	 * Therefore, it must be lower or equal than our *OWN* max turn around.
+	 * Jean II */
+	self->poll_timeout = self->qos_tx.max_turn_time.value * HZ / 1000;
+	/* The Final timeout applies only to the primary station.
+	 * It defines the maximum time the primary wait (mostly in RECV mode)
+	 * for an answer from the secondary station before polling it again.
+	 * Therefore, it must be greater or equal than our *PARTNER*
+	 * max turn around time - Jean II */
+	self->final_timeout = self->qos_rx.max_turn_time.value * HZ / 1000;
+	/* The Watchdog Bit timeout applies only to the secondary station.
+	 * It defines the maximum time the secondary wait (mostly in RECV mode)
+	 * for poll from the primary station before getting annoyed.
+	 * Therefore, it must be greater or equal than our *PARTNER*
+	 * max turn around time - Jean II */
+	self->wd_timeout = self->final_timeout * 2;
+
+	/*
+	 * N1 and N2 are maximum retry count for *both* the final timer
+	 * and the wd timer (with a factor 2) as defined above.
+	 * After N1 retry of a timer, we give a warning to the user.
+	 * After N2 retry, we consider the link dead and disconnect it.
+	 * Jean II
+	 */
+
 	/*
 	 *  Set N1 to 0 if Link Disconnect/Threshold Time = 3 and set it to 
 	 *  3 seconds otherwise. See page 71 in IrLAP for more details.
-	 *  TODO: these values should be calculated from the final timer
-         *  as well
 	 */
-	ASSERT(self->qos_tx.max_turn_time.value != 0, return;);
 	if (self->qos_tx.link_disc_time.value == 3)
 		/* 
 		 * If we set N1 to 0, it will trigger immediately, which is
 		 * not what we want. What we really want is to disable it,
 		 * Jean II 
 		 */
-		self->N1 = -1; /* Disable */
+		self->N1 = -2; /* Disable - Need to be multiple of 2*/
 	else
-		self->N1 = 3000 / self->qos_tx.max_turn_time.value;
+		self->N1 = 3000 / self->qos_rx.max_turn_time.value;
 	
 	IRDA_DEBUG(4, "Setting N1 = %d\n", self->N1);
 	
-	
+	/* Set N2 to match our own disconnect time */
 	self->N2 = self->qos_tx.link_disc_time.value * 1000 / 
-		self->qos_tx.max_turn_time.value;
+		self->qos_rx.max_turn_time.value;
 	IRDA_DEBUG(4, "Setting N2 = %d\n", self->N2);
-
-	/* 
-	 *  Initialize timeout values, some of the rules are listed on 
-	 *  page 92 in IrLAP.
-	 */
-	self->poll_timeout = self->qos_tx.max_turn_time.value * HZ / 1000;
-	self->wd_timeout = self->poll_timeout * 2;
-
-	/* 
-	 * Be careful to keep our promises to the peer device about how long
-	 * time it can keep the pf bit. So here we must use the rx_qos value
-	 */
-	self->final_timeout = self->qos_rx.max_turn_time.value * HZ / 1000;
-
-#ifdef CONFIG_IRDA_COMPRESSION
-	if (self->qos_tx.compression.value) {
-		IRDA_DEBUG(1, __FUNCTION__ "(), Initializing compression\n");
-		irda_set_compression(self, self->qos_tx.compression.value);
-
-		irlap_compressor_init(self, 0);
-	}
-#endif
 }
 
 /*
@@ -1226,10 +1143,6 @@
 			       self->qos_tx.min_turn_time.value);
 		len += sprintf(buf+len, "%d\t", 
 			       self->qos_tx.link_disc_time.value);
-#ifdef CONFIG_IRDA_COMPRESSION
-		len += sprintf(buf+len, "%d",
-			       self->qos_tx.compression.value);
-#endif
 		len += sprintf(buf+len, "\n");
 
 		len += sprintf(buf+len, "  rx\t%d\t", 
@@ -1246,10 +1159,6 @@
 			       self->qos_rx.min_turn_time.value);
 		len += sprintf(buf+len, "%d\t", 
 			       self->qos_rx.link_disc_time.value);
-#ifdef CONFIG_IRDA_COMPRESSION
-		len += sprintf(buf+len, "%d",
-			       self->qos_rx.compression.value);
-#endif
 		len += sprintf(buf+len, "\n");
 		
 		self = (struct irlap_cb *) hashbin_get_next(irlap);
diff -u --recursive --new-file v2.4.6/linux/net/irda/irlap_comp.c linux/net/irda/irlap_comp.c
--- v2.4.6/linux/net/irda/irlap_comp.c	Fri Mar  2 11:12:12 2001
+++ linux/net/irda/irlap_comp.c	Wed Dec 31 16:00:00 1969
@@ -1,354 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      irlap_comp.c
- * Version:       
- * Description:   
- * Status:        Experimental.
- * Author:        Dag Brattli <dagb@cs.uit.no>
- * Created at:    Fri Oct  9 09:18:07 1998
- * Modified at:   Tue Oct  5 11:34:52 1999
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * Modified at:   Fri May 28  3:11 CST 1999
- * Modified by:   Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
- * Sources:       ppp.c, isdn_ppp.c
- * 
- *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
- *      
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
- *     the License, or (at your option) any later version.
- *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
- *     provided "AS-IS" and at no charge.
- *     
- ********************************************************************/
-
-#include <linux/string.h>
-
-#include <net/irda/irda.h>
-#include <net/irda/irqueue.h>
-#include <net/irda/irlap.h>
-#include <net/irda/irlap_comp.h>
-#include "../../drivers/net/zlib.h"
-
-hashbin_t *irlap_compressors = NULL;
-
-/*
- * Function irda_register_compressor (cp)
- *
- *    Register new compressor with the IrLAP
- *
- */
-int irda_register_compressor( struct compressor *cp)
-{
-	struct irda_compressor *new;
-
-	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
-
-	/* Check if this compressor has been registred before */
-	if ( hashbin_find ( irlap_compressors, cp->compress_proto, NULL)) {
-		IRDA_DEBUG( 0, __FUNCTION__ "(), Compressor already registered\n");
-                return 0;
-        }
-	
-	/* Make new IrDA compressor */
-        new = (struct irda_compressor *) 
-		kmalloc( sizeof( struct irda_compressor), GFP_KERNEL);
-        if (new == NULL)
-                return 1;
-		
-	memset( new, 0, sizeof( struct irda_compressor));
-        new->cp = cp;
-
-	/* Insert IrDA compressor into hashbin */
-	hashbin_insert( irlap_compressors, (irda_queue_t *) new, cp->compress_proto,
-			NULL);
-	
-        return 0;
-}
-
-/*
- * Function irda_unregister_compressor (cp)
- *
- *    Unregister compressor
- *
- */
-void irda_unregister_compressor ( struct compressor *cp)
-{
-	struct irda_compressor *node;
-
-	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
-
-	node = hashbin_remove( irlap_compressors, cp->compress_proto, NULL);
-	if ( !node) {
-		IRDA_DEBUG( 0, __FUNCTION__ "(), compressor not found!\n");
-		return;
-	}	
-	kfree( node);
-}
-
-/*
- * Function irda_set_compression (self, proto)
- *
- *    The compression protocol to be used by this session
- *
- */
-int irda_set_compression( struct irlap_cb *self, int proto)
-{
-	struct compressor *cp;
-	struct irda_compressor *comp;
-
-	__u8 options[CILEN_DEFLATE];
-
-	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
-
-	ASSERT( self != NULL, return -ENODEV;);
-	ASSERT( self->magic == LAP_MAGIC, return -EBADR;);
-
-	/* Initialize options */
-	options[0] = CI_DEFLATE;
-	options[1] = CILEN_DEFLATE;
-	options[2] = DEFLATE_METHOD( DEFLATE_METHOD_VAL);
-	options[3] = DEFLATE_CHK_SEQUENCE;
-
-	comp = hashbin_find( irlap_compressors, proto, NULL);
-	if ( !comp) {
-		IRDA_DEBUG( 0, __FUNCTION__ "(), Unable to find compressor\n");
-		return -1;
-	}
-
-	cp = comp->cp;
-	/* 
-	 *  Compressor part
-	 */
-	if ( self->compressor.state != NULL)
-		(*self->compressor.cp->comp_free)( self->compressor.state);
-	self->compressor.state = NULL;
-	
-	self->compressor.cp = cp;
-	self->compressor.state = cp->comp_alloc( options, sizeof( options));
-	if ( self->compressor.state == NULL) {
-		IRDA_DEBUG( 0, __FUNCTION__ "(), Failed!\n");
-		return -ENOBUFS;
-	}
-
-	/* 
-	 *  Decompress part
-	 */
-	
-	if ( self->decompressor.state != NULL)
-		irda_decomp_free( self->decompressor.state);
-	self->decompressor.state = NULL;
-	
-	self->decompressor.cp = cp;
-	self->decompressor.state = cp->decomp_alloc( options, sizeof( options));
-	if ( self->decompressor.state == NULL) {
-		IRDA_DEBUG( 0, __FUNCTION__ "(), Failed!\n");
-		return -ENOBUFS;
-	}
-	return 0;
-}
-
-/*
- * Function irda_free_compression (self)
- *
- *    
- *
- */
-void irda_free_compression( struct irlap_cb *self)
-{
-	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
-
-	if ( self->compressor.state) {
-		irda_comp_free( self->compressor.state);
-		self->compressor.state = NULL;
-	}
-	
-	if ( self->decompressor.state) {
-		irda_decomp_free( self->decompressor.state);
-		self->decompressor.state = NULL;
-	}
-}
-
-/*
- * Function irlap_compress_init (self)
- *
- *    
- *
- */
-void irlap_compressor_init( struct irlap_cb *self, int compress)
-{
-	int debug = TRUE;
-	__u8 options[CILEN_DEFLATE];
-
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == LAP_MAGIC, return;);
-	
-	/* Initialize options */
-	options[0] = CI_DEFLATE;
-	options[1] = CILEN_DEFLATE;
-	options[2] = DEFLATE_METHOD_VAL;
-	options[3] = DEFLATE_CHK_SEQUENCE;
-	
-	/*
-	 *  We're agreeing to send compressed packets.
-	 */
-	if ( self->compressor.state == NULL) {
-		IRDA_DEBUG( 0, __FUNCTION__ "(), state == NULL\n");
-		return;
-	}
-	
-	if ((*self->compressor.cp->comp_init)( self->compressor.state, 
-					       options, sizeof( options),
-					       0, 0, debug)) 
-	{
-		IRDA_DEBUG( 0, __FUNCTION__ "(), Compressor running!\n");
-		/* ppp->flags |= SC_COMP_RUN; */
-	}
-	
-	/*
-	 *  Initialize decompressor
-	 */
-	if ( self->decompressor.state == NULL) {
-		IRDA_DEBUG( 0, __FUNCTION__ "(), state == NULL\n");
-		return;
-	}
-	
-	if (( self->decompressor.cp->decomp_init)( self->decompressor.state,
-						   options, sizeof( options),
-						   0, 0, 0, debug)) 
-	{
-		IRDA_DEBUG( 0, __FUNCTION__ "(), Decompressor running!\n");	
-		
-		/* ppp->flags |= SC_DECOMP_RUN; */
-		/* ppp->flags &= ~(SC_DC_ERROR | SC_DC_FERROR); */
-	}
-}
-
-/*
- * Function irlap_compress_frame (self, skb)
- *
- *
- *
- */
-struct sk_buff *irlap_compress_frame( struct irlap_cb *self, 
-				      struct sk_buff *skb)
-{
-	struct sk_buff *new_skb;
-	int count;
-	
-	ASSERT( skb != NULL, return NULL;);
-	
-	IRDA_DEBUG(4, __FUNCTION__ "() skb->len=%d, jiffies=%ld\n", (int) skb->len,
-	      jiffies);
-
-	ASSERT( self != NULL, return NULL;);
-	ASSERT( self->magic == LAP_MAGIC, return NULL;);
-
-	/* Check if compressor got initialized */
-	if ( self->compressor.state == NULL) {
-		/* Tell peer that this frame is not compressed */
-		skb_push( skb, LAP_COMP_HEADER);
-		skb->data[0] = IRDA_NORMAL;
-
-		return skb;
-	}
-
-	/* FIXME: Find out what is the max overhead (not 10) */
-	new_skb = dev_alloc_skb( skb->len+LAP_MAX_HEADER+10);
-	if(!new_skb)
-		return skb;
-
-	skb_reserve( new_skb, LAP_MAX_HEADER);
-	skb_put( new_skb, skb->len+10);
-	
-	count = (self->compressor.cp->compress)( self->compressor.state, 
-						 skb->data, new_skb->data, 
-						 skb->len, new_skb->len);
-	if( count <= 0) {
-		IRDA_DEBUG(4, __FUNCTION__ "(), Unable to compress frame!\n");
-		dev_kfree_skb( new_skb);
-
-		/* Tell peer that this frame is not compressed */
-		skb_push( skb, 1);
-		skb->data[0] = IRDA_NORMAL;
-
-		return skb;
-	}
-	skb_trim( new_skb, count);
-
-	/* Tell peer that this frame is compressed */
-	skb_push( new_skb, 1);
-	new_skb->data[0] = IRDA_COMPRESSED;
-
-	dev_kfree_skb( skb);
-	
-	IRDA_DEBUG(4, __FUNCTION__ "() new_skb->len=%d\n, jiffies=%ld", 
-	      (int) new_skb->len, jiffies);
-	
-	return new_skb;
-}
-
-/*
- * Function irlap_decompress_frame (self, skb)
- *
- *    
- *
- */
-struct sk_buff *irlap_decompress_frame( struct irlap_cb *self, 
-					struct sk_buff *skb)
-{
-	struct sk_buff *new_skb;
-	int count;
-
-	IRDA_DEBUG( 4, __FUNCTION__ "() skb->len=%d\n", (int) skb->len);
-
-	ASSERT( self != NULL, return NULL;);
-	ASSERT( self->magic == LAP_MAGIC, return NULL;);
-
-	ASSERT( self->compressor.state != NULL, return NULL;);
-
-	/* Check if frame is compressed */
-	if ( skb->data[0] == IRDA_NORMAL) {
-
-		/* Remove compression header */
-		skb_pull( skb, LAP_COMP_HEADER);
-
-		/*
-		 * The frame is not compressed. Pass it to the
-		 * decompression code so it can update its
-		 * dictionary if necessary.
-		 */
-		irda_incomp( self->decompressor.state, skb->data, skb->len);
-
-		return skb;
-	}
-
-	/* Remove compression header */
-	skb_pull( skb, LAP_COMP_HEADER);
-
-	new_skb = dev_alloc_skb( 2048); /* FIXME: find the right size */
-	if(!new_skb)
-		return skb;
-	skb_put( new_skb, 2048);
-
-	count = irda_decompress( self->decompressor.state, skb->data, 
-				 skb->len, new_skb->data, new_skb->len);
-	if ( count <= 0) {
-		IRDA_DEBUG( 4, __FUNCTION__ "(), Unable to decompress frame!\n");
-		
-		dev_kfree_skb( new_skb);
-		return skb;
-	}
-
-	skb_trim( new_skb, count);
-	
-	IRDA_DEBUG( 4, __FUNCTION__ "() new_skb->len=%d\n", (int) new_skb->len);
-
-	return new_skb;
-}
-
diff -u --recursive --new-file v2.4.6/linux/net/irda/irlap_event.c linux/net/irda/irlap_event.c
--- v2.4.6/linux/net/irda/irlap_event.c	Fri Mar  2 11:12:12 2001
+++ linux/net/irda/irlap_event.c	Wed Jul  4 11:50:38 2001
@@ -1870,11 +1870,24 @@
 				/* Update Nr received */
 				irlap_update_nr_received(self, info->nr);
 				irlap_wait_min_turn_around(self, &self->qos_tx);
+				irlap_start_wd_timer(self, self->wd_timeout);
 				
-				irlap_send_rr_frame(self, RSP_FRAME);
+				/* Note : if the link is idle (this case),
+				 * we never go in XMIT_S, so we never get a
+				 * chance to process any DISCONNECT_REQUEST.
+				 * Do it now ! - Jean II */
+				if (self->disconnect_pending) {
+					/* Disconnect */
+					irlap_send_rd_frame(self);
+					irlap_flush_all_queues(self);
+
+					irlap_next_state(self, LAP_SCLOSE);
+				} else {
+					/* Just send back pf bit */
+					irlap_send_rr_frame(self, RSP_FRAME);
 				
-				irlap_start_wd_timer(self, self->wd_timeout);
-				irlap_next_state(self, LAP_NRM_S);
+					irlap_next_state(self, LAP_NRM_S);
+				}
 			}
 		} else if (nr_status == NR_UNEXPECTED) {
 			self->remote_busy = FALSE;
@@ -1927,24 +1940,23 @@
 		 *  Wait until retry_count * n matches negotiated threshold/
 		 *  disconnect time (note 2 in IrLAP p. 82)
 		 *
-		 * Note : self->wd_timeout = (self->poll_timeout * 2),
-		 *   and self->final_timeout == self->poll_timeout,
-		 *   which explain why we use (self->retry_count * 2) here !!!
+		 * Note : self->wd_timeout = (self->final_timeout * 2),
+		 *   which explain why we use (self->N2 / 2) here !!!
 		 * Jean II
 		 */
 		IRDA_DEBUG(1, __FUNCTION__ "(), retry_count = %d\n", 
 			   self->retry_count);
 
-		if (((self->retry_count * 2) < self->N2)  && 
-		    ((self->retry_count * 2) != self->N1)) {
+		if ((self->retry_count <  (self->N2 / 2))  && 
+		    (self->retry_count != (self->N1 / 2))) {
 			
 			irlap_start_wd_timer(self, self->wd_timeout);
 			self->retry_count++;
-		} else if ((self->retry_count * 2) == self->N1) {
+		} else if (self->retry_count == (self->N1 / 2)) {
 			irlap_status_indication(self, STATUS_NO_ACTIVITY);
 			irlap_start_wd_timer(self, self->wd_timeout);
 			self->retry_count++;
-		} else if ((self->retry_count * 2) >= self->N2) {
+		} else if (self->retry_count >= (self->N2 / 2)) {
 			irlap_apply_default_connection_parameters(self);
 			
 			/* Always switch state before calling upper layers */
diff -u --recursive --new-file v2.4.6/linux/net/irda/irlap_frame.c linux/net/irda/irlap_frame.c
--- v2.4.6/linux/net/irda/irlap_frame.c	Sat May 19 17:47:55 2001
+++ linux/net/irda/irlap_frame.c	Wed Jul  4 11:50:38 2001
@@ -742,12 +742,6 @@
 			return;
 		}
 		
-		/*
-		 *  make sure the skb->sk accounting of memory usage is sane
-		 */
-		if (skb->sk != NULL)
-			skb_set_owner_w(tx_skb, skb->sk);
-		
 		/* 
 		 *  Insert frame in store, in case of retransmissions 
 		 */
@@ -788,12 +782,6 @@
 			return;
 		}
 		
-		/*
-		 *  make sure the skb->sk accounting of memory usage is sane
-		 */
-		if (skb->sk != NULL)
-			skb_set_owner_w(tx_skb, skb->sk);
-		
 		/* 
 		 *  Insert frame in store, in case of retransmissions 
 		 */
@@ -863,9 +851,6 @@
 			return;
 		}		
 
-		if (skb->sk != NULL)
-			skb_set_owner_w(tx_skb, skb->sk);
-		
 		/* Insert frame in store */
 		skb_queue_tail(&self->wx_list, skb_get(skb));
 		
@@ -917,9 +902,6 @@
 			return;
 		}		
 		
-		if (skb->sk != NULL)
-			skb_set_owner_w(tx_skb, skb->sk);
-		
 		/* Insert frame in store */
 		skb_queue_tail(&self->wx_list, skb_get(skb));
 		
@@ -973,12 +955,6 @@
 		tx_skb->next = tx_skb->prev = NULL;
 		tx_skb->list = NULL;
 
-		/*
-		 *  make sure the skb->sk accounting of memory usage is sane
-		 */
-		if (skb->sk != NULL)
-			skb_set_owner_w(tx_skb, skb->sk);
-
 		/* Clear old Nr field + poll bit */
 		tx_skb->data[1] &= 0x0f;
 
@@ -1058,12 +1034,6 @@
 		/* Unlink tx_skb from list */
 		tx_skb->next = tx_skb->prev = NULL;
 		tx_skb->list = NULL;
-
-		/*
-		 *  make sure the skb->sk accounting of memory usage is sane
-		 */
-		if (skb->sk != NULL)
-			skb_set_owner_w(tx_skb, skb->sk);
 
 		/* Clear old Nr field + poll bit */
 		tx_skb->data[1] &= 0x0f;
diff -u --recursive --new-file v2.4.6/linux/net/irda/irlmp.c linux/net/irda/irlmp.c
--- v2.4.6/linux/net/irda/irlmp.c	Sat May 19 17:47:55 2001
+++ linux/net/irda/irlmp.c	Wed Jul  4 11:50:38 2001
@@ -376,7 +376,7 @@
 	 * discovery log and check if any of the links has discovered a
 	 * device with the given daddr 
 	 */
-	if (!saddr) {
+	if ((!saddr) || (saddr == DEV_ADDR_ANY)) {
 		if (daddr != DEV_ADDR_ANY)
 			discovery = hashbin_find(irlmp->cachelog, daddr, NULL);
 		else {
diff -u --recursive --new-file v2.4.6/linux/net/irda/irlmp_event.c linux/net/irda/irlmp_event.c
--- v2.4.6/linux/net/irda/irlmp_event.c	Sat May 19 17:47:55 2001
+++ linux/net/irda/irlmp_event.c	Wed Jul  4 11:50:38 2001
@@ -379,13 +379,23 @@
 			irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT);
 		else {
 			/* No more connections, so close IrLAP */
-			irlmp_next_lap_state(self, LAP_STANDBY);
+
+			/* We don't want to change state just yet, because
+			 * we want to reflect accurately the real state of
+			 * the LAP, not the the state we whish it was in,
+			 * so that we don't loose LM_LAP_CONNECT_REQUEST.
+			 * In some cases, IrLAP won't close the LAP
+			 * immediately. For example, it might still be
+			 * retrying packets or waiting for the pf bit.
+			 * As the LAP always send a DISCONNECT_INDICATION
+			 * in PCLOSE or SCLOSE, just change state on that.
+			 * Jean II */
 			irlap_disconnect_request(self->irlap);
 		}
 		break;
 	case LM_LAP_IDLE_TIMEOUT:
 		if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
-			irlmp_next_lap_state(self, LAP_STANDBY);
+			/* Same reasoning as above - keep state */
 			irlap_disconnect_request(self->irlap);
 		}
 		break;
@@ -472,8 +482,6 @@
 		irlmp_start_watchdog_timer(self, 5*HZ);
 		break;
 	case LM_CONNECT_INDICATION:
-		irlmp_next_lsap_state(self, LSAP_CONNECT_PEND);
-
 		if (self->conn_skb) {
 			WARNING(__FUNCTION__ 
 				"(), busy with another request!\n");
@@ -481,7 +489,20 @@
 		}
 		self->conn_skb = skb;
 
+		irlmp_next_lsap_state(self, LSAP_CONNECT_PEND);
+
 		irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, NULL);
+
+		/* Start watchdog timer
+		 * This is not mentionned in the spec, but there is a rare
+		 * race condition that can get the socket stuck.
+		 * If we receive this event while our LAP is closing down,
+		 * the LM_LAP_CONNECT_REQUEST get lost and we get stuck in
+		 * CONNECT_PEND state forever.
+		 * Anyway, it make sense to make sure that we always have
+		 * a backup plan. 1 second is plenty (should be immediate).
+		 * Jean II */
+		irlmp_start_watchdog_timer(self, 1*HZ);
 		break;
 	default:
 		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", 
@@ -533,6 +554,16 @@
 
 		irlmp_next_lsap_state(self, LSAP_DATA_TRANSFER_READY);
 		break;
+	case LM_WATCHDOG_TIMEOUT:
+		/* May happen, who knows...
+		 * Jean II */
+		IRDA_DEBUG(0, __FUNCTION__ "() WATCHDOG_TIMEOUT!\n");
+
+		/* Here, we should probably disconnect proper */
+		self->dlsap_sel = LSAP_ANY;
+		self->conn_skb = NULL;
+		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
+		break;
 	default:
 		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
 			   irlmp_event[event]);
@@ -563,6 +594,15 @@
 	case LM_CONNECT_REQUEST:
 		/* Keep state */
 		break;
+	case LM_CONNECT_INDICATION:
+		/* Will happen in some rare cases when the socket get stuck,
+		 * the other side retries the connect request.
+		 * We just unstuck the socket - Jean II */
+		IRDA_DEBUG(0, __FUNCTION__ "(), LM_CONNECT_INDICATION, "
+			   "LSAP stuck in CONNECT_PEND state...\n");
+		/* Keep state */
+		irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, NULL);
+		break;
 	case LM_CONNECT_RESPONSE:
 		IRDA_DEBUG(0, __FUNCTION__ "(), LM_CONNECT_RESPONSE, "
 			   "no indication issued yet\n");
@@ -581,6 +621,17 @@
 		self->conn_skb = NULL;
 
 		irlmp_connect_indication(self, skb);
+		break;
+	case LM_WATCHDOG_TIMEOUT:
+		/* Will happen in some rare cases because of a race condition.
+		 * Just make sure we don't stay there forever...
+		 * Jean II */
+		IRDA_DEBUG(0, __FUNCTION__ "() WATCHDOG_TIMEOUT!\n");
+
+		/* Go back to disconnected mode, keep the socket waiting */
+		self->dlsap_sel = LSAP_ANY;
+		self->conn_skb = NULL;
+		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
 		break;
 	default:
 		IRDA_DEBUG(0, __FUNCTION__ "Unknown event %s\n", 
diff -u --recursive --new-file v2.4.6/linux/net/irda/irproc.c linux/net/irda/irproc.c
--- v2.4.6/linux/net/irda/irproc.c	Sat Nov 27 15:27:49 1999
+++ linux/net/irda/irproc.c	Wed Jul  4 11:50:38 2001
@@ -67,6 +67,8 @@
 	int i;
 
 	proc_irda = proc_mkdir("net/irda", NULL);
+	if (proc_irda == NULL)
+		return;
 	proc_irda->owner = THIS_MODULE;
 
 	for (i=0;i<IRDA_ENTRIES_NUM;i++)
@@ -83,10 +85,13 @@
 {
 	int i;
 
-	for (i=0;i<IRDA_ENTRIES_NUM;i++)
-		remove_proc_entry(dir[i].name, proc_irda);
+        if (proc_irda) {
+                for (i=0;i<IRDA_ENTRIES_NUM;i++)
+                        remove_proc_entry(dir[i].name, proc_irda);
 
-	remove_proc_entry("net/irda", NULL);
+                remove_proc_entry("net/irda", NULL);
+                proc_irda = NULL;
+        }
 }
 
 
diff -u --recursive --new-file v2.4.6/linux/net/irda/irqueue.c linux/net/irda/irqueue.c
--- v2.4.6/linux/net/irda/irqueue.c	Thu Jan  4 13:00:55 2001
+++ linux/net/irda/irqueue.c	Wed Jul  4 11:50:38 2001
@@ -739,7 +739,7 @@
 		/*
 		 * Queue was empty.
 		 */
-	} if ( (*queue)->q_next == *queue ) {
+	} else if ( (*queue)->q_next == *queue ) {
 		/* 
 		 *  Queue only contained a single element. It will now be
 		 *  empty.  
diff -u --recursive --new-file v2.4.6/linux/net/irda/irsyms.c linux/net/irda/irsyms.c
--- v2.4.6/linux/net/irda/irsyms.c	Sun Nov 12 20:43:11 2000
+++ linux/net/irda/irsyms.c	Wed Jul  4 11:50:38 2001
@@ -35,9 +35,6 @@
 #include <net/irda/irda.h>
 #include <net/irda/irmod.h>
 #include <net/irda/irlap.h>
-#ifdef CONFIG_IRDA_COMPRESSION
-#include <net/irda/irlap_comp.h>
-#endif /* CONFIG_IRDA_COMPRESSION */
 #include <net/irda/irlmp.h>
 #include <net/irda/iriap.h>
 #include <net/irda/irias_object.h>
@@ -66,12 +63,6 @@
 extern int irlpt_client_init(void);
 extern int irlpt_server_init(void);
 
-#ifdef CONFIG_IRDA_COMPRESSION
-#ifdef CONFIG_IRDA_DEFLATE
-extern irda_deflate_init();
-#endif /* CONFIG_IRDA_DEFLATE */
-#endif /* CONFIG_IRDA_COMPRESSION */
-
 /* IrTTP */
 EXPORT_SYMBOL(irttp_open_tsap);
 EXPORT_SYMBOL(irttp_close_tsap);
@@ -150,10 +141,6 @@
 /* IrLAP */
 EXPORT_SYMBOL(irlap_open);
 EXPORT_SYMBOL(irlap_close);
-#ifdef CONFIG_IRDA_COMPRESSION
-EXPORT_SYMBOL(irda_unregister_compressor);
-EXPORT_SYMBOL(irda_register_compressor);
-#endif /* CONFIG_IRDA_COMPRESSION */
 EXPORT_SYMBOL(irda_init_max_qos_capabilies);
 EXPORT_SYMBOL(irda_qos_bits_to_value);
 EXPORT_SYMBOL(irda_device_setup);
@@ -208,13 +195,6 @@
 	ircomm_init();
 	ircomm_tty_init();
 #endif
-
-#ifdef CONFIG_IRDA_COMPRESSION
-#ifdef CONFIG_IRDA_DEFLATE
-	irda_deflate_init();
-#endif /* CONFIG_IRDA_DEFLATE */
-#endif /* CONFIG_IRDA_COMPRESSION */
-
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.6/linux/net/irda/irsysctl.c linux/net/irda/irsysctl.c
--- v2.4.6/linux/net/irda/irsysctl.c	Sat Nov 11 18:11:23 2000
+++ linux/net/irda/irsysctl.c	Wed Jul  4 11:50:38 2001
@@ -32,7 +32,7 @@
 #include <net/irda/irias_object.h>
 
 #define NET_IRDA 412 /* Random number */
-enum { DISCOVERY=1, DEVNAME, COMPRESSION, DEBUG, SLOTS, DISCOVERY_TIMEOUT, 
+enum { DISCOVERY=1, DEVNAME, DEBUG, SLOTS, DISCOVERY_TIMEOUT, 
        SLOT_TIMEOUT, MAX_BAUD_RATE, MAX_INACTIVE_TIME };
 
 extern int  sysctl_discovery;
@@ -71,8 +71,6 @@
 	  sizeof(int), 0644, NULL, &proc_dointvec },
 	{ DEVNAME, "devname", sysctl_devname,
 	  65, 0644, NULL, &do_devname, &sysctl_string},
-	{ COMPRESSION, "compression", &sysctl_compression,
-	  sizeof(int), 0644, NULL, &proc_dointvec },
 #ifdef CONFIG_IRDA_DEBUG
         { DEBUG, "debug", &irda_debug,
 	  sizeof(int), 0644, NULL, &proc_dointvec },
diff -u --recursive --new-file v2.4.6/linux/net/irda/irttp.c linux/net/irda/irttp.c
--- v2.4.6/linux/net/irda/irttp.c	Tue May  1 16:05:00 2001
+++ linux/net/irda/irttp.c	Wed Jul  4 11:50:38 2001
@@ -1598,7 +1598,7 @@
 	self = (struct tsap_cb *) hashbin_get_first(irttp->tsaps);
 	while (self != NULL) {
 		if (!self || self->magic != TTP_TSAP_MAGIC)
-			return len;
+			break;
 
 		len += sprintf(buf+len, "TSAP %d, ", i++);
 		len += sprintf(buf+len, "stsap_sel: %02x, ", 
diff -u --recursive --new-file v2.4.6/linux/net/irda/qos.c linux/net/irda/qos.c
--- v2.4.6/linux/net/irda/qos.c	Mon Apr 30 16:26:09 2001
+++ linux/net/irda/qos.c	Wed Jul  4 11:50:38 2001
@@ -36,12 +36,6 @@
 #include <net/irda/parameters.h>
 #include <net/irda/qos.h>
 #include <net/irda/irlap.h>
-#ifdef CONFIG_IRDA_COMPRESSION
-#include <net/irda/irlap_comp.h>
-#include "../../drivers/net/zlib.h"
-
-#define CI_BZIP2  27 /* Random pick */
-#endif
 
 /*
  * Maximum values of the baud rate we negociate with the other end.
@@ -79,10 +73,6 @@
 __u32 max_turn_times[]  = { 500, 250, 100, 50 };                    /* ms */
 __u32 link_disc_times[] = { 3, 8, 12, 16, 20, 25, 30, 40 };         /* secs */
 
-#ifdef CONFIG_IRDA_COMPRESSION
-__u32 compressions[] = { CI_BZIP2, CI_DEFLATE, CI_DEFLATE_DRAFT };
-#endif
-
 __u32 max_line_capacities[10][4] = {
        /* 500 ms     250 ms  100 ms  50 ms (max turn time) */
 	{    100,      0,      0,     0 }, /*     2400 bps */
@@ -238,10 +228,6 @@
 	qos->link_disc_time.bits  &= new->link_disc_time.bits;
 	qos->additional_bofs.bits &= new->additional_bofs.bits;
 
-#ifdef CONFIG_IRDA_COMPRESSION
-	qos->compression.bits     &= new->compression.bits;
-#endif
-
 	irda_qos_bits_to_value(qos);
 }
 
@@ -280,10 +266,6 @@
 	qos->data_size.bits       = 0x3f;
 	qos->link_disc_time.bits &= 0xff;
 	qos->additional_bofs.bits = 0xff;
-
-#ifdef CONFIG_IRDA_COMPRESSION	
-	qos->compression.bits     = 0x03;
-#endif
 }
 
 /*
@@ -359,20 +341,10 @@
 int irlap_qos_negotiate(struct irlap_cb *self, struct sk_buff *skb) 
 {
 	int ret;
-#ifdef CONFIG_IRDA_COMPRESSION
-	int comp_seen = FALSE;
-#endif
+	
 	ret = irda_param_extract_all(self, skb->data, skb->len, 
 				     &irlap_param_info);
 	
-#ifdef CONFIG_IRDA_COMPRESSION
-	if (!comp_seen) {
-		IRDA_DEBUG( 4, __FUNCTION__ "(), Compression not seen!\n");
-		self->qos_tx.compression.bits = 0x00;
-		self->qos_rx.compression.bits = 0x00;
-	}
-#endif
-
 	/* Convert the negotiated bits to values */
 	irda_qos_bits_to_value(&self->qos_tx);
 	irda_qos_bits_to_value(&self->qos_rx);
@@ -393,10 +365,6 @@
 		   self->qos_tx.min_turn_time.value);
 	IRDA_DEBUG(2, "Setting LINK_DISC to %d secs.\n", 
 		   self->qos_tx.link_disc_time.value);
-#ifdef CONFIG_IRDA_COMPRESSION
-	IRDA_DEBUG(2, "Setting COMPRESSION to %d\n", 
-		   self->qos_tx.compression.value);
-#endif	
 	return ret;
 }
 
@@ -710,12 +678,4 @@
 	
 	index = msb_index(qos->additional_bofs.bits);
 	qos->additional_bofs.value = add_bofs[index];
-
-#ifdef CONFIG_IRDA_COMPRESSION
-	index = msb_index(qos->compression.bits);
-	if (index >= 0)
-		qos->compression.value = compressions[index];
-	else 
-		qos->compression.value = 0;
-#endif
 }
diff -u --recursive --new-file v2.4.6/linux/net/sunrpc/svcsock.c linux/net/sunrpc/svcsock.c
--- v2.4.6/linux/net/sunrpc/svcsock.c	Fri Apr 27 14:15:01 2001
+++ linux/net/sunrpc/svcsock.c	Wed Jul  4 11:50:38 2001
@@ -383,7 +383,7 @@
 
 	/* Sorry. */
 	if (skb_is_nonlinear(skb)) {
-		if (skb_linearize(skb, GFP_ATOMIC) != 0) {
+		if (skb_linearize(skb, GFP_KERNEL) != 0) {
 			kfree_skb(skb);
 			svc_sock_received(svsk, 0);
 			return 0;
