Date: Wed, 27 May 1998 21:42:12 +0100
From: Richard Hirst <richard@sleepie.demon.co.uk>
To: linux-m68k@lists.linux-m68k.org
Subject: L68K: 2.1.101 patches for VME
Sender: owner-linux-m68k@phil.uni-sb.de

Patches for 2.1.101 for the following:

Add support for the BVME4000 and BVME6000 boards.

Some tidy ups for MVME boards.

Add RTC support for the MVME boards.

Set VM_IO in vm_flags for /dev/memnc, so we dont try and add mmap-ed
areas of /dev/memnc to a core file.

Added a CONFIG_ADVANCED_CPU option, CONFIG_060_WRITETHROUGH, which makes
68060 systems use write-through caching for supervisor accesses.  This
is a work-a-round for the problems with 53c7xx driver and my modified
apricot.c ethernet driver, until such time as the drivers are fixed to
handle 060 cache coherency.  It doesn't have much impact on performance
when enabled as it only affects supervisor accesses.  I have run my 68060
with 53c710 for months without problems this way.

The major item yet to integrate for the current VME ports is the ethernet
driver.  I have added m68k support to apricot.c, but havn't yet found
anyone to test it on i386... so if you have an apricot PC in the cupboard,
let me know!  Ethernet support is included in the kernels from my web
site.

Richard.    <http://www.sleepie.demon.co.uk/linuxvme>



diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/Makefile linuxvme-2.1.101/arch/m68k/Makefile
--- linux68k-2.1.101/arch/m68k/Makefile	Wed May 13 14:06:46 1998
+++ linuxvme-2.1.101/arch/m68k/Makefile	Fri May 22 19:29:08 1998
@@ -79,6 +79,11 @@
 SUBDIRS := $(SUBDIRS) arch/m68k/mvme16x
 endif
 
+ifdef CONFIG_BVME6000
+CORE_FILES := $(CORE_FILES) arch/m68k/bvme6000/bvme6000.o
+SUBDIRS := $(SUBDIRS) arch/m68k/bvme6000
+endif
+
 ifdef CONFIG_M68040
 CORE_FILES := $(CORE_FILES) arch/m68k/fpsp040/fpsp.o
 SUBDIRS := $(SUBDIRS) arch/m68k/fpsp040
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/bvme6000/Makefile linuxvme-2.1.101/arch/m68k/bvme6000/Makefile
--- linux68k-2.1.101/arch/m68k/bvme6000/Makefile	Thu Jan  1 00:00:00 1970
+++ linuxvme-2.1.101/arch/m68k/bvme6000/Makefile	Fri May 22 19:29:08 1998
@@ -0,0 +1,14 @@
+#
+# Makefile for Linux arch/m68k/bvme6000 source directory
+#
+# 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 definitions are now in the main makefile...
+
+O_TARGET := bvme6000.o
+O_OBJS   := config.o bvmeints.o rtc.o
+#OX_OBJS = ksyms.o
+
+include $(TOPDIR)/Rules.make
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/bvme6000/bvmeints.c linuxvme-2.1.101/arch/m68k/bvme6000/bvmeints.c
--- linux68k-2.1.101/arch/m68k/bvme6000/bvmeints.c	Thu Jan  1 00:00:00 1970
+++ linuxvme-2.1.101/arch/m68k/bvme6000/bvmeints.c	Tue May 26 20:22:34 1998
@@ -0,0 +1,154 @@
+/*
+ * arch/m68k/bvme6000/bvmeints.c
+ *
+ * Copyright (C) 1997 Richard Hirst [richard@sleepie.demon.co.uk]
+ *
+ * based on amiints.c -- Amiga Linux interrupt handling code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+
+static void bvme6000_defhand (int irq, void *dev_id, struct pt_regs *fp);
+
+/*
+ * This should ideally be 4 elements only, for speed.
+ */
+
+static struct {
+	void		(*handler)(int, void *, struct pt_regs *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+	unsigned	count;
+} irq_tab[256];
+
+/*
+ * void bvme6000_init_IRQ (void)
+ *
+ * Parameters:	None
+ *
+ * Returns:	Nothing
+ *
+ * This function is called during kernel startup to initialize
+ * the bvme6000 IRQ handling routines.
+ */
+
+void bvme6000_init_IRQ (void)
+{
+	int i;
+
+	for (i = 0; i < 256; i++) {
+		irq_tab[i].handler = bvme6000_defhand;
+		irq_tab[i].flags = IRQ_FLG_STD;
+		irq_tab[i].dev_id = NULL;
+		irq_tab[i].devname = NULL;
+		irq_tab[i].count = 0;
+	}
+}
+
+int bvme6000_request_irq(unsigned int irq,
+		void (*handler)(int, void *, struct pt_regs *),
+                unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq > 255) {
+		printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+#if 0
+	/* Nothing special about auto-vectored devices for the BVME6000,
+	 * but treat it specially to avoid changes elsewhere.
+	 */
+
+	if (irq >= VEC_INT1 && irq <= VEC_INT7)
+		return sys_request_irq(irq - VEC_SPUR, handler, flags,
+						devname, dev_id);
+#endif
+	if (!(irq_tab[irq].flags & IRQ_FLG_STD)) {
+		if (irq_tab[irq].flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, irq_tab[irq].devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, irq_tab[irq].devname);
+			return -EBUSY;
+		}
+	}
+	irq_tab[irq].handler = handler;
+	irq_tab[irq].flags   = flags;
+	irq_tab[irq].dev_id  = dev_id;
+	irq_tab[irq].devname = devname;
+	return 0;
+}
+
+void bvme6000_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq > 255) {
+		printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+#if 0
+	if (irq >= VEC_INT1 && irq <= VEC_INT7) {
+		sys_free_irq(irq - VEC_SPUR, dev_id);
+		return;
+	}
+#endif
+	if (irq_tab[irq].dev_id != dev_id)
+		printk("%s: Removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, irq_tab[irq].devname);
+
+	irq_tab[irq].handler = bvme6000_defhand;
+	irq_tab[irq].flags   = IRQ_FLG_STD;
+	irq_tab[irq].dev_id  = NULL;
+	irq_tab[irq].devname = NULL;
+}
+
+void bvme6000_process_int (unsigned long vec, struct pt_regs *fp)
+{
+	if (vec > 255)
+		panic ("bvme6000_process_int: Illegal vector %ld", vec);
+	irq_tab[vec].count++;
+	irq_tab[vec].handler(vec, irq_tab[vec].dev_id, fp);
+}
+
+int bvme6000_get_irq_list (char *buf)
+{
+	int i, len = 0;
+
+	for (i = 0; i < 256; i++) {
+		if (irq_tab[i].count)
+			len += sprintf (buf+len, "Vec 0x%02x: %8d  %s\n",
+			    i, irq_tab[i].count,
+			    irq_tab[i].devname ? irq_tab[i].devname : "free");
+	}
+	return len;
+}
+
+
+static void bvme6000_defhand (int irq, void *dev_id, struct pt_regs *fp)
+{
+	printk ("Unknown interrupt 0x%02x\n", irq);
+}
+
+void bvme6000_enable_irq (unsigned int irq)
+{
+}
+
+
+void bvme6000_disable_irq (unsigned int irq)
+{
+}
+
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/bvme6000/config.c linuxvme-2.1.101/arch/m68k/bvme6000/config.c
--- linux68k-2.1.101/arch/m68k/bvme6000/config.c	Thu Jan  1 00:00:00 1970
+++ linuxvme-2.1.101/arch/m68k/bvme6000/config.c	Fri May 22 19:29:09 1998
@@ -0,0 +1,453 @@
+/*
+ *  arch/m68k/bvme6000/config.c
+ *
+ *  Copyright (C) 1997 Richard Hirst [richard@sleepie.demon.co.uk]
+ *
+ * Based on:
+ *
+ *  linux/amiga/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/kd.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <linux/major.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/bvme6000hw.h>
+
+extern void bvme6000_process_int (int level, struct pt_regs *regs);
+extern void bvme6000_init_IRQ (void);
+extern void bvme6000_free_irq (unsigned int, void *);
+extern int  bvme6000_get_irq_list (char *);
+extern void bvme6000_enable_irq (unsigned int);
+extern void bvme6000_disable_irq (unsigned int);
+static void bvme6000_get_model(char *model);
+static int  bvme6000_get_hardware_list(char *buffer);
+extern int  bvme6000_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
+extern void bvme6000_sched_init(void (*handler)(int, void *, struct pt_regs *));
+extern int  bvme6000_keyb_init(void);
+extern int  bvme6000_kbdrate (struct kbd_repeat *);
+extern unsigned long bvme6000_gettimeoffset (void);
+extern void bvme6000_gettod (int *year, int *mon, int *day, int *hour,
+                           int *min, int *sec);
+extern int bvme6000_hwclk (int, struct hwclk_time *);
+extern int bvme6000_set_clock_mmss (unsigned long);
+extern void bvme6000_check_partition (struct gendisk *hd, unsigned int dev);
+extern void bvme6000_mksound( unsigned int count, unsigned int ticks );
+extern void bvme6000_reset (void);
+extern void bvme6000_waitbut(void);
+void bvme6000_set_vectors (void);
+
+static unsigned char bcd2bin (unsigned char b);
+static unsigned char bin2bcd (unsigned char b);
+
+/* Save tick handler routine pointer, will point to do_timer() in
+ * kernel/sched.c, called via bvme6000_process_int() */
+
+static void (*tick_handler)(int, void *, struct pt_regs *);
+
+int bvme6000_kbdrate (struct kbd_repeat *k)
+{
+	return 0;
+}
+
+void bvme6000_mksound( unsigned int count, unsigned int ticks )
+{
+}
+
+void bvme6000_reset()
+{
+	volatile PitRegsPtr pit = (PitRegsPtr)BVME_PIT_BASE;
+
+	printk ("\r\n\nCalled bvme6000_reset\r\n"
+			"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r");
+	/* The string of returns is to delay the reset until the whole
+	 * message is output. */
+	/* Enable the watchdog, via PIT port C bit 4 */
+
+	pit->pcddr	|= 0x10;	/* WDOG enable */
+
+	while(1)
+		;
+}
+
+static void bvme6000_get_model(char *model)
+{
+    /* XXX Need to detect if BVME4000 or BVME6000 */
+    sprintf(model, "BVME6000");
+}
+
+
+/* No hardware options on BVME6000? */
+
+static int bvme6000_get_hardware_list(char *buffer)
+{
+    *buffer = '\0';
+    return 0;
+}
+
+
+__initfunc(void config_bvme6000(void))
+{
+    volatile PitRegsPtr pit = (PitRegsPtr)BVME_PIT_BASE;
+
+#if 0
+    /* Call bvme6000_set_vectors() so ABORT will work, along with BVMBug
+     * debugger.  Note trap_init() will splat the abort vector, but
+     * bvme6000_init_IRQ() will put it back again.  Hopefully. */
+
+    bvme6000_set_vectors();
+#endif
+
+    mach_sched_init      = bvme6000_sched_init;
+    mach_keyb_init       = bvme6000_keyb_init;
+    mach_kbdrate         = bvme6000_kbdrate;
+    mach_init_IRQ        = bvme6000_init_IRQ;
+    mach_gettimeoffset   = bvme6000_gettimeoffset;
+    mach_gettod  	 = bvme6000_gettod;
+    mach_hwclk           = bvme6000_hwclk;
+    mach_set_clock_mmss	 = bvme6000_set_clock_mmss;
+/*  mach_mksound         = bvme6000_mksound; */
+    mach_reset		 = bvme6000_reset;
+    mach_free_irq	 = bvme6000_free_irq;
+    mach_process_int	 = bvme6000_process_int;
+    mach_get_irq_list	 = bvme6000_get_irq_list;
+    mach_request_irq	 = bvme6000_request_irq;
+    enable_irq		 = bvme6000_enable_irq;
+    disable_irq          = bvme6000_disable_irq;
+    mach_get_model       = bvme6000_get_model;
+    mach_get_hardware_list = bvme6000_get_hardware_list;
+
+    printk ("Board is %sconfigured as a System Controller\n",
+		*config_reg_ptr & BVME_CONFIG_SW1 ? "" : "not ");
+
+    /* Now do the PIT configuration */
+
+    pit->pgcr	= 0x00;	/* Unidirectional 8 bit, no handshake for now */
+    pit->psrr	= 0x18;	/* PIACK and PIRQ fucntions enabled */
+    pit->pacr	= 0x00;	/* Sub Mode 00, H2 i/p, no DMA */
+    pit->padr	= 0x00;	/* Just to be tidy! */
+    pit->paddr	= 0x00;	/* All inputs for now (safest) */
+    pit->pbcr	= 0x80;	/* Sub Mode 1x, H4 i/p, no DMA */
+    pit->pbdr	= 0xbc | (*config_reg_ptr & BVME_CONFIG_SW1 ? 0 : 0x40);
+			/* PRI, SYSCON?, Level3, SCC clks from xtal */
+    pit->pbddr	= 0xf3;	/* Mostly outputs */
+    pit->pcdr	= 0x01;	/* PA transceiver disabled */
+    pit->pcddr	= 0x03;	/* WDOG disable */
+}
+
+
+void bvme6000_abort_int (int irq, void *dev_id, struct pt_regs *fp)
+{
+        unsigned long *new = (unsigned long *)vectors;
+        unsigned long *old = (unsigned long *)0xf8000000;;
+
+        /* Wait for button release */
+	while (*config_reg_ptr & BVME_ABORT_STATUS)
+		;
+
+        *(new+4) = *(old+4);            /* Illegal instruction */
+        *(new+9) = *(old+9);            /* Trace */
+        *(new+47) = *(old+47);          /* Trap #15 */
+        *(new+0x1f) = *(old+0x1f);      /* ABORT switch */
+}
+
+
+static void bvme6000_timer_int (int irq, void *dev_id, struct pt_regs *fp)
+{
+    volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
+    unsigned char msr = rtc->msr & 0xc0;
+
+    rtc->msr = msr | 0x20;		/* Ack the interrupt */
+
+    tick_handler(irq, dev_id, fp);
+}
+
+/*
+ * Set up the RTC timer 1 to mode 2, so T1 output toggles every 5ms
+ * (40000 x 125ns).  It will interrupt every 10ms, when T1 goes low.
+ * So, when reading the elapsed time, you should read timer1,
+ * subtract it from 39999, and then add 40000 if T1 is high.
+ * That gives you the number of 125ns ticks in to the 10ms period,
+ * so divide by 8 to get the microsecond result.
+ */
+
+void bvme6000_sched_init (void (*timer_routine)(int, void *, struct pt_regs *))
+{
+    volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
+    unsigned char msr = rtc->msr & 0xc0;
+
+    rtc->msr = 0;	/* Ensure timer registers accessible */
+
+    tick_handler = timer_routine;
+    if (request_irq(BVME_IRQ_RTC, bvme6000_timer_int, 0,
+				"timer", bvme6000_timer_int))
+	panic ("Couldn't register timer int");
+
+    rtc->t1cr_omr = 0x04;	/* Mode 2, ext clk */
+    rtc->t1msb = 39999 >> 8;
+    rtc->t1lsb = 39999 & 0xff;
+    rtc->irr_icr1 &= 0xef;	/* Route timer 1 to INTR pin */
+    rtc->msr = 0x40;		/* Access int.cntrl, etc */
+    rtc->pfr_icr0 = 0x80;	/* Just timer 1 ints enabled */
+    rtc->irr_icr1 = 0;
+    rtc->t1cr_omr = 0x0a;	/* INTR+T1 active lo, push-pull */
+    rtc->t0cr_rtmr &= 0xdf;	/* Stop timers in standby */
+    rtc->msr = 0;		/* Access timer 1 control */
+    rtc->t1cr_omr = 0x05;	/* Mode 2, ext clk, GO */
+
+    rtc->msr = msr;
+
+    if (request_irq(BVME_IRQ_ABORT, bvme6000_abort_int, 0,
+				"abort", bvme6000_abort_int))
+	panic ("Couldn't register abort int");
+}
+
+
+/* This is always executed with interrupts disabled.  */
+
+/*
+ * NOTE:  Don't accept any readings within 5us of rollover, as
+ * the T1INT bit may be a little slow getting set.  There is also
+ * a fault in the chip, meaning that reads may produce invalid
+ * results...
+ */
+
+unsigned long bvme6000_gettimeoffset (void)
+{
+    volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
+    volatile PitRegsPtr pit = (PitRegsPtr)BVME_PIT_BASE;
+    unsigned char msr = rtc->msr & 0xc0;
+    unsigned char t1int, t1op;
+    unsigned long v = 800000, ov;
+
+    rtc->msr = 0;	/* Ensure timer registers accessible */
+
+    do {
+	ov = v;
+	t1int = rtc->msr & 0x20;
+	t1op  = pit->pcdr & 0x04;
+	rtc->t1cr_omr |= 0x40;		/* Latch timer1 */
+	v = rtc->t1msb << 8;		/* Read timer1 */
+	v |= rtc->t1lsb;		/* Read timer1 */
+    } while (t1int != (rtc->msr & 0x20) ||
+		t1op != (pit->pcdr & 0x04) ||
+			abs(ov-v) > 80 ||
+				v > 39960);
+
+    v = 39999 - v;
+    if (!t1op)				/* If in second half cycle.. */
+	v += 40000;
+    v /= 8;				/* Convert ticks to microseconds */
+    if (t1int)
+	v += 10000;			/* Int pending, + 10ms */
+    rtc->msr = msr;
+
+    return v;
+}
+
+extern void bvme6000_gettod (int *year, int *mon, int *day, int *hour,
+                           int *min, int *sec)
+{
+	volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
+	unsigned char msr = rtc->msr & 0xc0;
+
+	rtc->msr = 0;		/* Ensure clock accessible */
+
+	do {	/* Loop until we get a reading with a stable seconds field */
+		*sec = bcd2bin (rtc->bcd_sec);
+		*min = bcd2bin (rtc->bcd_min);
+		*hour = bcd2bin (rtc->bcd_hr);
+		*day = bcd2bin (rtc->bcd_dom);
+		*mon = bcd2bin (rtc->bcd_mth);
+		*year = bcd2bin (rtc->bcd_year);
+	} while (bcd2bin (rtc->bcd_sec) != *sec);
+
+	rtc->msr = msr;
+}
+
+static unsigned char bcd2bin (unsigned char b)
+{
+	return ((b>>4)*10 + (b&15));
+}
+
+static unsigned char bin2bcd (unsigned char b)
+{
+	return (((b/10)*16) + (b%10));
+}
+
+
+/*
+ * Looks like op is non-zero for setting the clock, and zero for
+ * reading the clock.
+ *
+ *  struct hwclk_time {
+ *         unsigned        sec;       0..59
+ *         unsigned        min;       0..59
+ *         unsigned        hour;      0..23
+ *         unsigned        day;       1..31
+ *         unsigned        mon;       0..11
+ *         unsigned        year;      00...
+ *         int             wday;      0..6, 0 is Sunday, -1 means unknown/don't set
+ * };
+ */
+
+int bvme6000_hwclk(int op, struct hwclk_time *t)
+{
+	volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
+	unsigned char msr = rtc->msr & 0xc0;
+
+	rtc->msr = 0x40;	/* Ensure clock and real-time-mode-register
+				 * are accessible */
+	if (op)
+	{	/* Write.... */
+		rtc->t0cr_rtmr = t->year%4;
+		rtc->bcd_tenms = 0;
+		rtc->bcd_sec = bin2bcd(t->sec);
+		rtc->bcd_min = bin2bcd(t->min);
+		rtc->bcd_hr  = bin2bcd(t->hour);
+		rtc->bcd_dom = bin2bcd(t->day);
+		rtc->bcd_mth = bin2bcd(t->mon + 1);
+		rtc->bcd_year = bin2bcd(t->year%100);
+		if (t->wday >= 0)
+			rtc->bcd_dow = bin2bcd(t->wday+1);
+		rtc->t0cr_rtmr = t->year%4 | 0x08;
+	}
+	else
+	{	/* Read....  */
+		do {
+			t->sec =  bcd2bin(rtc->bcd_sec);
+			t->min =  bcd2bin(rtc->bcd_min);
+			t->hour = bcd2bin(rtc->bcd_hr);
+			t->day =  bcd2bin(rtc->bcd_dom);
+			t->mon =  bcd2bin(rtc->bcd_mth)-1;
+			t->year = bcd2bin(rtc->bcd_year);
+			if (t->year < 70)
+				t->year += 100;
+			t->wday = bcd2bin(rtc->bcd_dow)-1;
+		} while (t->sec != bcd2bin(rtc->bcd_sec));
+	}
+
+	rtc->msr = msr;
+
+	return 0;
+}
+
+/*
+ * Set the minutes and seconds from seconds value 'nowtime'.  Fail if
+ * clock is out by > 30 minutes.  Logic lifted from atari code.
+ * Algorithm is to wait for the 10ms register to change, and then to
+ * wait a short while, and then set it.
+ */
+
+int bvme6000_set_clock_mmss (unsigned long nowtime)
+{
+	int retval = 0;
+	short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+	unsigned char rtc_minutes, rtc_tenms;
+	volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
+	unsigned char msr = rtc->msr & 0xc0;
+	unsigned long flags;
+	volatile int i;
+
+	rtc->msr = 0;		/* Ensure clock accessible */
+	rtc_minutes = bcd2bin (rtc->bcd_min);
+
+	if ((rtc_minutes < real_minutes
+		? real_minutes - rtc_minutes
+			: rtc_minutes - real_minutes) < 30)
+	{
+		save_flags(flags);
+		cli();
+		rtc_tenms = rtc->bcd_tenms;
+		while (rtc_tenms == rtc->bcd_tenms)
+			;
+		for (i = 0; i < 1000; i++)
+			;
+		rtc->bcd_min = bin2bcd(real_minutes);
+		rtc->bcd_sec = bin2bcd(real_seconds);
+		restore_flags(flags);
+	}
+	else
+		retval = -1;
+
+	rtc->msr = msr;
+
+	return retval;
+}
+
+
+int bvme6000_keyb_init (void)
+{
+	return 0;
+}
+
+/*-------------------  Serial console stuff ------------------------*/
+
+static void bvme_scc_write(struct console *co, const char *str, unsigned cnt);
+
+
+void bvme6000_init_console_port (struct console *co, int cflag)
+{
+        co->write = bvme_scc_write;
+}
+
+
+static void scc_delay (void)
+{
+        int n;
+        char i;
+
+        for (n = 0; n < 20; n++)
+                i = *(volatile char *)0;
+}
+
+static void scc_write (char ch)
+{
+        volatile char *p = (volatile char *)BVME_SCC_A_ADDR;
+
+        do {
+                scc_delay();
+        }
+        while (!(*p & 4));
+        scc_delay();
+        *p = 8;
+        scc_delay();
+        *p = ch;
+}
+
+
+static void bvme_scc_write (struct console *co, const char *str, unsigned count)
+{
+        unsigned long   flags;
+
+        save_flags(flags);
+        cli();
+
+        while (count--)
+        {
+                if (*str == '\n')
+                        scc_write ('\r');
+                scc_write (*str++);
+        }
+        restore_flags(flags);
+}
+
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/bvme6000/rtc.c linuxvme-2.1.101/arch/m68k/bvme6000/rtc.c
--- linux68k-2.1.101/arch/m68k/bvme6000/rtc.c	Thu Jan  1 00:00:00 1970
+++ linuxvme-2.1.101/arch/m68k/bvme6000/rtc.c	Fri May 22 19:29:09 1998
@@ -0,0 +1,175 @@
+/*
+ *	Real Time Clock interface for Linux on the BVME6000
+ *
+ * Based on the PC driver by Paul Gortmaker.
+ */
+
+#define RTC_VERSION		"1.00"
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/miscdevice.h>
+#include <linux/malloc.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/mc146818rtc.h>	/* For struct rtc_time and ioctls, etc */
+#include <asm/bvme6000hw.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/setup.h>
+
+/*
+ *	We sponge a minor off of the misc major. No need slurping
+ *	up another valuable major dev number for this. If you add
+ *	an ioctl, make sure you don't conflict with SPARC's RTC
+ *	ioctls.
+ */
+
+#define BCD2BIN(val) (((val)&15) + ((val)>>4)*10)
+#define BIN2BCD(val) ((((val)/10)<<4) + (val)%10)
+
+static unsigned char days_in_mo[] =
+{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+static char rtc_status = 0;
+
+static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		     unsigned long arg)
+{
+	volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
+	unsigned char msr;
+	unsigned long flags;
+	struct rtc_time wtime; 
+
+	switch (cmd) {
+	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
+	{
+		save_flags(flags);
+		cli();
+		/* Ensure clock and real-time-mode-register are accessible */
+		msr = rtc->msr & 0xc0;
+		rtc->msr = 0x40;
+		do {
+			wtime.tm_sec =  BCD2BIN(rtc->bcd_sec);
+			wtime.tm_min =  BCD2BIN(rtc->bcd_min);
+			wtime.tm_hour = BCD2BIN(rtc->bcd_hr);
+			wtime.tm_mday =  BCD2BIN(rtc->bcd_dom);
+			wtime.tm_mon =  BCD2BIN(rtc->bcd_mth)-1;
+			wtime.tm_year = BCD2BIN(rtc->bcd_year);
+			if (wtime.tm_year < 70)
+				wtime.tm_year += 100;
+			wtime.tm_wday = BCD2BIN(rtc->bcd_dow)-1;
+		} while (wtime.tm_sec != BCD2BIN(rtc->bcd_sec));
+		rtc->msr = msr;
+		restore_flags(flags);
+		return copy_to_user((void *)arg, &wtime, sizeof wtime) ?
+								-EFAULT : 0;
+	}
+	case RTC_SET_TIME:	/* Set the RTC */
+	{
+		unsigned char leap_yr;
+		struct rtc_time rtc_tm;
+
+		if (!suser())
+			return -EACCES;
+
+		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
+				   sizeof(struct rtc_time)))
+			return -EFAULT;
+
+		leap_yr = ((!(rtc_tm.tm_year % 4) && (rtc_tm.tm_year % 100)) || !(rtc_tm.tm_year % 400));
+
+		if ((rtc_tm.tm_mon > 12) || (rtc_tm.tm_mday == 0))
+			return -EINVAL;
+
+		if (rtc_tm.tm_mday > (days_in_mo[rtc_tm.tm_mon] + ((rtc_tm.tm_mon == 2) && leap_yr)))
+			return -EINVAL;
+			
+		if ((rtc_tm.tm_hour >= 24) || (rtc_tm.tm_min >= 60) || (rtc_tm.tm_sec >= 60))
+			return -EINVAL;
+
+		save_flags(flags);
+		cli();
+		/* Ensure clock and real-time-mode-register are accessible */
+		msr = rtc->msr & 0xc0;
+		rtc->msr = 0x40;
+
+		rtc->t0cr_rtmr = rtc_tm.tm_year%4;
+		rtc->bcd_tenms = 0;
+		rtc->bcd_sec = BIN2BCD(rtc_tm.tm_sec);
+		rtc->bcd_min = BIN2BCD(rtc_tm.tm_min);
+		rtc->bcd_hr  = BIN2BCD(rtc_tm.tm_hour);
+		rtc->bcd_dom = BIN2BCD(rtc_tm.tm_mday);
+		rtc->bcd_mth = BIN2BCD(rtc_tm.tm_mon + 1);
+		rtc->bcd_year = BIN2BCD(rtc_tm.tm_year%100);
+		if (rtc_tm.tm_wday >= 0)
+			rtc->bcd_dow = BIN2BCD(rtc_tm.tm_wday+1);
+		rtc->t0cr_rtmr = rtc_tm.tm_year%4 | 0x08;
+
+		rtc->msr = msr;
+		restore_flags(flags);
+		return 0;
+	}
+	default:
+		return -EINVAL;
+	}
+}
+
+/*
+ *	We enforce only one user at a time here with the open/close.
+ *	Also clear the previous interrupt data on an open, and clean
+ *	up things on a close.
+ */
+
+static int rtc_open(struct inode *inode, struct file *file)
+{
+	if(rtc_status)
+		return -EBUSY;
+
+	rtc_status = 1;
+	return 0;
+}
+
+static int rtc_release(struct inode *inode, struct file *file)
+{
+	rtc_status = 0;
+	return 0;
+}
+
+/*
+ *	The various file operations we support.
+ */
+
+static struct file_operations rtc_fops = {
+	NULL,
+	NULL,
+	NULL,		/* No write */
+	NULL,		/* No readdir */
+	NULL,
+	rtc_ioctl,
+	NULL,		/* No mmap */
+	rtc_open,
+	rtc_release
+};
+
+static struct miscdevice rtc_dev=
+{
+	RTC_MINOR,
+	"rtc",
+	&rtc_fops
+};
+
+__initfunc(int rtc_DP8570A_init(void))
+{
+	if (!MACH_IS_BVME6000)
+		return -ENODEV;
+
+	printk(KERN_INFO "DP8570A Real Time Clock Driver v%s\n", RTC_VERSION);
+	misc_register(&rtc_dev);
+	return 0;
+}
+
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/config.in linuxvme-2.1.101/arch/m68k/config.in
--- linux68k-2.1.101/arch/m68k/config.in	Thu May 14 12:07:37 1998
+++ linuxvme-2.1.101/arch/m68k/config.in	Mon May 25 20:13:42 1998
@@ -34,7 +34,7 @@
 bool 'VME (Motorola and BVM) support' CONFIG_VME
 if [ "$CONFIG_VME" = "y" ]; then
   bool 'MVME162, 166 and 167 support' CONFIG_MVME16x
