Resent-Date: Sun, 20 Sep 1998 21:04:20 +0200 (MET DST)
X-Sender: ddkilzer@mail.earthlink.net
X-Files: Sundays at 8 PM CDT on Fox!
Date: Sun, 20 Sep 1998 14:03:33 -0500
To: Jes Sorensen <Jes.Sorensen@cern.ch>
From: "David D. Kilzer" <ddkilzer@earthlink.net>
Subject: 2.1.120 patch for Mac
Cc: Linux-m68k Mailing List <linux-m68k@lists.linux-m68k.org>
Resent-From: linux-m68k@phil.uni-sb.de

Hi Jes,

Here's patch against 2.1.120 for some Mac-specific stuff.  I've taken the 
mac-2.1.120-vanilla-980920.diff and removed the more volatile parts of it.

<ftp://maclinux.wwaves.com//pub/MacLinux/kernels/src/
  mac-2.1.120-vanilla-980920.diff.gz>


I left out the most recent head.S cleanup patch and the CONFIG_APM/mach_halt/mach_powerdown patches.

Here's a file-by-file breakdown of the changes.  Please let me know if 
you like this or if it can be done in a better way.


arch/m68k/mac/config.c
  o Cleaned up configs for Quadra 605, Performa 550, and PowerBook 170.
    (Various)


arch/m68k/mac/debug.c
  o Serial debug output now works.  Turn on with "debug=ser" or 
    "debug=ser1" for modem port, or "debug=ser2" for printer port in the 
    boot args. (David Kilzer)

    + Now uses boot info's SCC base address instead of hard-coded 
      0x50F04000.

    + Initializes scc_port to -1 to prevent accidental(?) use.

    + Changed "US" #define to more descriptive "uSEC".

    + Removed brgsrc_table from mac_init_scc_port().  No longer needed 
      for register 14 init.

    + Recalculated values for div_table in mac_init_scc_port() using
      trusty HP48sx.

    + Fixed init for register 14.

    + Cleaned up mac_debug_init().


arch/m68k/mac/macboing.c
  o Removed printk() of "BOING!" for AV Macs in macboing.c.  Very 
    annoying when you get a bell generated on the command line!
    (David Kilzer)

  o Fixed ASC base address for IIfx. (Alan Cox)


arch/m68k/mac/macints.c
  o Mac II fixes for VIA2. (Alan Cox)


arch/m68k/mac/via6522.c
  o Add via_memory_bogon for delay in via6522.h.  Add delay before 
    reboot to prevent message from printing.  (Alan Cox)


arch/m68k/mac/via6522.h
  o Add via_memory_bogon for delay in via_write() and via_read().
    (Alan Cox)


drivers/block/ide-proc.c
  o Clean up compiler warning by predeclaring ide_replace_subdriver.  
    (David Kilzer)


drivers/block/ll_rw_blk.c
  o Clean up compiler warning by predeclaring mac_floppy_init().
    (David Kilzer)


drivers/char/adbmouse.c
  o Left-over comments that weren't merged from earlier adbmouse.c and
    macmouse.c merger.  (Alan Cox???)


drivers/char/mac_SCC.c
  o Added sanity check for IIfx-class machines that didn't run Serial
    Switch to make the z8530 available.  (Alan Cox)

  o Cleaned up check for (MACH_IS_ATARI || MAC_IS_AMIGA) to 
    (!MACH_IS_MAC).  (David Kilzer)


drivers/char/misc.c
  o Left-over patch that wasn't merged from earlier adbmouse.c and
    macmouse.c merger.  (Alan Cox???)


drivers/net/daynaport.c
  o Clean up compiler warnings by declaring the type of "start_page" 
    args to dayna_block_output() and sane_block_output(). (David Kilzer)


drivers/scsi/Makefile
  o Add support for CONFIG_SCSI_MAC_ESP targets.  (Michael Schmitz)


drivers/scsi/NCR5380.c
  o Fixes for Mac NCR5380 SCSI problems.  (Michael Schmitz)


drivers/scsi/NCR53C9x.c
drivers/scsi/NCR53C9x.h
  o More fixes for Mac NCR53C9x SCSI.  (Michael Schmitz)
  o Disconnect and extremely slow target fixes.  (Carsten Pluntke)
    N.B.--May already be fixed in vger tree.


drivers/scsi/mac_esp.c
  o White space changes and a couple compiler warning fixes.  
    (David Kilzer)


drivers/video/fbcon.c
  o Fix for vbl_detected initialization.  (Michael Schmitz)
    N.B.--Is probably alread fixed in vger tree.


Dave


diff -urN -X diff-21.excl linux-2.1.120-vanilla/arch/m68k/mac/config.c linux-2.1.120/arch/m68k/mac/config.c
--- linux-2.1.120-vanilla/arch/m68k/mac/config.c	Mon Sep  7 09:39:07 1998
+++ linux-2.1.120/arch/m68k/mac/config.c	Sun Sep 20 00:44:20 1998
@@ -419,7 +421,7 @@
 	 *	confuse us. The 840AV has a SCSI location of its own (same as the 660AV).
 	 */	 
 
-	{	MAC_MODEL_Q605, "Quadra 605", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA,  MAC_IDE_NONE,   MAC_SCC_QUADRA,	MAC_ETHER_SONIC,	MAC_NUBUS},
+	{	MAC_MODEL_Q605, "Quadra 605", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA,  MAC_IDE_NONE,   MAC_SCC_QUADRA,	MAC_ETHER_NONE,		MAC_NUBUS},
 	{	MAC_MODEL_Q610, "Quadra 610", MAC_ADB_II,   MAC_VIA_QUADRA, MAC_SCSI_QUADRA,  MAC_IDE_NONE,   MAC_SCC_QUADRA,	MAC_ETHER_SONIC,	MAC_NUBUS},
 	{	MAC_MODEL_Q630, "Quadra 630", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA,  MAC_IDE_QUADRA, MAC_SCC_QUADRA,	MAC_ETHER_SONIC,	MAC_NUBUS},
  	{	MAC_MODEL_Q650, "Quadra 650", MAC_ADB_II,   MAC_VIA_QUADRA, MAC_SCSI_QUADRA,  MAC_IDE_NONE,   MAC_SCC_QUADRA,	MAC_ETHER_SONIC,	MAC_NUBUS},
@@ -439,7 +441,7 @@
 	{	MAC_MODEL_P475,  "Performa 475", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II,	MAC_ETHER_NONE, MAC_NUBUS},
 	{	MAC_MODEL_P475F, "Performa 475", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II,	MAC_ETHER_NONE, MAC_NUBUS},
 	{	MAC_MODEL_P520,  "Performa 520", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II,	MAC_ETHER_NONE,	MAC_NUBUS},
-	{	MAC_MODEL_P550,  "Performa 550", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II,	MAC_ETHER_NONE,	MAC_NUBUS},
+	{	MAC_MODEL_P550,  "Performa 550", MAC_ADB_CUDA, MAC_VIA_IIci,   MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II,	MAC_ETHER_NONE,	MAC_NUBUS},
 	{	MAC_MODEL_P575,  "Performa 575", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II,	MAC_ETHER_NONE,	MAC_NUBUS},
 	{	MAC_MODEL_P588,  "Performa 588", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II,	MAC_ETHER_NONE,	MAC_NUBUS},
 	{	MAC_MODEL_TV,    "TV",           MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_OLD,	MAC_IDE_NONE, MAC_SCC_II,	MAC_ETHER_NONE,	MAC_NUBUS},
@@ -466,7 +468,7 @@
 	{	MAC_MODEL_PB160,  "PowerBook 160",   MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA,	MAC_ETHER_NONE,	MAC_NUBUS},
 	{	MAC_MODEL_PB165,  "PowerBook 165",   MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA,	MAC_ETHER_NONE,	MAC_NUBUS},
 	{	MAC_MODEL_PB165C, "PowerBook 165c",  MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA,	MAC_ETHER_NONE,	MAC_NUBUS},
-	{	MAC_MODEL_PB170,  "PowerBook 170",   MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA,	MAC_ETHER_NONE,	MAC_NUBUS},
+	{	MAC_MODEL_PB170,  "PowerBook 170",   MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_OLD,    MAC_IDE_NONE, MAC_SCC_QUADRA,	MAC_ETHER_NONE,	MAC_NUBUS},
 	{	MAC_MODEL_PB180,  "PowerBook 180",   MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA,	MAC_ETHER_NONE,	MAC_NUBUS},
 	{	MAC_MODEL_PB180C, "PowerBook 180c",  MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA,	MAC_ETHER_NONE,	MAC_NUBUS},
 	{	MAC_MODEL_PB190,  "PowerBook 190",   MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_PB,   MAC_SCC_QUADRA,	MAC_ETHER_NONE,	MAC_NUBUS},
diff -urN -X diff-21.excl linux-2.1.120-vanilla/arch/m68k/mac/debug.c linux-2.1.120/arch/m68k/mac/debug.c
--- linux-2.1.120-vanilla/arch/m68k/mac/debug.c	Mon Jun  8 09:44:26 1998
+++ linux-2.1.120/arch/m68k/mac/debug.c	Sat Sep 19 22:18:15 1998
@@ -249,7 +249,6 @@
  * TODO: serial debug code
  */
 
-#define SCC_BAS (0x50F04000)
 struct SCC
  {
   u_char cha_b_ctrl;
@@ -260,7 +259,8 @@
   u_char char_dummy3;
   u_char cha_a_data;
  };
-# define scc ((*(volatile struct SCC*)SCC_BAS))
+
+# define scc (*((volatile struct SCC*)mac_bi_data.sccbase))
 
 /* Flag that serial port is already initialized and used */
 int mac_SCC_init_done = 0;
@@ -268,6 +268,8 @@
  * not be repeated; used by kgdb */
 int mac_SCC_reset_done = 0;
 
+static int scc_port = -1;
+
 static struct console mac_console_driver = {
 	"debug",
 	NULL,			/* write */
@@ -282,20 +284,18 @@
 	NULL
 };
 
-static int scc_port;
-
 /* Mac: loops_per_sec min. 1900000 ^= .5 us; MFPDELAY was 0.6 us*/
 
-#define US 1
+#define uSEC 1
 
 static inline void mac_sccb_out (char c)
 {
     int i;
     do {
-	for( i = US; i > 0; --i )
+	for( i = uSEC; i > 0; --i )
 		barrier();
     } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */
-    for( i = US; i > 0; --i )
+    for( i = uSEC; i > 0; --i )
 	barrier();
     scc.cha_b_data = c;
 }
@@ -304,10 +304,10 @@
 {
     int i;
     do {
-	for( i = US; i > 0; --i )
+	for( i = uSEC; i > 0; --i )
 		barrier();
     } while (!(scc.cha_a_ctrl & 0x04)); /* wait for tx buf empty */
-    for( i = US; i > 0; --i )
+    for( i = uSEC; i > 0; --i )
 	barrier();
     scc.cha_a_data = c;
 }
@@ -337,10 +337,10 @@
 {
     int i;
     do {
-	for( i = US; i > 0; --i )
+	for( i = uSEC; i > 0; --i )
 		barrier();
     } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */
-    for( i = US; i > 0; --i )
+    for( i = uSEC; i > 0; --i )
 	barrier();
     return( scc.cha_b_data );
 }
