From macro@ds2.pg.gda.pl  Thu Mar 21 19:04:07 2002
Received: (uucp@localhost) by guadalquivir.fnet.fr (8.8.8/97.02.12/Guadalquivir); id TAA23534; Thu, 21 Mar 2002 19:04:07 +0100 (MET)
Received-Date: Thu, 21 Mar 2002 19:04:07 +0100 (MET)
Received: from delta.ds2.pg.gda.pl(213.192.72.1)
 via SMTP by guadalquivir.fnet.fr, id smtpd023532; Thu Mar 21 19:04:03 2002
Received: from localhost by delta.ds2.pg.gda.pl (8.9.3/8.9.3) with SMTP id TAA26129;
	Thu, 21 Mar 2002 19:04:11 +0100 (MET)
Date: Thu, 21 Mar 2002 19:04:10 +0100 (MET)
From: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
Reply-To: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
To: Ralf Baechle <ralf@uni-koblenz.de>
cc: linux-mips@fnet.fr, linux-mips@oss.sgi.com
Subject: [patch] linux: declance multicast filter fixes
Message-ID: <Pine.GSO.3.96.1020321185116.22279D-100000@delta.ds2.pg.gda.pl>
Organization: Technical University of Gdansk
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Content-Length: 1653
Lines: 48

Hello,

 Following are a few trivial fixes for the DECstation's LANCE driver
needed for the chip's multicast filter to be set up correctly.  The patch
is needed for multicast reception to work, in particular for the IPv6's
neighbor discovery.  The CRC generation was verified using the AMD's
reference code and it was checked at the run time for selected multicast
addresses as well.  Please apply. 

 Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