-# bool 'BVME4000 and BVME6000 support' CONFIG_BVME6000
+  bool 'BVME4000 and BVME6000 support' CONFIG_BVME6000
 fi
 bool 'HP9000/300 support' CONFIG_HP300
 if [ "$CONFIG_HP300" = "y" ]; then
@@ -60,6 +61,7 @@
 bool 'Advanced processor options' CONFIG_ADVANCED_CPU
 if [ "$CONFIG_ADVANCED_CPU" = "y" ]; then
   bool 'Use read-modify-write instructions' CONFIG_RMW_INSNS
+  bool 'Use write-through caching for 68060 supervisor accesses' CONFIG_060_WRITETHROUGH
 fi
 endmenu
 
@@ -226,6 +228,10 @@
   bool 'NCR53C710 SCSI driver for MVME16x' CONFIG_MVME16x_SCSI
 fi
 
+if [ "$CONFIG_VME" = "y" -a "$CONFIG_BVME6000" = "y" ]; then
+  bool 'NCR53C710 SCSI driver for BVME6000' CONFIG_BVME6000_SCSI
+fi
+
 endmenu
 
 fi
@@ -274,6 +280,9 @@
 if [ "$CONFIG_VME" = "y" -a "$CONFIG_MVME16x" = "y" ]; then
   bool 'MVME16x Ethernet support' CONFIG_APRICOT
 fi
+if [ "$CONFIG_VME" = "y" -a "$CONFIG_BVME6000" = "y" ]; then
+  bool 'BVME6000 Ethernet support' CONFIG_APRICOT
+fi
 fi
 endmenu
 
@@ -350,8 +359,13 @@
 fi
 if [ "$CONFIG_VME" = "y" ]; then
   define_bool CONFIG_SERIAL_CONSOLE y
-  bool 'CD2401 support for MVME166/7 serial ports' CONFIG_SERIAL167
-  bool 'SCC support for MVME162 serial ports' CONFIG_MVME162_SCC
+  if [ "$CONFIG_MVME16x" = "y" ]; then
+    bool 'CD2401 support for MVME166/7 serial ports' CONFIG_SERIAL167
+    bool 'SCC support for MVME162 serial ports' CONFIG_MVME162_SCC
+  fi
+  if [ "$CONFIG_BVME6000" = "y" ]; then
+    bool 'SCC support for BVME6000 serial ports' CONFIG_BVME6000_SCC
+  fi
 fi
 if [ "$CONFIG_APOLLO" = "y" ]; then
   bool 'Support for DN serial port (dummy)' CONFIG_SERIAL
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/kernel/head.S linuxvme-2.1.101/arch/m68k/kernel/head.S
--- linux68k-2.1.101/arch/m68k/kernel/head.S	Wed May 13 14:06:50 1998
+++ linuxvme-2.1.101/arch/m68k/kernel/head.S	Tue May 26 18:33:12 1998
@@ -74,10 +74,25 @@
 #include <asm/pgtable.h>
 
 .globl SYMBOL_NAME(kernel_pg_dir), SYMBOL_NAME(kpt)
-.globl SYMBOL_NAME(availmem), SYMBOL_NAME(mvme_bdid_ptr)
+.globl SYMBOL_NAME(availmem)
 .globl SYMBOL_NAME(m68k_pgtable_cachemode)
 .globl SYMBOL_NAME(kernel_pmd_table), SYMBOL_NAME(swapper_pg_dir)
 
+#if defined(CONFIG_MVME16x)
+.globl SYMBOL_NAME(mvme_bdid_ptr)
+#endif
+
+/*
+ * Added m68k_supervisor_cachemode for 68060 boards where some drivers
+ * need writethrough caching for supervisor accesses.  Drivers known to
+ * be effected are 53c7xx.c and apricot.c (when used on VME boards).
+ * Richard Hirst.
+ */
+
+#ifdef CONFIG_060_WRITETHROUGH
+.globl SYMBOL_NAME(m68k_supervisor_cachemode)
+#endif
+
 D6B_0460 = 16		/* indicates 680[46]0 in d6 */
 D6B_060  = 17		/* indicates 68060 in d6 */
 D6F_040  = 1<<D6B_0460
@@ -147,6 +162,7 @@
 #define is_not_amiga(lab) moveq &MACH_AMIGA,%d7; cmpl %d4,%d7; jne lab
 #define is_not_atari(lab) moveq &MACH_ATARI,%d7; cmpl %d4,%d7; jne lab
 #define is_not_mvme16x(lab) moveq &MACH_MVME16x,%d7; cmpl %d4,%d7; jne lab
+#define is_not_bvme6000(lab) moveq &MACH_BVME6000,%d7; cmpl %d4,%d7; jne lab
 #define is_not_hp300(lab) moveq &MACH_HP300,%d7	;  cmpl %d4,%d7; jne lab
 
 #define is_040_or_060(lab) btst &D6B_0460,%d6; jne lab