@@ -349,10 +349,10 @@
 {
     int i;
     do {
-	for( i = US; i > 0; --i )
+	for( i = uSEC; i > 0; --i )
 		barrier();
     } while( !(scc.cha_a_ctrl & 0x01) ); /* wait for rx buf filled */
-    for( i = US; i > 0; --i )
+    for( i = uSEC; i > 0; --i )
 	barrier();
     return( scc.cha_a_data );
 }
@@ -365,10 +365,10 @@
     do {						\
 	int i;						\
 	scc.cha_b_ctrl = (reg);				\
-	for( i = US; i > 0; --i )			\
+	for( i = uSEC; i > 0; --i )			\
 		barrier();				\
 	scc.cha_b_ctrl = (val);				\
-	for( i = US; i > 0; --i )			\
+	for( i = uSEC; i > 0; --i )			\
 		barrier();				\
     } while(0)
 
@@ -376,10 +376,10 @@
     do {						\
 	int i;						\
 	scc.cha_a_ctrl = (reg);				\
-	for( i = US; i > 0; --i )			\
+	for( i = uSEC; i > 0; --i )			\
 		barrier();				\
 	scc.cha_a_ctrl = (val);				\
-	for( i = US; i > 0; --i )			\
+	for( i = uSEC; i > 0; --i )			\
 		barrier();				\
     } while(0)
 
@@ -389,7 +389,7 @@
 #define LONG_DELAY()				\
     do {					\
 	int i;					\
-	for( i = 60*US; i > 0; --i )		\
+	for( i = 60*uSEC; i > 0; --i )		\
 	    barrier();				\
     } while(0)
     
