Subject: Update to NCR 53c810 driver
To: None <current-users@NetBSD.ORG, perry@piermont.com>
From: Dave Huang <khym@bga.com>
List: current-users
Date: 12/27/1996 18:11:08
There's been a lot of work on the FreeBSD ncr driver recently, so I
decided to merge the changes into the NetBSD driver before they
diverged too much :)

Apply the following patch to the NetBSD-current ncr driver (ncr.c 1.54,
ncr_reg.h 1.9) to get version 1.91 of FreeBSD's driver.

This seems to be the most significant change:
----------------------------------------------------------------------
General cleanup and new features for 53c875 based cards, especially the
Tekram DC390W/U/F, whose config EEPROM can now be dumped, if the kernel
is built with option NCR_TEKRAM_EEPROM.

Other changes:

- add brackets to expansion of OUTB/W/L macro arguments.
- remove unused NCB structure element ns_async
- support sync. SCSI offset of 16 (instead of only 8) on 825A and 875
- correctly identify 53c810A and 53c825A chips
- preserve SCSI BIOS settings of PCI performance options
- remove (already disabled) support for NCR reset because of command timeout
- reverse order of reading of SCSI and DMA specific interrupt cause registers
- add definition of Tekram config EEPROM contents (not currently used)
----------------------------------------------------------------------

See http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/pci/ncr.c/ for a
description of the other changes... (that cvsweb thing is really cool, btw :)

I've been running the new driver for almost a week, and things seem to be
working just fine for me on my 53c810 (Asus SC200) card (no different from
the NetBSD-current driver, actually)... YMMV though, be careful with it.

I think I've also got a version for NetBSD 1.2, although I don't have a 1.2
system to try it on. Send me some email if you're interested though :)


--- /usr/src/sys/dev/pci/ncr.c	Wed Dec 11 06:20:20 1996
+++ ncr.c	Fri Dec 27 15:26:57 1996
@@ -44,18 +44,23 @@
 ***************************************************************************
 */
 
-#define NCR_DATE "pl23 95/09/07"
+#define NCR_DATE "pl24 96/12/14"
 
 #define NCR_VERSION	(2)
 #define	MAX_UNITS	(16)
 
 #define NCR_GETCC_WITHMSG
 
-#ifdef	FAILSAFE
+#if defined (__FreeBSD__) && defined(KERNEL)
+#include "opt_ncr.h"
+#endif /* defined (__FreeBSD__) && defined(KERNEL) */
+
+#ifdef FAILSAFE
+#ifndef SCSI_NCR_DFLT_TAGS
 #define	SCSI_NCR_DFLT_TAGS (0)
-#define	MAX_LUN		(1)
+#endif /* SCSI_NCR_DFLT_TAGS */
 #define	CDROM_ASYNC
-#endif	/* FAILSAFE */
+#endif /* FAILSAFE */
 
 /*==========================================================
 **
@@ -248,12 +253,12 @@
 **    Can be changed at runtime too.
 */
 
-#ifdef SCSI_DEBUG_FLAGS
+#ifdef SCSI_NCR_DEBUG
 	#define DEBUG_FLAGS ncr_debug
-#else /* SCSI_DEBUG_FLAGS */
-	#define SCSI_DEBUG_FLAGS	0
+#else /* SCSI_NCR_DEBUG */
+	#define SCSI_NCR_DEBUG	0
 	#define DEBUG_FLAGS	0
-#endif /* SCSI_DEBUG_FLAGS */
+#endif /* SCSI_NCR_DEBUG */
 
 
 
@@ -356,9 +361,9 @@
 #define	INL(r) (np->reg->r)
 #define	INL_OFF(o) (*((volatile INT32 *)((char *)np->reg + (o))))
 
-#define	OUTB(r, val) np->reg->r = val
-#define	OUTW(r, val) np->reg->r = val
-#define	OUTL(r, val) np->reg->r = val
+#define	OUTB(r, val) np->reg->r = (val)
+#define	OUTW(r, val) np->reg->r = (val)
+#define	OUTL(r, val) np->reg->r = (val)
 #define	OUTL_OFF(o, val) *((volatile INT32 *)((char *)np->reg + (o))) = val
 
 #endif