@@ -175,6 +191,7 @@
 	.long	MACH_AMIGA, AMIGA_BOOTI_VERSION
 	.long	MACH_ATARI, ATARI_BOOTI_VERSION
 	.long	MACH_MVME16x, MVME16x_BOOTI_VERSION
+	.long	MACH_BVME6000, BVME6000_BOOTI_VERSION
 	.long	0
 1:	jra	SYMBOL_NAME(_start)
 
@@ -235,6 +252,22 @@
 	movew	%d6,%d0
 	movel	%d0,%a0@		/* save cache mode for page tables */
 
+	/*
+	 * If this is a 68060 board using drivers with cache coherency
+	 * problems, then supervisor memory accesses need to be write-through
+         * also; otherwise, we want copyback.
+	 */
+
+#if defined(CONFIG_060_WRITETHROUGH)
+	is_not_060(Lset_norm)
+	jra	1f
+Lset_norm:
+	move.w	#_PAGE_CACHE040,%d0
+1:
+  	lea	%pc@(SYMBOL_NAME(m68k_supervisor_cachemode)),%a0
+	movel	%d0,%a0@
+#endif
+
 /*
  * raise interrupt level
  */
@@ -397,7 +430,12 @@
 
 	movel	%a3,%a0
 	movel	%d5,%a1
-	addw	#_PAGE_GLOBAL040+_PAGE_CACHE040+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
+#if defined(CONFIG_060_WRITETHROUGH)
+	addw	#_PAGE_GLOBAL040+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
+	addl	m68k_supervisor_cachemode,%a1
+#else
+	addw    #_PAGE_GLOBAL040+_PAGE_CACHE040+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
+#endif
 	movew	#(PAGE_TABLE_SIZE*TABLENR_4MB)-1,%d1
 	movel	#PAGESIZE,%d2
 1:	movel	%a1,%a0@+
@@ -668,6 +706,25 @@
 Lnot16x:
 #endif
 
+#if defined(CONFIG_BVME6000)
+	is_not_bvme6000(Lnotbvm)
+
+	/*
+	 * On BVME6000 we have already created kernel page tables for
+	 * 4MB of RAM at address 0, so now need to do a transparent
+	 * mapping of the top of memory space.  Make it 0.5GByte for now.
+	 */
+
+	movel	#0xe01f0000,%d2		/* logical address base */
+	orw	#0xa040,%d2		/* add in magic bits */
+	.long	0x4e7b2005		/* movec d2,ittr1 */
+	.long	0x4e7b2007		/* movec d2,dttr1 */
+	.long	0x4e7b2004		/* movec d2,ittr0 */
+	.long	0x4e7b2006		/* movec d2,dttr0 */
+
+Lnotbvm:
+#endif
+
 /*
  * Setup a transparent mapping of the physical memory we are executing in.
  *
@@ -933,6 +990,30 @@
 
 #endif
 
+#if defined(CONFIG_BVME6000)
+	is_not_bvme6000(Lmapphysnotbvm)
+	/*
+	 * save physaddr of phys mem in register a3
+	 */
+	moveq	#'L',%d7
+	jbsr	Lserial_putc
+
+	.word	0xf4d8		/* CINVA I/D    */
+	.word	0xf518		/* pflusha      */
+	.long	0x4e7bd807	/* movec a5,srp */
+	.long	0x4e7bd806	/* movec a5,urp */
+	movel	#(TC_ENABLE+TC_PAGE4K),%d0
+	/*
+	 * this value is also ok for the 68060, we don`t use the cache
+	 * mode/protection defaults
+	 */
+	.long	0x4e7b0003	/* movec d0,tc  (enable the MMU) */
+	jra	LdoneMMUenable	/* branch to continuation of startup */
+
+Lmapphysnotbvm:
+
+#endif
+
 LdoneMMUenable:
 
 /*
@@ -1080,6 +1161,11 @@
 #endif
 #endif
 
+#if defined (CONFIG_BVME6000)
+BVME_SCC_CTRL_A = 0xffb0000b
+BVME_SCC_DATA_A = 0xffb0000f
+#endif
+
 /*
  * Serial port output support.
  */
@@ -1166,6 +1252,16 @@
 	jne	2f
 	moveb	%d7,%sp@-
 	.long	0x4e4f0020
+	jra	9f
+2:
+#endif
+#ifdef CONFIG_BVME6000
+	cmpil	#MACH_BVME6000,%d4
+	jne	2f
+1:	btst	#2,BVME_SCC_CTRL_A
+	jeq	1b
+	moveb	%d7,BVME_SCC_DATA_A
+	jra	9f
 2:
 #endif
 #ifdef CONFIG_AMIGA
@@ -1292,5 +1388,11 @@
 	.long 0
 SYMBOL_NAME_LABEL(m68k_pgtable_cachemode)
 	.long 0
+#ifdef CONFIG_060_WRITETHROUGH
+SYMBOL_NAME_LABEL(m68k_supervisor_cachemode)
+	.long 0
+#endif
+#if defined(CONFIG_MVME16x)
 SYMBOL_NAME_LABEL(mvme_bdid_ptr)
 	.long 0
+#endif
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/kernel/ints.c linuxvme-2.1.101/arch/m68k/kernel/ints.c
--- linux68k-2.1.101/arch/m68k/kernel/ints.c	Wed Feb  4 15:51:03 1998
+++ linuxvme-2.1.101/arch/m68k/kernel/ints.c	Tue May 26 20:37:53 1998
@@ -31,6 +31,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 
+#include <asm/setup.h>
 #include <asm/system.h>
 #include <asm/irq.h>
 #include <asm/traps.h>
@@ -212,7 +213,7 @@
 
 asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
 {
-	if (vec >= VEC_INT1 && vec <= VEC_INT7) {
+	if (vec >= VEC_INT1 && vec <= VEC_INT7 && !MACH_IS_BVME6000) {
 		vec -= VEC_SPUR;
 		kstat.irqs[0][vec]++;
 		irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/kernel/setup.c linuxvme-2.1.101/arch/m68k/kernel/setup.c
--- linux68k-2.1.101/arch/m68k/kernel/setup.c	Wed May 13 14:06:51 1998
+++ linuxvme-2.1.101/arch/m68k/kernel/setup.c	Fri May 22 19:35:38 1998
@@ -102,6 +102,7 @@
 extern void config_sun3(void);
 extern void config_apollo(void);
 extern void config_mvme16x(void);
+extern void config_bmve6000(void);
 extern void config_hp300(void);
 
 #define MASK_256K 0xfffc0000
@@ -249,6 +250,11 @@
 #ifdef CONFIG_MVME16x
 	    case MACH_MVME16x:
 	    	config_mvme16x();
+	    	break;
+#endif
+#ifdef CONFIG_BVME6000
+	    case MACH_BVME6000:
+	    	config_bvme6000();
 	    	break;
 #endif
 #ifdef CONFIG_HP300
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/mm/fault.c linuxvme-2.1.101/arch/m68k/mm/fault.c
--- linux68k-2.1.101/arch/m68k/mm/fault.c	Thu Feb  5 14:10:30 1998
+++ linuxvme-2.1.101/arch/m68k/mm/fault.c	Fri May 22 19:29:15 1998
@@ -48,6 +48,8 @@
 	vma = find_vma(mm, address);
 	if (!vma)
 	  goto bad_area;
+	if (vma->vm_flags & VM_IO)
+		goto bad_area;
 	if (vma->vm_start <= address)
 		goto good_area;
 	if (!(vma->vm_flags & VM_GROWSDOWN))
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/mm/init.c linuxvme-2.1.101/arch/m68k/mm/init.c
--- linux68k-2.1.101/arch/m68k/mm/init.c	Thu Feb  5 14:10:31 1998
+++ linuxvme-2.1.101/arch/m68k/mm/init.c	Mon May 25 20:45:13 1998
@@ -231,7 +231,7 @@
 			 */
 			for (i = 0; i < 64; i++) {
 				pte_val(ktablep[i]) = physaddr | _PAGE_PRESENT
-					| _PAGE_CACHE040 | _PAGE_GLOBAL040
+				  | m68k_supervisor_cachemode | _PAGE_GLOBAL040
 					| _PAGE_ACCESSED;
 				physaddr += PAGE_SIZE;
 			}
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/mvme16x/16xints.c linuxvme-2.1.101/arch/m68k/mvme16x/16xints.c
--- linux68k-2.1.101/arch/m68k/mvme16x/16xints.c	Tue Mar 17 17:38:56 1998
+++ linuxvme-2.1.101/arch/m68k/mvme16x/16xints.c	Fri May 22 19:29:15 1998
@@ -127,7 +127,7 @@
 
 static void mvme16x_defhand (int irq, void *dev_id, struct pt_regs *fp)
 {
-	panic ("Unknown interrupt 0x%02x", irq);
+	printk ("Unknown interrupt 0x%02x\n", irq);
 }
 
 
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/mvme16x/Makefile linuxvme-2.1.101/arch/m68k/mvme16x/Makefile
--- linux68k-2.1.101/arch/m68k/mvme16x/Makefile	Sun Dec 14 16:34:51 1997
+++ linuxvme-2.1.101/arch/m68k/mvme16x/Makefile	Fri May 22 19:29:15 1998
@@ -8,7 +8,7 @@
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
 O_TARGET := mvme16x.o
-O_OBJS   := config.o 16xints.o
+O_OBJS   := config.o 16xints.o rtc.o
 #OX_OBJS = ksyms.o
 
 include $(TOPDIR)/Rules.make
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/mvme16x/config.c linuxvme-2.1.101/arch/m68k/mvme16x/config.c
--- linux68k-2.1.101/arch/m68k/mvme16x/config.c	Thu Jan  8 14:02:52 1998
+++ linuxvme-2.1.101/arch/m68k/mvme16x/config.c	Fri May 22 19:29:15 1998
@@ -34,26 +34,10 @@
 #include <asm/machdep.h>
 #include <asm/mvme16xhw.h>
 
-typedef struct {
-	unsigned char
-		ctrl,
-		bcd_sec,
-		bcd_min,
-		bcd_hr,
-		bcd_dow,
-		bcd_dom,
-		bcd_mth,
-		bcd_year;
-} MK48T08;
-
-#define RTC_WRITE	0x80
-#define RTC_READ	0x40
-#define RTC_STOP	0x20
-
 int atari_SCC_reset_done = 1;		/* So SCC doesn't get reset */
 u_long atari_mch_cookie = 0;
 
-MK48T08 * volatile rtc = (MK48T08 *)0xfffc1ff8;
+static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE;
 
 extern void mvme16x_process_int (int level, struct pt_regs *regs);
 extern void mvme16x_init_IRQ (void);
@@ -143,6 +127,11 @@
 }
 
 
+#define pcc2chip	((volatile u_char *)0xfff42000)
+#define PccSCCMICR	0x1d
+#define PccSCCTICR	0x1e
+#define PccSCCRICR	0x1f
+
 __initfunc(void config_mvme16x(void))
 {
     p_bdid p = (p_bdid)mvme_bdid_ptr;
@@ -197,7 +186,43 @@
 			rev & MVME16x_CONFIG_NO_ETHERNET ? "NOT " : "");
     }
     else
+    {
 	mvme16x_config = MVME16x_CONFIG_GOT_LP | MVME16x_CONFIG_GOT_CD2401;
+
+	/* Dont allow any interrupts from the CD2401 until the interrupt */
+	/* handlers are installed					 */
+
+	pcc2chip[PccSCCMICR] = 0x10;
+	pcc2chip[PccSCCTICR] = 0x10;
+	pcc2chip[PccSCCRICR] = 0x10;
+    }
+}
+
+static void mvme16x_abort_int (int irq, void *dev_id, struct pt_regs *fp)
+{
+	p_bdid p = (p_bdid)mvme_bdid_ptr;
+	unsigned long *new = (unsigned long *)vectors;
+	unsigned long *old = (unsigned long *)0xffe00000;
+	volatile unsigned char uc, *ucp;
+
+	if (p->brdno == 0x0162 || p->brdno == 0x172)
+	{
+		ucp = (volatile unsigned char *)0xfff42043;
+		uc = *ucp | 8;
+		*ucp = uc;
+	}
+	else
+	{
+		*(volatile unsigned long *)0xfff40074 = 0x40000000;
+	}
+	*(new+4) = *(old+4);		/* Illegal instruction */
+	*(new+9) = *(old+9);		/* Trace */
+	*(new+47) = *(old+47);		/* Trap #15 */
+
+	if (p->brdno == 0x0162 || p->brdno == 0x172)
+		*(new+0x5e) = *(old+0x5e);	/* ABORT switch */
+	else
+		*(new+0x6e) = *(old+0x6e);	/* ABORT switch */
 }
 
 static void mvme16x_timer_int (int irq, void *dev_id, struct pt_regs *fp)