@@ -399,19 +399,21 @@
 void mac_init_scc_port( int cflag, int port )
 #endif
 {
-    extern int mac_SCC_reset_done;
-    static int clksrc_table[9] =
-	/* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */
-    	{ 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 };
-    static int brgsrc_table[9] =
-	/* reg 14: 0 = RTxC, 2 = PCLK */
-    	{ 2, 2, 2, 2, 2, 2, 0, 2, 2 };
-    static int clkmode_table[9] =
-	/* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */
-    	{ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 };
-    static int div_table[9] =
-	/* reg12 (BRG low) */
-    	{ 208, 138, 103, 50, 24, 11, 1, 0, 0 };
+	extern int mac_SCC_reset_done;
+
+	/*
+	 * baud rates: 1200, 1800, 2400, 4800, 9600, 19.2k, 38.4k, 57.6k, 115.2k
+	 */
+
+	static int clksrc_table[9] =
+		/* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */
+    		{ 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 };
+	static int clkmode_table[9] =
+		/* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */
+    		{ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 };
+	static int div_table[9] =
+		/* reg12 (BRG low) */
+    		{ 94, 62, 46, 22, 10, 4, 1, 0, 0 };
 
     int baud = cflag & CBAUD;
     int clksrc, clkmode, div, reg3, reg5;
@@ -426,12 +428,10 @@
     clkmode = clkmode_table[baud];
     div     = div_table[baud];
 
-    reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40;
-    reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */;
+    reg3 = (((cflag & CSIZE) == CS8) ? 0xc0 : 0x40);
+    reg5 = (((cflag & CSIZE) == CS8) ? 0x60 : 0x20) | 0x82 /* assert DTR/RTS */;
 
-#if 0    
-    if (port) {
-#endif
+    if (port == 1) {
 	    (void)scc.cha_b_ctrl;	/* reset reg pointer */
 	    SCCB_WRITE( 9, 0xc0 );	/* reset */
 	    LONG_DELAY();		/* extra delay after WR9 access */
@@ -442,17 +442,14 @@
 	    SCCB_WRITE( 5, reg5 );
 	    SCCB_WRITE( 9, 0 );		/* no interrupts */
 	    LONG_DELAY();		/* extra delay after WR9 access */
-	    SCCB_WRITE( 10, 0 );		/* NRZ mode */
+	    SCCB_WRITE( 10, 0 );	/* NRZ mode */
 	    SCCB_WRITE( 11, clksrc );	/* main clock source */
 	    SCCB_WRITE( 12, div );	/* BRG value */
 	    SCCB_WRITE( 13, 0 );		/* BRG high byte */
-	    SCCB_WRITE( 14, brgsrc_table[baud] );
-	    SCCB_WRITE( 14, brgsrc_table[baud] | (div ? 1 : 0) );
+	    SCCB_WRITE( 14, 1 );
 	    SCCB_WRITE( 3, reg3 | 1 );
 	    SCCB_WRITE( 5, reg5 | 8 );
-#if 0
-    } else {
-#endif
+    } else if (port == 0) {
 	    (void)scc.cha_a_ctrl;	/* reset reg pointer */
 	    SCCA_WRITE( 9, 0xc0 );	/* reset */
 	    LONG_DELAY();		/* extra delay after WR9 access */
@@ -463,17 +460,15 @@
 	    SCCA_WRITE( 5, reg5 );
 	    SCCA_WRITE( 9, 0 );		/* no interrupts */
 	    LONG_DELAY();		/* extra delay after WR9 access */
-	    SCCA_WRITE( 10, 0 );		/* NRZ mode */
+	    SCCA_WRITE( 10, 0 );	/* NRZ mode */
 	    SCCA_WRITE( 11, clksrc );	/* main clock source */
 	    SCCA_WRITE( 12, div );	/* BRG value */
 	    SCCA_WRITE( 13, 0 );		/* BRG high byte */
-	    SCCA_WRITE( 14, brgsrc_table[baud] );
-	    SCCA_WRITE( 14, brgsrc_table[baud] | (div ? 1 : 0) );
+	    SCCA_WRITE( 14, 1 );
 	    SCCA_WRITE( 3, reg3 | 1 );
 	    SCCA_WRITE( 5, reg5 | 8 );
-#if 0
     }
-#endif
+
     mac_SCC_reset_done = 1;
     mac_SCC_init_done = 1;
 }
@@ -486,18 +481,20 @@
     return;
 #endif
 #ifdef DEBUG_SERIAL
-    if (!strcmp( m68k_debug_device, "ser" )) {
-	strcpy( m68k_debug_device, "ser1" );
-    }
-    if (!strcmp( m68k_debug_device, "ser1" )) {
-	/* ST-MFP Modem1 serial port */
+    if (   !strcmp( m68k_debug_device, "ser"  )
+        || !strcmp( m68k_debug_device, "ser1" )) {
+	/* Mac modem port */
 	mac_init_scc_port( B9600|CS8, 0 );
 	mac_console_driver.write = mac_scca_console_write;
+	mac_console_driver.wait_key = mac_scca_console_wait_key;
+	scc_port = 0;
     }
     else if (!strcmp( m68k_debug_device, "ser2" )) {
-	/* SCC Modem2 serial port */
+	/* Mac printer port */
 	mac_init_scc_port( B9600|CS8, 1 );
 	mac_console_driver.write = mac_sccb_console_write;
+	mac_console_driver.wait_key = mac_sccb_console_wait_key;
+	scc_port = 1;
     }
     if (mac_console_driver.write)
 	register_console(&mac_console_driver);
diff -urN -X diff-21.excl linux-2.1.120-vanilla/arch/m68k/mac/macboing.c linux-2.1.120/arch/m68k/mac/macboing.c
--- linux-2.1.120-vanilla/arch/m68k/mac/macboing.c	Mon Sep  7 09:39:07 1998
+++ linux-2.1.120/arch/m68k/mac/macboing.c	Sat Sep 19 23:41:28 1998
@@ -53,22 +53,26 @@
 		 *
 		 *   http://til.info.apple.com/techinfo.nsf/artnum/n16405
 		 *
-		 * Until we figure out how to drive it, though, just print "BOING!" 
-		 * and return.
-		 *
 		 * --David Kilzer
 		 */
 
-		printk("BOING!\n");
 		return;
 	}
-
+	
 	if(!inited)
 	{
 		int i=0;
 		int j=0;
 		int k=0;
 		int l=0;
+
+		/*
+		 *	The IIfx strikes again!
+		 */
+		 
+		if(macintosh_config->ident==MAC_MODEL_IIFX)
+			asc_base=(void *)0x50010000;
+
 		for(i=0;i<samples;i++)
 		{
 			asc_base[i]=sine_data[j];
diff -urN -X diff-21.excl linux-2.1.120-vanilla/arch/m68k/mac/macints.c linux-2.1.120/arch/m68k/mac/macints.c
--- linux-2.1.120-vanilla/arch/m68k/mac/macints.c	Mon Sep  7 09:39:08 1998
+++ linux-2.1.120/arch/m68k/mac/macints.c	Sat Sep 19 23:11:30 1998
@@ -622,7 +622,7 @@
 	        via_write(via, rIER, via_read(via, rIER)|0x80|(1<<(irqidx)));
 	else if (srcidx == SRC_VIA2 && via2_is_oss)
 		via_write(oss_regp, oss_map[irqidx]+8, 2);
-	else if (srcidx >= SRC_VIA2)
+	else if (srcidx > SRC_VIA2)
 	        via_write(via, (0x104 + 0x10*srcidx), 
 	        	via_read(via, (0x104 + 0x10*srcidx))|0x80|(1<<(irqidx)));
 	else
@@ -644,7 +644,11 @@
 		via_write(via, rIER, (via_read(via, rIER)&(1<<irqidx)));
 	else if (srcidx == SRC_VIA2 && via2_is_oss)
 		via_write(oss_regp, oss_map[irqidx]+8, 0);
-	else if (srcidx >= SRC_VIA2)
+	/*
+	 *	VIA2 is fixed. The stuff above VIA2 is for later
+	 *	macintoshes only.
+	 */
+	else if (srcidx > SRC_VIA2)
 	        via_write(via, (0x104 + 0x10*srcidx), 
 	        	via_read(via, (0x104 + 0x10*srcidx))|(1<<(irqidx)));
 	else
@@ -685,7 +689,7 @@
 		pending |= via_read(via, rIFR)&(1<<irqidx);
 	else if (srcidx == SRC_VIA2 && via2_is_oss)
 		pending |= via_read(via, oIFR)&0x03&(1<<oss_map[irqidx]);
-	else if (srcidx >= SRC_VIA2)
+	else if (srcidx > SRC_VIA2)
 	        pending |= via_read(via, (0x100 + 0x10*srcidx))&(1<<irqidx);
 	else
 		pending |= via_read(via, vIFR)&(1<<irqidx);
diff -urN -X diff-21.excl linux-2.1.120-vanilla/arch/m68k/mac/via6522.c linux-2.1.120/arch/m68k/mac/via6522.c
--- linux-2.1.120-vanilla/arch/m68k/mac/via6522.c	Mon Sep  7 09:39:09 1998
+++ linux-2.1.120/arch/m68k/mac/via6522.c	Thu Sep 10 00:16:32 1998
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/delay.h>
 
 #include <asm/adb.h> 
 #include <asm/bootinfo.h> 
@@ -21,6 +22,8 @@
 volatile unsigned char *via2=(unsigned char *)VIABASE2;
 volatile unsigned char *psc=(unsigned char *)PSCBASE;
 
+volatile long *via_memory_bogon=(long *)&via_memory_bogon;
+
 unsigned char via1_clock, via1_datab;
 
 static int rbv=0;
@@ -239,6 +242,8 @@
 			via_write(via2,vDirB,via_read(via2,vDirB)|0x04);
 			/* Send a value of 0 on that line */
 			via_write(via2,vBufB,via_read(via2,vBufB)&~0x04);
+			/* Otherwise it prints "It is now.." then shuts off */
+			mdelay(1000);
 		}
 
 		/* We should never make it this far... */
diff -urN -X diff-21.excl linux-2.1.120-vanilla/arch/m68k/mac/via6522.h linux-2.1.120/arch/m68k/mac/via6522.h
--- linux-2.1.120-vanilla/arch/m68k/mac/via6522.h	Mon Sep  7 09:39:09 1998
+++ linux-2.1.120/arch/m68k/mac/via6522.h	Thu Sep 10 00:16:33 1998
@@ -52,13 +52,27 @@
 #define VIA2B_vBusLk	0x02
 #define VIA2B_vCDis	0x01
 
+/*
+ *	The 6522 via is a 2MHz part, and needs a delay. MacOS seems to
+ *	execute MOV (Ax),(Ax) for this... Oh and we can't use udelay
+ *	here... see we need the via to calibrate the udelay loop ...
+ */
+
+extern volatile long *via_memory_bogon;
+ 
 extern __inline__ void via_write(volatile unsigned char *via,int reg, int v)
 {
+	*via_memory_bogon;
+	*via_memory_bogon;
+	*via_memory_bogon;
 	via[reg]=v;
 }
 
 extern __inline__ int via_read(volatile unsigned char *via,int reg)
 {
+	*via_memory_bogon;
+	*via_memory_bogon;
+	*via_memory_bogon;
 	return (int)via[reg];
 }
 
diff -urN -X diff-21.excl linux-2.1.120-vanilla/drivers/block/ide-proc.c linux-2.1.120/drivers/block/ide-proc.c
--- linux-2.1.120-vanilla/drivers/block/ide-proc.c	Fri May  8 07:23:26 1998
+++ linux-2.1.120/drivers/block/ide-proc.c	Wed Sep  9 00:55:05 1998
@@ -72,6 +72,8 @@
 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
 #endif
 
+extern int ide_replace_subdriver(ide_drive_t *drive, const char *driver);
+
 static int ide_getxdigit(char c)
 {
 	int digit;
diff -urN -X diff-21.excl linux-2.1.120-vanilla/drivers/block/ll_rw_blk.c linux-2.1.120/drivers/block/ll_rw_blk.c
--- linux-2.1.120-vanilla/drivers/block/ll_rw_blk.c	Wed Aug  5 05:26:41 1998
+++ linux-2.1.120/drivers/block/ll_rw_blk.c	Wed Sep  9 00:55:05 1998
@@ -25,6 +25,14 @@
 #include <linux/module.h>
 
 /*
+ * MAC Floppy IWM hooks
+ */
+
+#ifdef CONFIG_MAC_FLOPPY_IWM
+extern int mac_floppy_init(void);
+#endif
+
+/*
  * The request-struct contains all necessary data
  * to load a nr of sectors into memory
  */
diff -urN -X diff-21.excl linux-2.1.120-vanilla/drivers/char/adbmouse.c linux-2.1.120/drivers/char/adbmouse.c
--- linux-2.1.120-vanilla/drivers/char/adbmouse.c	Fri Aug 28 14:31:32 1998
+++ linux-2.1.120/drivers/char/adbmouse.c	Wed Sep  9 00:55:05 1998
@@ -61,14 +61,9 @@
     contain the following values:
 
                 BITS    COMMENTS
-    data[0] = 0000 0000 ADB packet identifer.
-    data[1] = ???? ???? (?)
-    data[2] = ???? ??00 Bits 0-1 should be zero for a mouse device.
-    data[3] = bxxx xxxx First button and x-axis motion.
-    data[4] = byyy yyyy Second button and y-axis motion.
-
-    NOTE: data[0] is confirmed by the parent function and need not be
-    checked here.
+    data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
+    data[1] = bxxx xxxx First button and x-axis motion.
+    data[2] = byyy yyyy Second button and y-axis motion.
   */
 
   /*
@@ -78,32 +73,22 @@
     following values:
 
 		BITS    COMMENTS
-    data[0] = 0000 0000 ADB packet identifer.
-    data[1] = 0100 0000 Extended protocol register.
-	      Bits 6-7 are the device id, which should be 1.
-	      Bits 4-5 are resolution which is in "units/inch".
-	      The Logitech MouseMan returns these bits clear but it has
-	      200/300cpi resolution.
-	      Bits 0-3 are unique vendor id.
-    data[2] = 0011 1100 Bits 0-1 should be zero for a mouse device.
-	      Bits 2-3 should be 8 + 4.
-		      Bits 4-7 should be 3 for a mouse device.
-    data[3] = bxxx xxxx Left button and x-axis motion.
-    data[4] = byyy yyyy Second button and y-axis motion.
-    data[5] = byyy bxxx Third button and fourth button.  
-    	      Y is additiona. high bits of y-axis motion.  
+    data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
+    data[1] = bxxx xxxx Left button and x-axis motion.
+    data[2] = byyy yyyy Second button and y-axis motion.
+    data[3] = byyy bxxx Third button and fourth button.  
+    	      Y is additional high bits of y-axis motion.  
     	      X is additional high bits of x-axis motion.
 
-    NOTE: data[0] and data[2] are confirmed by the parent function and
-    need not be checked here.
-  */
-
-    /*
-     * 'buttons' here means 'button down' states!
-     * Button 1 (left)  : bit 2, busmouse button 3
-     * Button 2 (right) : bit 0, busmouse button 1
-     * Button 3 (middle): bit 1, busmouse button 2
-     */
+    This procedure also gets called from the keyboard code if we
+    are emulating mouse buttons with keys.  In this case data[0] == 0
+    (data[0] cannot be 0 for a real ADB packet).
+
+    'buttons' here means 'button down' states!
+    Button 1 (left)  : bit 2, busmouse button 3
+    Button 2 (middle): bit 1, busmouse button 2
+    Button 3 (right) : bit 0, busmouse button 1
+*/
 
     /* x/y and buttons swapped */
     
diff -urN -X diff-21.excl linux-2.1.120-vanilla/drivers/char/mac_SCC.c linux-2.1.120/drivers/char/mac_SCC.c
--- linux-2.1.120-vanilla/drivers/char/mac_SCC.c	Mon Sep  7 09:39:13 1998
+++ linux-2.1.120/drivers/char/mac_SCC.c	Sat Sep 19 23:38:28 1998
@@ -67,6 +67,7 @@
 #include <asm/system.h>
 #include <asm/segment.h>
 #include <asm/bitops.h>
+#include <asm/hwtest.h>
 
 #include "mac_SCC.h"
 
@@ -1284,6 +1285,12 @@
 	/* testing: fix up broken 24 bit addresses (ClassicII) */
 	if ((mac_bi_data.sccbase & 0x00FFFFFF) == mac_bi_data.sccbase)
 		mac_bi_data.sccbase |= 0x50000000;
+		
+	if ( !hwreg_present((void *)mac_bi_data.sccbase))
+	{
+		printk(KERN_WARNING "z8530: Serial devices not accessible. Check serial switch.\n");
+		return;
+	}
 
 	for(n=0;n<2;n++)
 	{
@@ -1442,11 +1449,7 @@
 	printk("Mac68K Z8530 serial driver version 1.01\n");
 
 	/* SCC present at all? */
-	if (MACH_IS_ATARI || MACH_IS_AMIGA 
-#if 0
-	    || !(MACHW_PRESENT(SCC) || MACHW_PRESENT(ST_ESCC))
-#endif
-	   )
+	if (!MACH_IS_MAC)
 		return( -ENODEV );
 
 	if (zs_chain == 0)
diff -urN -X diff-21.excl linux-2.1.120-vanilla/drivers/char/misc.c linux-2.1.120/drivers/char/misc.c
--- linux-2.1.120-vanilla/drivers/char/misc.c	Fri Aug 28 14:31:43 1998
+++ linux-2.1.120/drivers/char/misc.c	Wed Sep  9 00:55:07 1998
@@ -72,7 +72,6 @@
 extern int atixl_busmouse_init(void);
 extern int amiga_mouse_init(void);
 extern int atari_mouse_init(void);
-extern int mac_mouse_init(void);
 extern int sun_mouse_init(void);
 extern int adb_mouse_init(void);
 extern void watchdog_init(void);
@@ -230,13 +229,10 @@
 #ifdef CONFIG_ATARIMOUSE
 	atari_mouse_init();
 #endif
-#ifdef CONFIG_ADBMOUSE
-	adb_mouse_init();
-#endif
 #ifdef CONFIG_SUN_MOUSE
 	sun_mouse_init();
 #endif
-#ifdef CONFIG_MACMOUSE
+#ifdef CONFIG_ADBMOUSE
 	adb_mouse_init();
 #endif
 #ifdef CONFIG_PC110_PAD
diff -urN -X diff-21.excl linux-2.1.120-vanilla/drivers/net/daynaport.c linux-2.1.120/drivers/net/daynaport.c
--- linux-2.1.120-vanilla/drivers/net/daynaport.c	Sun Jul 19 16:06:03 1998
+++ linux-2.1.120/drivers/net/daynaport.c	Wed Sep  9 00:55:08 1998
@@ -48,14 +48,14 @@
 static void dayna_block_input(struct device *dev, int count,
 						  struct sk_buff *skb, int ring_offset);
 static void dayna_block_output(struct device *dev, int count,
-							const unsigned char *buf, const start_page);
+						   const unsigned char *buf, const int start_page);
 
 static void sane_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
 						int ring_page);
 static void sane_block_input(struct device *dev, int count,
 						  struct sk_buff *skb, int ring_offset);
 static void sane_block_output(struct device *dev, int count,
-							const unsigned char *buf, const start_page);
+						   const unsigned char *buf, const int start_page);
 
 
 #define WD_START_PG	0x00	/* First page of TX buffer */
diff -urN -X diff-21.excl linux-2.1.120-vanilla/drivers/scsi/Makefile linux-2.1.120/drivers/scsi/Makefile
--- linux-2.1.120-vanilla/drivers/scsi/Makefile	Fri Aug 28 14:32:12 1998
+++ linux-2.1.120/drivers/scsi/Makefile	Wed Sep  9 00:55:10 1998
@@ -283,6 +283,14 @@
 	endif
 endif
 
+ifeq ($(CONFIG_SCSI_MAC_ESP),y)
+L_OBJS += mac_esp.o NCR53C9x.o
+else
+	ifeq ($(CONFIG_SCSI_MAC_ESP),m)
+	M_OBJS += mac_esp.o NCR53C9x.o
+	endif
+endif
+
 ifeq ($(CONFIG_SCSI_PPA),y)
 L_OBJS += ppa.o
 else
diff -urN -X diff-21.excl linux-2.1.120-vanilla/drivers/scsi/NCR5380.c linux-2.1.120/drivers/scsi/NCR5380.c
--- linux-2.1.120-vanilla/drivers/scsi/NCR5380.c	Mon Sep  7 07:29:53 1998
+++ linux-2.1.120/drivers/scsi/NCR5380.c	Sat Sep 19 23:26:55 1998
@@ -1326,7 +1326,11 @@
 						tmp->host_scribble = NULL;
 
 						/* reenable interrupts after finding one */
+#ifdef CONFIG_MAC
+						sti();   /* XXX MS: THIS one is critical !! */
+#else
 						restore_flags(flags);
+#endif /* CONFIG_MAC */
 
 						/* 
 						 * Attempt to establish an I_T_L nexus here. 
@@ -1372,12 +1376,36 @@
 							tmp->host_scribble = (unsigned char *)
 							    hostdata->issue_queue;
 							hostdata->issue_queue = tmp;
+							/*
+							 * prevent reset of issue queue search 
+							 */
+							 if (prev)
+								tmp = prev;
 							done = 0;
+#ifdef CONFIG_MAC
+							restore_flags(flags); /*seems OK, was: sti();*/
+#else
 							restore_flags(flags);
+#endif /* CONFIG_MAC */
 #if (NDEBUG & (NDEBUG_MAIN | NDEBUG_QUEUES))
 							printk("scsi%d : main(): select() failed, returned to issue_queue\n",
 							       instance->host_no);
 #endif
+							/* 
+							 * MSch: reselects happening between testing for hostdata->connected 
+							 * and successful arbitration by NCR5380_select abort the selection
+							 * above and reinsert the attempted command to the head of the issue
+							 * queue. Fine. But that also restarted the search at the head of the 
+							 * issue queue, attempting the next select, failing again etc. while 
+							 * the Right Thing would be to service the reconnected command.
+							 */
+							if (hostdata->connected) {
+#if (NDEBUG & NDEBUG_MAIN)
+							  printk("scsi%d: main(): reselection (%d) while select (%d) attempted\n", 
+								 instance->host_no, hostdata->connected->target, tmp->target);
+#endif
+							  break;
+							}
 						}
 					}	/* if target/lun is not busy */
 				}	/* for */