@@ -1066,9 +1071,17 @@
 	/*
 	**	timing parameters
 	*/
-	u_char		ns_async;
 	u_char		ns_sync;
+	u_char		maxoffs;
+
+	/*
+	**	BIOS supplied PCI bus options
+	*/
 	u_char		rv_scntl3;
+	u_char		rv_dcntl;
+	u_char		rv_dmode;
+	u_char		rv_ctest3;
+	u_char		rv_ctest5;
 
 	/*-----------------------------------------------
 	**	Link to the generic SCSI driver
@@ -1354,7 +1367,7 @@
 ncb_p         ncrp [MAX_UNITS];		/* XXX to be replaced by SYSCTL */
 #endif /* !__NetBSD__ */
 
-static int ncr_debug = SCSI_DEBUG_FLAGS;
+static int ncr_debug = SCSI_NCR_DEBUG;
 #ifndef __NetBSD__
 SYSCTL_INT(_debug, OID_AUTO, ncr_debug, CTLFLAG_RW, &ncr_debug, 0, "");
 #endif /* !__NetBSD__ */
@@ -1371,7 +1384,6 @@
 */
 
 #define	NCR_810_ID	(0x00011000ul)
-#define	NCR_810AP_ID	(0x00051000ul)
 #define	NCR_815_ID	(0x00041000ul)
 #define	NCR_825_ID	(0x00031000ul)
 #define	NCR_860_ID	(0x00061000ul)