@@ -208,15 +233,26 @@
 
 void mvme16x_sched_init (void (*timer_routine)(int, void *, struct pt_regs *))
 {
+    p_bdid p = (p_bdid)mvme_bdid_ptr;
+    int irq;
+
     tick_handler = timer_routine;
     /* Using PCCchip2 or MC2 chip tick timer 1 */
     *(volatile unsigned long *)0xfff42008 = 0;
     *(volatile unsigned long *)0xfff42004 = 10000;	/* 10ms */
     *(volatile unsigned char *)0xfff42017 |= 3;
     *(volatile unsigned char *)0xfff4201b = 0x16;
-    if (request_irq(IRQ_MVME16x_TIMER, mvme16x_timer_int, 0,
+    if (request_irq(MVME16x_IRQ_TIMER, mvme16x_timer_int, 0,
 				"timer", mvme16x_timer_int))
 	panic ("Couldn't register timer int");
+
+    if (p->brdno == 0x0162 || p->brdno == 0x172)
+	irq = MVME162_IRQ_ABORT;
+    else
+        irq = MVME167_IRQ_ABORT;
+    if (request_irq(irq, mvme16x_abort_int, 0,
+				"abort", mvme16x_abort_int))
+	panic ("Couldn't register abort int");
 }
 
 
@@ -254,76 +290,11 @@
 	return 0;
 }
 
-/*
- * console_map_init(), here to avoid having to modify drivers/block/genhd.c
- */
-
-void console_map_init(void)
-{
-}
-
-/*
- * fbmem_init(), here to avoid having to modify drivers/char/mem.c
- */
-
-void fbmem_init(void)
-{
-}
-
-/* Avoid mods to drivers/char/tty_io.c */
-
-unsigned long con_init(unsigned long kmem_start)
-{
-	return (kmem_start);
-}
-
-/* Avoid mods to drivers/char/tty_io.c */
-
-int vcs_init(void)
-{
-	return (0);
-}
-
-/* Avoid mods to drivers/char/tty_io.c */
-
-int kbd_init(void)
-{
-	return (0);
-}
-
-/* Avoid mods to init/main.c */
-
-void no_scroll(char *str, int *ints)
-{
-}
-
-/* Avoid mods to kernel/panic.c */
-
-void do_unblank_screen(void)
-{
-}
-
 int mvme16x_keyb_init (void)
 {
 	return 0;
 }
 
-void mvme16x_set_vectors (void)
-{
-	p_bdid p = (p_bdid)mvme_bdid_ptr;
-	unsigned long *new = (unsigned long *)vectors;
-	unsigned long *old = (unsigned long *)0xffe00000;;
-
-	*(new+4) = *(old+4);		/* Illegal instruction */
-	*(new+9) = *(old+9);		/* Trace */
-	*(new+47) = *(old+47);		/* Trap #15 */
-
-	if (p->brdno == 0x0162 || p->brdno == 0x172)
-		*(new+0x5e) = *(old+0x5e);	/* ABORT switch */
-	else
-		*(new+0x6e) = *(old+0x6e);	/* ABORT switch */
-}
-
 /*-------------------  Serial console stuff ------------------------*/
 
 extern void mvme167_serial_console_setup(int cflag);
@@ -372,7 +343,7 @@
 
 static void scc_write (char ch)
 {
-	volatile char *p = (volatile char *)SCC_A_ADDR;
+	volatile char *p = (volatile char *)MVME_SCC_A_ADDR;
 
 	do {
 		scc_delay();
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/arch/m68k/mvme16x/rtc.c linuxvme-2.1.101/arch/m68k/mvme16x/rtc.c
--- linux68k-2.1.101/arch/m68k/mvme16x/rtc.c	Thu Jan  1 00:00:00 1970
+++ linuxvme-2.1.101/arch/m68k/mvme16x/rtc.c	Fri May 22 19:29:15 1998
@@ -0,0 +1,166 @@
+/*
+ *	Real Time Clock interface for Linux on the MVME16x
+ *
+ * Based on the PC driver by Paul Gortmaker.
+ */
+
+#define RTC_VERSION		"1.00"
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/miscdevice.h>
+#include <linux/malloc.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/mc146818rtc.h>	/* For struct rtc_time and ioctls, etc */
+#include <asm/mvme16xhw.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/setup.h>
+
+/*
+ *	We sponge a minor off of the misc major. No need slurping
+ *	up another valuable major dev number for this. If you add
+ *	an ioctl, make sure you don't conflict with SPARC's RTC
+ *	ioctls.
+ */
+
+#define BCD2BIN(val) (((val)&15) + ((val)>>4)*10)
+#define BIN2BCD(val) ((((val)/10)<<4) + (val)%10)
+
+static unsigned char days_in_mo[] =
+{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+static char rtc_status = 0;
+
+static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		     unsigned long arg)
+{
+	volatile MK48T08ptr_t rtc = (MK48T08ptr_t)MVME_RTC_BASE;
+	unsigned long flags;
+	struct rtc_time wtime; 
+
+	switch (cmd) {
+	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
+	{
+		save_flags(flags);
+		cli();
+		/* Ensure clock and real-time-mode-register are accessible */
+		rtc->ctrl = RTC_READ;
+		wtime.tm_sec =  BCD2BIN(rtc->bcd_sec);
+		wtime.tm_min =  BCD2BIN(rtc->bcd_min);
+		wtime.tm_hour = BCD2BIN(rtc->bcd_hr);
+		wtime.tm_mday =  BCD2BIN(rtc->bcd_dom);
+		wtime.tm_mon =  BCD2BIN(rtc->bcd_mth)-1;
+		wtime.tm_year = BCD2BIN(rtc->bcd_year);
+		if (wtime.tm_year < 70)
+			wtime.tm_year += 100;
+		wtime.tm_wday = BCD2BIN(rtc->bcd_dow)-1;
+		rtc->ctrl = 0;
+		restore_flags(flags);
+		return copy_to_user((void *)arg, &wtime, sizeof wtime) ?
+								-EFAULT : 0;
+	}
+	case RTC_SET_TIME:	/* Set the RTC */
+	{
+		unsigned char leap_yr;
+		struct rtc_time rtc_tm;
+
+		if (!suser())
+			return -EACCES;
+
+		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
+				   sizeof(struct rtc_time)))
+			return -EFAULT;
+
+		leap_yr = ((!(rtc_tm.tm_year % 4) && (rtc_tm.tm_year % 100)) || !(rtc_tm.tm_year % 400));
+
+		if ((rtc_tm.tm_mon > 12) || (rtc_tm.tm_mday == 0))
+			return -EINVAL;
+
+		if (rtc_tm.tm_mday > (days_in_mo[rtc_tm.tm_mon] + ((rtc_tm.tm_mon == 2) && leap_yr)))
+			return -EINVAL;
+			
+		if ((rtc_tm.tm_hour >= 24) || (rtc_tm.tm_min >= 60) || (rtc_tm.tm_sec >= 60))
+			return -EINVAL;
+
+		save_flags(flags);
+		cli();
+		rtc->ctrl = RTC_WRITE;
+
+		rtc->bcd_sec = BIN2BCD(rtc_tm.tm_sec);
+		rtc->bcd_min = BIN2BCD(rtc_tm.tm_min);
+		rtc->bcd_hr  = BIN2BCD(rtc_tm.tm_hour);
+		rtc->bcd_dom = BIN2BCD(rtc_tm.tm_mday);
+		rtc->bcd_mth = BIN2BCD(rtc_tm.tm_mon + 1);
+		rtc->bcd_year = BIN2BCD(rtc_tm.tm_year%100);
+		if (rtc_tm.tm_wday >= 0)
+			rtc->bcd_dow = BIN2BCD(rtc_tm.tm_wday+1);
+
+		rtc->ctrl = 0;
+		restore_flags(flags);
+		return 0;
+	}
+	default:
+		return -EINVAL;
+	}
+}
+
+/*
+ *	We enforce only one user at a time here with the open/close.
+ *	Also clear the previous interrupt data on an open, and clean
+ *	up things on a close.
+ */
+
+static int rtc_open(struct inode *inode, struct file *file)
+{
+	if(rtc_status)
+		return -EBUSY;
+
+	rtc_status = 1;
+	return 0;
+}
+
+static int rtc_release(struct inode *inode, struct file *file)
+{
+	rtc_status = 0;
+	return 0;
+}
+
+/*
+ *	The various file operations we support.
+ */
+
+static struct file_operations rtc_fops = {
+	NULL,
+	NULL,
+	NULL,		/* No write */
+	NULL,		/* No readdir */
+	NULL,
+	rtc_ioctl,
+	NULL,		/* No mmap */
+	rtc_open,
+	rtc_release
+};
+
+static struct miscdevice rtc_dev=
+{
+	RTC_MINOR,
+	"rtc",
+	&rtc_fops
+};
+
+__initfunc(int rtc_MK48T08_init(void))
+{
+	if (!MACH_IS_MVME16x)
+		return -ENODEV;
+
+	printk(KERN_INFO "MK48T08 Real Time Clock Driver v%s\n", RTC_VERSION);
+	misc_register(&rtc_dev);
+	return 0;
+}
+
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/char/Makefile linuxvme-2.1.101/drivers/char/Makefile
--- linux68k-2.1.101/drivers/char/Makefile	Wed May 13 14:06:57 1998
+++ linuxvme-2.1.101/drivers/char/Makefile	Fri May 22 19:40:14 1998
@@ -165,6 +165,20 @@
   endif
 endif
 
+ifeq ($(CONFIG_SERIAL167),y)
+L_OBJS += serial167.o
+endif
+
+ifeq ($(CONFIG_MVME162_SCC),y)
+L_OBJS += atari_SCC.o
+S = y
+endif
+
+ifeq ($(CONFIG_BVME6000_SCC),y)
+L_OBJS += atari_SCC.o
+S = y
+endif
+
 ifeq ($(ARCH),m68k)
 
 ifdef CONFIG_USERIAL
@@ -594,14 +608,6 @@
   ALL_SUB_DIRS += hfmodem
   MOD_SUB_DIRS += hfmodem
   endif
-endif
-
-ifeq ($(CONFIG_SERIAL167),y)
-L_OBJS += serial167.o
-endif
-
-ifeq ($(CONFIG_MVME162_SCC),y)
-L_OBJS += m68kserial.o atari_SCC.o
 endif
 
 include $(TOPDIR)/Rules.make
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/char/atari_SCC.c linuxvme-2.1.101/drivers/char/atari_SCC.c
--- linux68k-2.1.101/drivers/char/atari_SCC.c	Fri May  1 16:34:25 1998
+++ linuxvme-2.1.101/drivers/char/atari_SCC.c	Fri May 22 21:37:39 1998
@@ -9,7 +9,7 @@
  *
  * Adapted to 1.2 by Andreas Schwab
  *
- * Adapted to support MVME162 by Richard Hirst
+ * Adapted to support MVME162  and BVME6000 by Richard Hirst
  *
  * 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
@@ -54,6 +54,9 @@
 #ifdef CONFIG_MVME162_SCC
 #include <asm/mvme16xhw.h>
 #endif
+#ifdef CONFIG_BVME6000_SCC
+#include <asm/bvme6000hw.h>
+#endif
 #ifdef CONFIG_ATARI
 #include <asm/atarihw.h>
 #include <asm/atariints.h>
@@ -228,6 +231,32 @@
 };
 #endif
 
+#ifdef CONFIG_BVME6000_SCC
+
+/* This table is used if RTxC = 7.3728 MHz. This is the case for BVMs
+ */
+static BAUD_ENTRY bdtab_bvme[18] = {
+	/* B0      */ { 0, 0 },
+	/* B50     */ { CLK_RTxC, 9216 },
+	/* B75     */ { CLK_RTxC, 6144 },
+	/* B110    */ { CLK_RTxC, 4188 },
+	/* B134    */ { CLK_RTxC, 3424 },
+	/* B150    */ { CLK_RTxC, 3072 },
+	/* B200    */ { CLK_RTxC, 2304 },
+	/* B300    */ { CLK_RTxC, 1536 },
+	/* B600    */ { CLK_RTxC, 768 },
+	/* B1200   */ { CLK_RTxC, 384 },
+	/* B1800   */ { CLK_RTxC, 256 },
+	/* B2400   */ { CLK_RTxC, 192 },
+	/* B4800   */ { CLK_RTxC, 96 },
+	/* B9600   */ { CLK_RTxC, 48 },
+	/* B19200  */ { CLK_RTxC, 24 },
+	/* B38400  */ { CLK_RTxC, 12 },
+	/* B57600  */ { CLK_RTxC, 8 },
+	/* B115200 */ { CLK_RTxC, 4 }
+};
+#endif
+
 
 /* User settable tables */
 static BAUD_ENTRY bdtab_usr[2][20];
@@ -384,7 +413,10 @@
 static void SCC_init_port( struct m68k_async_struct *info, int type, int channel );
 #endif
 #ifdef CONFIG_MVME162_SCC
-static void vme_init_port( struct m68k_async_struct *info, int type, int channel );
+static void mvme_init_port( struct m68k_async_struct *info, int type, int channel );
+#endif
+#ifdef CONFIG_BVME6000_SCC
+static void bvme_init_port( struct m68k_async_struct *info, int type, int channel );
 #endif
 #ifdef MODULE
 static void SCC_deinit_port( struct m68k_async_struct *info, int channel );
@@ -438,9 +470,110 @@
 extern int atari_SCC_reset_done;
 
 
+#ifdef CONFIG_BVME6000_SCC
+
+int bvme_SCC_init( void )
+{
+	struct serial_struct req;
+	int nr = 0;
+
+	if (!MACH_IS_BVME6000)
+		return (-ENODEV);
+
+	scc_del = (unsigned char *)0;
+
+	SCC_chan_a_switchable = SCCA_SWITCH_SERIAL2_ONLY;
+	SCC_PCLK = SCC_BAUD_BASE_BVME_PCLK;
+
+	/* General initialization */
+	ChannelsReversed = 8;
+	SCC_chan_a_open = 0;
+
+	req.line = DEFAULT_CHANNEL_B_LINE;
+	req.type = SER_SCC_BVME;
+	req.port = BVME_SCC_B_ADDR;
+	if ((chb_line = register_serial( &req )) >= 0) {
+		bvme_init_port( &rs_table[chb_line], req.type, CHANNEL_B );
+		++nr;
+	}
+	else
+		printk(KERN_WARNING "Cannot allocate ttyS%d for SCC channel B\n", req.line );
+
+	/* Init channel A, RS232 part (Serial2) */
+	req.line = 0;
+	req.type = SER_SCC_BVME;
+	req.port = BVME_SCC_A_ADDR;
+	if ((cha232_line = register_serial( &req )) >= 0) {
+		bvme_init_port( &rs_table[cha232_line], req.type, CHANNEL_A );
+		++nr;
+	}
+	else
+		printk(KERN_WARNING "Cannot allocate ttyS%d for SCC channel A\n", req.line );
+
+	return( nr > 0 ? 0 : -ENODEV );
+}
+
+
+static void bvme_init_port( struct m68k_async_struct *info, int type, int channel )
+{
+	static int called = 0, ch_a_inited = 0;
+	SCC_ACCESS_INIT(info);
+
+	info->sw = &SCC_switch;
+
+	/* set ISRs, but don't enable interrupts yet (done in init());
+	 */
+	if (channel == CHANNEL_B || !ch_a_inited) {
+		request_irq(channel ? BVME_IRQ_SCCB_TX : BVME_IRQ_SCCA_TX,
+		            SCC_tx_int, BVME_IRQ_TYPE_PRIO,
+		            channel ? "SCC-B TX" : "SCC-A TX", info);
+		request_irq(channel ? BVME_IRQ_SCCB_STAT : BVME_IRQ_SCCA_STAT,
+		            SCC_stat_int, BVME_IRQ_TYPE_PRIO,
+		            channel ? "SCC-B status" : "SCC-A status", info);
+		request_irq(channel ? BVME_IRQ_SCCB_RX : BVME_IRQ_SCCA_RX,
+		            SCC_rx_int, BVME_IRQ_TYPE_PRIO,
+		            channel ? "SCC-B RX" : "SCC-A RX", info);
+		request_irq(channel ? BVME_IRQ_SCCB_SPCOND : BVME_IRQ_SCCA_SPCOND,
+		            SCC_spcond_int, BVME_IRQ_TYPE_PRIO,
+		            channel ? "SCC-B special cond" : "SCC-A special cond", info);
+
+	}
+
+	/* Hardware initialization */
+
+	if (!called) {
+		/* Set the interrupt vector */
+		SCCwrite( INT_VECTOR_REG, BVME_IRQ_SCC_BASE );
+
+		/* Interrupt parameters: vector includes status, status low */
+		SCCwrite( MASTER_INT_CTRL, MIC_VEC_INCL_STAT );
+
+		/* Set the baud tables */
+		SCC_baud_table[CHANNEL_A] = bdtab_bvme;
+		SCC_baud_table[CHANNEL_B] = bdtab_bvme;
+
+		/* Set the clocks */
+		SCC_clocks[CHANNEL_A][CLK_RTxC] = SCC_BAUD_BASE_BVME;
+		SCC_clocks[CHANNEL_A][CLK_TRxC] = SCC_BAUD_BASE_NONE;
+		SCC_clocks[CHANNEL_B][CLK_RTxC] = SCC_BAUD_BASE_BVME;
+		SCC_clocks[CHANNEL_B][CLK_TRxC] = SCC_BAUD_BASE_NONE;
+
+		SCCmod( MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB );
+	}
+
+	/* disable interrupts for this channel */
+	SCCwrite( INT_AND_DMA_REG, 0 );
+
+	called = 1;
+	if (CHANNR(info) == CHANNEL_A) ch_a_inited = 1;
+}
+
+#endif
+
+
 #ifdef CONFIG_MVME162_SCC
 
-int vme_SCC_init( void )
+int mvme_SCC_init( void )
 {
 	struct serial_struct req;
 	int nr = 0;
@@ -459,9 +592,9 @@
 
 	req.line = DEFAULT_CHANNEL_B_LINE;
 	req.type = SER_SCC_MVME;
-	req.port = SCC_B_ADDR;
+	req.port = MVME_SCC_B_ADDR;
 	if ((chb_line = register_serial( &req )) >= 0) {
-		vme_init_port( &rs_table[chb_line], req.type, CHANNEL_B );
+		mvme_init_port( &rs_table[chb_line], req.type, CHANNEL_B );
 		++nr;
 	}
 	else
@@ -470,9 +603,9 @@
 	/* Init channel A, RS232 part (Serial2) */
 	req.line = 0;
 	req.type = SER_SCC_MVME;
-	req.port = SCC_A_ADDR;
+	req.port = MVME_SCC_A_ADDR;
 	if ((cha232_line = register_serial( &req )) >= 0) {
-		vme_init_port( &rs_table[cha232_line], req.type, CHANNEL_A );
+		mvme_init_port( &rs_table[cha232_line], req.type, CHANNEL_A );
 		++nr;
 	}
 	else
@@ -486,7 +619,7 @@
 }
 
 