@@ -1482,7 +1510,11 @@
 					if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) ==
 					    (SR_SEL | SR_IO)) {
 						done = 0;
+#ifdef CONFIG_MAC
+						ENABLE_IRQ(); /*required for level triggered ints; was: sti();*/
+#else
 						restore_flags(flags);
+#endif /* CONFIG_MAC */
 #if (NDEBUG & NDEBUG_INTR)
 						printk("scsi%d : SEL interrupt\n", instance->host_no);
 #endif
@@ -1623,6 +1655,17 @@
  *
  *      If failed (no target) : cmd->scsi_done() will be called, and the 
  *              cmd->result host byte set to DID_BAD_TARGET.
+ *
+ *	MSch 980914: since NCR5380_main enables interrupts before selection
+ *		(we need the timer int.) it is possible that a reselection 
+ *		happens while NCR5380_select is arbitrating for the bus or 
+ *		selecting the target. Numerous steps in this function are 
+ *		run without timeouts, so commands hanging on select will 
+ *		time out in the midlevel code if lucky. 
+ *		Roman Hodek fixed this in the Atari driver, and I've 
+ *		experienced driver hangup due to reselect while selecting
+ *		on the Mac, so I've adopted the Atari fixes for the generic
+ *		driver.
  */
 static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag) {
 	NCR5380_local_declare();
@@ -1643,6 +1686,10 @@
 	}
 #endif
 
+	if (hostdata->connected) {
+	  	return -1;
+	}
+
 	 hostdata->restart_select = 0;
 #if defined (NDEBUG) && (NDEBUG & NDEBUG_ARBITRATION)
 	 NCR5380_print(instance);
@@ -1652,6 +1699,10 @@
 	 save_flags(flags);
 	 cli();
 
+	 if (hostdata->connected) {
+		restore_flags(flags);
+	  	return -1;
+	}
 	/* 
 	 * Set the phase bits to 0, otherwise the NCR5380 won't drive the 
 	 * data bus during SELECTION.
@@ -1689,7 +1740,8 @@
 		}
 	}
 #else				/* NCR_TIMEOUT */
-	while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS));
+	while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
+	       && !hostdata->connected);
 #endif
 
 #if (NDEBUG & NDEBUG_ARBITRATION)
@@ -1698,6 +1750,11 @@
 	 __asm__("nop");
 #endif
 
+	if (hostdata->connected) {
+	  NCR5380_write(MODE_REG, MR_BASE); 
+	  return -1;
+	}
+
 	/* 
 	 * The arbitration delay is 2.2us, but this is a minimum and there is 
 	 * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate
@@ -1709,8 +1766,9 @@
 
 	/* Check for lost arbitration */
 	if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
-	     (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
-	  (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
+	    (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
+	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || 
+	    hostdata->connected) {
 		NCR5380_write(MODE_REG, MR_BASE);
 #if (NDEBUG & NDEBUG_ARBITRATION)
 		printk("scsi%d : lost arbitration, deasserting MR_ARBITRATE\n",
@@ -1718,14 +1776,21 @@
 #endif
 		return -1;
 	}
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
+	/* 
+	 * MSch: need to asert BSY while selecting, otherwise a target might 
+	 * detect bus free and burst in after we won arbitration
+	 * Fix by Roman Hodek; see atari_NCR5380.c 
+	 */
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL |
+		                             ICR_ASSERT_BSY );
 
 	if (!(hostdata->flags & FLAG_DTC3181E) &&
 		/* RvC: DTC3181E has some trouble with this
 		 *	so we simply removed it. Seems to work with
 		 *	only Mustek scanner attached
 		 */
-		(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) 
+		((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
+	         hostdata->connected)) 
 	{
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1742,6 +1807,12 @@
 
 	udelay(2);
 
+	if (hostdata->connected) {
+	  NCR5380_write(MODE_REG, MR_BASE);
+	  NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	  return -1;
+	}
+
 #if (NDEBUG & NDEBUG_ARBITRATION)
 	printk("scsi%d : won arbitration\n", instance->host_no);
 #endif
@@ -1764,6 +1835,11 @@
 		     ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL));
 	NCR5380_write(MODE_REG, MR_BASE);
 
+	if (hostdata->connected) {
+	  NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	  return -1;
+	}
+
 	/* 
 	 * Reselect interrupts must be turned off prior to the dropping of BSY,
 	 * otherwise we will trigger an interrupt.
@@ -1839,11 +1915,14 @@
 	hostdata->selecting = 0; /* clear this pointer, because we passed the
 				waiting period */
 #else
+#if 0   /* MSch: testing */
 	spin_unlock_irq(&io_request_lock);
 	while ((jiffies < timeout) && !(NCR5380_read(STATUS_REG) &
 					(SR_BSY | SR_IO)));
 	spin_lock_irq(&io_request_lock);
 #endif
+#endif
+#if 0   /* MSch: testing */
 	if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) ==
 	    (SR_SEL | SR_IO)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1853,6 +1932,16 @@
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return -1;
 	}
+#else
+	/* MSch: fix from Atari driver */
+	/* ++roman: If a target conformed to the SCSI standard, it wouldn't assert
+	 * IO while SEL is true. But again, there are some disks out the in the
+	 * world that do that nevertheless. (Somebody claimed that this announces
+	 * reselection capability of the target.) So we better skip that test and
+	 * only wait for BSY... (Famous german words: Der Kl|gere gibt nach :-)
+	 */
+	while ((jiffies < timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY));
+#endif
 	/* 
 	 * No less than two deskew delays after the initiator detects the 
 	 * BSY signal is true, it shall release the SEL signal and may 
@@ -1928,7 +2017,12 @@
 	printk("scsi%d : target %d selected, going into MESSAGE OUT phase.\n",
 	       instance->host_no, cmd->target);
 #endif
+#ifdef CONFIG_MAC
+	/* MSch: Mac kludge, prohibit disconnects if can_queue <= 2 */
+	tmp[0] = IDENTIFY(( ((instance->irq == IRQ_NONE) || (instance->can_queue < 3)) ? 0 : 1), cmd->lun);
+#else
 	tmp[0] = IDENTIFY(((instance->irq == IRQ_NONE) ? 0 : 1), cmd->lun);
+#endif
 #ifdef SCSI2
 	if (cmd->device->tagged_queue && (tag != TAG_NONE)) {
 		tmp[1] = SIMPLE_QUEUE_TAG;
@@ -2170,15 +2264,18 @@
 	 udelay(25);
 	 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 	 restore_flags(flags);
-}				/*
+}
+/*
+ * Function : do_abort (Scsi_Host *host)
+ * 
+ * Purpose : abort the currently established nexus.  Should only be 
+ *      called from a routine which can drop into a 
+ * 
+ * Returns : 0 on success, -1 on failure.
+ */ 
+
+static int do_abort(struct Scsi_Host *host) {
 
-				 * Function : do_abort (Scsi_Host *host)
-				 * 
-				 * Purpose : abort the currently established nexus.  Should only be 
-				 *      called from a routine which can drop into a 
-				 * 
-				 * Returns : 0 on success, -1 on failure.
-				 */ static int do_abort(struct Scsi_Host *host) {
 	NCR5380_local_declare();
 	unsigned char tmp, *msgptr, phase;
 	int len;
@@ -3294,6 +3391,9 @@
  *       connected, you have to wait for it to complete.  If this is 
  *       a problem, we could implement longjmp() / setjmp(), setjmp()
  *       called where the loop started in NCR5380_main().
+ *
+ * XXX - MSch: I've changed the abort and reset code to work like the code
+ *       in the Atari NCR5380 driver, the old reset code was broken there.
  */
 
 #ifndef NCR5380_abort
@@ -3312,10 +3412,6 @@
 
 	NCR5380_print_status(instance);
 
-	printk("scsi%d : aborting command\n", instance->host_no);
-	print_Scsi_Cmnd(cmd);
-
-	NCR5380_print_status(instance);
 
 	save_flags(flags);
 	cli();
@@ -3344,7 +3440,9 @@
  * into BUS FREE.
  */
 
+#if 0
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN);
+#endif
 /* 
  * Since we can't change phases until we've completed the current 
  * handshake, we have to source or sink a byte of data if the current
@@ -3355,8 +3453,19 @@
  * Return control to the executing NCR drive so we can clear the
  * aborted flag and get back into our main loop.
  */
-
-		return 0;
+		if (do_abort(instance) == 0) {
+			hostdata->aborted = 1;
+			hostdata->connected = NULL;
+			cmd->result = DID_ABORT << 16;
+			hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+			restore_flags(flags);
+			cmd->scsi_done(cmd);
+			return SCSI_ABORT_SUCCESS;
+		} else {
+/*			restore_flags(flags); */
+			printk("scsi%d: abort of connected command failed!\n", instance->host_no);
+			return SCSI_ABORT_ERROR;
+		}
 	}
 #endif
 
@@ -3382,7 +3491,7 @@
 			printk("scsi%d : abort removed command from issue queue.\n",
 			       instance->host_no);
 #endif
-			tmp->done(tmp);
+			tmp->scsi_done(tmp);
 			return SCSI_ABORT_SUCCESS;
 		}
 #if (NDEBUG  & NDEBUG_ABORT)
@@ -3407,7 +3516,7 @@
 #if (NDEBUG & NDEBUG_ABORT)
 		printk("scsi%d : abort failed, command connected.\n", instance->host_no);
 #endif
-		return SCSI_ABORT_NOT_RUNNING;
+		return SCSI_ABORT_SNOOZE;	/* was: SCSI_ABORT_NOT_RUNNING */
 	}
 /*
  * Case 4: If the command is currently disconnected from the bus, and 
@@ -3461,8 +3570,9 @@
 					*prev = (Scsi_Cmnd *) tmp->host_scribble;
 					tmp->host_scribble = NULL;
 					tmp->result = DID_ABORT << 16;
+					hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
 					restore_flags(flags);
-					tmp->done(tmp);
+					tmp->scsi_done(tmp);
 					return SCSI_ABORT_SUCCESS;
 				}
 		}
@@ -3490,6 +3600,10 @@
  *
  * Returns : SCSI_RESET_WAKEUP
  *
+ *	MSch: commands affected by a bus reset are subject to timeout, but the
+ *	midlevel code (using old error handling code) doesn't disable timeouts
+ *	immediately. Plus do_reset just resets the bus, without inserting connected
+ *	and disconnected commands into the issue queue. 
  */
 
 #ifndef NCR5380_reset