patch-mips-2.4.17-20020129-declance-mcast-11
diff -up --recursive --new-file linux-mips-2.4.17-20020129.macro/drivers/net/declance.c linux-mips-2.4.17-20020129/drivers/net/declance.c
--- linux-mips-2.4.17-20020129.macro/drivers/net/declance.c	Wed Aug 22 04:27:03 2001
+++ linux-mips-2.4.17-20020129/drivers/net/declance.c	Tue Mar 19 19:42:20 2002
@@ -793,6 +793,8 @@ static int lance_open(struct net_device 
 	ib->mode = 0;
 	ib->filter [0] = 0;
 	ib->filter [2] = 0;
+	ib->filter [4] = 0;
+	ib->filter [6] = 0;
 
 	lance_init_ring(dev);
 	load_csrs(lp);
@@ -920,7 +922,7 @@ static void lance_load_multicast(struct 
 	struct dev_mc_list *dmi = dev->mc_list;
 	char *addrs;
 	int i, j, bit, byte;
-	u32 crc, poly = CRC_POLYNOMIAL_BE;
+	u32 crc, poly = CRC_POLYNOMIAL_LE;
 
 	/* set all multicast bits */
 	if (dev->flags & IFF_ALLMULTI) {
@@ -959,7 +961,7 @@ static void lance_load_multicast(struct 
 			}
 
 		crc = crc >> 26;
-		mcast_table[crc >> 3] |= 1 << (crc & 0xf);
+		mcast_table[2 * (crc >> 4)] |= 1 << (crc & 0xf);
 	}
 	return;
 }


From airlied@csn.ul.ie  Fri Mar 22 12:08:33 2002
Received: (uucp@localhost) by guadalquivir.fnet.fr (8.8.8/97.02.12/Guadalquivir); id MAA02319; Fri, 22 Mar 2002 12:08:33 +0100 (MET)
Received-Date: Fri, 22 Mar 2002 12:08:33 +0100 (MET)
Received: from holly.csn.ul.ie(136.201.105.4)
 via SMTP by guadalquivir.fnet.fr, id smtpd002317; Fri Mar 22 12:08:31 2002
Received: from skynet.csn.ul.ie (skynet [136.201.105.2])
	by holly.csn.ul.ie (Postfix) with ESMTP
	id A0F6D2B303; Fri, 22 Mar 2002 11:08:27 +0000 (GMT)
Received: by skynet.csn.ul.ie (Postfix, from userid 2139)
	id 6F5FEE95F; Fri, 22 Mar 2002 11:08:27 +0000 (GMT)
Received: from localhost (localhost [127.0.0.1])
	by skynet.csn.ul.ie (Postfix) with ESMTP
	id 6DFD97243; Fri, 22 Mar 2002 11:08:27 +0000 (GMT)
Date: Fri, 22 Mar 2002 11:08:27 +0000 (GMT)
From: Dave Airlie <airlied@csn.ul.ie>
X-X-Sender: <airlied@skynet>
To: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
Cc: Ralf Baechle <ralf@uni-koblenz.de>, <linux-mips@fnet.fr>,
        <linux-mips@oss.sgi.com>
Subject: Re: [patch] linux: declance multicast filter fixes
In-Reply-To: <Pine.GSO.3.96.1020321185116.22279D-100000@delta.ds2.pg.gda.pl>
Message-ID: <Pine.LNX.4.32.0203221107170.1949-100000@skynet>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Content-Length: 941
Lines: 33


I've created declance_2_4.c on http://www.csn.ul.ie/~airlied/mips

for the DS5000/200 series of DecStations..

it only required the BE -> LE and the additional zeroing of the filter, it
already did the mcast_table access correctly... (by luck rather than
design :-)

un-compiled and untested but it should work ..

Dave.

On Thu, 21 Mar 2002, Maciej W. Rozycki wrote:

> Hello,
>
>  Following are a few trivial fixes for the DECstation's LANCE driver
> needed for the chip's multicast filter to be set up correctly.  The patch
> is needed for multicast reception to work, in particular for the IPv6's
> neighbor discovery.  The CRC generation was verified using the AMD's
> reference code and it was checked at the run time for selected multicast
> addresses as well.  Please apply.
>
>  Maciej
>
>

-- 
David Airlie, Software Engineer
http://www.skynet.ie/~airlied / airlied@skynet.ie
pam_smb / Linux DecStation / Linux VAX / ILUG person


From macro@ds2.pg.gda.pl  Sat Mar 23 15:01:40 2002
Received: (uucp@localhost) by guadalquivir.fnet.fr (8.8.8/97.02.12/Guadalquivir); id PAA27190; Sat, 23 Mar 2002 15:01:40 +0100 (MET)
Received-Date: Sat, 23 Mar 2002 15:01:40 +0100 (MET)
Received: from delta.ds2.pg.gda.pl(213.192.72.1)
 via SMTP by guadalquivir.fnet.fr, id smtpd027188; Sat Mar 23 15:01:35 2002
Received: from localhost by delta.ds2.pg.gda.pl (8.9.3/8.9.3) with SMTP id PAA16944;
	Sat, 23 Mar 2002 15:01:49 +0100 (MET)
Date: Sat, 23 Mar 2002 15:01:48 +0100 (MET)
From: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
Reply-To: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
To: Dave Airlie <airlied@csn.ul.ie>
cc: Ralf Baechle <ralf@uni-koblenz.de>, linux-mips@fnet.fr,
        linux-mips@oss.sgi.com
Subject: Re: [patch] linux: declance multicast filter fixes
In-Reply-To: <Pine.LNX.4.32.0203221107170.1949-100000@skynet>
Message-ID: <Pine.GSO.3.96.1020323010132.3959A-100000@delta.ds2.pg.gda.pl>
Organization: Technical University of Gdansk
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Content-Length: 856
Lines: 21

On Fri, 22 Mar 2002, Dave Airlie wrote:

> I've created declance_2_4.c on http://www.csn.ul.ie/~airlied/mips
> 
> for the DS5000/200 series of DecStations..

 Thanks for the reference -- I definitely want to look how to merge the
drivers one day (well, actually the LANCE core should be common to all
drivers eventually).  There is certainly no point in keeping your code
separately.  I suppose your driver should work for the PMAD card as well. 

> it only required the BE -> LE and the additional zeroing of the filter, it
> already did the mcast_table access correctly... (by luck rather than
> design :-)

 Well, the I/O ASIC wiring of LANCE is weird.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

From airlied@csn.ul.ie  Sun Mar 24 14:51:35 2002
Received: (uucp@localhost) by guadalquivir.fnet.fr (8.8.8/97.02.12/Guadalquivir); id OAA06104; Sun, 24 Mar 2002 14:51:35 +0100 (MET)
Received-Date: Sun, 24 Mar 2002 14:51:35 +0100 (MET)
Received: from holly.csn.ul.ie(136.201.105.4)
 via SMTP by guadalquivir.fnet.fr, id smtpd006102; Sun Mar 24 14:51:31 2002
Received: from skynet.csn.ul.ie (skynet [136.201.105.2])
	by holly.csn.ul.ie (Postfix) with ESMTP
	id 08AC82B6B5; Sun, 24 Mar 2002 13:51:28 +0000 (GMT)
Received: by skynet.csn.ul.ie (Postfix, from userid 2139)
	id 9550AE960; Sun, 24 Mar 2002 13:51:22 +0000 (GMT)
Received: from localhost (localhost [127.0.0.1])
	by skynet.csn.ul.ie (Postfix) with ESMTP
	id 5CFB87243; Sun, 24 Mar 2002 13:51:22 +0000 (GMT)
Date: Sun, 24 Mar 2002 13:51:22 +0000 (GMT)
From: Dave Airlie <airlied@csn.ul.ie>
X-X-Sender: <airlied@skynet>
To: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
Cc: Ralf Baechle <ralf@uni-koblenz.de>, <linux-mips@fnet.fr>,
        <linux-mips@oss.sgi.com>
Subject: Re: [patch] linux: declance multicast filter fixes
In-Reply-To: <Pine.GSO.3.96.1020323010132.3959A-100000@delta.ds2.pg.gda.pl>
Message-ID: <Pine.LNX.4.32.0203241349380.32481-100000@skynet>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Content-Length: 875
Lines: 24


> > I've created declance_2_4.c on http://www.csn.ul.ie/~airlied/mips
> >
> > for the DS5000/200 series of DecStations..
>
>  Thanks for the reference -- I definitely want to look how to merge the
> drivers one day (well, actually the LANCE core should be common to all
> drivers eventually).  There is certainly no point in keeping your code
> separately.  I suppose your driver should work for the PMAD card as well.
>

well it should work for the PMAD and I've got a version for the VAX that
splits off from my one, the VAX uses a similiar wiring as the DS5000/200,
I've been waiting for the LANCE core to be separated out a lot of people
have talked about it and I hear for 2.5 maybe someone is actually going to
do it ...

Dave

-- 
David Airlie, Software Engineer
http://www.skynet.ie/~airlied / airlied@skynet.ie
pam_smb / Linux DecStation / Linux VAX / ILUG person


From macro@ds2.pg.gda.pl  Mon Mar 25 12:41:10 2002
Received: (uucp@localhost) by guadalquivir.fnet.fr (8.8.8/97.02.12/Guadalquivir); id MAA16677; Mon, 25 Mar 2002 12:41:10 +0100 (MET)
Received-Date: Mon, 25 Mar 2002 12:41:10 +0100 (MET)
Received: from delta.ds2.pg.gda.pl(213.192.72.1)
 via SMTP by guadalquivir.fnet.fr, id smtpd016674; Mon Mar 25 12:41:00 2002
Received: from localhost by delta.ds2.pg.gda.pl (8.9.3/8.9.3) with SMTP id MAA05215;
	Mon, 25 Mar 2002 12:40:09 +0100 (MET)
Date: Mon, 25 Mar 2002 12:40:09 +0100 (MET)
From: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
To: Dave Airlie <airlied@csn.ul.ie>
cc: Ralf Baechle <ralf@uni-koblenz.de>, linux-mips@fnet.fr,
        linux-mips@oss.sgi.com
Subject: Re: [patch] linux: declance multicast filter fixes
In-Reply-To: <Pine.LNX.4.32.0203241349380.32481-100000@skynet>
Message-ID: <Pine.GSO.3.96.1020325123322.4605A-100000@delta.ds2.pg.gda.pl>
Organization: Technical University of Gdansk
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Content-Length: 983
Lines: 21

On Sun, 24 Mar 2002, Dave Airlie wrote:

> well it should work for the PMAD and I've got a version for the VAX that
> splits off from my one, the VAX uses a similiar wiring as the DS5000/200,
> I've been waiting for the LANCE core to be separated out a lot of people
> have talked about it and I hear for 2.5 maybe someone is actually going to
> do it ...

 Well, the core seems to be already separated -- see drivers/net/7990.c.
I haven't yet checked how suitable it is and many front-end drivers use it
already.

 For the I/O ASIC front-end I'm going to check if the ASIC is capable of
mapping the LANCE more sensibly before starting any further work.  The
current configuration is a major loss, doubling the CPU's work and I can't
see any reasonable explanation for such a setup.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

From macro@ds2.pg.gda.pl  Mon Mar 25 14:23:39 2002
Received: (uucp@localhost) by guadalquivir.fnet.fr (8.8.8/97.02.12/Guadalquivir); id OAA18775; Mon, 25 Mar 2002 14:23:39 +0100 (MET)
Received-Date: Mon, 25 Mar 2002 14:23:39 +0100 (MET)
Received: from delta.ds2.pg.gda.pl(213.192.72.1)
 via SMTP by guadalquivir.fnet.fr, id smtpd018631; Mon Mar 25 14:18:35 2002
Received: from localhost by delta.ds2.pg.gda.pl (8.9.3/8.9.3) with SMTP id OAA07290;
	Mon, 25 Mar 2002 14:05:47 +0100 (MET)
Date: Mon, 25 Mar 2002 14:05:46 +0100 (MET)
From: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
To: Ralf Baechle <ralf@uni-koblenz.de>, Harald Koerfgen <hkoerfg@web.de>
cc: linux-mips@fnet.fr, linux-mips@oss.sgi.com
Subject: [patch] linux: LK201 hot-plug updates and associated zs.c fixes
Message-ID: <Pine.GSO.3.96.1020325131520.4605C-100000@delta.ds2.pg.gda.pl>
Organization: Technical University of Gdansk
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Content-Length: 17336
Lines: 599

Hello,

 Here is the long-promised LK201 update.  It allows booting without a
keyboard attached and plugging it and unplugging at any time.  Additional
status is provided upon a keyboard initialization -- a self-test result is
printed as well as the model name.  Since the new code requires serial
interrupts to be already initialized and enabled at the time the zs.c hook
is executed, a few minor changes were made to the zs.c driver.  There are
also a few obvious bug fixes. 

 A few receive errors may happen and be reported upon a keyboard being
plugged in during system's operation.  The reason is probably bouncing of
contacts and it appears harmless -- I plugged and unplugged my keyboards
many times and there was never a character loss in the initial
transmission from a keyboard to the host, thus the driver didn't get out
of sync.  I'm told both the LK201 keyboard and the VSXXX mouse are
designed for hot-plugging (the host side being as well, due to EIA-232
requirements), so there should be no electrical problems.

 The code was tested with an LK201-AA and an LK401-AG successfully. 

 The remaining to-do list:

1. Pass raw scancodes up, only doing a remap for the medium-raw mode
   (requires changes to the generic code).

2. Use handshaking for mode commands.

3. Add typematic rate and LED state restoration after a replug.

I'm going to address these issues gradually, probably in the order listed. 

 Please apply.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

patch-mips-2.4.18-20020323-lk201-23
diff -up --recursive --new-file linux-mips-2.4.18-20020323.macro/drivers/tc/lk201.c linux-mips-2.4.18-20020323/drivers/tc/lk201.c
--- linux-mips-2.4.18-20020323.macro/drivers/tc/lk201.c	Sat Mar 23 04:58:18 2002
+++ linux-mips-2.4.18-20020323/drivers/tc/lk201.c	Sun Mar 24 21:12:46 2002
@@ -5,7 +5,7 @@
  * for more details.
  *
  * Copyright (C) 1999-2002 Harald Koerfgen <hkoerfg@web.de>
- * Copyright (C) 2001 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+ * Copyright (C) 2001, 2002  Maciej W. Rozycki <macro@ds2.pg.gda.pl>
  */
 
 #include <linux/config.h>
@@ -21,7 +21,6 @@
 #include <linux/vt_kern.h>
 
 #include <asm/keyboard.h>
-#include <asm/wbflush.h>
 #include <asm/dec/tc.h>
 #include <asm/dec/machtype.h>
 
@@ -48,19 +47,18 @@ static void __init lk201_info(struct dec
 static void lk201_kbd_rx_char(unsigned char, unsigned char);
 
 struct zs_hook lk201_kbdhook = {
-	init_channel:   lk201_init,
-	init_info:      lk201_info,
-	rx_char:        NULL,
-	poll_rx_char:   NULL,
-	poll_tx_char:   NULL,
-	cflags:         B4800 | CS8 | CSTOPB | CLOCAL
+	init_channel:	lk201_init,
+	init_info:	lk201_info,
+	rx_char:	NULL,
+	poll_rx_char:	NULL,
+	poll_tx_char:	NULL,
+	cflags:		B4800 | CS8 | CSTOPB | CLOCAL
 };
 
 /*
  * This is used during keyboard initialisation
  */
 static unsigned char lk201_reset_string[] = {
-	LK_CMD_LEDS_ON, LK_PARAM_LED_MASK(0xf),	/* show we are resetting */
 	LK_CMD_SET_DEFAULTS,
 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 1),
 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 2),
@@ -76,28 +74,85 @@ static unsigned char lk201_reset_string[
 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 12),
 	LK_CMD_MODE(LK_MODE_DOWN, 13),
 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 14),