-static void vme_init_port( struct m68k_async_struct *info, int type, int channel )
+static void mvme_init_port( struct m68k_async_struct *info, int type, int channel )
 {
 	static int called = 0, ch_a_inited = 0;
 	SCC_ACCESS_INIT(info);
@@ -496,17 +629,17 @@
 	/* set ISRs, but don't enable interrupts yet (done in init());
 	 */
 	if (channel == CHANNEL_B || !ch_a_inited) {
-		request_irq(channel ? IRQ_MVME162_SCCB_TX : IRQ_MVME162_SCCA_TX,
-		            SCC_tx_int, IRQ_MVME162_TYPE_PRIO,
+		request_irq(channel ? MVME162_IRQ_SCCB_TX : MVME162_IRQ_SCCA_TX,
+		            SCC_tx_int, MVME162_IRQ_TYPE_PRIO,
 		            channel ? "SCC-B TX" : "SCC-A TX", info);
-		request_irq(channel ? IRQ_MVME162_SCCB_STAT : IRQ_MVME162_SCCA_STAT,
-		            SCC_stat_int, IRQ_MVME162_TYPE_PRIO,
+		request_irq(channel ? MVME162_IRQ_SCCB_STAT : MVME162_IRQ_SCCA_STAT,
+		            SCC_stat_int, MVME162_IRQ_TYPE_PRIO,
 		            channel ? "SCC-B status" : "SCC-A status", info);
-		request_irq(channel ? IRQ_MVME162_SCCB_RX : IRQ_MVME162_SCCA_RX,
-		            SCC_rx_int, IRQ_MVME162_TYPE_PRIO,
+		request_irq(channel ? MVME162_IRQ_SCCB_RX : MVME162_IRQ_SCCA_RX,
+		            SCC_rx_int, MVME162_IRQ_TYPE_PRIO,
 		            channel ? "SCC-B RX" : "SCC-A RX", info);
-		request_irq(channel ? IRQ_MVME162_SCCB_SPCOND : IRQ_MVME162_SCCA_SPCOND,
-		            SCC_spcond_int, IRQ_MVME162_TYPE_PRIO,
+		request_irq(channel ? MVME162_IRQ_SCCB_SPCOND : MVME162_IRQ_SCCA_SPCOND,
+		            SCC_spcond_int, MVME162_IRQ_TYPE_PRIO,
 		            channel ? "SCC-B special cond" : "SCC-A special cond", info);
 
 	}
@@ -515,7 +648,7 @@
 
 	if (!called) {
 		/* Set the interrupt vector */
-		SCCwrite( INT_VECTOR_REG, IRQ_MVME162_SCC_BASE );
+		SCCwrite( INT_VECTOR_REG, MVME162_IRQ_SCC_BASE );
 
 		/* Interrupt parameters: vector includes status, status low */
 		SCCwrite( MASTER_INT_CTRL, MIC_VEC_INCL_STAT );
@@ -804,12 +937,21 @@
 #endif
 	}
 #endif
-#ifdef CONFIG_MVME162
+#ifdef CONFIG_MVME16x
 	if (MACH_IS_MVME16x) {
-		free_irq(channel ? IRQ_MVME162_SCCB_TX : IRQ_MVME162_SCCA_TX, info);
-		free_irq(channel ? IRQ_MVME162_SCCB_STAT : IRQ_MVME162_SCCA_STAT, info);
-		free_irq(channel ? IRQ_MVME162_SCCB_RX : IRQ_MVME162_SCCA_RX, info);
-		free_irq(channel ? IRQ_MVME162_SCCB_SPCOND : IRQ_MVME162_SCCA_SPCOND,
+		free_irq(channel ? MVME162_IRQ_SCCB_TX : MVME162_IRQ_SCCA_TX, info);
+		free_irq(channel ? MVME162_IRQ_SCCB_STAT : MVME162_IRQ_SCCA_STAT, info);
+		free_irq(channel ? MVME162_IRQ_SCCB_RX : MVME162_IRQ_SCCA_RX, info);
+		free_irq(channel ? MVME162_IRQ_SCCB_SPCOND : MVME162_IRQ_SCCA_SPCOND,
+			info);
+	}
+#endif
+#ifdef CONFIG_BVME6000
+	if (MACH_IS_BVME6000) {
+		free_irq(channel ? BVME_IRQ_SCCB_TX : BVME_IRQ_SCCA_TX, info);
+		free_irq(channel ? BVME_IRQ_SCCB_STAT : BVME_IRQ_SCCA_STAT, info);
+		free_irq(channel ? BVME_IRQ_SCCB_RX : BVME_IRQ_SCCA_RX, info);
+		free_irq(channel ? BVME_IRQ_SCCB_SPCOND : BVME_IRQ_SCCA_SPCOND,
 			info);
 	}
 #endif
@@ -1194,7 +1336,7 @@
 	struct m68k_async_struct *info = data;
 	unsigned char	ch;
 	SCC_ACCESS_INIT(info);
-	
+
 	SETUP_INFO(info);
 
 	ch = SCCread_NB( RX_DATA_REG );
@@ -1554,10 +1696,42 @@
 		  IDR_PARERR_AS_SPCOND | IDR_RX_INT_ALL }
 	};
 #endif
+#ifdef CONFIG_BVME6000_SCC
+	static const struct {
+		unsigned reg, val;
+	} bvme_init_tab[] = {
+		/* Values for BVME6000 */
+		/* no parity, 1 stop bit, async, 1:16 */
+		{ AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x16 },
+		/* parity error is special cond, ints disabled, no DMA */
+		{ INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB },
+		/* Rx 8 bits/char, no auto enable, Rx off */
+		{ RX_CTRL_REG, RCR_CHSIZE_8 },
+		/* DTR off, Tx 8 bits/char, RTS off, Tx off */
+		{ TX_CTRL_REG, TCR_CHSIZE_8 },
+		/* special features off */
+		{ AUX2_CTRL_REG, 0 },
+		{ CLK_CTRL_REG, CCR_RTxC_XTAL | CCR_RXCLK_BRG | CCR_TXCLK_BRG },
+		{ DPLL_CTRL_REG, DCR_BRG_ENAB },
+		/* Start Rx */
+		{ RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 },
+		/* Start Tx */
+		{ TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 },
+		/* Ext/Stat ints: CTS, DCD, SYNC (DSR) */
+		{ INT_CTRL_REG, ICR_ENAB_DCD_INT | ICR_ENAB_CTS_INT | ICR_ENAB_SYNC_INT },
+		/* Reset Ext/Stat ints */
+		{ COMMAND_REG, CR_EXTSTAT_RESET },
+		/* ...again */
+		{ COMMAND_REG, CR_EXTSTAT_RESET },
+		/* Rx int always, TX int off, Ext/Stat int on */
+		{ INT_AND_DMA_REG, IDR_EXTSTAT_INT_ENAB |
+		  IDR_PARERR_AS_SPCOND | IDR_RX_INT_ALL }
+	};
+#endif
 	save_flags(flags);
 	cli();
 
-	if (!MACH_IS_MVME16x) {
+	if (!MACH_IS_MVME16x && !MACH_IS_BVME6000) {
 		SCCmod( MASTER_INT_CTRL, 0x3f,
 			channel == 0 ? MIC_CH_A_RESET : MIC_CH_B_RESET );
 		udelay(40); /* extra delay after a reset */
@@ -1612,6 +1786,12 @@
 			SCCwrite( mvme_init_tab[i].reg, mvme_init_tab[i].val );
 	}
 #endif
+#ifdef CONFIG_BVME6000_SCC
+	if (MACH_IS_BVME6000) {
+		for (i=0; i<sizeof(bvme_init_tab)/sizeof(*bvme_init_tab); ++i)
+			SCCwrite( bvme_init_tab[i].reg, bvme_init_tab[i].val );
+	}
+#endif
 
 	/* remember status register for detection of DCD and CTS changes */
 	SCC_last_status_reg[channel] = SCCread( STATUS_REG );
@@ -1637,6 +1817,8 @@
 
 	if (MACH_IS_MVME16x && CHANNR(info) == CHANNEL_A)
 		return;		/* 162Bug uses channel A */
+	if (MACH_IS_BVME6000 && CHANNR(info) == CHANNEL_A)
+		return;		/* BVMbug uses channel A */
 
 	save_flags(flags);
 	cli();
@@ -1769,6 +1951,8 @@
 
 	if (MACH_IS_MVME16x && channel == CHANNEL_A)
 		return;		/* Settings controlled by 162Bug */
+	if (MACH_IS_BVME6000 && channel == CHANNEL_A)
+		return;		/* Settings controlled by BVMBug */
 
 	cflag  = info->tty->termios->c_cflag;
 	baud   = cflag & CBAUD;
@@ -2003,8 +2187,8 @@
 	printk( "SCC channel %d: get info, sr=%02x tcr=%02x\n",
 			CHANNR(info), sr, tcr );
 #endif
-#ifdef CONFIG_MVME162_SCC
-	if (MACH_IS_MVME16x) {
+#if defined(CONFIG_MVME162_SCC) || defined(CONFIG_BVME6000_SCC)
+	if (MACH_IS_MVME16x || MACH_IS_BVME6000) {
 		ri = 0;
 		dsr = sr & SR_SYNC_ABORT ? TIOCM_DSR : 0;
 	}
@@ -2074,7 +2258,7 @@
 	SCCmod (INT_AND_DMA_REG, ~IDR_RX_INT_MASK, 0);
 
 	/* disable Rx */
-	if (!(MACH_IS_MVME16x && CHANNR(info) == CHANNEL_A))
+	if (!((MACH_IS_MVME16x || MACH_IS_BVME6000) && CHANNR(info) == CHANNEL_A))
 		SCCmod (RX_CTRL_REG, ~RCR_RX_ENAB, 0);
 }
 
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/char/atari_SCC.h linuxvme-2.1.101/drivers/char/atari_SCC.h
--- linux68k-2.1.101/drivers/char/atari_SCC.h	Fri May  1 17:05:58 1998
+++ linuxvme-2.1.101/drivers/char/atari_SCC.h	Tue May 26 21:00:17 1998
@@ -19,6 +19,9 @@
 #ifdef CONFIG_MVME162_SCC
 #include <asm/mvme16xhw.h>
 #endif
+#ifdef CONFIG_BVME6000_SCC
+#include <asm/bvme6000hw.h>
+#endif
 #ifdef CONFIG_ATARI
 #include <asm/atarihw.h>
 #endif
@@ -325,7 +328,7 @@
 
 /* Compute the channel number from the base address */
 
-#define CHANNR(info)	(((info)->port & 4) != ChannelsReversed)
+#define CHANNR(info)	(((info)->port & (MACH_IS_BVME6000 ? 8 : 4)) != ChannelsReversed)
 
 
 /***********************************************************************/
@@ -358,7 +361,7 @@
 
 #define scc_reg_delay() \
     do {			\
-	if (MACH_IS_MVME16x)	\
+	if (MACH_IS_MVME16x || MACH_IS_BVME6000)	\
 		udelay(1);	\
 	else			\
 		__asm__ __volatile__ ( "tstb %0" : : "g" (*_scc_del) : "cc" );\
@@ -371,7 +374,7 @@
  */
 
 #define scc_reg3_delay() \
-	if (MACH_IS_MVME16x)	\
+	if (MACH_IS_MVME16x || MACH_IS_BVME6000)	\
 		udelay(1);	\
 	else			\
 		__asm__ __volatile__ ( "tstb %0" : : "g" (*_scc_del) : "cc" );
@@ -468,7 +471,7 @@
 
 	  case TX_DATA_REG:		/* WR8 */
 		/* TX_DATA_REG can be accessed directly on some h/w */
-		if (MACH_IS_MVME16x)
+		if (MACH_IS_MVME16x || MACH_IS_BVME6000)
 		{
 			sc->ctrl = regno;
 			scc_reg_delay();
@@ -533,12 +536,12 @@
 	  case INT_PENDING_REG:
 		/* RR3: read only from Channel A! */
 		sc = (volatile struct PARTIAL_SCC *)
-			(((unsigned long)sc & ~4) ^ ChannelsReversed);
+			(((unsigned long)sc & ~(MACH_IS_BVME6000 ? 8 : 4)) ^ ChannelsReversed);
 		goto normal_case;
 
 	  case RX_DATA_REG:
 		/* RR8 can be accessed directly on some h/w */
-		if (MACH_IS_MVME16x)
+		if (MACH_IS_MVME16x || MACH_IS_BVME6000)
 		{
 			sc->ctrl = 8;
 			scc_reg_delay();
@@ -551,7 +554,7 @@
 	  case CURR_VECTOR_REG:
 		/* RR2 (vector including status) from Ch. B */
 		sc = (volatile struct PARTIAL_SCC *)
-			(((unsigned long)sc | 4) ^ ChannelsReversed);
+			(((unsigned long)sc | (MACH_IS_BVME6000 ? 8 : 4)) ^ ChannelsReversed);
 		goto normal_case;
 		
 		/* --- reading write registers: access the shadow --- */
@@ -589,6 +592,22 @@
 	return rv;
 }
 
+/*
+ * The BVME6000 maps the two halves of the SCC 8 bytes apart rather than 4.
+ * My first attempt at doing this in assembler didn't work, so I've done it
+ * the easy way for now.  Richard.
+ */
+
+#ifdef CONFIG_BVME6000
+
+#define SCC_ACCESS_INIT(info)												\
+	volatile struct PARTIAL_SCC *_SCC_p =									\
+		(volatile struct PARTIAL_SCC *)info->port;							\
+	unsigned char *_SCC_shadow = SCC_shadow[0] +							\
+		(MACH_IS_BVME6000 ? ((u32)_SCC_p & 8) * 2 : ((u32)_SCC_p & 4) * 4)
+
+#else
+
 #define SCC_ACCESS_INIT(info)												\
 	volatile struct PARTIAL_SCC *_SCC_p =									\
 		(volatile struct PARTIAL_SCC *)info->port;							\
@@ -602,6 +621,8 @@
 					  : "d" (_SCC_p), "0" (_rv) );							\
 			_rv;															\
 		})
+
+#endif
 
 #define	SCCwrite(reg,val)		_SCCwrite(_SCC_p,_SCC_shadow,scc_del,(reg),(val),1)
 #define	SCCwrite_NB(reg,val)	_SCCwrite(_SCC_p,_SCC_shadow,scc_del,(reg),(val),0)
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/char/lp_intern.c linuxvme-2.1.101/drivers/char/lp_intern.c
--- linux68k-2.1.101/drivers/char/lp_intern.c	Tue Jan  6 17:33:04 1998
+++ linuxvme-2.1.101/drivers/char/lp_intern.c	Fri May 22 19:29:17 1998
@@ -32,6 +32,12 @@
 #include <asm/atarihw.h>
 #include <asm/atariints.h>
 #endif
+#ifdef CONFIG_MVME16x
+#include <asm/mvme16xhw.h>
+#endif
+#ifdef CONFIG_BVME6000
+#include<asm/bvme6000hw.h>
+#endif
 #include <linux/lp_intern.h>
 
 static int minor = -1;
@@ -71,6 +77,25 @@
 	 break;
        }
 #endif
+#ifdef CONFIG_MVME16x
+    case MACH_MVME16x:
+      {
+	int wait = 0;
+	while (wait != lp_table[dev]->wait) wait++;
+        mvmelp.data = c;
+        break;
+      }
+#endif
+#ifdef CONFIG_BVME6000
+    case MACH_BVME6000:
+      {
+	int wait = 0;
+	while (wait != lp_table[dev]->wait) wait++;
+        bvmepit.padr = c;
+        bvmepit.pacr |= 0x02;
+        break;
+      }
+#endif
     }
 }
 
@@ -87,6 +112,14 @@
     case MACH_ATARI:
       return mfp.par_dt_reg & 1;
 #endif
+#ifdef CONFIG_MVME16x
+    case MACH_MVME16x:
+      return mvmelp.isr & 1;
+#endif
+#ifdef CONFIG_BVME6000
+    case MACH_BVME6000:
+      return 0 /* !(bvmepit.psr & 0x40) */ ;
+#endif
     default:
       return 0;
     }
@@ -103,6 +136,15 @@
 #endif
 #ifdef CONFIG_ATARI
     case MACH_ATARI:
+      return 0;
+#endif
+#ifdef CONFIG_MVME16x
+    case MACH_MVME16x:
+      return mvmelp.isr & 2;
+#endif
+#ifdef CONFIG_BVME6000
+    case MACH_BVME6000:
+      return 0;
 #endif
     default:
       return 0;
@@ -122,6 +164,14 @@
     case MACH_ATARI:
       return !(mfp.par_dt_reg & 1);
 #endif
+#ifdef CONFIG_MVME16x
+    case MACH_MVME16x:
+      return mvmelp.isr & 4;
+#endif
+#ifdef CONFIG_BVME6000
+    case MACH_BVME6000:
+      return 1;
+#endif
     default:
       return 0;
     }
@@ -129,6 +179,14 @@
 
 static void lp_int_interrupt(int irq, void *data, struct pt_regs *fp)
 {
+#ifdef CONFIG_MVME16x
+  if (MACH_IS_MVME16x)
+    mvmelp.ack_icr |= 0x08;
+#endif
+#ifdef CONFIG_BVME6000
+  if (MACH_IS_BVME6000)
+    bvmepit.pacr &= ~0x02;
+#endif
   lp_interrupt(minor);
 }
 
@@ -197,6 +255,58 @@
     if (MACH_IS_MAC)
     	return -ENODEV;
 #endif
+#ifdef CONFIG_MVME16x
+    if (MACH_IS_MVME16x)
+    {
+      unsigned long flags;
+
+      if (!(mvme16x_config & MVME16x_CONFIG_GOT_LP))
+        return -ENODEV;
+
+      save_flags(flags);
+      cli();
+      mvmelp.ack_icr = 0x08;
+      mvmelp.flt_icr = 0x08;
+      mvmelp.sel_icr = 0x08;
+      mvmelp.pe_icr =  0x08;
+      mvmelp.bsy_icr = 0x08;
+      mvmelp.cr =      0x10;
+      mvmelp.ack_icr = 0xd9; /* Int on trailing edge of ACK */
+      restore_flags(flags);
+
+      if (lp_irq)
+        tab.irq = request_irq(MVME167_IRQ_PRN, lp_int_interrupt,
+          0, "builtin printer port", lp_int_interrupt);
+      tab.base = (void *)&mvmelp; /* dummy, not used */
+      tab.type = LP_MVME167;
+    }
+#endif
+#ifdef CONFIG_BVME6000
+    if (MACH_IS_BVME6000)
+    {
+      unsigned long flags;
+
+      save_flags(flags);
+      cli();
+      bvmepit.pgcr =   0x0f;
+      bvmepit.psrr =   0x18;
+      bvmepit.paddr =  0xff;
+      bvmepit.pcdr  =  (bvmepit.pcdr & 0xfc) | 0x02;
+      bvmepit.pcddr |= 0x03;
+      bvmepit.pacr =   0x78;
+      bvmepit.pbcr =   0x00;
+      bvmepit.pivr =   BVME_IRQ_PRN;
+      bvmepit.pgcr =   0x1f;
+      restore_flags(flags);
+
+      if (lp_irq)
+        tab.irq = request_irq(BVME_IRQ_PRN, lp_int_interrupt,
+          0, "builtin printer port", lp_int_interrupt);
+      tab.base = (void *)&bvmepit; /* dummy, not used */
+      tab.type = LP_BVME6000;
+    }
+#endif
+
 
   if ((minor = register_parallel(&tab, minor)) < 0) {
     printk("builtin lp init: cant get a minor\n");
@@ -209,6 +319,14 @@
       if (MACH_IS_ATARI)
 	free_irq(IRQ_MFP_BUSY, lp_int_interrupt);
 #endif
+#ifdef CONFIG_MVME16x
+      if (MACH_IS_MVME16x)
+        free_irq(MVME167_IRQ_PRN, lp_int_interrupt);
+#endif
+#ifdef CONFIG_BVME6000
+      if (MACH_IS_BVME6000)
+        free_irq(BVME_IRQ_PRN, lp_int_interrupt);
+#endif
     }
     return -ENODEV;
   }
@@ -232,6 +350,14 @@
 #ifdef CONFIG_ATARI
   if (MACH_IS_ATARI)
     free_irq(IRQ_MFP_BUSY, lp_int_interrupt);