@@ -3497,10 +3611,88 @@
 #endif
 int NCR5380_reset(Scsi_Cmnd * cmd, unsigned int dummy) {
 	NCR5380_local_declare();
+	struct Scsi_Host *instance;
+	struct NCR5380_hostdata *hostdata;
+	int           i;
+	unsigned long flags;
+	Scsi_Cmnd *connected, *disconnected_queue;
+
 	NCR5380_setup(cmd->host);
 
+	instance = cmd->host;
+	hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+
 	NCR5380_print_status(cmd->host);
+
+#if 0	/* old code */
 	do_reset(cmd->host);
 
 	return SCSI_RESET_WAKEUP;
+#else
+	/* get in phase */
+	NCR5380_write( TARGET_COMMAND_REG,
+		      PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
+	/* assert RST */
+	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
+	udelay (40);
+	/* reset NCR registers */
+	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
+	NCR5380_write( MODE_REG, MR_BASE );
+	NCR5380_write( TARGET_COMMAND_REG, 0 );
+	NCR5380_write( SELECT_ENABLE_REG, 0 );
+	/* ++roman: reset interrupt condition! otherwise no interrupts don't get
+	 * through anymore ... */
+	(void)NCR5380_read( RESET_PARITY_INTERRUPT_REG );
+
+	/* XXX Should now be done by midlevel code, but it's broken XXX */
+	/* XXX see below                                            XXX */
+
+	/* MSch: old-style reset: actually abort all command processing here */
+
+	/* After the reset, there are no more connected or disconnected commands
+	 * and no busy units; to avoid problems with re-inserting the commands
+	 * into the issue_queue (via scsi_done()), the aborted commands are
+	 * remembered in local variables first.
+	 */
+	save_flags(flags);
+	cli();
+	connected = (Scsi_Cmnd *)hostdata->connected;
+	hostdata->connected = NULL;
+	disconnected_queue = (Scsi_Cmnd *)hostdata->disconnected_queue;
+	hostdata->disconnected_queue = NULL;
+
+	for( i = 0; i < 8; ++i )
+	  hostdata->busy[i] = 0;
+#ifdef REAL_DMA
+	hostdata->dma_len = 0;
+#endif
+	restore_flags(flags);
+
+	/* In order to tell the mid-level code which commands were aborted, 
+	 * set the command status to DID_RESET and call scsi_done() !!!
+	 * This ultimately aborts processing of these commands in the mid-level.
+	 */
+
+	if ((cmd = connected)) {
+	  printk("scsi%d: reset aborted a connected command\n", (cmd)->host->host_no);
+	  cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16);
+	  cmd->scsi_done( cmd );
+	}
+
+	for (i = 0; (cmd = disconnected_queue); ++i) {
+	  disconnected_queue = (Scsi_Cmnd *) cmd->host_scribble;
+	  (Scsi_Cmnd *) cmd->host_scribble = NULL;
+	  cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16);
+	  cmd->scsi_done( cmd );
+	}
+	if (i > 0)
+	  printk("scsi: reset aborted %d disconnected command(s)\n", i);
+
+	/* since all commands have been explicitly terminated, we need to tell
+	 * the midlevel code that the reset was SUCCESSFUL, and there is no 
+	 * need to 'wake up' the commands by a request_sense
+	 */
+	return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
+
+#endif
 }
diff -urN -X diff-21.excl linux-2.1.120-vanilla/drivers/scsi/NCR53C9x.c linux-2.1.120/drivers/scsi/NCR53C9x.c
--- linux-2.1.120-vanilla/drivers/scsi/NCR53C9x.c	Mon Jun  8 07:08:06 1998
+++ linux-2.1.120/drivers/scsi/NCR53C9x.c	Sun Sep 13 13:47:50 1998
@@ -694,6 +694,7 @@
 	/* Initialize the command queues */
 	esp->current_SC = 0;
 	esp->disconnected_SC = 0;
+	esp->disconnected_mask = 0;
 	esp->issue_SC = 0;
 	
 	/* Clear the state machines. */
@@ -987,22 +988,41 @@
 static inline void esp_exec_cmd(struct NCR_ESP *esp)
 {
 	struct ESP_regs *eregs = esp->eregs;
-	Scsi_Cmnd *SCptr;
+	Scsi_Cmnd *SCptr, **SCptr2;
 	Scsi_Device *SDptr;
 	volatile unchar *cmdp = esp->esp_command;
 	unsigned char the_esp_command;
 	int lun, target;
 	int i;
 
-	/* Hold off if we've been reselected or an IRQ is showing... */
-	if(esp->disconnected_SC || esp->dma_irq_p(esp))
-		return;
+	/* Hold off if an IRQ is showing... */
+	if(esp->dma_irq_p(esp)) return;
 
-	/* Grab first member of the issue queue. */
-	SCptr = esp->current_SC = remove_first_SC(&esp->issue_SC);
+	SCptr2 = &(esp->issue_SC);
 
 	/* Safe to panic here because current_SC is null. */
-	if(!SCptr) panic("esp: esp_exec_cmd and issue queue is NULL");
+	if(!(*SCptr2)) panic("esp: esp_exec_cmd and issue queue is NULL");
+
+	/* Search for first command whose target is not disconnected
+	 * (free bus means target is idle in that case)
+	 */
+	while(*SCptr2)
+	 {
+	  if(!(esp->disconnected_mask & (1 << ((*SCptr2)->target)))) break;
+	  SCptr2 = (Scsi_Cmnd **) &((*SCptr2)->host_scribble);
+	 }
+
+	/* Here it means no suitable command found. */
+	if(!(*SCptr2)) return;
+	
+	/* Grab member of the issue queue. */
+	SCptr = esp->current_SC = remove_first_SC(SCptr2);
+
+	/*
+	 * Some devices (like my scanner) are so slow that we really need to
+	 * make sure that the bus is free.
+	 */
+        while(esp->eregs->esp_status & ESP_STAT_PMASK);
 
 	SDptr = SCptr->device;
 	lun = SCptr->lun;
@@ -1045,7 +1065,7 @@
 
 	if(SDptr->sync) {
 		/* this targets sync is known */
-#ifdef CONFIG_SCSI_SUNESP
+#if defined(CONFIG_SCSI_SUNESP) || defined(CONFIG_SCSI_MAC_ESP)
 do_sync_known:
 #endif
 		if(SDptr->disconnect)
@@ -1101,6 +1121,19 @@
 			goto do_sync_known;
 		}
 #endif
+
+#ifdef CONFIG_SCSI_MAC_ESP
+		/* Never allow synchronous transfers (disconnect OK) on
+		 * Macintosh. Well, maybe later when we figured out how to 
+		 * do DMA on the machines that support it ...
+		 */
+		SDptr->disconnect = 1;
+		SDptr->sync_max_offset = 0;
+		SDptr->sync_min_period = 0;
+		SDptr->sync = 1;
+		esp->snip = 0;
+		goto do_sync_known;
+#endif
 		/* We've talked to this guy before,
 		 * but never negotiated.  Let's try,
 		 * need to attempt WIDE first, before
@@ -1208,6 +1241,12 @@
 	if(esp->do_pio_cmds){
 		int j = 0;
 
+		/* 
+		 * It seems this is required, at least to clean up
+		 * after failed commands when using PIO mode ...
+		 */
+		esp_cmd(esp, eregs, ESP_CMD_FLUSH);
+
 		for(;j<i;j++)
 			eregs->esp_fdata = esp->esp_command[j];
 		the_esp_command &= ~ESP_CMD_DMA;
@@ -1890,24 +1929,192 @@
 	esp_advance_phase(SCptr, thisphase);
 	ESPDATA(("newphase<%s> ", (thisphase == in_datain) ? "DATAIN" : "DATAOUT"));
 	hmuch = esp->dma_can_transfer(esp, SCptr);
-	ESPDATA(("hmuch<%d> ", hmuch));
-	esp->current_transfer_size = hmuch;
-	if(esp->erev == fashme) {
-		/* Touchy chip, this stupid HME scsi adapter... */
-		esp_setcount(eregs, hmuch, 1);
-		esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
 
-		if(thisphase == in_datain)
-			esp->dma_init_read(esp, (__u32)((unsigned long)SCptr->SCp.ptr), hmuch);
-		else
-			esp->dma_init_write(esp, (__u32)((unsigned long)SCptr->SCp.ptr), hmuch);
-	} else {
+	if (hmuch) {	/* DMA */
+		ESPDATA(("hmuch<%d> ", hmuch));
+		esp->current_transfer_size = hmuch;
+		if(esp->erev == fashme) {
+			/* Touchy chip, this stupid HME scsi adapter... */
+			esp_setcount(eregs, hmuch, 1);
+			esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
+
+			if(thisphase == in_datain)
+				esp->dma_init_read(esp, (__u32)((unsigned long)SCptr->SCp.ptr), hmuch);
+			else
+				esp->dma_init_write(esp, (__u32)((unsigned long)SCptr->SCp.ptr), hmuch);
+		} else {
+			esp_setcount(eregs, hmuch, 0);
+			esp->dma_setup(esp, 
+				       (__u32)((unsigned long)SCptr->SCp.ptr), 
+				       hmuch, (thisphase == in_datain));
+			ESPDATA(("DMA|TI --> do_intr_end\n"));
+			esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
+		}
+		return do_intr_end;
+	} else {	/* PIO :-(( This sucks ... */
+		int oldphase, i = 0; /* or where we left off last time ?? esp->current_data ?? */
+		int fifocnt = 0;
+
+		oldphase = eregs->esp_status & ESP_STAT_PMASK;
+
+		/*
+		 * polled transfer; ugly, can we make this happen in a DRQ 
+		 * interrupt handler ??
+		 * requires keeping track of state information in host or 
+		 * command struct!
+		 * Problem: I've never seen a DRQ happen on Mac, not even
+		 * with ESP_CMD_DMA ...
+		 */
+
+		/* figure out how much needs to be transfered */
+		hmuch = SCptr->SCp.this_residual;
+		ESPDATA(("hmuch<%d> pio ", hmuch));
+		esp->current_transfer_size = hmuch;
+
+		/* tell the ESP ... */
 		esp_setcount(eregs, hmuch, 0);
-		esp->dma_setup(esp, 
-			       (__u32)((unsigned long)SCptr->SCp.ptr), 
-			       hmuch, (thisphase == in_datain));
-		ESPDATA(("DMA|TI --> do_intr_end\n"));
-		esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
+
+		/* loop */
+		while (hmuch) {
+			int j, fifo_stuck = 0, newphase;
+			unsigned long flags, timeout;
+#if 0
+			if ( i % 10 )
+				ESPDATA(("\r"));
+			else
+				ESPDATA(( /*"\n"*/ "\r"));
+#endif
+			save_flags(flags);
+#if 0
+			cli();
+#endif
+			if(thisphase == in_datain) {
+				/* 'go' ... */ 
+				esp_cmd(esp, eregs, ESP_CMD_TI);
+
+				/* wait for data */
+				timeout = 1000000;
+				while (!((esp->sreg=eregs->esp_status) & ESP_STAT_INTR) && --timeout)
+					udelay(2);
+				if (timeout == 0)
+					printk("DRQ datain timeout! \n");
+
+				newphase = esp->sreg & ESP_STAT_PMASK;
+
+				/* see how much we got ... */
+				fifocnt = (eregs->esp_fflags & ESP_FF_FBYTES);
+
+				if (!fifocnt)
+					fifo_stuck++;
+				else
+					fifo_stuck = 0;
+
+				ESPDATA(("\rgot %d st %x ph %x", fifocnt, esp->sreg, newphase));
+
+				/* read fifo */
+				for(j=0;j<fifocnt;j++)
+					SCptr->SCp.ptr[i++] = eregs->esp_fdata;
+
+				ESPDATA(("(%d) ", i));
+
+				/* how many to go ?? */
+				hmuch -= fifocnt;
+
+				/* break if status phase !! */
+				if(newphase == ESP_STATP) {
+					/* clear int. */
+					esp->ireg = eregs->esp_intrpt;
+					break;
+				}
+			} else {
+#define MAX_FIFO 8
+				/* how much will fit ? */
+				int this_count = MAX_FIFO - fifocnt;
+				if (this_count > hmuch)
+					this_count = hmuch;
+
+				/* fill fifo */
+				for(j=0;j<this_count;j++)
+					eregs->esp_fdata = SCptr->SCp.ptr[i++];
+
+				/* how many left if this goes out ?? */
+				hmuch -= this_count;
+
+				/* 'go' ... */ 
+				esp_cmd(esp, eregs, ESP_CMD_TI);
+
+				/* wait for 'got it' */
+				timeout = 1000000;
+				while (!((esp->sreg=eregs->esp_status) & ESP_STAT_INTR) && --timeout)
+					udelay(2);
+				if (timeout == 0)
+					printk("DRQ dataout timeout!  \n");
+
+				newphase = esp->sreg & ESP_STAT_PMASK;
+
+				/* need to check how much was sent ?? */
+				fifocnt = (eregs->esp_fflags & ESP_FF_FBYTES);
+
+				ESPDATA(("\rsent %d st %x ph %x", this_count - fifocnt, esp->sreg, newphase));
+
+				ESPDATA(("(%d) ", i));
+
+				/* break if status phase !! */
+				if(newphase == ESP_STATP) {
+					/* clear int. */
+					esp->ireg = eregs->esp_intrpt;
+					break;
+				}
+
+			}
+
+			/* clear int. */
+			esp->ireg = eregs->esp_intrpt;
+
+			ESPDATA(("ir %x ... ", esp->ireg));
+
+			if (hmuch == 0)
+				ESPDATA(("done! \n"));
+
+			restore_flags(flags);
+
+			/* check new bus phase */
+			if (newphase != oldphase && i < esp->current_transfer_size) {
+				/* something happened; disconnect ?? */
+				ESPDATA(("phase change, dropped out with %d done ... ", i));
+				break;
+			}
+
+			/* check int. status */
+			if (esp->ireg & ESP_INTR_DC) {
+				/* disconnect */
+				ESPDATA(("disconnect; %d transfered ... ", i));
+				break;
+			} else if (esp->ireg & ESP_INTR_FDONE) {
+				/* function done */
+				ESPDATA(("function done; %d transfered ... ", i));
+				break;
+			}
+
+			/* XXX fixme: bail out on stall */
+			if (fifo_stuck > 10) {
+				/* we're stuck */
+				ESPDATA(("fifo stall; %d transfered ... ", i));
+				break;
+			}
+		}
+
+		ESPDATA(("\n"));
+		/* check successful completion ?? */
+
+		if (thisphase == in_dataout)
+			hmuch += fifocnt; /* stuck?? adjust data pointer ...*/
+
+		/* tell do_data_finale how much was transfered */
+		esp->current_transfer_size -= hmuch;
+
+		/* still not completely sure on this one ... */		
+		return /*do_intr_end*/ do_work_bus /*do_phase_determine*/ ;
 	}
 	return do_intr_end;
 }
@@ -2057,7 +2264,12 @@
 			advance_sg(esp, SCptr);
 		if(sreg_datainp(esp->sreg) || sreg_dataoutp(esp->sreg)) {
 			ESPDATA(("to more data\n"));
-			return esp_do_data(esp, eregs);
+			/*
+			 * required for proper termination of data transfer 
+			 * phase in PIO mode
+			 */
+			if (!((esp->sreg & ESP_STAT_PMASK) == ESP_STATP))
+				return esp_do_data(esp, eregs);
 		}
 		ESPDATA(("to new phase\n"));
 		return esp_do_phase_determine(esp, eregs);
@@ -2130,6 +2342,7 @@
 		esp_cmd(esp, eregs, ESP_CMD_ESEL);
 		ESPDISC(("D<%02x,%02x>", SCptr->target, SCptr->lun));
 		append_SC(&esp->disconnected_SC, SCptr);
+		esp->disconnected_mask |= (1 << (SCptr->target));
 		esp->current_SC = NULL;
 		if(esp->issue_SC)
 			esp_exec_cmd(esp);
@@ -2180,6 +2393,8 @@
 		esp_cmd(esp, eregs, ESP_CMD_NULL);
 	}
 