-	LK_CMD_ENB_RPT,
 	LK_CMD_DIS_KEYCLK,
-	LK_CMD_RESUME,
 	LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4),
-	LK_CMD_LEDS_OFF, LK_PARAM_LED_MASK(0xf)
 };
 
 static struct dec_serial* lk201kbd_info;
 
-static int __init lk201_reset(struct dec_serial *info)
+static int lk201_send(struct dec_serial *info, unsigned char ch)
 {
-	int i;
+	if (info->hook->poll_tx_char(info, ch)) {
+		printk(KERN_ERR "lk201: transmit timeout\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+static inline int lk201_get_id(struct dec_serial *info)
+{
+	return lk201_send(info, LK_CMD_REQ_ID);
+}
+
+static int lk201_reset(struct dec_serial *info)
+{
+	int i, r;
 
 	for (i = 0; i < sizeof(lk201_reset_string); i++) {
-		if (info->hook->poll_tx_char(info, lk201_reset_string[i]) < 0) {
-			return -EIO;
-		}
+		r = lk201_send(info, lk201_reset_string[i]);
+		if (r < 0)
+			return r;
 	}
-
 	return 0;
 }
 
+static void lk201_report(unsigned char id[6])
+{
+	char *report = "lk201: keyboard attached, ";
+
+	switch (id[2]) {
+	case LK_STAT_PWRUP_OK:
+		printk(KERN_INFO "%sself-test OK\n", report);
+		break;
+	case LK_STAT_PWRUP_KDOWN:
+		/* The keyboard will resend the power-up ID
+		   after all keys are released, so we don't
+		   bother handling the error specially.  Still
+		   there may be a short-circuit inside.
+		 */
+		printk(KERN_ERR "%skey down (stuck?), code: 0x%02x\n",
+		       report, id[3]);
+		break;
+	case LK_STAT_PWRUP_ERROR:
+		printk(KERN_ERR "%sself-test failure\n", report);
+		break;
+	default:
+		printk(KERN_ERR "%sunknown error: 0x%02x\n",
+		       report, id[2]);
+	}
+}
+
+static void lk201_id(unsigned char id[6])
+{
+	/*
+	 * Report whether there is an LK201 or an LK401
+	 * The LK401 has ALT keys...
+	 */
+	switch (id[4]) {
+	case 1:
+		printk(KERN_INFO "lk201: LK201 detected\n");
+		break;
+	case 2:
+		printk(KERN_INFO "lk201: LK401 detected\n");
+		break;
+	default:
+		printk(KERN_WARNING
+		       "lk201: unknown keyboard detected, ID %d\n", id[4]);
+		printk(KERN_WARNING "lk201: ... please report to "
+		       "<linux-mips@oss.sgi.com>\n");
+	}
+}
+
 #define DEFAULT_KEYB_REP_DELAY	(250/5)	/* [5ms] */
 #define DEFAULT_KEYB_REP_RATE	30	/* [cps] */
 
@@ -233,118 +288,111 @@ char kbd_unexpected_up(unsigned char key
 
 static void lk201_kbd_rx_char(unsigned char ch, unsigned char stat)
 {
+	static unsigned char id[6];
+	static int id_i;
+
 	static int shift_state = 0;
 	static int prev_scancode;
 	unsigned char c = scancodeRemap[ch];
 
-	if (!stat || stat == 4) {
-		switch (ch) {
-		case LK_STAT_RESUME_ERR:
-		case LK_STAT_ERROR:
-		case LK_STAT_INHIBIT_ACK:
-		case LK_STAT_TEST_ACK:
-		case LK_STAT_MODE_KEYDOWN:
-		case LK_STAT_MODE_ACK:
-			break;
-		case LK_KEY_LOCK:
-			shift_state ^= LK_LOCK;
-			handle_scancode(c, shift_state && LK_LOCK ? 1 : 0);
-			break;
-		case LK_KEY_SHIFT:
-			shift_state ^= LK_SHIFT;
-			handle_scancode(c, shift_state && LK_SHIFT ? 1 : 0);
-			break;
-		case LK_KEY_CTRL:
-			shift_state ^= LK_CTRL;
-			handle_scancode(c, shift_state && LK_CTRL ? 1 : 0);
-			break;
-		case LK_KEY_COMP:
-			shift_state ^= LK_COMP;
-			handle_scancode(c, shift_state && LK_COMP ? 1 : 0);
-			break;
-		case LK_KEY_RELEASE:
-			if (shift_state & LK_SHIFT)
-				handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0);
-			if (shift_state & LK_CTRL)
-				handle_scancode(scancodeRemap[LK_KEY_CTRL], 0);
-			if (shift_state & LK_COMP)
-				handle_scancode(scancodeRemap[LK_KEY_COMP], 0);
-			if (shift_state & LK_LOCK)
-				handle_scancode(scancodeRemap[LK_KEY_LOCK], 0);
-			shift_state = 0;
-			break;
-		case LK_KEY_REPEAT:
-			handle_scancode(prev_scancode, 1);
-			break;
-		default:
-			prev_scancode = c;
-			handle_scancode(c, 1);
-			break;
-		}
-	} else
-		printk("Error reading LKx01 keyboard: 0x%02x\n", stat);
-	tasklet_schedule(&keyboard_tasklet);
-}
-
-static void __init lk201_info(struct dec_serial *info)
-{
-}
-
-static int __init lk201_init(struct dec_serial *info)
-{
-	int ch, id = 0;
-
-	printk("DECstation LK keyboard driver v0.04... ");
-
-
-	if (lk201_reset(info) < 0) {
-		printk("reset failed!\n");
-		return -ENODEV;
+	if (stat && stat != 4) {
+		printk(KERN_ERR "lk201: keyboard receive error: 0x%02x\n",
+		       stat);
+		return;
 	}
 
-	mdelay(10);
-
-	/*
-	 * Detect whether there is an LK201 or an LK401
-	 * The LK401 has ALT keys...
-	 */
-	if (info->hook->poll_tx_char(info, LK_CMD_REQ_ID) < 0) {
-		printk("tx request ID timeout!\n");
-		return -ENODEV;
+	/* Assume this is a power-up ID. */
+	if (ch == LK_STAT_PWRUP_ID && !id_i) {
+		id[id_i++] = ch;
+		return;
 	}
 
-	mdelay(10);
-
-	while ((ch = info->hook->poll_rx_char(info)) > 0)
-		id = ch;
-
-	if (ch < 0) {
-		printk("rx request ID timeout!\n");
-		return -ENODEV;
+	/* Handle the power-up sequence. */
+	if (id_i) {
+		id[id_i++] = ch;
+		if (id_i == 4) {
+			/* OK, the power-up concluded. */
+			lk201_report(id);
+			if (id[2] == LK_STAT_PWRUP_OK)
+				lk201_get_id(lk201kbd_info);
+			else {
+				id_i = 0;
+				printk(KERN_ERR "lk201: keyboard power-up "
+				       "error, skipping initialization\n");
+			}
+		} else if (id_i == 6) {
+			/* We got the ID; report it and start an operation. */
+			id_i = 0;
+			lk201_id(id);
+			lk201_reset(lk201kbd_info);
+		}
+		return;
 	}
 
-	switch (id) {
-	case 1:
-		printk("LK201 detected\n");
+	/* Everything else is a scancode/status response. */
+	id_i = 0;
+	switch (ch) {
+	case LK_STAT_RESUME_ERR:
+	case LK_STAT_ERROR:
+	case LK_STAT_INHIBIT_ACK:
+	case LK_STAT_TEST_ACK:
+	case LK_STAT_MODE_KEYDOWN:
+	case LK_STAT_MODE_ACK:
 		break;
-	case 2:
-		printk("LK401 detected\n");
+	case LK_KEY_LOCK:
+		shift_state ^= LK_LOCK;
+		handle_scancode(c, shift_state && LK_LOCK ? 1 : 0);
+		break;
+	case LK_KEY_SHIFT:
+		shift_state ^= LK_SHIFT;
+		handle_scancode(c, shift_state && LK_SHIFT ? 1 : 0);
+		break;
+	case LK_KEY_CTRL:
+		shift_state ^= LK_CTRL;
+		handle_scancode(c, shift_state && LK_CTRL ? 1 : 0);
+		break;
+	case LK_KEY_COMP:
+		shift_state ^= LK_COMP;
+		handle_scancode(c, shift_state && LK_COMP ? 1 : 0);
+		break;
+	case LK_KEY_RELEASE:
+		if (shift_state & LK_SHIFT)
+			handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0);
+		if (shift_state & LK_CTRL)
+			handle_scancode(scancodeRemap[LK_KEY_CTRL], 0);
+		if (shift_state & LK_COMP)
+			handle_scancode(scancodeRemap[LK_KEY_COMP], 0);
+		if (shift_state & LK_LOCK)
+			handle_scancode(scancodeRemap[LK_KEY_LOCK], 0);
+		shift_state = 0;
+		break;
+	case LK_KEY_REPEAT:
+		handle_scancode(prev_scancode, 1);
 		break;
 	default:
-		printk("unknown keyboard, ID %d,\n", id);
-		printk("... please report to <linux-mips@oss.sgi.com>\n");
+		prev_scancode = c;
+		handle_scancode(c, 1);
 		break;
 	}
+	tasklet_schedule(&keyboard_tasklet);
+}
 
-	/*
-	 * now we're ready
-	 */
-	info->hook->rx_char = lk201_kbd_rx_char;
+static void __init lk201_info(struct dec_serial *info)
+{
+}
 
+static int __init lk201_init(struct dec_serial *info)
+{
+	/* First install handlers. */
 	lk201kbd_info = info;
 	kbd_rate = lk201kbd_rate;
 	kd_mksound = lk201kd_mksound;
 
+	info->hook->rx_char = lk201_kbd_rx_char;
+
+	/* Then just issue a reset -- the handlers will do the rest. */
+	lk201_send(info, LK_CMD_POWER_UP);
+
 	return 0;
 }
 
@@ -353,26 +401,29 @@ void __init kbd_init_hw(void)
 	extern int register_zs_hook(unsigned int, struct zs_hook *);
 	extern int unregister_zs_hook(unsigned int);
 
+	/* Maxine uses LK501 at the Access.Bus. */
+	if (mips_machtype == MACH_DS5000_XX)
+		return;
+
+	printk(KERN_INFO "lk201: DECstation LK keyboard driver v0.05.\n");
+
 	if (TURBOCHANNEL) {
-		if (mips_machtype != MACH_DS5000_XX) {
-			/*
-			 * This is not a MAXINE, so:
-			 *
-			 * kbd_init_hw() is being called before
-			 * rs_init() so just register the kbd hook
-			 * and let zs_init do the rest :-)
-			 */
-			if (mips_machtype == MACH_DS5000_200)
-				printk("LK201 Support for DS5000/200 not yet ready ...\n");
-			else
-				if(!register_zs_hook(KEYB_LINE, &lk201_kbdhook))
-					unregister_zs_hook(KEYB_LINE);
-		}
+		/*
+		 * kbd_init_hw() is being called before
+		 * rs_init() so just register the kbd hook
+		 * and let zs_init do the rest :-)
+		 */
+		if (mips_machtype == MACH_DS5000_200)
+			printk(KERN_ERR "lk201: support for DS5000/200 "
+			       "not yet ready.\n");
+		else
+			if(!register_zs_hook(KEYB_LINE, &lk201_kbdhook))
+				unregister_zs_hook(KEYB_LINE);
 	} else {
 		/*
 		 * TODO: modify dz.c to allow similar hooks
 		 * for LK201 handling on DS2100, DS3100, and DS5000/200
 		 */
-		printk("LK201 Support for DS3100 not yet ready ...\n");
+		printk(KERN_ERR "lk201: support for DS3100 not yet ready.\n");
 	}
 }
diff -up --recursive --new-file linux-mips-2.4.18-20020323.macro/drivers/tc/lk201.h linux-mips-2.4.18-20020323/drivers/tc/lk201.h
--- linux-mips-2.4.18-20020323.macro/drivers/tc/lk201.h	Wed Oct 31 05:26:17 2001
+++ linux-mips-2.4.18-20020323/drivers/tc/lk201.h	Sun Mar 24 14:31:12 2002
@@ -115,6 +115,7 @@
 					/* the keycode follows */
 #define LK_STAT_MODE_ACK	0xba	/* the mode command succeeded */
 
+#define LK_STAT_PWRUP_ID	0x01	/* the power-up response start mark */
 #define LK_STAT_PWRUP_OK	0x00	/* the power-up self test OK */
 #define LK_STAT_PWRUP_KDOWN	0x3d	/* a key was down during the test */
 #define LK_STAT_PWRUP_ERROR	0x3e	/* keyboard self test failure */
diff -up --recursive --new-file linux-mips-2.4.18-20020323.macro/drivers/tc/zs.c linux-mips-2.4.18-20020323/drivers/tc/zs.c
--- linux-mips-2.4.18-20020323.macro/drivers/tc/zs.c	Sat Mar 23 04:58:18 2002
+++ linux-mips-2.4.18-20020323/drivers/tc/zs.c	Sun Mar 24 20:51:10 2002
@@ -5,8 +5,8 @@
  * Derived from drivers/macintosh/macserial.c by Harald Koerfgen.
  *
  * DECstation changes
- * Copyright (C) 1998-2002 Harald Koerfgen
- * Copyright (C) 2000,2001 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+ * Copyright (C) 1998-2000 Harald Koerfgen
+ * Copyright (C) 2000, 2001, 2002  Maciej W. Rozycki <macro@ds2.pg.gda.pl>
  *
  * For the rest of the code the original Copyright applies:
  * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
@@ -409,7 +409,7 @@ static _INLINE_ void receive_chars(struc
 		stat = read_zsreg(info->zs_channel, R1);
 		ch = read_zsdata(info->zs_channel);
 
-		if (!tty && !info->hook && !info->hook->rx_char)
+		if (!tty && (!info->hook || !info->hook->rx_char))
 			continue;
 
 		if (tty_break) {
@@ -524,9 +524,9 @@ static _INLINE_ void status_handle(struc
 
 	if (info->zs_channel != info->zs_chan_a) {
 
-		/* FIXEM: Check for DCD transitions */
-		if (((stat ^ info->read_reg_zero) & DCD) != 0
-		    && info->tty && !C_CLOCAL(info->tty)) {
+		/* Check for DCD transitions */
+		if (info->tty && !C_CLOCAL(info->tty) &&
+		    ((stat ^ info->read_reg_zero) & DCD) != 0 ) {
 			if (stat & DCD) {
 				wake_up_interruptible(&info->open_wait);
 			} else if (!(info->flags & ZILOG_CALLOUT_ACTIVE)) {
@@ -1721,7 +1721,7 @@ int rs_open(struct tty_struct *tty, stru
 
 static void __init show_serial_version(void)
 {
-	printk("DECstation Z8530 serial driver version 0.06\n");
+	printk("DECstation Z8530 serial driver version 0.07\n");
 }
 
 /*  Initialize Z8530s zs_channels
@@ -1934,34 +1934,30 @@ int __init zs_init(void)
 	save_flags(flags); cli();
 
 	for (channel = 0; channel < zs_channels_found; ++channel) {
-		if (zs_soft[channel].hook &&
-		    zs_soft[channel].hook->init_channel)
-			(*zs_soft[channel].hook->init_channel)
-				(&zs_soft[channel]);
-
-		zs_soft[channel].clk_divisor = 16;
-		zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]);
-
 		if (request_irq(zs_parms->irq, rs_interrupt, SA_SHIRQ,
 				"SCC", &zs_soft[channel]))
 			printk(KERN_ERR "decserial: can't get irq %d\n",
 			       zs_parms->irq);
+
+		zs_soft[channel].clk_divisor = 16;
+		zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]);
 	}
 
-	for (info = zs_chain, i = 0; info; info = info->zs_next, i++)
-	{
-		if (info->hook && info->hook->init_info) {
-			(*info->hook->init_info)(info);
+	for (info = zs_chain, i = 0; info; info = info->zs_next, i++) {
+
+		/* Needed before interrupts are enabled. */
+		info->tty = 0;
+		info->x_char = 0;
+
+		if (info->hook && info->hook->init_info)
 			continue;
-		}
+
 		info->magic = SERIAL_MAGIC;
 		info->port = (int) info->zs_channel->control;
 		info->line = i;
-		info->tty = 0;
 		info->custom_divisor = 16;
 		info->close_delay = 50;
 		info->closing_wait = 3000;
-		info->x_char = 0;
 		info->event = 0;
 		info->count = 0;
 		info->blocked_open = 0;
@@ -1983,6 +1979,18 @@ int __init zs_init(void)
 
 	restore_flags(flags);
 
+	for (channel = 0; channel < zs_channels_found; ++channel) {
+		if (zs_soft[channel].hook &&
+		    zs_soft[channel].hook->init_channel)
+			(*zs_soft[channel].hook->init_channel)
+				(&zs_soft[channel]);
+	}
+
+	for (info = zs_chain, i = 0; info; info = info->zs_next, i++) {
+		if (info->hook && info->hook->init_info)
+			(*info->hook->init_info)(info);
+	}
+
 	return 0;
 }
 
@@ -2013,21 +2021,13 @@ zs_poll_tx_char(struct dec_serial *info,
 	if(chan) {
 		int loops = 10000;
 
- 		RECOVERY_DELAY;
-               	wbflush();
-		RECOVERY_DELAY;
-
-		while (loops && !(*(chan->control) & Tx_BUF_EMP)) {
+		while (loops && !(read_zsreg(chan, 0) & Tx_BUF_EMP))
 			loops--;
-	        	RECOVERY_DELAY;
-		}
 
 		if (loops) {
-			*(chan->data) = ch;
-			wbflush();
-			RECOVERY_DELAY;
+			write_zsdata(chan, ch);
 			ret = 0;
-                } else
+		} else
 			ret = -EAGAIN;
 
 		return ret;
@@ -2044,9 +2044,8 @@ zs_poll_rx_char(struct dec_serial *info)
 	if(chan) {
                 int loops = 10000;
 
-                while(loops && ((read_zsreg(chan, 0) & Rx_CH_AV) == 0)) {
+		while (loops && !(read_zsreg(chan, 0) & Rx_CH_AV))
 			loops--;
-		}
 
                 if (loops)
                         ret = read_zsdata(chan);
@@ -2054,8 +2053,8 @@ zs_poll_rx_char(struct dec_serial *info)
                         ret = -EAGAIN;
 
 		return ret;
-        } else
-                return -ENODEV;
+	} else
+		return -ENODEV;
 }
 
 unsigned int register_zs_hook(unsigned int channel, struct zs_hook *hook)

From hkoerfg@web.de  Wed Mar 27 22:21:37 2002
Received: (uucp@localhost) by guadalquivir.fnet.fr (8.8.8/97.02.12/Guadalquivir); id WAA13024; Wed, 27 Mar 2002 22:21:37 +0100 (MET)
Received-Date: Wed, 27 Mar 2002 22:21:37 +0100 (MET)
Received: from smtp02.web.de(217.72.192.151), claiming to be "smtp.web.de"
 via SMTP by guadalquivir.fnet.fr, id smtpd013022; Wed Mar 27 22:21:30 2002
Received: from [80.141.91.231] (helo=there)
	by smtp.web.de with smtp (WEB.DE(Exim) 4.43 #48)
	id 16qKqX-00062M-00; Wed, 27 Mar 2002 22:20:41 +0100
Content-Type: text/plain;
  charset="iso-8859-1"
From: Harald Koerfgen <hkoerfg@web.de>
Organization: none to speak of
To: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>, Dave Airlie <airlied@csn.ul.ie>
Subject: Re: [patch] linux: declance multicast filter fixes
Date: Wed, 27 Mar 2002 22:20:46 +0100
X-Mailer: KMail [version 1.3.2]
Cc: Ralf Baechle <ralf@uni-koblenz.de>, linux-mips@fnet.fr,
        linux-mips@oss.sgi.com
References: <Pine.GSO.3.96.1020325123322.4605A-100000@delta.ds2.pg.gda.pl>
In-Reply-To: <Pine.GSO.3.96.1020325123322.4605A-100000@delta.ds2.pg.gda.pl>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Message-Id: <E16qKqX-00062M-00@smtp.web.de>
Sender: hkoerfg@web.de
Content-Length: 1371
Lines: 30

Hi,

On Monday 25 March 2002 12:40, Maciej W. Rozycki wrote:
>  Well, the core seems to be already separated -- see drivers/net/7990.c.
> I haven't yet checked how suitable it is and many front-end drivers use it
> already.
>
>  For the I/O ASIC front-end I'm going to check if the ASIC is capable of
> mapping the LANCE more sensibly before starting any further work.  The
> current configuration is a major loss, doubling the CPU's work and I can't
> see any reasonable explanation for such a setup.

It's been quite some time since I have hacked the declance driver and I don't 
remember all the details, so take the following with a grain of salt.

The 7990 is basically a 16-bit chip in a 32-bit environment, and, AFAIR, uses 
two different DMA modes to access host memory. One is a 16-bit word-by-word 
access for the ring descriptors and the other is 8 16-bit-words-bursts for 
accessing the ring buffers themselves, where the LANCE only generates one 
target address per burst.

The IOASIC is, just as the CPU, only capable of doing 32-bit transfers 
to/from memory. So 16-bit LANCE accesses are translated into 32-bit IOASIC 
accesses but a part of the DMA target addresses are generated by the LANCE.

This leads to a 16-bit -> 32-bit mapping for the ring descriptors and a 
8*16-bit -> 8*32-bit mapping for ring buffers. Very efficient :-(.

Greetings,
Harald

From macro@ds2.pg.gda.pl  Thu Mar 28 14:01:43 2002
Received: (uucp@localhost) by guadalquivir.fnet.fr (8.8.8/97.02.12/Guadalquivir); id OAA20229; Thu, 28 Mar 2002 14:01:43 +0100 (MET)
Received-Date: Thu, 28 Mar 2002 14:01:43 +0100 (MET)
Received: from delta.ds2.pg.gda.pl(213.192.72.1)
 via SMTP by guadalquivir.fnet.fr, id smtpd020227; Thu Mar 28 14:01:39 2002
Received: from localhost by delta.ds2.pg.gda.pl (8.9.3/8.9.3) with SMTP id OAA11915;
	Thu, 28 Mar 2002 14:01:51 +0100 (MET)
Date: Thu, 28 Mar 2002 14:01:51 +0100 (MET)
From: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
To: Harald Koerfgen <hkoerfg@web.de>
cc: Dave Airlie <airlied@csn.ul.ie>, Ralf Baechle <ralf@uni-koblenz.de>,
        linux-mips@fnet.fr, linux-mips@oss.sgi.com
Subject: Re: [patch] linux: declance multicast filter fixes
In-Reply-To: <E16qKqX-00062M-00@smtp.web.de>
Message-ID: <Pine.GSO.3.96.1020328134253.11187B-100000@delta.ds2.pg.gda.pl>
Organization: Technical University of Gdansk
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Content-Length: 1329
Lines: 26

On Wed, 27 Mar 2002, Harald Koerfgen wrote:

> The 7990 is basically a 16-bit chip in a 32-bit environment, and, AFAIR, uses 
> two different DMA modes to access host memory. One is a 16-bit word-by-word 
> access for the ring descriptors and the other is 8 16-bit-words-bursts for 
> accessing the ring buffers themselves, where the LANCE only generates one 
> target address per burst.
> 
> The IOASIC is, just as the CPU, only capable of doing 32-bit transfers 
> to/from memory. So 16-bit LANCE accesses are translated into 32-bit IOASIC 
> accesses but a part of the DMA target addresses are generated by the LANCE.

 But the I/O ASIC chip is smart enough to merge data from the 8-bit ROM
device without problems and present four consecutive bytes as 32-bit
quantities to the host CPU.  Why couldn't it do the same for the LANCE?
Host memory addresses are generated on behalf of the LANCE by the I/O ASIC
anyway.

 Of course not all designers have a clue, sigh...  A brief study of
available documentation suggests no merging mode was implemented for the
LANCE and bit 0 of addresses generated is simply hardwired to 0. :-(

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

From macro@ds2.pg.gda.pl  Thu Mar 28 14:26:53 2002
Received: (uucp@localhost) by guadalquivir.fnet.fr (8.8.8/97.02.12/Guadalquivir); id OAA21282; Thu, 28 Mar 2002 14:26:53 +0100 (MET)
Received-Date: Thu, 28 Mar 2002 14:26:53 +0100 (MET)
Received: from delta.ds2.pg.gda.pl(213.192.72.1)
 via SMTP by guadalquivir.fnet.fr, id smtpd021280; Thu Mar 28 14:26:44 2002
Received: from localhost by delta.ds2.pg.gda.pl (8.9.3/8.9.3) with SMTP id OAA12347;
	Thu, 28 Mar 2002 14:26:56 +0100 (MET)
Date: Thu, 28 Mar 2002 14:26:55 +0100 (MET)
From: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
To: David Woodhouse <dwmw2@redhat.com>, Ralf Baechle <ralf@uni-koblenz.de>,
        Harald Koerfgen <hkoerfg@web.de>
cc: linux-mips@fnet.fr, linux-mips@oss.sgi.com
Subject: [patch] linux 2.4: DEC MS02-NV NVRAM module support
Message-ID: <Pine.GSO.3.96.1020328140909.11187D-100000@delta.ds2.pg.gda.pl>
Organization: Technical University of Gdansk
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Content-Length: 13649
Lines: 441

Hello,

 The patch adds support for the DEC MS02-type lithium battery backed-up
NVRAM board.  The board provides 1MB (architecturally up to 4MB) of fast
SRAM originally meant as a PrestoServe NFS accelerator for the MIPS-based
DECstations.

 The code works fine for me since its creation back in August.  It was not
tested by anyone else -- after announcing the code at the "linux-mips" 
list last year I've read from two volunteers but they did not come back
with results ever. 

 I believe it's suitable for inclusion in the official kernel.  The patch
applies both to 2.4.19-pre4 and to the current CVS tree at oss.sgi.com. 

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

patch-mips-2.4.18-20020327-ms02-nv-69
diff -up --recursive --new-file linux-mips-2.4.18-20020327.macro/Documentation/Configure.help linux-mips-2.4.18-20020327/Documentation/Configure.help
--- linux-mips-2.4.18-20020327.macro/Documentation/Configure.help	2002-02-27 05:27:43.000000000 +0000
+++ linux-mips-2.4.18-20020327/Documentation/Configure.help	2002-03-28 09:30:03.000000000 +0000
@@ -12495,6 +12495,18 @@ CONFIG_MTD_SLRAM
   you can still use it for storage or swap by using this driver to
   present it to the system as a Memory Technology Device.
 
+DEC MS02-NV NVRAM module support
+CONFIG_MTD_MS02NV
+  This is a MTD driver for the DEC's MS02-type battery backed-up NVRAM
+  module.  The module was originally meant as an NFS accelerator.  Say Y
+  here if you have a DECstation 5000/2x0 or a DECsystem 5900 equipped
+  with such a module.
+
+  If you want to compile this driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt.  The module will be
+  called ms02-nv.o.
+
 Debugging RAM test driver
 CONFIG_MTD_MTDRAM
   This enables a test MTD device driver which uses vmalloc() to
diff -up --recursive --new-file linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/Config.in linux-mips-2.4.18-20020327/drivers/mtd/devices/Config.in
--- linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/Config.in	2001-11-06 05:27:13.000000000 +0000
+++ linux-mips-2.4.18-20020327/drivers/mtd/devices/Config.in	2002-03-28 09:29:07.000000000 +0000
@@ -10,6 +10,7 @@ if [ "$CONFIG_MTD_PMC551" = "y" -o  "$CO
    bool '    PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX
    bool '    PMC551 Debugging' CONFIG_MTD_PMC551_DEBUG
 fi
+dep_tristate '  DEC MS02-NV NVRAM module support' CONFIG_MTD_MS02NV $CONFIG_MTD $CONFIG_DECSTATION
 dep_tristate '  Uncached system RAM' CONFIG_MTD_SLRAM $CONFIG_MTD
 if [ "$CONFIG_SA1100_LART" = "y" ]; then
   dep_tristate '  28F160xx flash driver for LART' CONFIG_MTD_LART $CONFIG_MTD
diff -up --recursive --new-file linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/Makefile linux-mips-2.4.18-20020327/drivers/mtd/devices/Makefile
--- linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/Makefile	2001-11-06 05:27:13.000000000 +0000
+++ linux-mips-2.4.18-20020327/drivers/mtd/devices/Makefile	2002-03-28 09:29:07.000000000 +0000
@@ -18,6 +18,7 @@ obj-$(CONFIG_MTD_DOC2001)	+= doc2001.o
 obj-$(CONFIG_MTD_DOCPROBE)	+= docprobe.o docecc.o
 obj-$(CONFIG_MTD_SLRAM)		+= slram.o
 obj-$(CONFIG_MTD_PMC551)	+= pmc551.o
+obj-$(CONFIG_MTD_MS02NV)	+= ms02-nv.o
 obj-$(CONFIG_MTD_MTDRAM)	+= mtdram.o
 obj-$(CONFIG_MTD_LART)		+= lart.o
 obj-$(CONFIG_MTD_BLKMTD)	+= blkmtd.o
diff -up --recursive --new-file linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/ms02-nv.c linux-mips-2.4.18-20020327/drivers/mtd/devices/ms02-nv.c
--- linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/ms02-nv.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-mips-2.4.18-20020327/drivers/mtd/devices/ms02-nv.c	2002-03-28 09:35:33.000000000 +0000
@@ -0,0 +1,323 @@
+/*
+ *      Copyright (c) 2001 Maciej W. Rozycki
+ *
+ *      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/init.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/kn02.h>
+#include <asm/dec/kn03.h>
+#include <asm/io.h>
+#include <asm/paccess.h>
+
+#include "ms02-nv.h"
+
+
+static char version[] __initdata =
+        "ms02-nv.c: v.1.0.0  13 Aug 2001  Maciej W. Rozycki.\n";
+
+MODULE_AUTHOR("Maciej W. Rozycki <macro@ds2.pg.gda.pl>");
+MODULE_DESCRIPTION("DEC MS02-NV NVRAM module driver");
+MODULE_LICENSE("GPL");
+
+
+/*
+ * Addresses we probe for an MS02-NV at.  Modules may be located
+ * at any 8MB boundary within a 0MB up to 112MB range or at any 32MB
+ * boundary within a 0MB up to 448MB range.  We don't support a module
+ * at 0MB, though.
+ */
+static ulong ms02nv_addrs[] __initdata = {
+	0x07000000, 0x06800000, 0x06000000, 0x05800000, 0x05000000,
+	0x04800000, 0x04000000, 0x03800000, 0x03000000, 0x02800000,
+	0x02000000, 0x01800000, 0x01000000, 0x00800000
+};
+
+static const char ms02nv_name[] = "DEC MS02-NV NVRAM";
+static const char ms02nv_res_diag_ram[] = "Diagnostic RAM";
+static const char ms02nv_res_user_ram[] = "General-purpose RAM";
+static const char ms02nv_res_csr[] = "Control and status register";
+
+static struct mtd_info *root_ms02nv_mtd;
+
+
+static int ms02nv_read(struct mtd_info *mtd, loff_t from,
+			size_t len, size_t *retlen, u_char *buf)
+{
+	struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv;
+
+	if (from + len > mtd->size)
+		return -EINVAL;
+
+	memcpy(buf, mp->uaddr + from, len);
+	*retlen = len;
+
+	return 0;
+}
+
+static int ms02nv_write(struct mtd_info *mtd, loff_t to,
+			size_t len, size_t *retlen, const u_char *buf)
+{
+	struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv;
+
+	if (to + len > mtd->size)
+		return -EINVAL;
+
+	memcpy(mp->uaddr + to, buf, len);
+	*retlen = len;
+
+	return 0;
+}
+
+
+static inline uint ms02nv_probe_one(ulong addr)
+{
+	ms02nv_uint *ms02nv_diagp;
+	ms02nv_uint *ms02nv_magicp;
+	uint ms02nv_diag;
+	uint ms02nv_magic;
+	size_t size;
+
+	int err;
+
+	/*
+	 * The firmware writes MS02NV_ID at MS02NV_MAGIC and also
+	 * a diagnostic status at MS02NV_DIAG.
+	 */
+	ms02nv_diagp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_DIAG));
+	ms02nv_magicp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_MAGIC));
+	err = get_dbe(ms02nv_magic, ms02nv_magicp);
+	if (err)
+		return 0;
+	if (ms02nv_magic != MS02NV_ID)
+		return 0;
+
+	ms02nv_diag = *ms02nv_diagp;
+	size = (ms02nv_diag & MS02NV_DIAG_SIZE_MASK) << MS02NV_DIAG_SIZE_SHIFT;
+	if (size > MS02NV_CSR)
+		size = MS02NV_CSR;
+
+	return size;
+}
+
+static int __init ms02nv_init_one(ulong addr)
+{
+	struct mtd_info *mtd;
+	struct ms02nv_private *mp;
+	struct resource *mod_res;
+	struct resource *diag_res;
+	struct resource *user_res;
+	struct resource *csr_res;
+	ulong fixaddr;
+	size_t size, fixsize;
+
+	static int version_printed;
+
+	int ret = -ENODEV;
+
+	/* The module decodes 8MB of address space. */
+	mod_res = kmalloc(sizeof(*mod_res), GFP_KERNEL);
+	if (!mod_res)
+		return -ENOMEM;
+
+	memset(mod_res, 0, sizeof(*mod_res));
+	mod_res->name = ms02nv_name;
+	mod_res->start = addr;
+	mod_res->end = addr + MS02NV_SLOT_SIZE - 1;
+	mod_res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+	if (request_resource(&iomem_resource, mod_res) < 0)
+		goto err_out_mod_res;
+
+	size = ms02nv_probe_one(addr);
+	if (!size)
+		goto err_out_mod_res_rel;
+
+	if (!version_printed) {
+		printk(KERN_INFO "%s", version);
+		version_printed = 1;
+	}
+
+	ret = -ENOMEM;
+	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
+	if (!mtd)
+		goto err_out_mod_res_rel;
+	memset(mtd, 0, sizeof(*mtd));
+	mp = kmalloc(sizeof(*mp), GFP_KERNEL);
+	if (!mp)
+		goto err_out_mtd;
+	memset(mp, 0, sizeof(*mp));
+
+	mtd->priv = mp;
+	mp->resource.module = mod_res;
+
+	/* Firmware's diagnostic NVRAM area. */
+	diag_res = kmalloc(sizeof(*diag_res), GFP_KERNEL);
+	if (!diag_res)
+		goto err_out_mp;
+
+	memset(diag_res, 0, sizeof(*diag_res));
+	diag_res->name = ms02nv_res_diag_ram;
+	diag_res->start = addr;
+	diag_res->end = addr + MS02NV_RAM - 1;
+	diag_res->flags = IORESOURCE_BUSY;
+	request_resource(mod_res, diag_res);
+
+	mp->resource.diag_ram = diag_res;
+
+	/* User-available general-purpose NVRAM area. */
+	user_res = kmalloc(sizeof(*user_res), GFP_KERNEL);
+	if (!user_res)
+		goto err_out_diag_res;
+
+	memset(user_res, 0, sizeof(*user_res));
+	user_res->name = ms02nv_res_user_ram;
+	user_res->start = addr + MS02NV_RAM;
+	user_res->end = addr + size - 1;
+	user_res->flags = IORESOURCE_BUSY;
+	request_resource(mod_res, user_res);
+
+	mp->resource.user_ram = user_res;
+
+	/* Control and status register. */
+	csr_res = kmalloc(sizeof(*csr_res), GFP_KERNEL);
+	if (!csr_res)
+		goto err_out_user_res;
+
+	memset(csr_res, 0, sizeof(*csr_res));
+	csr_res->name = ms02nv_res_csr;
+	csr_res->start = addr + MS02NV_CSR;
+	csr_res->end = addr + MS02NV_CSR + 3;
+	csr_res->flags = IORESOURCE_BUSY;
+	request_resource(mod_res, csr_res);
+
+	mp->resource.csr = csr_res;
+
+	mp->addr = phys_to_virt(addr);
+	mp->size = size;
+
+	/*
+	 * Hide the firmware's diagnostic area.  It may get destroyed
+	 * upon a reboot.  Take paging into account for mapping support.
+	 */
+	fixaddr = (addr + MS02NV_RAM + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+	fixsize = (size - (fixaddr - addr)) & ~(PAGE_SIZE - 1);
+	mp->uaddr = phys_to_virt(fixaddr);
+
+	mtd->type = MTD_RAM;
+	mtd->flags = MTD_CAP_RAM | MTD_XIP;
+	mtd->size = fixsize;
+	mtd->name = (char *)ms02nv_name;
+	mtd->module = THIS_MODULE;
+	mtd->read = ms02nv_read;
+	mtd->write = ms02nv_write;
+
+	ret = -EIO;
+	if (add_mtd_device(mtd)) {
+		printk(KERN_ERR
+			"ms02-nv: Unable to register MTD device, aborting!\n");
+		goto err_out_csr_res;
+	}
+
+	printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %uMB.\n",
+		mtd->index, ms02nv_name, addr, size >> 20);
+
+	mp->next = root_ms02nv_mtd;
+	root_ms02nv_mtd = mtd;
+
+	return 0;
+
+
+err_out_csr_res:
+	release_resource(csr_res);
+	kfree(csr_res);
+err_out_user_res:
+	release_resource(user_res);
+	kfree(user_res);
+err_out_diag_res:
+	release_resource(diag_res);
+	kfree(diag_res);
+err_out_mp:
+	kfree(mp);
+err_out_mtd:
+	kfree(mtd);
+err_out_mod_res_rel:
+	release_resource(mod_res);
+err_out_mod_res:
+	kfree(mod_res);
+	return ret;
+}
+
+static void __exit ms02nv_remove_one(void)
+{
+	struct mtd_info *mtd = root_ms02nv_mtd;
+	struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv;
+
+	root_ms02nv_mtd = mp->next;
+
+	del_mtd_device(mtd);
+
+	release_resource(mp->resource.csr);
+	kfree(mp->resource.csr);
+	release_resource(mp->resource.user_ram);
+	kfree(mp->resource.user_ram);
+	release_resource(mp->resource.diag_ram);
+	kfree(mp->resource.diag_ram);
+	release_resource(mp->resource.module);
+	kfree(mp->resource.module);
+	kfree(mp);
+	kfree(mtd);
+}
+
+
+static int __init ms02nv_init(void)
+{
+	volatile u32 *csr;
+	uint stride = 0;
+	int count = 0;
+	int i;
+
+	switch (mips_machtype) {
+	case MACH_DS5000_200:
+		csr = (volatile u32 *)KN02_CSR_ADDR;
+		if (*csr & KN02_CSR_BNK32M)
+			stride = 2;
+		break;
+	case MACH_DS5000_2X0:
+		csr = (volatile u32 *)KN03_MCR_BASE;
+		if (*csr & KN03_MCR_BNK32M)
+			stride = 2;
+		break;
+	default:
+		return -ENODEV;
+		break;
+	}
+
+	for (i = 0; i < (sizeof(ms02nv_addrs) / sizeof(*ms02nv_addrs)); i++)
+		if (!ms02nv_init_one(ms02nv_addrs[i] << stride))
+			count++;
+
+	return (count > 0) ? 0 : -ENODEV;
+}
+
+static void __exit ms02nv_cleanup(void)
+{
+	while (root_ms02nv_mtd)
+		ms02nv_remove_one();
+}
+
+
+module_init(ms02nv_init);
+module_exit(ms02nv_cleanup);
diff -up --recursive --new-file linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/ms02-nv.h linux-mips-2.4.18-20020327/drivers/mtd/devices/ms02-nv.h
--- linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/ms02-nv.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-mips-2.4.18-20020327/drivers/mtd/devices/ms02-nv.h	2001-08-12 20:10:10.000000000 +0000
@@ -0,0 +1,43 @@
+/*
+ *      Copyright (c) 2001 Maciej W. Rozycki
+ *
+ *      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/ioport.h>
+#include <linux/mtd/mtd.h>
+
+/* MS02-NV iomem register offsets. */
+#define MS02NV_CSR		0x400000	/* control & status register */
+
+/* MS02-NV memory offsets. */
+#define MS02NV_DIAG		0x0003f8	/* diagnostic status */
+#define MS02NV_MAGIC		0x0003fc	/* MS02-NV magic ID */
+#define MS02NV_RAM		0x000400	/* general-purpose RAM start */
+
+/* MS02-NV diagnostic status constants. */
+#define MS02NV_DIAG_SIZE_MASK	0xf0		/* RAM size mask */
+#define MS02NV_DIAG_SIZE_SHIFT	0x10		/* RAM size shift (left) */
+
+/* MS02-NV general constants. */
+#define MS02NV_ID		0x03021966	/* MS02-NV magic ID value */
+#define MS02NV_SLOT_SIZE	0x800000	/* size of the address space
+						   decoded by the module */
+
+typedef volatile u32 ms02nv_uint;
+
+struct ms02nv_private {
+	struct mtd_info *next;
+	struct {
+		struct resource *module;
+		struct resource *diag_ram;
+		struct resource *user_ram;
+		struct resource *csr;
+	} resource;
+	u_char *addr;
+	size_t size;
+	u_char *uaddr;
+};

From hkoerfg@web.de  Fri Mar 29 09:01:39 2002
Received: (uucp@localhost) by guadalquivir.fnet.fr (8.8.8/97.02.12/Guadalquivir); id JAA01789; Fri, 29 Mar 2002 09:01:39 +0100 (MET)
Received-Date: Fri, 29 Mar 2002 09:01:39 +0100 (MET)
Received: from smtp02.web.de(217.72.192.151), claiming to be "smtp.web.de"
 via SMTP by guadalquivir.fnet.fr, id smtpd001787; Fri Mar 29 09:01:31 2002
Received: from [80.141.104.82] (helo=there)
	by smtp.web.de with smtp (WEB.DE(Exim) 4.43 #48)
	id 16qrGh-0004Vu-00; Fri, 29 Mar 2002 08:57:51 +0100
Content-Type: text/plain;
  charset="iso-8859-1"
From: Harald Koerfgen <hkoerfg@web.de>
Organization: none to speak of
To: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
Subject: Re: [patch] linux: declance multicast filter fixes
Date: Fri, 29 Mar 2002 08:57:50 +0100
X-Mailer: KMail [version 1.3.2]
Cc: Dave Airlie <airlied@csn.ul.ie>, Ralf Baechle <ralf@uni-koblenz.de>,
        linux-mips@fnet.fr, linux-mips@oss.sgi.com
References: <Pine.GSO.3.96.1020328134253.11187B-100000@delta.ds2.pg.gda.pl>
In-Reply-To: <Pine.GSO.3.96.1020328134253.11187B-100000@delta.ds2.pg.gda.pl>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Message-Id: <E16qrGh-0004Vu-00@smtp.web.de>
Sender: hkoerfg@web.de
Content-Length: 793
Lines: 21

On Thursday 28 March 2002 14:01, Maciej W. Rozycki wrote:
>  But the I/O ASIC chip is smart enough to merge data from the 8-bit ROM
> device without problems and present four consecutive bytes as 32-bit
> quantities to the host CPU.

A simple 4 to 1 mapping is easy, even for the average hardware developer :-)

> Why couldn't it do the same for the LANCE?
> Host memory addresses are generated on behalf of the LANCE by the I/O ASIC
> anyway.

Probably because this would have made the IOASIC 0.0034 cents more expensive?

> Of course not all designers have a clue, sigh...  A brief study of
> available documentation suggests no merging mode was implemented for the
> LANCE and bit 0 of addresses generated is simply hardwired to 0. :-(

That's my interpretation as well.

Greetings,
Harald

From ralf@linux-mips.net  Sat Mar 30 09:19:13 2002
Received: (uucp@localhost) by guadalquivir.fnet.fr (8.8.8/97.02.12/Guadalquivir); id JAA12212; Sat, 30 Mar 2002 09:19:13 +0100 (MET)
Received-Date: Sat, 30 Mar 2002 09:19:13 +0100 (MET)
Received: from oss.sgi.com(216.32.174.27)
 via SMTP by guadalquivir.fnet.fr, id smtpd012210; Sat Mar 30 09:19:10 2002
Received: from dea.linux-mips.net (localhost [127.0.0.1])
	by oss.sgi.com (8.11.2/8.11.3) with ESMTP id g2U8Jhv08981
	for <linux-mips@fnet.fr>; Sat, 30 Mar 2002 00:19:43 -0800
Received: (from ralf@localhost)
	by dea.linux-mips.net (8.11.6/8.11.1) id g2U8J1331741;
	Sat, 30 Mar 2002 00:19:01 -0800
Date: Sat, 30 Mar 2002 00:19:01 -0800
From: Ralf Baechle <ralf@oss.sgi.com>
To: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
Cc: David Woodhouse <dwmw2@redhat.com>, Harald Koerfgen <hkoerfg@web.de>,
        linux-mips@fnet.fr, linux-mips@oss.sgi.com
Subject: Re: [patch] linux 2.4: DEC MS02-NV NVRAM module support
Message-ID: <20020330001901.A31717@dea.linux-mips.net>
References: <Pine.GSO.3.96.1020328140909.11187D-100000@delta.ds2.pg.gda.pl>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
User-Agent: Mutt/1.2.5i
In-Reply-To: <Pine.GSO.3.96.1020328140909.11187D-100000@delta.ds2.pg.gda.pl>; from macro@ds2.pg.gda.pl on Thu, Mar 28, 2002 at 02:26:55PM +0100
X-Accept-Language: de,en,fr
Content-Length: 941
Lines: 24

On Thu, Mar 28, 2002 at 02:26:55PM +0100, Maciej W. Rozycki wrote:

>  The patch adds support for the DEC MS02-type lithium battery backed-up
> NVRAM board.  The board provides 1MB (architecturally up to 4MB) of fast
> SRAM originally meant as a PrestoServe NFS accelerator for the MIPS-based
> DECstations.
> 
>  The code works fine for me since its creation back in August.  It was not
> tested by anyone else -- after announcing the code at the "linux-mips" 
> list last year I've read from two volunteers but they did not come back
> with results ever. 
> 
>  I believe it's suitable for inclusion in the official kernel.  The patch
> applies both to 2.4.19-pre4 and to the current CVS tree at oss.sgi.com. 

Looks good, applied to 2.4 and 2.5.

If you would have submitted this patch without prior testing in August I
certainly would have approved it as well as it had not potencial to break
things for other machines.

Thanks,

  Ralf