+#endif
+#ifdef CONFIG_MVME16x
+  if (MACH_IS_MVME16x)
+    free_irq(MVME167_IRQ_PRN, lp_int_interrupt);
+#endif
+#ifdef CONFIG_BVME6000
+  if (MACH_IS_BVME6000)
+    free_irq(BVME_IRQ_PRN, lp_int_interrupt);
 #endif
 }
 unregister_parallel(minor);
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/char/m68kserial.c linuxvme-2.1.101/drivers/char/m68kserial.c
--- linux68k-2.1.101/drivers/char/m68kserial.c	Fri May 22 19:15:02 1998
+++ linuxvme-2.1.101/drivers/char/m68kserial.c	Fri May 22 19:50:09 1998
@@ -111,7 +111,11 @@
 #endif
 
 #ifdef CONFIG_MVME162_SCC
-int vme_SCC_init(void);
+int mvme_SCC_init(void);
+#endif
+
+#ifdef CONFIG_BVME6000_SCC
+int bvme_SCC_init(void);
 #endif
 
 #ifdef CONFIG_WHIPPET
@@ -169,9 +173,10 @@
 	"MIDI",
 	"Amiga builtin", "GVP IO-Extender (16c552)", "BSC MultiFaceCard III",
 	"Hisoft Whippet",
-	"SCC on VME",
+	"SCC on MVME",
 	"8350 ESCC w/o DMA",
-	"HP DCA"
+	"HP DCA",
+	"SCC on BVME"
 };
 #define M68K_PORT_MAX (sizeof(serialtypes68k)/sizeof(*serialtypes68k))
 #endif
@@ -1487,7 +1492,12 @@
 	    break;
 	case MACH_MVME16x:
 #ifdef CONFIG_MVME162_SCC
-	    vme_SCC_init();
+	    mvme_SCC_init();
+#endif
+	    break;
+	case MACH_BVME6000:
+#ifdef CONFIG_BVME6000_SCC
+	    bvme_SCC_init();
 #endif
 	    break;
 	case MACH_MAC:
@@ -1646,6 +1656,7 @@
 extern int atari_midi_console_wait_key(struct console *co);
 extern void atari_init_midi_port( int cflag );
 extern void mvme16x_init_console_port (struct console *co, int cflag);
+extern void bvme6000_init_console_port (struct console *co, int cflag);
 
 extern void hpdca_serial_console_write(struct console *co, const char *str,
 					unsigned int count);
@@ -1752,6 +1763,8 @@
 	}
 	else if (MACH_IS_MVME16x && co->index == 0)
 		mvme16x_init_console_port (co, cflag);
+	else if (MACH_IS_BVME6000 && co->index == 0)
+		bvme6000_init_console_port (co, cflag);
 	else if (MACH_IS_HP300 && co->index == 0) {
 		co->write = hpdca_serial_console_write;
 		co->wait_key = hpdca_serial_console_wait_key;
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/char/mem.c linuxvme-2.1.101/drivers/char/mem.c
--- linux68k-2.1.101/drivers/char/mem.c	Fri May  1 17:06:01 1998
+++ linuxvme-2.1.101/drivers/char/mem.c	Fri May 22 19:51:53 1998
@@ -180,6 +180,7 @@
 			     vma->vm_page_prot))
 		return -EAGAIN;
 	vma->vm_file = file;
+	vma->vm_flags |= VM_IO;	/* So we dont add to core file!!! */
 	file->f_count++;
 	return 0;
 }
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/char/misc.c linuxvme-2.1.101/drivers/char/misc.c
--- linux68k-2.1.101/drivers/char/misc.c	Wed Mar 18 16:02:53 1998
+++ linuxvme-2.1.101/drivers/char/misc.c	Fri May 22 19:29:18 1998
@@ -79,6 +79,8 @@
 extern void acq_init(void);
 extern void pcwatchdog_init(void);
 extern int rtc_init(void);
+extern int rtc_DP8570A_init(void);
+extern int rtc_MK48T08_init(void);
 extern int dsp56k_init(void);
 extern int nvram_init(void);
 extern int radio_init(void);
@@ -259,6 +261,12 @@
 #endif
 #ifdef CONFIG_H8
 	h8_init();
+#endif
+#ifdef CONFIG_MVME16x
+	rtc_MK48T08_init();
+#endif
+#ifdef CONFIG_BVME6000
+	rtc_DP8570A_init();
 #endif
 #ifdef CONFIG_RTC
 	rtc_init();
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/char/serial167.c linuxvme-2.1.101/drivers/char/serial167.c
--- linux68k-2.1.101/drivers/char/serial167.c	Thu Jan  8 14:02:58 1998
+++ linuxvme-2.1.101/drivers/char/serial167.c	Fri May 22 19:29:21 1998
@@ -120,10 +120,10 @@
 /* This is the per-port data structure */
 struct cyclades_port cy_port[] = {
       /* CARD#  */
-        {-1 },      /* ttyC0 */
-        {-1 },      /* ttyC1 */
-        {-1 },      /* ttyC2 */
-        {-1 },      /* ttyC3 */
+        {-1 },      /* ttyS0 */
+        {-1 },      /* ttyS1 */
+        {-1 },      /* ttyS2 */
+        {-1 },      /* ttyS3 */
 };
 #define NR_PORTS        (sizeof(cy_port)/sizeof(struct cyclades_port))
 
@@ -337,7 +337,7 @@
   unsigned long flags;
 
 #ifdef SERIAL_DEBUG_OTHER
-    printk("cy_stop ttyC%d\n", info->line); /* */
+    printk("cy_stop ttyS%d\n", info->line); /* */
 #endif
 
     if (serial_paranoia_check(info, tty->device, "cy_stop"))
@@ -362,7 +362,7 @@
   unsigned long flags;
 
 #ifdef SERIAL_DEBUG_OTHER
-    printk("cy_start ttyC%d\n", info->line); /* */
+    printk("cy_start ttyS%d\n", info->line); /* */
 #endif
 
     if (serial_paranoia_check(info, tty->device, "cy_start"))
@@ -1169,7 +1169,7 @@
   unsigned long flags;
 
 #ifdef SERIAL_DEBUG_IO
-    printk("cy_put_char ttyC%d(0x%02x)\n", info->line, ch);
+    printk("cy_put_char ttyS%d(0x%02x)\n", info->line, ch);
 #endif
 
     if (serial_paranoia_check(info, tty->device, "cy_put_char"))
@@ -1200,7 +1200,7 @@
   int channel;
 				
 #ifdef SERIAL_DEBUG_IO
-    printk("cy_flush_chars ttyC%d\n", info->line); /* */
+    printk("cy_flush_chars ttyS%d\n", info->line); /* */
 #endif
 
     if (serial_paranoia_check(info, tty->device, "cy_flush_chars"))
@@ -1234,7 +1234,7 @@
   int c, total = 0;
 
 #ifdef SERIAL_DEBUG_IO