+	esp->disconnected_mask &= ~(1 << target);
+	
 	SCptr = remove_SC(&esp->disconnected_SC, (unchar) target, (unchar) lun);
 	if(!SCptr) {
 		Scsi_Cmnd *sp;
@@ -3639,6 +3854,7 @@
 	return;
 }
 
+
 #ifndef __sparc_v9__
 
 #ifndef __SMP__
@@ -3652,7 +3868,7 @@
 	again = 0;
 	for_each_esp(esp) {
 #ifndef __mips__	    
-		if(((esp)->irq & 0xf) == irq) {
+		if(((esp)->irq & 0xff) == irq) {
 #endif		    
 			if(esp->dma_irq_p(esp)) {
 				again = 1;
diff -urN -X diff-21.excl linux-2.1.120-vanilla/drivers/scsi/NCR53C9x.h linux-2.1.120/drivers/scsi/NCR53C9x.h
--- linux-2.1.120-vanilla/drivers/scsi/NCR53C9x.h	Thu Jul  9 03:40:53 1998
+++ linux-2.1.120/drivers/scsi/NCR53C9x.h	Sun Sep 13 13:47:50 1998
@@ -13,6 +13,13 @@
 
 #include <linux/config.h>
 
+/* djweis for mac driver */
+#if defined(CONFIG_MAC)
+#define PAD_SIZE 15
+#else
+#define PAD_SIZE 3
+#endif
+
 /* Macros for debugging messages */
 
 /* #define DEBUG_ESP */
@@ -26,6 +33,7 @@
 /* #define DEBUG_STATE_MACHINE */
 /* #define DEBUG_ESP_CMDS */
 /* #define DEBUG_ESP_IRQS */
+/* #define DEBUG_ESP_DBG */
 /* #define DEBUG_SDTR */
 /* #define DEBUG_ESP_SG */
 
@@ -83,6 +91,12 @@
 #define ESPBUS(foo)
 #endif
 
+#if defined(DEBUG_ESP_CMDS)
+#define ESPCMDS(foo)  printk foo
+#else
+#define ESPCMDS(foo)
+#endif
+
 #if defined(DEBUG_ESP_IRQS)
 #define ESPIRQ(foo)  printk foo
 #else
@@ -101,6 +115,14 @@
 #define ESPMISC(foo)
 #endif
 
+#if defined(DEBUG_ESP_DBG)
+#define ESPDBG(foo)  printk foo
+#else
+#define ESPDBG(foo)
+#endif
+
+#define ESPDBG2(foo)
+
 #define INTERNAL_ESP_ERROR \
         (panic ("Internal ESP driver error in file %s, line %d\n", \
 		__FILE__, __LINE__))
@@ -115,7 +137,7 @@
 #ifdef CONFIG_JAZZ_ESP
 #define EREGS_PAD(n)
 #else
-#define EREGS_PAD(n)    unchar n[3];
+#define EREGS_PAD(n)    unchar n[PAD_SIZE];
 #endif
 
 /* The ESP SCSI controllers have their register sets in three
@@ -167,7 +189,7 @@
     /* The following is only found on the 53C9X series SCSI chips */
     volatile unchar esp_cfg3;   /* rw  Third configuration register   0x30  */
                                 EREGS_PAD(holep);
-    volatile unchar esp_hole;   /* hole in register map               0x34  */
+    volatile unchar esp_cfg4;   /* rw  Fourth configuration register  0x34  */
                                 EREGS_PAD(thpd);    
     /* The following is found on all chips except the NCR53C90 (ESP100) */
     volatile unchar esp_tchi;   /* rw  High bits of transfer count    0x38  */
@@ -277,6 +299,11 @@
   Scsi_Cmnd *issue_SC;           /* Commands to be issued */
   Scsi_Cmnd *current_SC;         /* Who is currently working the bus */
   Scsi_Cmnd *disconnected_SC;    /* Commands disconnected from the bus */
+
+  /* when fetching the next command out of issue_SC, ignore the targets
+   * whose bit is set; they're currently busy.
+   */
+  int disconnected_mask;         /* bit mask of disconnected targets */
 
   /* Message goo */
   unchar cur_msgout[16];
diff -urN -X diff-21.excl linux-2.1.120-vanilla/drivers/scsi/mac_esp.c linux-2.1.120/drivers/scsi/mac_esp.c
--- linux-2.1.120-vanilla/drivers/scsi/mac_esp.c	Fri Aug  7 11:07:40 1998
+++ linux-2.1.120/drivers/scsi/mac_esp.c	Wed Sep  9 00:55:12 1998
@@ -1,12 +1,11 @@
 
 /*
-
-68k mac 53c9[46] scsi driver
-
-copyright (c) 1998, David Weis weisd3458@uni.edu
-
-based loosely on cyber_esp.c
-*/
+ * 68k mac 53c9[46] scsi driver
+ *
+ * copyright (c) 1998, David Weis weisd3458@uni.edu
+ *
+ * based loosely on cyber_esp.c
+ */
 
 /* these are unused for now */
 #define myreadl(addr) (*(volatile unsigned int *) (addr))
@@ -40,6 +39,9 @@
 
 #include <asm/macintosh.h>
 
+extern inline void esp_handle(struct NCR_ESP *esp);
+extern void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs);
+
 static int  dma_bytes_sent(struct NCR_ESP * esp, int fifo_count);
 static int  dma_can_transfer(struct NCR_ESP * esp, Scsi_Cmnd *sp);
 static void dma_dump_state(struct NCR_ESP * esp);
@@ -61,333 +63,456 @@
 
 static int esp_initialized = 0;
 
+/*
+ * Experimental ESP inthandler; check macints.c to make sure dev_id is 
+ * set up properly!
+ */
+
+void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
+{
+	struct NCR_ESP *esp = (struct NCR_ESP *) dev_id;
+	int irq_p = 0;
+
+	/* Handle the one ESP interrupt showing at this IRQ level. */
+	if(((esp)->irq & 0xff) == irq) {
+	/*
+	 * Debug ..
+	 */
+		irq_p = esp->dma_irq_p(esp);
+	 	printk("mac_esp: irq_p %x current %p disconnected %p\n",
+	 		irq_p, esp->current_SC, esp->disconnected_SC);
+	 		
+		/*
+		 * Mac: if we're here, it's an ESP interrupt for sure!
+		 */
+		if((esp->current_SC || esp->disconnected_SC)) {
+			esp->dma_ints_off(esp);
+
+			ESPIRQ(("I%d(", esp->esp_id));
+			esp_handle(esp);
+			ESPIRQ((")"));
+
+			esp->dma_ints_on(esp);
+		}
+	}
+}
+
+/*
+ * Debug hooks; use for playing with the interrupt flag testing and interrupt
+ * acknowledge on the various machines
+ */
+
 void scsi_esp_polled(int irq, void *dev_id, struct pt_regs *pregs)
 {
+	if (esp_initialized == 0)
+		return;
 
-  if (esp_initialized == 0)
-    return;
-
-  mac_esp_intr(irq, dev_id, pregs);
-
+	mac_esp_intr(irq, dev_id, pregs);
 }
 
 void fake_intr(int irq, void *dev_id, struct pt_regs *pregs)
 {
 #ifdef DEBUG_MAC_ESP
-  printk("mac_esp: got irq\n");
+	printk("mac_esp: got irq\n");
 #endif
 
-  mac_esp_intr(irq, dev_id, pregs);
-
+	mac_esp_intr(irq, dev_id, pregs);
 }
 
 void fake_drq(int irq, void *dev_id, struct pt_regs *pregs)
 {
-  printk("mac_esp: got drq\n");
-
+	printk("mac_esp: got drq\n");
 }
 
+/*
+ * ESP address 'detection'
+ */
+
 unsigned long get_base(int chip_num)
 {
-  /*
-    using the chip_num and mac model, figure out where the
-    chips are mapped
-    */
-
-  unsigned long io_base = 0x50f00000;
-  unsigned int second_offset = 0x402;
-  unsigned long scsi_loc = 0;
-
-  switch (macintosh_config->scsi_type) {
-
-    /* 950, 900, 700 */
-  case MAC_SCSI_QUADRA2:
-    scsi_loc =  io_base + 0xf000 + ((chip_num == 0) ? 0 : second_offset);
-    break;
-
-    /* av's */
-  case MAC_SCSI_QUADRA3:
-    scsi_loc = io_base + 0x18000 + ((chip_num == 0) ? 0 : second_offset);
-    break;
-
-  /* most quadra/centris models are like this */	
-  case MAC_SCSI_QUADRA:
-    scsi_loc = io_base + 0x10000;
-    break;
-
-  default:
-    printk("mac_esp: get_base: hit default!\n");
-    scsi_loc = io_base + 0x10000;
-    break;
+	/*
+	 * using the chip_num and mac model, figure out where the
+	 * chips are mapped
+	 */
 
-  } /* switch */
+	unsigned long io_base = 0x50f00000;
+	unsigned int second_offset = 0x402;
+	unsigned long scsi_loc = 0;
 
-  printk("mac_esp: io base at 0x%lx\n", scsi_loc);
-  return scsi_loc;
+	switch (macintosh_config->scsi_type) {
 
-}
+	/* 950, 900, 700 */
+	case MAC_SCSI_QUADRA2:
+		scsi_loc =  io_base + 0xf000 + ((chip_num == 0) ? 0 : second_offset);
+		break;
 
+	/* av's */
+	case MAC_SCSI_QUADRA3:
+		scsi_loc = io_base + 0x18000 + ((chip_num == 0) ? 0 : second_offset);
+		break;
 
-int mac_esp_detect(Scsi_Host_Template * tpnt)
-{
-  int quick = 0;
-  int chipnum, chipspresent = 0;
-  unsigned long timeout;
+	/* most quadra/centris models are like this */	
+	case MAC_SCSI_QUADRA:
+		scsi_loc = io_base + 0x10000;
+		break;
 
-  /* what do we have in this machine... */
-  if (MACHW_PRESENT(MAC_SCSI_96)) {
-    chipspresent ++;
-  }
+	default:
+		printk("mac_esp: get_base: hit default!\n");
+		scsi_loc = io_base + 0x10000;
+		break;
 
-  if (MACHW_PRESENT(MAC_SCSI_96_2)) {
-    chipspresent ++;
-  }
+	} /* switch */
 
+	printk("mac_esp: io base at 0x%lx\n", scsi_loc);
 
-  for (chipnum = 0; chipnum < chipspresent; chipnum ++) {
-    struct NCR_ESP * esp;
+	return scsi_loc;
+}
 
-    esp = esp_allocate(tpnt, (void *) NULL);
-    esp->eregs = (struct ESP_regs *) get_base(chipnum);
+/*
+ * Model dependent ESP setup
+ */
 
-    esp->dma_irq_p = &esp_dafb_dma_irq_p;
-    if (chipnum == 0) {
+int mac_esp_detect(Scsi_Host_Template * tpnt)
+{
+	int quick = 0;
+	int chipnum, chipspresent = 0;
+#if 0
+	unsigned long timeout;
+#endif
 
-      if (macintosh_config->scsi_type == MAC_SCSI_QUADRA) {
-	/* most machines except those below :-) */
-	quick = 1;
-	esp->dma_irq_p = &esp_iosb_dma_irq_p;
-      } else if (macintosh_config->scsi_type == MAC_SCSI_QUADRA3) {
-	/* mostly av's */
-	quick = 0;
-      } else {
-	/* q950, 900, 700 */
-	quick = 1;
-	writel(0x1d1, 0xf9800024);
-	esp->dregs = 0xf9800024;
-      }
+	/* what do we have in this machine... */
+	if (MACHW_PRESENT(MAC_SCSI_96)) {
+		chipspresent ++;
+	}
 
-    } else { /* chipnum */
+	if (MACHW_PRESENT(MAC_SCSI_96_2)) {
+		chipspresent ++;
+	}
 
-      quick = 1;
-      writel(0x1d1, 0xf9800028);
-      esp->dregs = 0xf9800028;
 
-    } /* chipnum == 0 */
+	for (chipnum = 0; chipnum < chipspresent; chipnum ++) {
+		struct NCR_ESP * esp;
 
+		esp = esp_allocate(tpnt, (void *) NULL);
+		esp->eregs = (struct ESP_regs *) get_base(chipnum);
 
-    /* use pio for command bytes; pio for message/data: TBI */
-    esp->do_pio_cmds = 1;
+		esp->dma_irq_p = &esp_dafb_dma_irq_p;
+		if (chipnum == 0) {
 
-    /* various functions */
-    esp->dma_bytes_sent = &dma_bytes_sent;
-    esp->dma_can_transfer = &dma_can_transfer;
-    esp->dma_dump_state = &dma_dump_state;
-    esp->dma_init_read = NULL;
-    esp->dma_init_write = NULL;
-    esp->dma_ints_off = &dma_ints_off;
-    esp->dma_ints_on = &dma_ints_on;
+			if (macintosh_config->scsi_type == MAC_SCSI_QUADRA) {
+				/* most machines except those below :-) */
+				quick = 1;
+				esp->dma_irq_p = &esp_iosb_dma_irq_p;
+			} else if (macintosh_config->scsi_type == MAC_SCSI_QUADRA3) {
+				/* mostly av's */
+				quick = 0;
+			} else {
+				/* q950, 900, 700 */
+				quick = 1;
+				writel(0x1d1, 0xf9800024);
+				esp->dregs = (void *) 0xf9800024;
+			}
 
-    esp->dma_ports_p = &dma_ports_p;
+		} else { /* chipnum */
 
+			quick = 1;
+			writel(0x1d1, 0xf9800028);
+			esp->dregs = (void *) 0xf9800028;
 
-    /* Optional functions */
-    esp->dma_barrier = NULL;
-    esp->dma_drain = NULL;
-    esp->dma_invalidate = NULL;
-    esp->dma_irq_entry = NULL;
-    esp->dma_irq_exit = NULL;
-    esp->dma_led_on = NULL;
-    esp->dma_led_off = NULL;
-    esp->dma_poll = NULL;
-    esp->dma_reset = NULL;
+		} /* chipnum == 0 */
 
-    /* SCSI chip speed */
-    /* below esp->cfreq = 40000000; */
 
+		/* use pio for command bytes; pio for message/data: TBI */
+		esp->do_pio_cmds = 1;
 
-    if (quick) {
-      /* use fast versions i guess... */
-      esp->dma_setup = &dma_setup_quick;
+		/* various functions */
+		esp->dma_bytes_sent = &dma_bytes_sent;
+		esp->dma_can_transfer = &dma_can_transfer;
+		esp->dma_dump_state = &dma_dump_state;
+		esp->dma_init_read = NULL;
+		esp->dma_init_write = NULL;
+		esp->dma_ints_off = &dma_ints_off;
+		esp->dma_ints_on = &dma_ints_on;
 
-    } else {
-      esp->dma_setup = &dma_setup;
+		esp->dma_ports_p = &dma_ports_p;
 
-    }
 
-    if (chipnum == 0) {
+		/* Optional functions */
+		esp->dma_barrier = NULL;
+		esp->dma_drain = NULL;
+		esp->dma_invalidate = NULL;
+		esp->dma_irq_entry = NULL;
+		esp->dma_irq_exit = NULL;
+		esp->dma_led_on = NULL;
+		esp->dma_led_off = NULL;
+		esp->dma_poll = NULL;
+		esp->dma_reset = NULL;
 
-      esp->irq = IRQ_MAC_SCSI;
+		/* SCSI chip speed */
+		/* below esp->cfreq = 40000000; */
 
-      request_irq(IRQ_MAC_SCSI, fake_intr, 0, "Mac ESP SCSI", fake_intr);
 
-      request_irq(IRQ_MAC_SCSIDRQ, fake_drq, 0, "Mac ESP DRQ", fake_drq);
+		if (quick) {
+			/* use fast versions i guess... */
+			esp->dma_setup = &dma_setup_quick;
+		} else {
+			esp->dma_setup = &dma_setup;
+		}
 
-      if (macintosh_config->scsi_type == MAC_SCSI_QUADRA) {
-	esp->cfreq = 16500000;
-      } else {
-	esp->cfreq = 25000000;
-      }
+		if (chipnum == 0) {
 
+			esp->irq = IRQ_MAC_SCSI;
 
-    } else { /* chipnum == 1 */
+			request_irq(IRQ_MAC_SCSI, esp_intr, 0, "Mac ESP SCSI", esp);
+			request_irq(IRQ_MAC_SCSIDRQ, fake_drq, 0, "Mac ESP DRQ", esp);
 
-      esp->irq = IRQ_MAC_SCSIDRQ;
+			if (macintosh_config->scsi_type == MAC_SCSI_QUADRA) {
+				esp->cfreq = 16500000;
+			} else {
+				esp->cfreq = 25000000;
+			}
 
-      request_irq(IRQ_MAC_SCSIDRQ, fake_intr, 0, "Mac ESP SCSI 2", fake_intr);
 
-      esp->cfreq = 25000000;
+		} else { /* chipnum == 1 */
 
-    }
+			esp->irq = IRQ_MAC_SCSIDRQ;
 
-    if (quick) {
-      printk("esp: using quick version\n");
-    }
+			request_irq(IRQ_MAC_SCSIDRQ, esp_intr, 0, "Mac ESP SCSI 2", esp);
 
-    printk("esp: addr at 0x%p\n", esp->eregs);
+			esp->cfreq = 25000000;
 
-    esp->scsi_id = 7;
-    esp->diff = 0;
+		}
 
+		if (quick) {
+			printk("esp: using quick version\n");
+		}
 
-    esp_initialize(esp);
-#if 0
-    timeout = jiffies + HZ*10;
-    while (jiffies < timeout)
-    	barrier();
-#endif
-  } /* for chipnum */
+		printk("esp: addr at 0x%p\n", esp->eregs);
+
+		esp->scsi_id = 7;
+		esp->diff = 0;
 
-  if (chipspresent)
-     printk("\nmac_esp: %d esp controllers found\n", chipspresent);
+		esp_initialize(esp);
 
-  esp_initialized = chipspresent;
+	} /* for chipnum */
 
-  return chipspresent;
+	if (chipspresent)
+		printk("\nmac_esp: %d esp controllers found\n", chipspresent);
 
+	esp_initialized = chipspresent;
+
+	return chipspresent;
 }
 
+/*
+ * I've been wondering what this is supposed to do, for some time. Talking 
+ * to Allen Briggs: These machines have an extra register someplace where the
+ * DRQ pin of the ESP can be monitored. That isn't useful for determining 
+ * anything else (such as reselect interrupt or other magic) though. 
+ * Maybe make the semantics should be changed like 
+ * if (esp->current_SC)
+ *	... check DRQ flag ...
+ * else 
+ *	... disconnected, check pending VIA interrupt ...
+ *
+ * There's a problem with using the dabf flag or mac_irq_pending() here: both
+ * seem to return 1 even though no interrupt is currently pending, resulting
+ * in esp_exec_cmd() holding off the next command, and possibly infinite loops
+ * in esp_intr(). 
+ * Short term fix: just use esp_status & ESP_STAT_INTR here, as long as we
+ * use simple PIO. The DRQ status will be important when implementing pseudo
+ * DMA mode (set up ESP transfer count, return, do a batch of bytes in PIO or 
+ * 'hardware handshake' mode upon DRQ).
+ * If you plan on changing this (i.e. to save the esp_status register access in 
+ * favor of a VIA register access or a shadow register for the IFR), make sure
+ * to try a debug version of this first to monitor what registers would be a good
+ * indicator of the ESP interrupt.
+ */
 
 static int esp_dafb_dma_irq_p(struct NCR_ESP * esp)
 {
-  unsigned int ret;
+	unsigned int ret;
+	int sreg = esp->eregs->esp_status;
 
 #ifdef DEBUG_MAC_ESP
-  printk("mac_esp: esp_dafb_dma_irq_p\n");
+	printk("mac_esp: esp_dafb_dma_irq_p dafb %d irq %d\n", 
+		readl(esp->dregs), mac_irq_pending(IRQ_MAC_SCSI));
 #endif
 
-  ret = readl(esp->dregs);
+	sreg &= ESP_STAT_INTR;
+
+	/*
+	 * maybe working; this is essentially what's used for iosb_dma_irq_p
+	 */
+	if (sreg)
+		return 1;
+	else
+		return 0;
+
+	/*
+	 * didn't work ...
+	 */
+#if 0
+	if (esp->current_SC)
+		ret = readl(esp->dregs) & 0x200;
+	else if (esp->disconnected_SC)
+		ret = 1; /* sreg ?? */
+	else
+		ret = mac_irq_pending(IRQ_MAC_SCSI);
 
-  return(ret & 0x200);
+	return(ret);
+#endif
 
 }
 
+/*
+ * See above: testing mac_irq_pending always returned 8 (SCSI IRQ) regardless 
+ * of the actual ESP status.
+ */
 
 static int esp_iosb_dma_irq_p(struct NCR_ESP * esp)
 {
-  int ret = mac_irq_pending(IRQ_MAC_SCSIDRQ);
+	int ret  = mac_irq_pending(IRQ_MAC_SCSI) || mac_irq_pending(IRQ_MAC_SCSIDRQ);
+	int sreg = esp->eregs->esp_status;
 
 #ifdef DEBUG_MAC_ESP
-  printk("mac_esp: esp_iosb_dma_irq_p drq %d irq %d\n", 
-  	ret, mac_irq_pending(IRQ_MAC_SCSI));
+	printk("mac_esp: dma_irq_p drq %d irq %d sreg %x curr %p disc %p\n", 
+		mac_irq_pending(IRQ_MAC_SCSIDRQ), mac_irq_pending(IRQ_MAC_SCSI), 
+		sreg, esp->current_SC, esp->disconnected_SC);
 #endif
 
-  return (ret);
+	sreg &= ESP_STAT_INTR;
 
+	if (sreg)
+		return (sreg);
+	else
+		return 0;
 }
 
+/*
+ * This seems to be OK for PIO at least ... usually 0 after PIO.
+ */
 
 static int dma_bytes_sent(struct NCR_ESP * esp, int fifo_count)
 {
 
 #ifdef DEBUG_MAC_ESP
-  printk("mac_esp: dma bytes sent = %x\n", fifo_count);
+	printk("mac_esp: dma bytes sent = %x\n", fifo_count);
 #endif
 
-  return fifo_count;
+	return fifo_count;
 }
 
+/*
+ * dma_can_transfer is used to switch between DMA and PIO, if DMA (pseudo)
+ * is ever implemented. Returning 0 here will use PIO.
+ */
 
 static int dma_can_transfer(struct NCR_ESP * esp, Scsi_Cmnd * sp)
 {
-  unsigned long sz = sp->SCp.this_residual;
+	unsigned long sz = sp->SCp.this_residual;
 #if 0	/* no DMA yet; make conditional */
-  if (sz > 0x10000000) {
-    sz = 0x10000000;
-  }
-  printk("mac_esp: dma can transfer = 0x%x\n", sz);
+	if (sz > 0x10000000) {
+		sz = 0x10000000;
+	}
+	printk("mac_esp: dma can transfer = 0lx%x\n", sz);
 #else
 
 #ifdef DEBUG_MAC_ESP
-  printk("mac_esp: pio to transfer = %d\n", sz);
+	printk("mac_esp: pio to transfer = %ld\n", sz);
 #endif
 
-  sz = 0;
+	sz = 0;
 #endif
-  return sz;
+	return sz;
 }
 
+/*
+ * Not yet ...
+ */
 
 static void dma_dump_state(struct NCR_ESP * esp)
 {
 #ifdef DEBUG_MAC_ESP
-  printk("mac_esp: dma_dump_state: called\n");
+	printk("mac_esp: dma_dump_state: called\n");
 #endif
 #if 0
-  ESPLOG(("esp%d: dma -- cond_reg<%02x>\n",
-	  esp->esp_id, ((struct mac_dma_registers *)
-#endif			(esp->dregs))->cond_reg));
+	ESPLOG(("esp%d: dma -- cond_reg<%02x>\n",
+		esp->esp_id, ((struct mac_dma_registers *)
+		(esp->dregs))->cond_reg));
+#endif
 }
 
+/*
+ * DMA setup: should be used to set up the ESP transfer count for pseudo
+ * DMA transfers; need a DRQ transfer function to do the actual transfer
+ */
 
 static void dma_init_read(struct NCR_ESP * esp, char * vaddress, int length)
 {
-  printk("mac_esp: dma_init_read\n");
+	printk("mac_esp: dma_init_read\n");
 }
 
 
 static void dma_init_write(struct NCR_ESP * esp, char * vaddress, int length)
 {
-  printk("mac_esp: dma_init_write\n");
+	printk("mac_esp: dma_init_write\n");
 }
 
 
 static void dma_ints_off(struct NCR_ESP * esp)
 {
-  mac_turnoff_irq(esp->irq);
+	mac_turnoff_irq(esp->irq);
 }
 
 
 static void dma_ints_on(struct NCR_ESP * esp)
 {
-  mac_turnon_irq(esp->irq);
+	mac_turnon_irq(esp->irq);
 }
 
+/*
+ * generic dma_irq_p(), unused
+ */
 
 static int dma_irq_p(struct NCR_ESP * esp)
 {
-  int i = esp->eregs->esp_status;
+	int i = esp->eregs->esp_status;
 
 #ifdef DEBUG_MAC_ESP
-  printk("mac_esp: dma_irq_p status %d\n", i);
+	printk("mac_esp: dma_irq_p status %d\n", i);
 #endif
 
-  return (i & ESP_STAT_INTR);
+	return (i & ESP_STAT_INTR);
 }
 
-#if 0
 static int dma_irq_p_quick(struct NCR_ESP * esp)
 {
+	/*
+	 * Copied from iosb_dma_irq_p()
+	 */
+	int ret  = mac_irq_pending(IRQ_MAC_SCSI) || mac_irq_pending(IRQ_MAC_SCSIDRQ);
+	int sreg = esp->eregs->esp_status;
+
+#ifdef DEBUG_MAC_ESP
+	printk("mac_esp: dma_irq_p drq %d irq %d sreg %x curr %p disc %p\n", 
+		mac_irq_pending(IRQ_MAC_SCSIDRQ), mac_irq_pending(IRQ_MAC_SCSI), 
+		sreg, esp->current_SC, esp->disconnected_SC);
+#endif
 
-XXX ;
+	sreg &= ESP_STAT_INTR;
+
+	if (sreg)
+		return (sreg);
+	else
+		return 0;
 
 }
-#endif
 
 static void dma_led_off(struct NCR_ESP * esp)
 {
 #ifdef DEBUG_MAC_ESP
-  printk("mac_esp: dma_led_off: called\n");
+	printk("mac_esp: dma_led_off: called\n");
 #endif
 }
 
@@ -395,14 +520,14 @@
 static void dma_led_on(struct NCR_ESP * esp)
 {
 #ifdef DEBUG_MAC_ESP
-  printk("mac_esp: dma_led_on: called\n");
+	printk("mac_esp: dma_led_on: called\n");
 #endif
 }
 
 
 static int dma_ports_p(struct NCR_ESP * esp)
 {
-  return 0;
+	return 0;
 }
 
 
@@ -410,20 +535,20 @@
 {
 
 #ifdef DEBUG_MAC_ESP
-  printk("mac_esp: dma_setup\n");
+	printk("mac_esp: dma_setup\n");
 #endif
 
-  if (write) {
-    dma_init_read(esp, addr, count);
-  } else {
-    dma_init_write(esp, addr, count);
-  }
+	if (write) {
+		dma_init_read(esp, (char *) addr, count);
+	} else {
+		dma_init_write(esp, (char *) addr, count);
+	}
 }
 
 
 static void dma_setup_quick(struct NCR_ESP * esp, __u32 addr, int count, int write)
 {
 #ifdef DEBUG_MAC_ESP
-  printk("mac_esp: dma_setup_quick\n");
+	printk("mac_esp: dma_setup_quick\n");
 #endif
 }
diff -urN -X diff-21.excl linux-2.1.120-vanilla/drivers/video/fbcon.c linux-2.1.120/drivers/video/fbcon.c
--- linux-2.1.120-vanilla/drivers/video/fbcon.c	Wed Sep  2 05:56:54 1998
+++ linux-2.1.120/drivers/video/fbcon.c	Wed Sep  9 03:15:43 1998
@@ -278,6 +278,7 @@
        /*
         * ... and spin for 20 ms ...
         */
+       vbl_detected = 0;
        while (!vbl_detected && ++ct<1000)
           udelay(20);
  