@@ -3308,7 +3320,6 @@
 		return 0;
 #endif
 	if (pa->pa_id != NCR_810_ID &&
-	    pa->pa_id != NCR_810AP_ID &&
 	    pa->pa_id != NCR_815_ID &&
 	    pa->pa_id != NCR_825_ID &&
 	    pa->pa_id != NCR_860_ID &&
@@ -3323,19 +3334,21 @@
 
 static	char* ncr_probe (pcici_t tag, pcidi_t type)
 {
+	u_char rev = pci_conf_read (tag, PCI_CLASS_REG) & 0xff;
 	switch (type) {
 
 	case NCR_810_ID:
-		return ("ncr 53c810 scsi");
-
-	case NCR_810AP_ID:
-		return ("ncr 53c810ap scsi");
+		return (rev & 0xf0) == 0x00
+			? ("ncr 53c810 scsi") 
+			: ("ncr 53c810a scsi");
 
 	case NCR_815_ID:
 		return ("ncr 53c815 scsi");
 
 	case NCR_825_ID:
-		return ("ncr 53c825 wide scsi");
+		return (rev & 0xf0) == 0x00
+			? ("ncr 53c825 wide scsi")
+			: ("ncr 53c825a wide scsi");
 
 	case NCR_860_ID:
 		return ("ncr 53c860 scsi");
@@ -3376,20 +3389,18 @@
 	const char *intrstr;
 	ncb_p np = (void *)self;
 	int wide = 0;
+	u_char rev = pci_conf_read(pc, pa->pa_tag, PCI_CLASS_REG) & 0xff;
 
 	printf(": NCR ");
 	switch (pa->pa_id) {
 	case NCR_810_ID:
-		printf("53c810");
-		break;
-	case NCR_810AP_ID:
-		printf("53c810ap");
+		printf((rev & 0xf0) == 0x00 ? "53c810" : "53c810a");
 		break;
 	case NCR_815_ID:
 		printf("53c815");
 		break;
 	case NCR_825_ID:
-		printf("53c825 Wide");
+		printf((rev & 0xf0) == 0x00 ? "53c825 Wide" : "53c825a Wide");
 		wide = 1;
 		break;
 	case NCR_860_ID:
@@ -3505,13 +3516,22 @@
 #endif /* !__NetBSD__ */
 
 	/*
-	**	Do chip dependent initialization.
+	**	Save some controller register default values
 	*/
 
-	np->maxwide = 0;
+	np->rv_dmode  = INB (nc_dmode);
+	np->rv_dcntl  = INB (nc_dcntl) | CLSE | PFEN | NOCOM;
+	np->rv_ctest3 = INB (nc_ctest3);
+	np->rv_ctest5 = 0;
 	np->rv_scntl3 = 0x13;	/* default: 40MHz clock */
-	np->ns_sync = 25;
-	np->ns_async = 50;
+
+	/*
+	**	Do chip dependent initialization.
+	*/
+
+	np->maxwide   = 0;
+	np->ns_sync   = 25;	/* in units of 4ns */
+	np->maxoffs   = 8;
 
 	/*
 	**	Get the frequency of the chip's clock.
@@ -3524,13 +3544,32 @@
 	switch (pci_conf_read (config_id, PCI_ID_REG)) {
 #endif /* __NetBSD__ */
 	case NCR_825_ID:
+	    {
+#ifndef __NetBSD__
+		u_char rev = pci_conf_read (config_id, PCI_CLASS_REG) & 0xff;
+#endif /* !__NetBSD__ */
+		if ((rev & 0xf0) == 0x10)
+			np->maxoffs = 16;
 		np->maxwide = 1;
 		break;
+	    }
 	case NCR_860_ID:
 		np->rv_scntl3 = 0x35;	/* always assume 80MHz clock for 860 */
+		/*np->ns_sync   = 12;*/	/* in units of 4ns */
 		break;
 	case NCR_875_ID:
 		np->maxwide = 1;
+		/*np->ns_sync   = 12;*/	/* in units of 4ns */
+		np->maxoffs = 16;
+#ifdef NCR_TEKRAM_EEPROM
+		if (bootverbose) 
+		{
+			printf ("%s: Tekram EEPROM read %s\n",
+				ncr_name(np),
+				read_tekram_eeprom (np, NULL) ?
+				"succeeded" : "failed");
+		}
+#endif /* NCR_TEKRAM_EEPROM */
 		ncr_getclock(np);
 		break;
 	}
@@ -3557,14 +3596,6 @@
 	np->myaddr = INB(nc_scid) & 0x07;
 	if (!np->myaddr) np->myaddr = SCSI_NCR_MYADDR;
 
-	/*
-	**	Reset chip.
-	*/
-
-	OUTB (nc_istat,  SRST);
-	DELAY (1000);
-	OUTB (nc_istat,  0   );
-
 #ifdef NCR_DUMP_REG
 	/*
 	**	Log the initial register contents
@@ -3580,16 +3611,16 @@
 			if (reg%16==12) printf ("\n");
 		}
 	}
+#endif /* NCR_DUMP_REG */
 
 	/*
-	**	Reset chip, once again.
+	**	Reset chip.
 	*/
 
 	OUTB (nc_istat,  SRST);
 	DELAY (1000);
 	OUTB (nc_istat,  0   );
 
-#endif /* NCR_DUMP_REG */
 
 	/*
 	**	Now check the cache handling of the pci chipset.
@@ -4628,29 +4659,34 @@
 	**	Init chip.
 	*/
 
-#ifndef __NetBSD__
-	if (pci_max_burst_len < 4) {
-		static u_char tbl[4]={0,0,0x40,0x80};
-		burstlen = tbl[pci_max_burst_len];
-	} else burstlen = 0xc0;
-#else /* !__NetBSD__ */
-	burstlen = 0xc0;
-#endif /* __NetBSD__ */
+	burstlen = 0xc0;		/* XXX 53c875 needs code change to   */
+					/*     be able to use larger bursts  */
 
-	OUTB (nc_istat,  0      );      /*  Remove Reset, abort ...	     */
+	OUTB (nc_istat,  0x00   );      /*  Remove Reset, abort ...	     */
 	OUTB (nc_scntl0, 0xca   );      /*  full arb., ena parity, par->ATN  */
 	OUTB (nc_scntl1, 0x00	);	/*  odd parity, and remove CRST!!    */
 	OUTB (nc_scntl3, np->rv_scntl3);/*  timing prescaler		     */
 	OUTB (nc_scid  , RRE|np->myaddr);/*  host adapter SCSI address       */
 	OUTW (nc_respid, 1ul<<np->myaddr);/*  id to respond to		     */
 	OUTB (nc_istat , SIGP	);	/*  Signal Process		     */
-	OUTB (nc_dmode , burstlen);	/*  Burst length = 2 .. 16 transfers */
-	OUTB (nc_dcntl , NOCOM  );      /*  no single step mode, protect SFBR*/
-	OUTB (nc_ctest4, 0x08	);	/*  enable master parity checking    */
+	OUTB (nc_dmode , np->rv_dmode);	/* XXX modify burstlen ??? */
+	OUTB (nc_dcntl , np->rv_dcntl);
+	OUTB (nc_ctest3, np->rv_ctest3);
+	OUTB (nc_ctest5, np->rv_ctest5);
+	OUTB (nc_ctest4, MPEE	);	/*  enable master parity checking    */
 	OUTB (nc_stest2, EXT    );	/*  Extended Sreq/Sack filtering     */
 	OUTB (nc_stest3, TE     );	/*  TolerANT enable		     */
 	OUTB (nc_stime0, 0x0b	);	/*  HTH = disabled, STO = 0.1 sec.   */
 
+	if (bootverbose) {
+	  printf ("\tBIOS values: dmode: %02x, dcntl: %02x, ctest3: %02x\n",
+		np->rv_dmode, np->rv_dcntl, np->rv_ctest3);
+	  printf ("\tdmode: %02x/%02x, dcntl: %02x/%02x, ctest3: %02x/%02x\n",
+		burstlen | ERL | ERMP | BOF, INB (nc_dmode),
+		CLSE | PFEN | NOCOM, INB (nc_dcntl),
+		WRIE, INB (nc_ctest3));
+	}
+
 	/*
 	**	Reinitialize usrsync.
 	**	Have to renegotiate synch mode.
@@ -4728,8 +4764,6 @@
 
 	u_long minsync = tp->usrsync;
 
-	if (minsync < 25) minsync=25;
-
 	/*
 	**	if not scsi 2
 	**	don't believe FAST!
@@ -4753,7 +4787,7 @@
 		minsync = 255;
 
 	tp->minsync = minsync;
-	tp->maxoffs = (minsync<255 ? 8 : 0);
+	tp->maxoffs = (minsync<255 ? np->maxoffs : 0);
 
 	/*
 	**	period=0: has to negotiate sync transfer
@@ -4789,7 +4823,7 @@
 	assert (target == (xp->sc_link->target & 0x0f));
 
 	tp = &np->target[target];
-	tp->period= sxfer&0xf ? ((sxfer>>5)+4) * np->ns_sync : 0xffff;
+	tp->period= sxfer&0x1f ? ((sxfer>>5)+4) * np->ns_sync : 0xffff;
 
 	if (tp->sval == sxfer) return;
 	tp->sval = sxfer;
@@ -4798,15 +4832,15 @@
 	**	Bells and whistles   ;-)
 	*/
 	PRINT_ADDR(xp);
-	if (sxfer & 0x0f) {
+	if (sxfer & 0x1f) {
+		unsigned f10 = 10000 << (tp->widedone ? tp->widedone -1 : 0);
+		unsigned mb10 = (f10 + tp->period/2) / tp->period;
 		/*
 		**  Disable extended Sreq/Sack filtering
 		*/
 		if (tp->period <= 200) OUTB (nc_stest2, 0);
-		printf ("%s%dns (%d Mb/sec) offset %d.\n",
-			tp->period<200 ? "FAST SCSI-2 ":"",
-			tp->period, (1000+tp->period/2)/tp->period,
-			sxfer & 0x0f);
+		printf ("%d.%d MB/s (%d ns, offset %d)\n",
+			mb10 / 10, mb10 % 10, tp->period, sxfer & 0x1f);
 	} else  printf ("asynchronous.\n");
 
 	/*
@@ -4857,9 +4891,9 @@
 	*/
 	PRINT_ADDR(xp);
 	if (scntl3 & EWS)
-		printf ("WIDE SCSI (16 bit) enabled.\n");
+		printf ("WIDE SCSI (16 bit) enabled");
 	else
-		printf ("WIDE SCSI disabled.\n");
+		printf ("WIDE SCSI disabled");
 
 	/*
 	**	set actual value and sync_status
@@ -5055,30 +5089,11 @@
 			**      If there are no requests, the script
 			**      processor will sleep on SEL_WAIT_RESEL.
 			**      But we have to check whether it died.
-			**      Let's wake it up.
+			**      Let's try to wake it up.
 			*/
 			OUTB (nc_istat, SIGP);
 		};
 
-#ifdef undef
-		if (np->latetime>4) {
-			/*
-			**	Although we tried to wake it up,
-			**	the script processor didn't respond.
-			**
-			**	May be a target is hanging,
-			**	or another initator lets a tape device
-			**	rewind with disconnect disabled :-(
-			**
-			**	We won't accept that.
-			*/
-			if (INB (nc_sbcl) & CBSY)
-				OUTB (nc_scntl1, CRST);
-			DELAY (1000);
-			ncr_init (np, "ncr dead ?", HS_TIMEOUT);
-			np->heartbeat = thistime;
-		};
-#endif
 		/*----------------------------------------------------
 		**
 		**	handle ccb timeouts
@@ -5182,8 +5197,8 @@
 	**	Never test for an error condition you don't know how to handle.
 	*/
 
-	dstat = INB (nc_dstat);
-	sist  = INW (nc_sist) ;
+ 	sist  = (istat & SIP) ? INW (nc_sist)  : 0;
+	dstat = (istat & DIP) ? INB (nc_dstat) : 0;
 	np->profile.num_int++;
 
 	if (DEBUG_FLAGS & DEBUG_TINY)
@@ -5344,7 +5359,8 @@
 	     !(dstat & DFE)) {
 		printf ("%s: have to clear fifos.\n", ncr_name (np));
 		OUTB (nc_stest3, TE|CSF);	/* clear scsi fifo */
-		OUTB (nc_ctest3, CLF);		/* clear dma fifo  */
+		OUTB (nc_ctest3, np->rv_ctest3 | CLF);
+						/* clear dma fifo  */
 	}
 
 	/*----------------------------------------
@@ -5392,7 +5408,7 @@
 			**	It's an early reconnect.
 			**	Let's continue ...
 			*/
-			OUTB (nc_dcntl, (STD|NOCOM));
+			OUTB (nc_dcntl, np->rv_dcntl | STD);
 			/*
 			**	info message
 			*/
@@ -5417,7 +5433,7 @@
 	if ((dstat & SSI) &&
 		!(sist  & (STO|GEN|HTH|MA|SGE|UDC|RST|PAR)) &&
 		!(dstat & (MDPE|BF|ABRT|SIR|IID))) {
-		OUTB (nc_dcntl, (STD|NOCOM));
+		OUTB (nc_dcntl, np->rv_dcntl | STD);
 		return;
 	};
 
@@ -5430,7 +5446,8 @@
 */
 
 	if (sist & SGE) {
-		OUTB (nc_ctest3, CLF);		/* clear scsi offsets */
+		/* clear scsi offsets */
+		OUTB (nc_ctest3, np->rv_ctest3 | CLF);
 	}
 
 	/*
@@ -5590,8 +5607,8 @@
 		if (ss2 & OLF1) rest++;
 		if (ss2 & ORF1) rest++;
 	};
-	OUTB (nc_ctest3, CLF   );	/* clear dma fifo  */
-	OUTB (nc_stest3, TE|CSF);	/* clear scsi fifo */
+	OUTB (nc_ctest3, np->rv_ctest3 | CLF);	/* clear dma fifo  */
+	OUTB (nc_stest3, TE|CSF);		/* clear scsi fifo */
 
 	/*
 	**	locate matching cp
@@ -5682,7 +5699,7 @@
 			cmd&7, sbcl&7, (unsigned)olen,
 			(unsigned)oadr, (unsigned)rest);
 
-		OUTB (nc_dcntl, (STD|NOCOM));
+		OUTB (nc_dcntl, np->rv_dcntl | STD);
 		return;
 	};
 
@@ -6325,7 +6342,7 @@
 	};
 
 out:
-	OUTB (nc_dcntl, (STD|NOCOM));
+	OUTB (nc_dcntl, np->rv_dcntl | STD);
 }
 
 /*==========================================================
@@ -6342,7 +6359,9 @@
 {
 	lcb_p lp;
 	ccb_p cp = (ccb_p) 0;
+	int oldspl;
 
+	oldspl = splhigh();
 	/*
 	**	Lun structure available ?
 	*/
@@ -6355,7 +6374,9 @@
 		**	Look for free CCB
 		*/
 
-		while (cp && cp->magic) cp = cp->next_ccb;
+		while (cp && cp->magic) {
+			cp = cp->next_ccb;
+		}
 	}
 
 	/*
@@ -6374,10 +6395,13 @@
 			break;
 	};
 
-	if (cp->magic)
+	if (cp->magic) {
+		splx(oldspl);
 		return ((ccb_p) 0);
+	}
 
 	cp->magic = 1;
+	splx(oldspl);
 	return (cp);
 }
 
@@ -6818,6 +6842,9 @@
 	*/
 	if (pc != NCB_SCRIPT_PHYS (np, snoopend)+8) {
 		printf ("CACHE TEST FAILED: script execution failed.\n");
+		printf ("\tstart=%08lx, pc=%08lx, end=%08lx\n", 
+			NCB_SCRIPT_PHYS (np, snooptest), pc,
+			NCB_SCRIPT_PHYS (np, snoopend) +8);
 		return (0x40);
 	};
 	/*
@@ -7068,8 +7095,6 @@
 		}
 	}
 
-	np->ns_sync   = 25;
-	np->ns_async  = 50;
 	np->rv_scntl3 = ((scntl3 & 0x7) << 4) -0x20 + (scntl3 & 0x7);
 
 	if (bootverbose) {
@@ -7077,6 +7102,117 @@
 			scntl3, np->rv_scntl3);
 	}
 }
+
+/*=========================================================================*/
+
+#ifdef NCR_TEKRAM_EEPROM
+
+struct tekram_eeprom_dev {
+  u_char	devmode;
+#define	TKR_PARCHK	0x01
+#define	TKR_TRYSYNC	0x02
+#define	TKR_ENDISC	0x04
+#define	TKR_STARTUNIT	0x08
+#define	TKR_USETAGS	0x10
+#define	TKR_TRYWIDE	0x20
+  u_char	syncparam;	/* max. sync transfer rate (table ?) */
+  u_char	filler1;
+  u_char	filler2;
+};
+
+
+struct tekram_eeprom {
+  struct tekram_eeprom_dev 
+		dev[16];
+  u_char	adaptid;
+  u_char	adaptmode;
+#define	TKR_ADPT_GT2DRV	0x01
+#define	TKR_ADPT_GT1GB	0x02
+#define	TKR_ADPT_RSTBUS	0x04
+#define	TKR_ADPT_ACTNEG	0x08
+#define	TKR_ADPT_NOSEEK	0x10
+#define	TKR_ADPT_MORLUN	0x20
+  u_char	delay;		/* unit ? (table ???) */
+  u_char	tags;		/* use 4 times as many ... */
+  u_char	filler[60];
+};
+
+static void
+tekram_write_bit (ncb_p np, int bit)
+{
+	u_char val = 0x10 + ((bit & 1) << 1);
+
+	DELAY(10);
+	OUTB (nc_gpreg, val);
+	DELAY(10);
+	OUTB (nc_gpreg, val | 0x04);
+	DELAY(10);
+	OUTB (nc_gpreg, val);
+	DELAY(10);
+}
+
+static int
+tekram_read_bit (ncb_p np)
+{
+	OUTB (nc_gpreg, 0x10);
+	DELAY(10);
+	OUTB (nc_gpreg, 0x14);
+	DELAY(10);
+	return INB (nc_gpreg) & 1;
+}
+
+static u_short
+read_tekram_eeprom_reg (ncb_p np, int reg)
+{
+	int bit;
+	u_short result = 0;
+	int cmd = 0x80 | reg;
+
+	OUTB (nc_gpreg, 0x10);
+
+	tekram_write_bit (np, 1);
+	for (bit = 7; bit >= 0; bit--)
+	{
+		tekram_write_bit (np, cmd >> bit);
+	}
+
+	for (bit = 0; bit < 16; bit++)
+	{
+		result <<= 1;
+		result |= tekram_read_bit (np);
+	}
+
+	OUTB (nc_gpreg, 0x00);
+	return result;
+}
+
+static int 
+read_tekram_eeprom(ncb_p np, struct tekram_eeprom *buffer)
+{
+	u_short *p = (u_short *) buffer;
+	u_short sum = 0;
+	int i;
+
+	if (INB (nc_gpcntl) != 0x09)
+	{
+		return 0;
+        }
+	for (i = 0; i < 64; i++)
+	{
+		u_short val;
+if((i&0x0f) == 0) printf ("%02x:", i*2);
+		val = read_tekram_eeprom_reg (np, i);
+		if (p)
+			*p++ = val;
+		sum += val;
+if((i&0x01) == 0x00) printf (" ");
+		printf ("%02x%02x", val & 0xff, (val >> 8) & 0xff);
+if((i&0x0f) == 0x0f) printf ("\n");
+	}
+printf ("Sum = %04x\n", sum);
+	return sum == 0x1234;
+}
+#endif /* NCR_TEKRAM_EEPROM */
 
 /*=========================================================================*/
 #endif /* KERNEL */
--- /usr/src/sys/dev/pci/ncr_reg.h	Thu Nov 21 06:20:18 1996
+++ ncr_reg.h	Sat Dec 21 14:40:53 1996
@@ -172,12 +172,18 @@
 	#define   CSIGP   0x40
 
 /*1b*/  U_INT8    nc_ctest3;
-	#define   CLF	  0x04	/* clear scsi fifo		    */
+        #define   FLF     0x08  /* cmd: flush dma fifo              */
+        #define   CLF	  0x04	/* cmd: clear dma fifo		    */
+        #define   FM      0x02  /* mod: fetch pin mode              */
+        #define   WRIE    0x01  /* mod: write and invalidate enable */
 
 /*1c*/  U_INT32   nc_temp;	/* ### Temporary stack              */
 
 /*20*/	U_INT8	  nc_dfifo;
 /*21*/  U_INT8    nc_ctest4;
+        #define   BDIS    0x80  /* mod: burst disable               */
+        #define   MPEE    0x08  /* mod: master parity error enable  */
+
 /*22*/  U_INT8    nc_ctest5;
 /*23*/  U_INT8    nc_ctest6;
 
@@ -188,12 +194,23 @@
 /*34*/  U_INT32   nc_scratcha;  /* ??? Temporary register a         */
 
 /*38*/  U_INT8    nc_dmode;
+        #define   BL_2    0x80  /* mod: burst length shift value +2 */
+        #define   BL_1    0x40  /* mod: burst length shift value +1 */
+        #define   ERL     0x08  /* mod: enable read line            */
+        #define   ERMP    0x04  /* mod: enable read multiple        */
+        #define   BOF     0x02  /* mod: burst op code fetch         */
+
 /*39*/  U_INT8    nc_dien;
 /*3a*/  U_INT8    nc_dwt;
 
 /*3b*/  U_INT8    nc_dcntl;	/* --> Script execution control     */
+        #define   CLSE    0x80  /* mod: cache line size enable      */
+        #define   PFF     0x40  /* cmd: pre-fetch flush             */
+        #define   PFEN    0x20  /* mod: pre-fetch enable            */
         #define   SSM     0x10  /* mod: single step mode            */
+        #define   IRQM    0x08  /* mod: irq mode (1 = totem pole !) */
         #define   STD     0x04  /* cmd: start dma mode              */
+        #define   IRQD    0x02  /* mod: irq disable                 */
 	#define	  NOCOM   0x01	/* cmd: protect sfbr while reselect */
 
 /*3c*/  U_INT32   nc_adder;