-    printk("cy_write ttyC%d\n", info->line); /* */
+    printk("cy_write ttyS%d\n", info->line); /* */
 #endif
 
     if (serial_paranoia_check(info, tty->device, "cy_write")){
@@ -1288,7 +1288,7 @@
   int	ret;
 				
 #ifdef SERIAL_DEBUG_IO
-    printk("cy_write_room ttyC%d\n", info->line); /* */
+    printk("cy_write_room ttyS%d\n", info->line); /* */
 #endif
 
     if (serial_paranoia_check(info, tty->device, "cy_write_room"))
@@ -1306,7 +1306,7 @@
   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
 				
 #ifdef SERIAL_DEBUG_IO
-    printk("cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt); /* */
+    printk("cy_chars_in_buffer ttyS%d %d\n", info->line, info->xmit_cnt); /* */
 #endif
 
     if (serial_paranoia_check(info, tty->device, "cy_chars_in_buffer"))
@@ -1323,7 +1323,7 @@
   unsigned long flags;
 				
 #ifdef SERIAL_DEBUG_IO
-    printk("cy_flush_buffer ttyC%d\n", info->line); /* */
+    printk("cy_flush_buffer ttyS%d\n", info->line); /* */
 #endif
 
     if (serial_paranoia_check(info, tty->device, "cy_flush_buffer"))
@@ -1355,7 +1355,7 @@
 	
     printk("throttle %s: %d....\n", _tty_name(tty, buf),
 	   tty->ldisc.chars_in_buffer(tty));
-    printk("cy_throttle ttyC%d\n", info->line);
+    printk("cy_throttle ttyS%d\n", info->line);
 #endif
 
     if (serial_paranoia_check(info, tty->device, "cy_nthrottle")){
@@ -1391,7 +1391,7 @@
 	
     printk("throttle %s: %d....\n", _tty_name(tty, buf),
 	   tty->ldisc.chars_in_buffer(tty));
-    printk("cy_unthrottle ttyC%d\n", info->line);
+    printk("cy_unthrottle ttyS%d\n", info->line);
 #endif
 
     if (serial_paranoia_check(info, tty->device, "cy_nthrottle")){
@@ -1709,7 +1709,7 @@
   int ret_val = 0;
 
 #ifdef SERIAL_DEBUG_OTHER
-    printk("cy_ioctl ttyC%d, cmd = %x arg = %lx\n", info->line, cmd, arg); /* */
+    printk("cy_ioctl ttyS%d, cmd = %x arg = %lx\n", info->line, cmd, arg); /* */
 #endif
 
     switch (cmd) {
@@ -1858,7 +1858,7 @@
   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
 
 #ifdef SERIAL_DEBUG_OTHER
-    printk("cy_set_termios ttyC%d\n", info->line);
+    printk("cy_set_termios ttyS%d\n", info->line);
 #endif
 
     if (tty->termios->c_cflag == old_termios->c_cflag)
@@ -1887,7 +1887,7 @@
 
 /* CP('C'); */
 #ifdef SERIAL_DEBUG_OTHER
-    printk("cy_close ttyC%d\n", info->line);
+    printk("cy_close ttyS%d\n", info->line);
 #endif
 
     if (!info
@@ -1895,7 +1895,7 @@
         return;
     }
 #ifdef SERIAL_DEBUG_OPEN
-    printk("cy_close ttyC%d, count = %d\n", info->line, info->count);
+    printk("cy_close ttyS%d, count = %d\n", info->line, info->count);
 #endif
 
     if ((tty->count == 1) && (info->count != 1)) {
@@ -1977,7 +1977,7 @@
   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
 	
 #ifdef SERIAL_DEBUG_OTHER
-    printk("cy_hangup ttyC%d\n", info->line); /* */
+    printk("cy_hangup ttyS%d\n", info->line); /* */
 #endif
 
     if (serial_paranoia_check(info, tty->device, "cy_hangup"))
@@ -2071,7 +2071,7 @@
     retval = 0;
     add_wait_queue(&info->open_wait, &wait);
 #ifdef SERIAL_DEBUG_OPEN
-    printk("block_til_ready before block: ttyC%d, count = %d\n",
+    printk("block_til_ready before block: ttyS%d, count = %d\n",
 	   info->line, info->count);/**/
 #endif
     info->count--;
@@ -2121,7 +2121,7 @@
 	    break;
 	}
 #ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready blocking: ttyC%d, count = %d\n",
+	printk("block_til_ready blocking: ttyS%d, count = %d\n",
 	       info->line, info->count);/**/
 #endif
 	schedule();
@@ -2136,7 +2136,7 @@
     }
     info->blocked_open--;
 #ifdef SERIAL_DEBUG_OPEN
-    printk("block_til_ready after blocking: ttyC%d, count = %d\n",
+    printk("block_til_ready after blocking: ttyS%d, count = %d\n",
 	   info->line, info->count);/**/
 #endif
     if (retval)
@@ -2165,13 +2165,13 @@
         return -ENODEV;
     }
 #ifdef SERIAL_DEBUG_OTHER
-    printk("cy_open ttyC%d\n", info->line); /* */
+    printk("cy_open ttyS%d\n", info->line); /* */
 #endif
     if (serial_paranoia_check(info, tty->device, "cy_open")){
         return -ENODEV;
     }
 #ifdef SERIAL_DEBUG_OPEN
-    printk("cy_open ttyC%d, count = %d\n", info->line, info->count);/**/
+    printk("cy_open ttyS%d, count = %d\n", info->line, info->count);/**/
 #endif
     info->count++;
 #ifdef SERIAL_DEBUG_COUNT
@@ -2511,7 +2511,7 @@
                                        | CyPARITY| CyFRAME| CyOVERRUN;
 		/* info->timeout */
 
-		printk("ttyC%1d ", info->line);
+		printk("ttyS%1d ", info->line);
 		port_num++;info++;
 		if(!(port_num & 7)){
 		    printk("\n               ");
@@ -2527,17 +2527,19 @@
 #ifdef CONFIG_REMOTE_DEBUG
     debug_setup();
 #endif
-    if (request_irq (IRQ_MVME167_SER_ERR, cd2401_rxerr_interrupt, 0,
+    if (request_irq (MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt, 0,
 				"cd2401_errors", cd2401_rxerr_interrupt) ||
-	request_irq (IRQ_MVME167_SER_MODEM, cd2401_modem_interrupt, 0,
+	request_irq (MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt, 0,
 				"cd2401_modem", cd2401_modem_interrupt) ||
-	request_irq (IRQ_MVME167_SER_TX, cd2401_tx_interrupt, 0,
+	request_irq (MVME167_IRQ_SER_TX, cd2401_tx_interrupt, 0,
 				"cd2401_txints", cd2401_tx_interrupt) ||
-	request_irq (IRQ_MVME167_SER_RX, cd2401_rx_interrupt, 0,
+	request_irq (MVME167_IRQ_SER_RX, cd2401_rx_interrupt, 0,
 				"cd2401_rxints", cd2401_rx_interrupt))
     {
 	panic ("Couldn't get serial IRQs");
     }
+
+    /* Now we have registered the interrupt handlers, allow the interrupts */
 
     pcc2chip[PccSCCMICR] = 0x15;		/* Serial ints are level 5 */
     pcc2chip[PccSCCTICR] = 0x15;
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/char/tty_io.c linuxvme-2.1.101/drivers/char/tty_io.c
--- linux68k-2.1.101/drivers/char/tty_io.c	Wed Apr 29 16:43:39 1998
+++ linuxvme-2.1.101/drivers/char/tty_io.c	Fri May 22 19:29:22 1998
@@ -2057,7 +2057,8 @@
     defined(CONFIG_ATARI_SCC) || defined(CONFIG_ATARI_MIDI) || \
     defined(CONFIG_AMIGA_BUILTIN_SERIAL) || defined(CONFIG_GVIOEXT) || \
     defined(CONFIG_MULTIFACE_III_TTY) || defined(CONFIG_USERIAL) || \
-    defined(CONFIG_MVME162_SCC) || defined(CONFIG_MAC_SCC)
+    defined(CONFIG_MVME162_SCC) || defined(CONFIG_MAC_SCC) || \
+    defined(CONFIG_BVME6000_SCC)
 	rs_init();
 #endif
 #ifdef CONFIG_ROCKETPORT
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/scsi/53c7xx.c linuxvme-2.1.101/drivers/scsi/53c7xx.c
--- linux68k-2.1.101/drivers/scsi/53c7xx.c	Wed Apr 29 12:47:03 1998
+++ linuxvme-2.1.101/drivers/scsi/53c7xx.c	Tue May 26 20:30:52 1998
@@ -273,6 +273,15 @@
 #define VALID_IDS
 #endif
 
+#ifdef CONFIG_BVME6000
+#include <asm/pgtable.h>
+#include <asm/bvme6000hw.h>
+
+#define BIG_ENDIAN
+#define NO_IO_SPACE
+#define VALID_IDS
+#endif
+
 #include "scsi.h"
 #include "hosts.h"
 #include "53c7xx.h"
@@ -791,7 +800,7 @@
     hostdata->talked_to = 0;
     hostdata->idle = 1;
 
-    if (!MACH_IS_MVME16x)
+    if (!MACH_IS_MVME16x && !MACH_IS_BVME6000)
 	cache_push(virt_to_bus(hostdata->script), flushsize);
 }
 
@@ -981,26 +990,23 @@
      * default value may not be optimal anyway.
      * Even worse, it may never have been set up since reset.
      */
-	hostdata->saved_ctest7 = NCR53c7x0_read8(CTEST7_REG) & CTEST7_SAVE;
-	revision = (NCR53c7x0_read8(CTEST8_REG) & 0xF0) >> 4;
-	switch (revision) {
-		case 1:
-			revision = 0;
-			break;
-		case 2:
-			revision = 1;
-			break;
-		case 4: 
-			revision = 2;
-			break;
-		case 8:
-			revision = 3;
-			break;
-		default:
-			revision = 255;
-			break;
-	}
-	printk("scsi%d: Revision 0x%x\n",host->host_no,revision);
+    hostdata->saved_ctest7 = NCR53c7x0_read8(CTEST7_REG) & CTEST7_SAVE;
+    revision = (NCR53c7x0_read8(CTEST8_REG) & 0xF0) >> 4;
+    switch (revision) {
+	case 1: revision = 0;    break;
+	case 2: revision = 1;    break;
+	case 4: revision = 2;    break;
+	case 8: revision = 3;    break;
+	default: revision = 255; break;
+    }
+    printk("scsi%d: Revision 0x%x\n",host->host_no,revision);
+
+    if ((revision == 0 || revision == 255) && (hostdata->options & (OPTION_SYNCHRONOUS|OPTION_DISCONNECT|OPTION_ALWAYS_SYNCHRONOUS)))
+    {
+	printk ("scsi%d: Disabling sync working and disconnect/reselect\n",
+							host->host_no);
+	hostdata->options &= ~(OPTION_SYNCHRONOUS|OPTION_DISCONNECT|OPTION_ALWAYS_SYNCHRONOUS);
+    }
 
     /*
      * On NCR53c700 series chips, DCNTL controls the SCSI clock divisor,
@@ -1070,22 +1076,34 @@
      */
 
 #ifdef CONFIG_MVME16x
-    if (request_irq(IRQ_MVME16x_SCSI, NCR53c7x0_intr, 0, "SCSI-script", NULL))
-	panic ("Couldn't get SCSI IRQ");
+    if (MACH_IS_MVME16x)
+    {
+        if (request_irq(MVME16x_IRQ_SCSI, NCR53c7x0_intr, 0, "SCSI-script", NULL))
+	    panic ("Couldn't get SCSI IRQ");
 #ifdef MVME16x_INTFLY
-    else if (request_irq(IRQ_MVME16x_FLY, NCR53c7x0_intr, 0, "SCSI-intfly", NULL))
-	panic ("Couldn't get INT_FLY IRQ");
+        else if (request_irq(MVME16x_IRQ_FLY, NCR53c7x0_intr, 0, "SCSI-intfly", NULL))
+	    panic ("Couldn't get INT_FLY IRQ");
 #endif
-#else
+    }
+#endif
+#ifdef CONFIG_BVME6000
+    if (MACH_IS_BVME6000)
+    {
+        if (request_irq(BVME_IRQ_SCSI, NCR53c7x0_intr, 0, "SCSI-script", NULL))
+            panic ("Couldn't get SCSI IRQ");
+    }
+#endif
+#ifndef CONFIG_VME
     for (search = first_host; search && !(search->hostt == the_template &&
 	search->irq == host->irq && search != host); search=search->next);
 
     if (!search) {
 #ifdef CONFIG_AMIGA
-	if (request_irq(IRQ_AMIGA_PORTS, NCR53c7x0_intr, 0, "53c7xx", NCR53c7x0_intr)) {
+	if (request_irq(IRQ_AMIGA_PORTS, NCR53c7x0_intr, 0, "53c7xx", NCR53c7x0_intr))
 #else
-	if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7xx", NULL)) {
+	if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7xx", NULL))
 #endif
+	{
 	    printk("scsi%d : IRQ%d not free, detaching\n"
 	           "         You have either a configuration problem, or a\n"
                    "         broken BIOS.  You may wish to manually assign\n"
@@ -1406,7 +1424,7 @@
      * register.  Make sure SCRIPTS start automagically.
      */
 
-#if defined(CONFIG_MVME16x)
+#if defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000)
     /* We know better what we want than 16xBug does! */
     tmp = DMODE_10_BL_8 | DMODE_10_FC2;
 #else
@@ -1557,7 +1575,7 @@
     printk("scsi%d : NCR code relocated to 0x%lx (virt 0x%p)\n", host->host_no,
 	virt_to_bus(hostdata->script), hostdata->script);
 
-    if (!MACH_IS_MVME16x)
+    if (!MACH_IS_MVME16x && !MACH_IS_BVME6000)
 	cache_push(virt_to_bus(hostdata->script), flushsize);
 }
 
@@ -1612,7 +1630,7 @@
 	start = virt_to_bus (hostdata->script) + hostdata->E_test_1;
     	hostdata->state = STATE_RUNNING;
 	printk ("scsi%d : test 1", host->host_no);
-	if (!MACH_IS_MVME16x)
+	if (!MACH_IS_MVME16x && !MACH_IS_BVME6000)
 	    cache_push(virt_to_bus(hostdata->script), flushsize);
 	NCR53c7x0_write32 (DSP_REG, start);
 	if (hostdata->options & OPTION_DEBUG_TRACE)
@@ -1707,7 +1725,7 @@
 	    hostdata->test_completed = -1;
 	    start = virt_to_bus(hostdata->script) + hostdata->E_test_2;
 	    hostdata->state = STATE_RUNNING;
-	    if(!MACH_IS_MVME16x)
+	    if(!MACH_IS_MVME16x && !MACH_IS_BVME6000)
 		cache_clear(virt_to_bus(hostdata->script), flushsize);
 	    NCR53c7x0_write32 (DSA_REG, virt_to_bus(dsa));
 	    NCR53c7x0_write32 (DSP_REG, start);
@@ -1815,7 +1833,7 @@
     patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
 	dsa_temp_addr_dsa_value, virt_to_bus(&cmd->dsa_addr));
 
-    if (!MACH_IS_MVME16x) {
+    if (!MACH_IS_MVME16x && !MACH_IS_BVME6000) {
 	cache_push(virt_to_bus(hostdata->script), flushsize);
     	cache_push(virt_to_bus(cmd->dsa), flushsize);
     }
@@ -2888,7 +2906,7 @@
 	return SPECIFIC_INT_PANIC;
     }
 
-    if (!MACH_IS_MVME16x)
+    if (!MACH_IS_MVME16x && !MACH_IS_BVME6000)
 	flush_cache_all();
 }
 
@@ -2927,9 +2945,6 @@
 NCR53c7x0_soft_reset (struct Scsi_Host *host) {
     NCR53c7x0_local_declare();
     unsigned long flags;
-#ifdef CONFIG_MVME16x
-    volatile unsigned long v;
-#endif
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
 	host->hostdata;
     NCR53c7x0_local_setup(host);
@@ -2940,15 +2955,19 @@
     /* Disable scsi chip and s/w level 7 ints */
 
 #ifdef CONFIG_MVME16x
-    v = *(volatile unsigned long *)0xfff4006c;
-    v &= ~0x8000;
-    *(volatile unsigned long *)0xfff4006c = v;
-    v = *(volatile unsigned long *)0xfff4202c;
-    v &= ~0x10;
-    *(volatile unsigned long *)0xfff4202c = v;
-#else
-    /* Anything specific for your hardware? */
+    if (MACH_IS_MVME16x)
+    {
+        volatile unsigned long v;
+
+        v = *(volatile unsigned long *)0xfff4006c;
+        v &= ~0x8000;
+        *(volatile unsigned long *)0xfff4006c = v;
+        v = *(volatile unsigned long *)0xfff4202c;
+        v &= ~0x10;
+        *(volatile unsigned long *)0xfff4202c = v;
+    }
 #endif
+    /* Anything specific for your hardware? */
 
     /*
      * Do a soft reset of the chip so that everything is 
@@ -3015,20 +3034,23 @@
 		SIEN_SGE | SIEN_MA);
 
 #ifdef CONFIG_MVME16x
-    /* Enable scsi chip and s/w level 7 ints */
+    if (MACH_IS_MVME16x)
+    {
+        volatile unsigned long v;
 
-    v = *(volatile unsigned long *)0xfff40080;
-    v = (v & ~(0xf << 28)) | (4 << 28);
-    *(volatile unsigned long *)0xfff40080 = v;
-    v = *(volatile unsigned long *)0xfff4006c;
-    v |= 0x8000;
-    *(volatile unsigned long *)0xfff4006c = v;
-    v = *(volatile unsigned long *)0xfff4202c;
-    v = (v & ~0xff) | 0x10 | 4;
-    *(volatile unsigned long *)0xfff4202c = v;
-#else
-    /* Anything needed for your hardware */
+        /* Enable scsi chip and s/w level 7 ints */
+        v = *(volatile unsigned long *)0xfff40080;
+        v = (v & ~(0xf << 28)) | (4 << 28);
+        *(volatile unsigned long *)0xfff40080 = v;
+        v = *(volatile unsigned long *)0xfff4006c;
+        v |= 0x8000;
+        *(volatile unsigned long *)0xfff4006c = v;
+        v = *(volatile unsigned long *)0xfff4202c;
+        v = (v & ~0xff) | 0x10 | 4;
+        *(volatile unsigned long *)0xfff4202c = v;
+    }
 #endif
+    /* Anything needed for your hardware? */
     restore_flags(flags);
 }
 
@@ -3711,7 +3733,7 @@
      * soon as it is idle.
      */
 
-    if (!MACH_IS_MVME16x)
+    if (!MACH_IS_MVME16x && !MACH_IS_BVME6000)
 	flush_cache_all();
 
     if (hostdata->idle) {
@@ -4118,7 +4140,7 @@
 			/* We have two different interrupts pointing
 			 * at this routine, so remove this check */
 #else
-				&& host->irq == irq
+				&& host->irq == irq
 #endif
 							) {
     	    NCR53c7x0_local_setup(host);
@@ -4326,7 +4348,7 @@
 #endif
 		
 		hostdata->state = STATE_RUNNING;
-		if (!MACH_IS_MVME16x)
+		if (!MACH_IS_MVME16x && !MACH_IS_BVME6000)
 		    flush_cache_all();
 		NCR53c7x0_write32 (DSP_REG, virt_to_bus(hostdata->dsp));
 		if (hostdata->options & OPTION_DEBUG_TRACE) {
@@ -4737,7 +4759,7 @@
     }
 #endif
 
-    if (!MACH_IS_MVME16x)
+    if (!MACH_IS_MVME16x && !MACH_IS_BVME6000)
 	cache_push(virt_to_bus(hostdata->script), flushsize);
 }
 
@@ -5083,7 +5105,7 @@
  * FIXME : (void *) cast in virt_to_bus should be unnecessary, because
  * 	it should take const void * as argument.
  */
-#ifndef CONFIG_MVME16x
+#if !defined(CONFIG_MVME16x) && !defined(CONFIG_BVME6000)
 	sprintf(buf, "%s0x%lx (virt 0x%p) : 0x%08x 0x%08x (virt 0x%p)", 
 	    (prefix ? prefix : ""), virt_to_bus((void *) insn), insn,  
 	    insn[0], insn[1], bus_to_virt (insn[1]));
@@ -5096,7 +5118,7 @@
 #endif
 	tmp = buf + strlen(buf);
 	if ((dcmd & DCMD_TYPE_MASK) == DCMD_TYPE_MMI)  {
-#ifndef CONFIG_MVME16x
+#if !defined(CONFIG_MVME16x) && !defined(CONFIG_BVME6000)
 	    sprintf (tmp, " 0x%08x (virt 0x%p)\n", insn[2], 
 		bus_to_virt(insn[2]));
 #else
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/scsi/Makefile linuxvme-2.1.101/drivers/scsi/Makefile
--- linux68k-2.1.101/drivers/scsi/Makefile	Fri May 22 19:15:02 1998
+++ linuxvme-2.1.101/drivers/scsi/Makefile	Fri May 22 19:29:24 1998
@@ -123,6 +123,14 @@
   endif
 endif
 
+ifeq ($(CONFIG_BVME6000_SCSI),y)
+L_OBJS += bvme6000.o 53c7xx.o
+else
+  ifeq ($(CONFIG_BVME6000_SCSI),m)
+  M_OBJS += bvme6000.o 53c7xx.o
+  endif
+endif
+
 ifeq ($(CONFIG_A4000T_SCSI),y)
 L_OBJS += amiga7xx.o 53c7xx.o
 else
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/scsi/bvme6000.c linuxvme-2.1.101/drivers/scsi/bvme6000.c
--- linux68k-2.1.101/drivers/scsi/bvme6000.c	Thu Jan  1 00:00:00 1970
+++ linuxvme-2.1.101/drivers/scsi/bvme6000.c	Fri May 22 19:29:24 1998
@@ -0,0 +1,58 @@
+/*
+ * Detection routine for the NCR53c710 based MVME16x SCSI Controllers for Linux.
+ *
+ * Based on work by Alan Hourihane
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/blk.h>
+#include <linux/sched.h>
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/zorro.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/bvme6000hw.h>
+#include <asm/irq.h>
+
+#include "scsi.h"
+#include "hosts.h"
+#include "53c7xx.h"
+#include "bvme6000.h"
+
+#include<linux/stat.h>
+
+struct proc_dir_entry proc_scsi_bvme6000 = {
+    PROC_SCSI_BVME6000, 8, "BVME6000",
+    S_IFDIR | S_IRUGO | S_IXUGO, 2
+};
+
+extern ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip,
+			u32 base, int io_port, int irq, int dma,
+			long long options, int clock);
+
+int bvme6000_scsi_detect(Scsi_Host_Template *tpnt)
+{
+    static unsigned char called = 0;
+    int clock;
+    long long options;
+
+    if (called)
+	return 0;
+    if (!MACH_IS_BVME6000)
+	return 0;
+
+    tpnt->proc_dir = &proc_scsi_bvme6000;
+
+    options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT;
+
+    clock = 40000000;	/* 66MHz SCSI Clock */
+
+    ncr53c7xx_init(tpnt, 0, 710, (u32)BVME_NCR53C710_BASE,
+			0, BVME_IRQ_SCSI, DMA_NONE,
+			options, clock);
+    called = 1;
+    return 1;
+}
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/scsi/bvme6000.h linuxvme-2.1.101/drivers/scsi/bvme6000.h
--- linux68k-2.1.101/drivers/scsi/bvme6000.h	Thu Jan  1 00:00:00 1970
+++ linuxvme-2.1.101/drivers/scsi/bvme6000.h	Fri May 22 20:31:16 1998
@@ -0,0 +1,43 @@
+#ifndef BVME6000_SCSI_H
+#define BVME6000_SCSI_H
+
+#include <linux/types.h>
+
+int bvme6000_scsi_detect(Scsi_Host_Template *);
+const char *NCR53c7x0_info(void);
+int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+int NCR53c7xx_abort(Scsi_Cmnd *);
+int NCR53c7x0_release (struct Scsi_Host *);
+int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
+void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef CMD_PER_LUN
+#define CMD_PER_LUN 3
+#endif
+
+#ifndef CAN_QUEUE
+#define CAN_QUEUE 24
+#endif
+
+#if defined(HOSTS_C) || defined(MODULE)
+#include <scsi/scsicam.h>
+
+extern struct proc_dir_entry proc_scsi_mvme16x;
+
+#define BVME6000_SCSI  {name:                "BVME6000 NCR53c710 SCSI", \
+		       detect:              bvme6000_scsi_detect,    \
+		       queuecommand:        NCR53c7xx_queue_command, \
+		       abort:               NCR53c7xx_abort,   \
+		       reset:               NCR53c7xx_reset,   \
+		       bios_param:          scsicam_bios_param,   \
+		       can_queue:           24,       \
+		       this_id:             7,               \
+		       sg_tablesize:        127,          \
+		       cmd_per_lun:	    3,     \
+		       use_clustering:      DISABLE_CLUSTERING }
+#endif
+#endif /* BVME6000_SCSI_H */
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/scsi/hosts.c linuxvme-2.1.101/drivers/scsi/hosts.c
--- linux68k-2.1.101/drivers/scsi/hosts.c	Thu May 14 12:07:49 1998
+++ linuxvme-2.1.101/drivers/scsi/hosts.c	Fri May 22 19:29:25 1998
@@ -49,6 +49,10 @@
 #include "mvme16x.h"
 #endif
 
+#ifdef CONFIG_BVME6000_SCSI
+#include "bvme6000.h"
+#endif
+
 #ifdef CONFIG_A3000_SCSI
 #include "a3000.h"
 #endif
@@ -313,6 +317,9 @@
 
 #ifdef CONFIG_MVME16x_SCSI
 	MVME16x_SCSI,
+#endif
+#ifdef CONFIG_BVME6000_SCSI
+	BVME6000_SCSI,
 #endif
 #ifdef CONFIG_SCSI_ADVANSYS
 	ADVANSYS,
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/scsi/mvme16x.c linuxvme-2.1.101/drivers/scsi/mvme16x.c
--- linux68k-2.1.101/drivers/scsi/mvme16x.c	Fri May  1 17:06:06 1998
+++ linuxvme-2.1.101/drivers/scsi/mvme16x.c	Fri May 22 19:55:00 1998
@@ -37,6 +37,8 @@
     int clock;
     long long options;
 
+    if (!MACH_IS_MVME16x)
+		return 0;
     if (mvme16x_config & MVME16x_CONFIG_NO_SCSICHIP) {
 	printk ("SCSI detection disabled, SCSI chip not present\n");
 	return 0;
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/drivers/scsi/mvme16x.h linuxvme-2.1.101/drivers/scsi/mvme16x.h
--- linux68k-2.1.101/drivers/scsi/mvme16x.h	Sun Dec 14 16:35:01 1997
+++ linuxvme-2.1.101/drivers/scsi/mvme16x.h	Fri May 22 20:31:16 1998
@@ -7,7 +7,7 @@
 const char *NCR53c7x0_info(void);
 int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int NCR53c7xx_abort(Scsi_Cmnd *);
-int NCR53c7x0_release (Scsi_Host_Template *);
+int NCR53c7x0_release (struct Scsi_Host *);
 int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
 void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
 
@@ -28,26 +28,16 @@
 
 extern struct proc_dir_entry proc_scsi_mvme16x;
 
-#define MVME16x_SCSI {/* next */                NULL,            \
-		      /* usage_count */         NULL,	         \
-		      /* proc_dir_entry */      NULL, \
-		      /* proc_info */           NULL,            \
-		      /* name */                "MVME16x SCSI", \
-		      /* detect */              mvme16x_scsi_detect,    \
-		      /* release */             NULL,   \
-		      /* info */                NULL,	         \
-		      /* command */             NULL,            \
-		      /* queuecommand */        NCR53c7xx_queue_command, \
-		      /* abort */               NCR53c7xx_abort,   \
-		      /* reset */               NCR53c7xx_reset,   \
-		      /* slave_attach */        NULL,            \
-		      /* bios_param */          NULL /*scsicam_bios_param*/, \
-		      /* can_queue */           24,       \
-		      /* this_id */             7,               \
-		      /* sg_tablesize */        127,          \
-		      /* cmd_per_lun */	        3,     \
-		      /* present */             0,               \
-		      /* unchecked_isa_dma */   0,               \
-		      /* use_clustering */      DISABLE_CLUSTERING }
+#define MVME16x_SCSI  {name:                "MVME16x NCR53c710 SCSI", \
+		       detect:              mvme16x_scsi_detect,    \
+		       queuecommand:        NCR53c7xx_queue_command, \
+		       abort:               NCR53c7xx_abort,   \
+		       reset:               NCR53c7xx_reset,   \
+		       bios_param:          scsicam_bios_param,   \
+		       can_queue:           24,       \
+		       this_id:             7,               \
+		       sg_tablesize:        127,          \
+		       cmd_per_lun:	    3,     \
+		       use_clustering:      DISABLE_CLUSTERING }
 #endif
 #endif /* MVME16x_SCSI_H */
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/include/asm-m68k/atari_SCCserial.h linuxvme-2.1.101/include/asm-m68k/atari_SCCserial.h
--- linux68k-2.1.101/include/asm-m68k/atari_SCCserial.h	Thu Jan  8 14:03:06 1998
+++ linuxvme-2.1.101/include/asm-m68k/atari_SCCserial.h	Fri May 22 19:29:25 1998
@@ -29,8 +29,9 @@
 						 * clock sources */
 
 #define SCC_BAUD_BASE_MVME_PCLK	781250	/* 12.5 MHz */
-#define SCC_BAUD_BASE_BVM	460800	/* 7.3728 MHz */
 #define SCC_BAUD_BASE_MVME	625000	/* 10.000 MHz */
+#define SCC_BAUD_BASE_BVME_PCLK	781250	/* 12.5 MHz */   /* XXX ??? */
+#define SCC_BAUD_BASE_BVME	460800	/* 7.3728 MHz */
 
 /* The SCC configuration structure */
 
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/include/asm-m68k/bootinfo.h linuxvme-2.1.101/include/asm-m68k/bootinfo.h
--- linux68k-2.1.101/include/asm-m68k/bootinfo.h	Wed Jan 14 15:40:10 1998
+++ linuxvme-2.1.101/include/asm-m68k/bootinfo.h	Fri May 22 19:29:25 1998
@@ -198,6 +198,7 @@
 #define ATARI_BOOTI_VERSION    MK_BI_VERSION( 2, 1 )
 #define MAC_BOOTI_VERSION      MK_BI_VERSION( 2, 0 )
 #define MVME16x_BOOTI_VERSION  MK_BI_VERSION( 2, 0 )
+#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
 
 
 #ifdef BOOTINFO_COMPAT_1_0
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/include/asm-m68k/bvme6000hw.h linuxvme-2.1.101/include/asm-m68k/bvme6000hw.h
--- linux68k-2.1.101/include/asm-m68k/bvme6000hw.h	Thu Jan  1 00:00:00 1970
+++ linuxvme-2.1.101/include/asm-m68k/bvme6000hw.h	Fri May 22 20:24:33 1998
@@ -0,0 +1,129 @@
+#ifndef _M68K_BVME6000HW_H_
+#define _M68K_BVME6000HW_H_
+
+#include <asm/irq.h>
+
+/*
+ * PIT structure
+ */
+
+#define BVME_PIT_BASE	0xffa00000
+
+typedef struct {
+	unsigned char
+	pad_a[3], pgcr,
+	pad_b[3], psrr,
+	pad_c[3], paddr,
+	pad_d[3], pbddr,
+	pad_e[3], pcddr,
+	pad_f[3], pivr,
+	pad_g[3], pacr,
+	pad_h[3], pbcr,
+	pad_i[3], padr,
+	pad_j[3], pbdr,
+	pad_k[3], paar,
+	pad_l[3], pbar,
+	pad_m[3], pcdr,
+	pad_n[3], psr,
+	pad_o[3], res1,
+	pad_p[3], res2,
+	pad_q[3], tcr,
+	pad_r[3], tivr,
+	pad_s[3], res3,
+	pad_t[3], cprh,
+	pad_u[3], cprm,
+	pad_v[3], cprl,
+	pad_w[3], res4,
+	pad_x[3], crh,
+	pad_y[3], crm,
+	pad_z[3], crl,
+	pad_A[3], tsr,
+	pad_B[3], res5;
+} PitRegs_t, *PitRegsPtr;
+
+#define bvmepit   ((*(volatile PitRegsPtr)(BVME_PIT_BASE)))
+
+#define BVME_RTC_BASE	0xff900000
+
+typedef struct {
+	unsigned char
+	pad_a[3], msr,
+	pad_b[3], t0cr_rtmr,
+	pad_c[3], t1cr_omr,
+	pad_d[3], pfr_icr0,
+	pad_e[3], irr_icr1,
+	pad_f[3], bcd_tenms,
+	pad_g[3], bcd_sec,
+	pad_h[3], bcd_min,
+	pad_i[3], bcd_hr,
+	pad_j[3], bcd_dom,
+	pad_k[3], bcd_mth,
+	pad_l[3], bcd_year,
+	pad_m[3], bcd_ujcc,
+	pad_n[3], bcd_hjcc,
+	pad_o[3], bcd_dow,
+	pad_p[3], t0lsb,
+	pad_q[3], t0msb,
+	pad_r[3], t1lsb,
+	pad_s[3], t1msb,
+	pad_t[3], cmp_sec,
+	pad_u[3], cmp_min,
+	pad_v[3], cmp_hr,
+	pad_w[3], cmp_dom,
+	pad_x[3], cmp_mth,
+	pad_y[3], cmp_dow,
+	pad_z[3], sav_sec,
+	pad_A[3], sav_min,
+	pad_B[3], sav_hr,
+	pad_C[3], sav_dom,
+	pad_D[3], sav_mth,
+	pad_E[3], ram,
+	pad_F[3], test;
+} RtcRegs_t, *RtcPtr_t;
+
+
+#define BVME_I596_BASE	0xff100000
+
+#define BVME_ETHIRQ_REG	0xff20000b
+
+#define BVME_LOCAL_IRQ_STAT  0xff20000f
+
+#define BVME_ETHERR          0x02
+#define BVME_ABORT_STATUS    0x08
+
+#define BVME_NCR53C710_BASE	0xff000000
+
+#define BVME_SCC_A_ADDR	0xffb0000b
+#define BVME_SCC_B_ADDR	0xffb00003
+
+#define BVME_CONFIG_REG	0xff500003
+
+#define config_reg_ptr	(unsigned char *)BVME_CONFIG_REG
+
+#define BVME_CONFIG_SW1	0x08
+#define BVME_CONFIG_SW2	0x04
+#define BVME_CONFIG_SW3	0x02
+#define BVME_CONFIG_SW4	0x01
+
+
+#define BVME_IRQ_TYPE_PRIO	0
+
+#define BVME_IRQ_PRN		0x54
+#define BVME_IRQ_I596		0x1a
+#define BVME_IRQ_SCSI		0x1b
+#define BVME_IRQ_TIMER		0x59
+#define BVME_IRQ_RTC		0x1e
+#define BVME_IRQ_ABORT		0x1f
+
+/* SCC interrupts */
+#define BVME_IRQ_SCC_BASE		0x40
+#define BVME_IRQ_SCCB_TX		0x40
+#define BVME_IRQ_SCCB_STAT		0x42
+#define BVME_IRQ_SCCB_RX		0x44
+#define BVME_IRQ_SCCB_SPCOND		0x46
+#define BVME_IRQ_SCCA_TX		0x48
+#define BVME_IRQ_SCCA_STAT		0x4a
+#define BVME_IRQ_SCCA_RX		0x4c
+#define BVME_IRQ_SCCA_SPCOND		0x4e
+
+#endif
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/include/asm-m68k/mvme16xhw.h linuxvme-2.1.101/include/asm-m68k/mvme16xhw.h
--- linux68k-2.1.101/include/asm-m68k/mvme16xhw.h	Thu Jan  8 14:03:06 1998
+++ linuxvme-2.1.101/include/asm-m68k/mvme16xhw.h	Fri May 22 20:24:33 1998
@@ -34,37 +34,59 @@
 		spare3,
 		spare4,
 		data;
-} lpr_ctrl;
+} MVMElp, *MVMElpPtr;
 
-#define LPR_REGS	((volatile lpr_ctrl *)0xfff42030)
+#define MVME_LPR_BASE	0xfff42030
 
-#define I596_BASE	0xfff46000
+#define mvmelp   ((*(volatile MVMElpPtr)(MVME_LPR_BASE)))
 
-#define SCC_A_ADDR	0xfff45005
-#define SCC_B_ADDR	0xfff45001
-
-#define IRQ_MVME162_TYPE_PRIO	0
-
-#define IRQ_MVME167_PRN		0x54
-#define IRQ_MVME16x_I596	0x57
-#define IRQ_MVME16x_SCSI	0x55
-#define IRQ_MVME16x_FLY		0x7f
-#define IRQ_MVME167_SER_ERR	0x5c
-#define IRQ_MVME167_SER_MODEM	0x5d
-#define IRQ_MVME167_SER_TX	0x5e
-#define IRQ_MVME167_SER_RX	0x5f
-#define IRQ_MVME16x_TIMER	0x59
+typedef struct {
+	unsigned char
+		ctrl,
+		bcd_sec,
+		bcd_min,
+		bcd_hr,
+		bcd_dow,
+		bcd_dom,
+		bcd_mth,
+		bcd_year;
+} MK48T08_t, *MK48T08ptr_t;
+
+#define RTC_WRITE	0x80
+#define RTC_READ	0x40
+#define RTC_STOP	0x20
+
+#define MVME_RTC_BASE	0xfffc1ff8
+
+#define MVME_I596_BASE	0xfff46000
+
+#define MVME_SCC_A_ADDR	0xfff45005
+#define MVME_SCC_B_ADDR	0xfff45001
+
+#define MVME162_IRQ_TYPE_PRIO	0
+                
+#define MVME167_IRQ_PRN		0x54
+#define MVME16x_IRQ_I596	0x57
+#define MVME16x_IRQ_SCSI	0x55
+#define MVME16x_IRQ_FLY		0x7f
+#define MVME167_IRQ_SER_ERR	0x5c
+#define MVME167_IRQ_SER_MODEM	0x5d
+#define MVME167_IRQ_SER_TX	0x5e
+#define MVME167_IRQ_SER_RX	0x5f
+#define MVME16x_IRQ_TIMER	0x59
+#define MVME167_IRQ_ABORT	0x6e
+#define MVME162_IRQ_ABORT	0x5e
 
 /* SCC interrupts, for MVME162 */
-#define IRQ_MVME162_SCC_BASE		0x40
-#define IRQ_MVME162_SCCB_TX		0x40
-#define IRQ_MVME162_SCCB_STAT		0x42
-#define IRQ_MVME162_SCCB_RX		0x44
-#define IRQ_MVME162_SCCB_SPCOND		0x46
-#define IRQ_MVME162_SCCA_TX		0x48
-#define IRQ_MVME162_SCCA_STAT		0x4a
-#define IRQ_MVME162_SCCA_RX		0x4c
-#define IRQ_MVME162_SCCA_SPCOND		0x4e
+#define MVME162_IRQ_SCC_BASE		0x40
+#define MVME162_IRQ_SCCB_TX		0x40
+#define MVME162_IRQ_SCCB_STAT		0x42
+#define MVME162_IRQ_SCCB_RX		0x44
+#define MVME162_IRQ_SCCB_SPCOND		0x46
+#define MVME162_IRQ_SCCA_TX		0x48
+#define MVME162_IRQ_SCCA_STAT		0x4a
+#define MVME162_IRQ_SCCA_RX		0x4c
+#define MVME162_IRQ_SCCA_SPCOND		0x4e
 
 /* MVME162 version register */
 
@@ -85,34 +107,4 @@
 #define MVME16x_CONFIG_GOT_SCCA		0x0400
 #define MVME16x_CONFIG_GOT_SCCB		0x0800
 
-/* Specials for the ethernet driver */
-
-#define CA()		(((struct i596_reg *)dev->base_addr)->ca = 1)
-
-#define MPU_PORT(c,x)	\
-  ((struct i596_reg *)(dev->base_addr))->porthi = ((c) | (u32)(x)) & 0xffff; \
-  ((struct i596_reg *)(dev->base_addr))->portlo = ((c) | (u32)(x)) >> 16
-
-#define SCP_SYSBUS	0x00000054
-
-#define WSWAPrfd(x)	((struct i596_rfd *) (((u32)(x)<<16) | ((((u32)(x)))>>16)))
-#define WSWAPrbd(x)	((struct i596_rbd *) (((u32)(x)<<16) | ((((u32)(x)))>>16)))
-#define WSWAPiscp(x)	((struct i596_iscp *)(((u32)(x)<<16) | ((((u32)(x)))>>16)))
-#define WSWAPscb(x)	((struct i596_scb *) (((u32)(x)<<16) | ((((u32)(x)))>>16)))
-#define WSWAPcmd(x)	((struct i596_cmd *) (((u32)(x)<<16) | ((((u32)(x)))>>16)))
-#define WSWAPtbd(x)	((struct i596_tbd *) (((u32)(x)<<16) | ((((u32)(x)))>>16)))
-#define WSWAPchar(x)	((char *)            (((u32)(x)<<16) | ((((u32)(x)))>>16)))
-
-/*
- * The MPU_PORT command allows direct access to the 82596. With PORT access
- * the following commands are available (p5-18). The 32-bit port command
- * must be word-swapped with the most significant word written first.
- */
-#define PORT_RESET	0x00	/* reset 82596 */
-#define PORT_SELFTEST	0x01	/* selftest */
-#define PORT_ALTSCP	0x02	/* alternate SCB address */
-#define PORT_ALTDUMP	0x03	/* Alternate DUMP address */
-
-#define ISCP_BUSY	0x00010000
-
-#endif /* _M68K_MVME16xHW_H_ */
+#endif
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/include/asm-m68k/pgtable.h linuxvme-2.1.101/include/asm-m68k/pgtable.h
--- linux68k-2.1.101/include/asm-m68k/pgtable.h	Sun Dec 14 21:46:57 1997
+++ linuxvme-2.1.101/include/asm-m68k/pgtable.h	Tue May 26 18:34:24 1998
@@ -325,6 +325,16 @@
  * and initialized in head.S */
 extern int m68k_pgtable_cachemode;
 
+/* This is the cache mode for normal pages, for supervisor access on
+ * processors >= '040. It is used in pte_mkcache(), and the variable is
+ * defined and initialized in head.S */
+
+#if defined(CONFIG_060_WRITETHROUGH)
+extern int m68k_supervisor_cachemode;
+#else
+#define m68k_supervisor_cachemode _PAGE_CACHE040
+#endif
+
 #if defined(CPU_M68040_OR_M68060_ONLY)
 #define mm_cachebits _PAGE_CACHE040
 #elif defined(CPU_M68020_OR_M68030_ONLY)
@@ -492,7 +502,7 @@
 	pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_pgtable_cachemode;
 	return pte;
 }
-extern inline pte_t pte_mkcache(pte_t pte)	{ pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | _PAGE_CACHE040; return pte; }
+extern inline pte_t pte_mkcache(pte_t pte)	{ pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_supervisor_cachemode; return pte; }
 
 /* to set the page-dir */
 extern inline void SET_PAGE_DIR(struct task_struct * tsk, pgd_t * pgdir)
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/include/asm-m68k/serial.h linuxvme-2.1.101/include/asm-m68k/serial.h
--- linux68k-2.1.101/include/asm-m68k/serial.h	Wed May 13 14:07:12 1998
+++ linuxvme-2.1.101/include/asm-m68k/serial.h	Mon May 25 22:27:45 1998
@@ -35,6 +35,7 @@
 #define SER_SCC_MVME	109	/* MVME162/MVME172 ports */
 #define SER_SCC_MAC	110	/* Macintosh SCC channel */
 #define SER_HPDCA	111	/* HP DCA serial */
+#define SER_SCC_BVME	112	/* BVME6000 ports */
 
 struct serial_struct {
 	int	type;
diff -ur -X dodiffs-exclude --new-file linux68k-2.1.101/include/linux/lp_m68k.h linuxvme-2.1.101/include/linux/lp_m68k.h
--- linux68k-2.1.101/include/linux/lp_m68k.h	Mon Apr 14 11:29:44 1997
+++ linuxvme-2.1.101/include/linux/lp_m68k.h	Fri May 22 19:29:26 1998
@@ -92,7 +92,9 @@
 LP_AMIGA = 1,
 LP_ATARI = 2,
 LP_MFC = 3,
-LP_IOEXT = 4
+LP_IOEXT = 4,
+LP_MVME167 = 5,
+LP_BVME6000 = 6
 };
 
 /*
