Date: Thu, 17 Jul 1997 14:11:17 +0200 (MET DST)
From: Jesper Skov <jskov@cs.auc.dk>
To: linux-m68k@phil.uni-sb.de
Subject: L68K: ESP patches & new Email! :)
Sender: owner-linux-m68k@phil.uni-sb.de
Reply-To: linux-m68k@phil.uni-sb.de

Hi 

Below a patch of the ESP drivers which makes eases the use of
VTOP. Also adjusted for easier sparc merge later on (it compiles now
on the sparc :)

And if you have an alias for my email somewhere (fat chance), please
change it to jskov@cygnus.co.uk from August 1st.

Cheers,
-- Jesper

This patch is relative to the original 2.1.42 release. There are
probably conflicts with the previous ESP patch I released.
The sparc_esp.[ch] files can be ignored, but I felt like making a
"backup" B]

diff -u --recursive -B --exclude-from=/pack/kernel/tools/lib/diff-excludes -P ../dist/linux-2.1.42-m68k/drivers/scsi/blz1230_esp.c ./drivers/scsi/blz1230_esp.c
--- ../dist/linux-2.1.42-m68k/drivers/scsi/blz1230_esp.c	Tue Feb 25 13:27:18 1997
+++ ./drivers/scsi/blz1230_esp.c	Thu Jul 17 12:19:41 1997
@@ -43,13 +43,13 @@
 static int  dma_bytes_sent(struct Sparc_ESP *esp, int fifo_count);
 static int  dma_can_transfer(struct Sparc_ESP *esp, Scsi_Cmnd *sp);
 static void dma_dump_state(struct Sparc_ESP *esp);
-static void dma_init_read(struct Sparc_ESP *esp, char *vaddress, int length);
-static void dma_init_write(struct Sparc_ESP *esp, char *vaddress, int length);
+static void dma_init_read(struct Sparc_ESP *esp, __u32 addr, int length);
+static void dma_init_write(struct Sparc_ESP *esp, __u32 addr, int length);
 static void dma_ints_off(struct Sparc_ESP *esp);
 static void dma_ints_on(struct Sparc_ESP *esp);
 static int  dma_irq_p(struct Sparc_ESP *esp);
 static int  dma_ports_p(struct Sparc_ESP *esp);
-static void dma_setup(struct Sparc_ESP *esp, char *addr, int count, int write);
+static void dma_setup(struct Sparc_ESP *esp, __u32 addr, int count, int write);
 
 volatile unsigned char cmd_buffer[16];
 				/* This is where all commands are put
@@ -134,6 +134,7 @@
 
 		/* Set the command buffer */
 		esp->esp_command = (volatile unsigned char*) cmd_buffer;
+		esp->esp_command_dvma = VTOP((unsigned long) cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
 		request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, "Blizzard 1230 SCSI IV", esp_intr);
@@ -184,7 +185,7 @@
 		custom.intreqr, custom.intenar));
 }
 
-void dma_init_read(struct Sparc_ESP *esp, char *vaddress, int length)
+void dma_init_read(struct Sparc_ESP *esp, __u32 addr, int length)
 {
 #if MKIV
 	struct blz1230_dma_registers *dregs = 
@@ -193,7 +194,6 @@
 	struct blz1230II_dma_registers *dregs = 
 		(struct blz1230II_dma_registers *) esp->dregs;
 #endif
-	unsigned long addr = VTOP((unsigned long) vaddress);
 
 	cache_clear(addr, length);
 
@@ -212,9 +212,8 @@
 	dregs->dma_addr = (addr      ) & 0xff;
 }
 
-void dma_init_write(struct Sparc_ESP *esp, char *vaddress, int length)
+void dma_init_write(struct Sparc_ESP *esp, __u32 addr, int length)
 {
-	unsigned long addr = VTOP((unsigned long) vaddress);
 #if MKIV
 	struct blz1230_dma_registers *dregs = 
 		(struct blz1230_dma_registers *) esp->dregs;
@@ -260,7 +259,7 @@
 	return ((custom.intenar) & IF_PORTS);
 }
 
-static void dma_setup(struct Sparc_ESP *esp, char *addr, int count, int write)
+static void dma_setup(struct Sparc_ESP *esp, __u32 addr, int count, int write)
 {
 	/* On the Sparc, DMA_ST_WRITE means "move data from device to memory"
 	 * so when (write) is true, it actually means READ!
diff -u --recursive -B --exclude-from=/pack/kernel/tools/lib/diff-excludes -P ../dist/linux-2.1.42-m68k/drivers/scsi/blz2060_esp.c ./drivers/scsi/blz2060_esp.c
--- ../dist/linux-2.1.42-m68k/drivers/scsi/blz2060_esp.c	Tue Feb 25 13:27:18 1997
+++ ./drivers/scsi/blz2060_esp.c	Thu Jul 17 12:21:06 1997
@@ -41,15 +41,15 @@
 static int  dma_bytes_sent(struct Sparc_ESP *esp, int fifo_count);
 static int  dma_can_transfer(struct Sparc_ESP *esp, Scsi_Cmnd *sp);
 static void dma_dump_state(struct Sparc_ESP *esp);
-static void dma_init_read(struct Sparc_ESP *esp, char *vaddress, int length);
-static void dma_init_write(struct Sparc_ESP *esp, char *vaddress, int length);
+static void dma_init_read(struct Sparc_ESP *esp, __u32 addr, int length);
+static void dma_init_write(struct Sparc_ESP *esp, __u32 addr, int length);
 static void dma_ints_off(struct Sparc_ESP *esp);
 static void dma_ints_on(struct Sparc_ESP *esp);
 static int  dma_irq_p(struct Sparc_ESP *esp);
 static void dma_led_off(struct Sparc_ESP *esp);
 static void dma_led_on(struct Sparc_ESP *esp);
 static int  dma_ports_p(struct Sparc_ESP *esp);
-static void dma_setup(struct Sparc_ESP *esp, char *addr, int count, int write);
+static void dma_setup(struct Sparc_ESP *esp, __u32 addr, int count, int write);
 
 volatile unsigned char cmd_buffer[16];
 				/* This is where all commands are put
@@ -110,6 +110,7 @@
 		
 		/* Set the command buffer */
 		esp->esp_command = (volatile unsigned char*) cmd_buffer;
+		esp->esp_command_dvma = VTOP((unsigned long) cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
 		request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, "Blizzard 2060 SCSI", esp_intr);
@@ -161,11 +162,10 @@
 		custom.intreqr, custom.intenar));
 }
 
-static void dma_init_read(struct Sparc_ESP *esp, char *vaddress, int length)
+static void dma_init_read(struct Sparc_ESP *esp, __u32 addr, int length)
 {
 	struct blz2060_dma_registers *dregs = 
 		(struct blz2060_dma_registers *) esp->dregs;
-	unsigned long addr = VTOP((unsigned long) vaddress);
 
 	cache_clear(addr, length);
 
@@ -177,9 +177,8 @@
 	dregs->dma_addr0 = (addr >> 24) & 0xff;
 }
 
-static void dma_init_write(struct Sparc_ESP *esp, char *vaddress, int length)
+static void dma_init_write(struct Sparc_ESP *esp, __u32 addr, int length)
 {
-	unsigned long addr = VTOP((unsigned long) vaddress);
 	struct blz2060_dma_registers *dregs = 
 		(struct blz2060_dma_registers *) esp->dregs;
 
@@ -224,7 +223,7 @@
 	return ((custom.intenar) & IF_PORTS);
 }
 
-static void dma_setup(struct Sparc_ESP *esp, char *addr, int count, int write)
+static void dma_setup(struct Sparc_ESP *esp, __u32 addr, int count, int write)
 {
 	/* On the Sparc, DMA_ST_WRITE means "move data from device to memory"
 	 * so when (write) is true, it actually means READ!
diff -u --recursive -B --exclude-from=/pack/kernel/tools/lib/diff-excludes -P ../dist/linux-2.1.42-m68k/drivers/scsi/cyberII_esp.c ./drivers/scsi/cyberII_esp.c
--- ../dist/linux-2.1.42-m68k/drivers/scsi/cyberII_esp.c	Tue Feb 25 13:27:19 1997
+++ ./drivers/scsi/cyberII_esp.c	Thu Jul 17 12:15:06 1997
@@ -40,15 +40,15 @@
 static int  dma_bytes_sent(struct Sparc_ESP *esp, int fifo_count);
 static int  dma_can_transfer(struct Sparc_ESP *esp, Scsi_Cmnd *sp);
 static void dma_dump_state(struct Sparc_ESP *esp);
-static void dma_init_read(struct Sparc_ESP *esp, char *vaddress, int length);
-static void dma_init_write(struct Sparc_ESP *esp, char *vaddress, int length);
+static void dma_init_read(struct Sparc_ESP *esp, __u32 addr, int length);
+static void dma_init_write(struct Sparc_ESP *esp, __u32 addr, int length);
 static void dma_ints_off(struct Sparc_ESP *esp);
 static void dma_ints_on(struct Sparc_ESP *esp);
 static int  dma_irq_p(struct Sparc_ESP *esp);
 static void dma_led_off(struct Sparc_ESP *esp);
 static void dma_led_on(struct Sparc_ESP *esp);
 static int  dma_ports_p(struct Sparc_ESP *esp);
-static void dma_setup(struct Sparc_ESP *esp, char *addr, int count, int write);
+static void dma_setup(struct Sparc_ESP *esp, __u32 addr, int count, int write);
 
 volatile unsigned char cmd_buffer[16];
 				/* This is where all commands are put
@@ -121,6 +121,7 @@
 		
 		/* Set the command buffer */
 		esp->esp_command = (volatile unsigned char*) cmd_buffer;
+		esp->esp_command_dvma = VTOP((unsigned long) cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
 		request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, "CyberStorm SCSI Mk II", esp_intr);
@@ -174,11 +175,10 @@
 		custom.intreqr, custom.intenar));
 }
 
-static void dma_init_read(struct Sparc_ESP *esp, char *vaddress, int length)
+static void dma_init_read(struct Sparc_ESP *esp, __u32 addr, int length)
 {
 	struct cyberII_dma_registers *dregs = 
 		(struct cyberII_dma_registers *) esp->dregs;
-	unsigned long addr = VTOP((unsigned long) vaddress);
 
 	cache_clear(addr, length);
 
@@ -189,9 +189,8 @@
 	dregs->dma_addr3 = (addr      ) & 0xff;
 }
 
-static void dma_init_write(struct Sparc_ESP *esp, char *vaddress, int length)
+static void dma_init_write(struct Sparc_ESP *esp, __u32 addr, int length)
 {
-	unsigned long addr = VTOP((unsigned long) vaddress);
 	struct cyberII_dma_registers *dregs = 
 		(struct cyberII_dma_registers *) esp->dregs;
 
@@ -235,7 +234,7 @@
 	return ((custom.intenar) & IF_PORTS);
 }
 
-static void dma_setup(struct Sparc_ESP *esp, char *addr, int count, int write)
+static void dma_setup(struct Sparc_ESP *esp, __u32 addr, int count, int write)
 {
 	/* On the Sparc, DMA_ST_WRITE means "move data from device to memory"
 	 * so when (write) is true, it actually means READ!
diff -u --recursive -B --exclude-from=/pack/kernel/tools/lib/diff-excludes -P ../dist/linux-2.1.42-m68k/drivers/scsi/cyber_esp.c ./drivers/scsi/cyber_esp.c
--- ../dist/linux-2.1.42-m68k/drivers/scsi/cyber_esp.c	Tue Feb 25 13:27:19 1997
+++ ./drivers/scsi/cyber_esp.c	Thu Jul 17 12:26:50 1997
@@ -44,15 +44,15 @@
 static int  dma_bytes_sent(struct Sparc_ESP *esp, int fifo_count);
 static int  dma_can_transfer(struct Sparc_ESP *esp, Scsi_Cmnd *sp);
 static void dma_dump_state(struct Sparc_ESP *esp);
-static void dma_init_read(struct Sparc_ESP *esp, char *vaddress, int length);
-static void dma_init_write(struct Sparc_ESP *esp, char *vaddress, int length);
+static void dma_init_read(struct Sparc_ESP *esp, __u32 addr, int length);
+static void dma_init_write(struct Sparc_ESP *esp, __u32 addr, int length);
 static void dma_ints_off(struct Sparc_ESP *esp);
 static void dma_ints_on(struct Sparc_ESP *esp);
 static int  dma_irq_p(struct Sparc_ESP *esp);
 static void dma_led_off(struct Sparc_ESP *esp);
 static void dma_led_on(struct Sparc_ESP *esp);
 static int  dma_ports_p(struct Sparc_ESP *esp);
-static void dma_setup(struct Sparc_ESP *esp, char *addr, int count, int write);
+static void dma_setup(struct Sparc_ESP *esp, __u32 addr, int count, int write);
 
 static unsigned char ctrl_data = 0;	/* Keep backup of the stuff written
 				 * to ctrl_reg. Always write a copy
@@ -129,6 +129,7 @@
 		
 		/* Set the command buffer */
 		esp->esp_command = (volatile unsigned char*) cmd_buffer;
+		esp->esp_command_dvma = VTOP((unsigned long) cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
 		request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, "CyberStorm SCSI", esp_intr);
@@ -186,11 +187,10 @@
 		custom.intreqr, custom.intenar));
 }
 
-static void dma_init_read(struct Sparc_ESP *esp, char *vaddress, int length)
+static void dma_init_read(struct Sparc_ESP *esp, __u32 addr, int length)
 {
 	struct cyber_dma_registers *dregs = 
 		(struct cyber_dma_registers *) esp->dregs;
-	unsigned long addr = VTOP((unsigned long) vaddress);
 
 	cache_clear(addr, length);
 
@@ -224,9 +224,8 @@
 	dregs->ctrl_reg = ctrl_data;
 }
 
-static void dma_init_write(struct Sparc_ESP *esp, char *vaddress, int length)
+static void dma_init_write(struct Sparc_ESP *esp, __u32 addr, int length)
 {
-	unsigned long addr = VTOP((unsigned long) vaddress);
 	struct cyber_dma_registers *dregs = 
 		(struct cyber_dma_registers *) esp->dregs;
 
@@ -287,7 +286,7 @@
 	return ((custom.intenar) & IF_PORTS);
 }
 
-static void dma_setup(struct Sparc_ESP *esp, char *addr, int count, int write)
+static void dma_setup(struct Sparc_ESP *esp, __u32 addr, int count, int write)
 {
 	/* On the Sparc, DMA_ST_WRITE means "move data from device to memory"
 	 * so when (write) is true, it actually means READ!
diff -u --recursive -B --exclude-from=/pack/kernel/tools/lib/diff-excludes -P ../dist/linux-2.1.42-m68k/drivers/scsi/esp.c ./drivers/scsi/esp.c
--- ../dist/linux-2.1.42-m68k/drivers/scsi/esp.c	Fri May 16 09:09:45 1997
+++ ./drivers/scsi/esp.c	Thu Jul 17 13:34:53 1997
@@ -85,6 +85,7 @@
 	S_IFDIR | S_IRUGO | S_IXUGO, 2
 };
 
+/* The master ring of all esp hosts we are managing in this driver. */
 struct Sparc_ESP *espchain = 0;
 int nesps = 0, esps_in_use = 0, esps_running = 0;
 
@@ -210,7 +211,7 @@
 		   (stepreg == ESP_STEP_FINI4 ? "CMD_SENT_OK" :
 		    "UNKNOWN"))))));
 }
-#if defined(DEBUG_STATE_MACHINE) || defined(DEBUG_ESP)
+
 static char *phase_string(int phase)
 {
 	switch(phase) {
@@ -266,7 +267,7 @@
 		return "UNKNOWN";
 	};
 }
-#endif
+
 
 static inline void esp_advance_phase(Scsi_Cmnd *s, int newphase)
 {
@@ -277,8 +278,8 @@
 	s->SCp.phase = newphase;
 }
 
-extern inline void esp_cmd(struct Sparc_ESP *esp, struct ESP_regs *eregs,
-			   unchar cmd)
+static inline void esp_cmd(struct Sparc_ESP *esp,
+			   struct ESP_regs *eregs, unchar cmd)
 {
 #ifdef DEBUG_ESP_CMDS
 	esp->espcmdlog[esp->espcmdent] = cmd;
@@ -389,7 +390,7 @@
 	eregs->esp_timeo = esp->neg_defp;
 
 	/* This is the only point at which it is reliable to read
-	 * the ID-code for a fast ESP chip variant.
+	 * the ID-code for a fast ESP chip variants.
 	 */
 	esp->max_period = ((35 * esp->ccycle) / 1000);
 	if(esp->erev == fast) {
@@ -612,7 +613,6 @@
 
 	/* Fill in ehost data */
 	esp->ehost->base = (unsigned char *) eregs;
-	esp->ehost->io_port = (unsigned int) eregs;
 	esp->ehost->this_id = esp->scsi_id;
 	esp->ehost->irq = esp->irq;
 
@@ -796,7 +796,7 @@
 	};
 #ifdef CONFIG_SCSI_SUNESP
 	copy_info(&info, "\tDMA Revision\t\t");
-	switch(esp->dma->revision) {
+	switch(((struct Linux_SBus_DMA*)esp->dma)->revision) {
 	case dvmarev0:
 		copy_info(&info, "Rev 0\n");
 		break;
@@ -956,7 +956,7 @@
 	int i;
 
 	/* Hold off if we've been reselected or an IRQ is showing... */
-	if(esp->disconnected_SC || DMA_IRQ_P(dregs))
+	if(esp->disconnected_SC || esp->dma_irq_p(esp))
 		return;
 
 	/* Grab first member of the issue queue. */
@@ -1185,12 +1185,12 @@
 			eregs->fas_rlo = 0;
 			eregs->fas_rhi = 0;
 			esp_cmd(esp, eregs, the_esp_command);
-			esp->dma_init_write(esp, (char *) esp->esp_command, 16);
+			esp->dma_init_write(esp, esp->esp_command_dvma, 16);
 		} else {
 			/* Set up the ESP counters */
 			eregs->esp_tclow = i;
 			eregs->esp_tcmed = 0;
-			esp->dma_init_write(esp, (char *) esp->esp_command, i);
+			esp->dma_init_write(esp, esp->esp_command_dvma, i);
 
 			/* Tell ESP to "go". */
 			esp_cmd(esp, eregs, the_esp_command);
@@ -1226,14 +1226,14 @@
 		/* Sneaky. */
 		SCpnt->SCp.have_data_in = mmu_get_scsi_one((char *)SCpnt->SCp.buffer,
 							   SCpnt->SCp.this_residual,
-							   esp->edev->my_bus);
+							   ((struct linux_sbus_device*) esp->edev)->my_bus);
 		/* XXX The casts are extremely gross, but with 64-bit kernel
 		 * XXX and 32-bit SBUS what am I to do? -DaveM
 		 */
 		SCpnt->SCp.ptr = (char *)((unsigned long)SCpnt->SCp.have_data_in);
 #else
 		SCpnt->SCp.have_data_in = (int) SCpnt->SCp.ptr =
-			(char *)SCpnt->request_buffer;
+			(char *) VTOP((unsigned long) SCpnt->request_buffer);
 #endif
 
 	} else {
@@ -1248,11 +1248,11 @@
 #ifdef CONFIG_SCSI_SUNESP
 		mmu_get_scsi_sgl((struct mmu_sglist *) SCpnt->SCp.buffer,
 				 SCpnt->SCp.buffers_residual,
-				 ((struct linux_sbus_device *) (esp->edev))->my_bus);
-		SCpnt->SCp.ptr              = (char *) SCpnt->SCp.buffer->dvma_address;
-#else
+				 ((struct linux_sbus_device *) esp->edev)->my_bus);
 		/* XXX Again these casts are sick... -DaveM */
 		SCpnt->SCp.ptr=(char *)((unsigned long)SCpnt->SCp.buffer->dvma_address);
+#else
+		SCpnt->SCp.ptr =(char *) VTOP((unsigned long) SCpnt->SCp.buffer->address);
 #endif
 	}
 	SCpnt->SCp.Status           = CHECK_CONDITION;
@@ -1384,7 +1384,7 @@
 	 */
 	don = esp->dma_ports_p(esp);
 	if(don) {
-		DMA_INTSOFF(dregs);
+		esp->dma_ints_off(esp);
 		synchronize_irq();
 	}
 	if(esp->issue_SC) {
@@ -1454,7 +1454,7 @@
 			/* Sneaky. */
 			mmu_release_scsi_one(done_SC->SCp.have_data_in,
 					     done_SC->request_bufflen,
-					     ((struct linux_sbus_device *) (esp->edev))->my_bus);
+					     ((struct linux_sbus_device *) esp->edev)->my_bus);
 #endif
 		} else {
 #ifdef DEBUG_ESP_SG
@@ -1464,7 +1464,7 @@
 			struct scatterlist *scl = (struct scatterlist *)done_SC->buffer;
 			mmu_release_scsi_sgl((struct mmu_sglist *) scl,
 					     done_SC->use_sg - 1,
-					     ((struct linux_sbus_device *) (esp->edev))->my_bus);
+					     ((struct linux_sbus_device *) esp->edev)->my_bus);
 #endif
 #ifdef DEBUG_ESP_SG
 			printk("done.\n");
@@ -1839,7 +1839,7 @@
 #ifdef CONFIG_SCSI_SUNESP
 	sp->SCp.ptr = (char *)((unsigned long)sp->SCp.buffer->dvma_address);
 #else
-	sp->SCp.ptr = sp->SCp.buffer->address;
+	sp->SCp.ptr = (char *)VTOP((unsigned long) sp->SCp.buffer->address);
 #endif
 }
 
@@ -1881,12 +1881,13 @@
 		esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
 
 		if(thisphase == in_datain)
-			esp->dma_init_read(esp, SCptr->SCp.ptr, hmuch);
+			esp->dma_init_read(esp, (__u32) SCptr->SCp.ptr, hmuch);
 		else
-			esp->dma_init_write(esp, SCptr->SCp.ptr, hmuch);
+			esp->dma_init_write(esp, (__u32) SCptr->SCp.ptr, hmuch);
 	} else {
 		esp_setcount(eregs, hmuch, 0);
-		esp->dma_setup(esp, SCptr->SCp.ptr, hmuch, (thisphase == in_datain));
+		esp->dma_setup(esp, (__u32) SCptr->SCp.ptr, hmuch, 
+					   (thisphase == in_datain));
 		ESPDATA(("DMA|TI --> do_intr_end\n"));
 		esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
 	}
@@ -2361,7 +2362,7 @@
 					esp->esp_command[1] = 0xff;
 					eregs->esp_tclow = 2;
 					eregs->esp_tcmed = 0;
-					esp->dma_init_read(esp, (char *) esp->esp_command, 2);
+					esp->dma_init_read(esp, esp->esp_command_dvma, 2);
 					esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_ICCSEQ);
 				} else {
 					/* Using DVMA for status/message bytes is
@@ -3110,7 +3111,7 @@
 		esp_cmd(esp, eregs, ESP_CMD_FLUSH);
 		esp_setcount(eregs, i, 1);
 		esp_cmd(esp, eregs, (ESP_CMD_DMA | ESP_CMD_TI));
-		esp->dma_init_write(esp, (char *) esp->esp_command, i);
+		esp->dma_init_write(esp, esp->esp_command_dvma, i);
 	} else {
 		esp_cmd(esp, eregs, ESP_CMD_FLUSH);
 		eregs->esp_fdata = *esp->esp_scmdp++;
@@ -3160,7 +3161,7 @@
 				hme_fifo_push(esp, eregs, &esp->cur_msgout[0], 2);
 				esp_cmd(esp, eregs, ESP_CMD_TI);
 			} else {
-				esp->dma_setup(esp, (char *) esp->esp_command, 2, 0);
+				esp->dma_setup(esp, esp->esp_command_dvma, 2, 0);
 				esp_setcount(eregs, 2, 0);
 				esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
 			}
@@ -3184,7 +3185,7 @@
 				hme_fifo_push(esp, eregs, &esp->cur_msgout[0], 4);
 				esp_cmd(esp, eregs, ESP_CMD_TI);
 			} else {
-				esp->dma_setup(esp, (char *) esp->esp_command, 4, 0);
+				esp->dma_setup(esp, esp->esp_command_dvma, 4, 0);
 				esp_setcount(eregs, 4, 0);
 				esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
 			}
@@ -3210,7 +3211,7 @@
 				hme_fifo_push(esp, eregs, &esp->cur_msgout[0], 5);
 				esp_cmd(esp, eregs, ESP_CMD_TI);
 			} else {
-				esp->dma_setup(esp, (char *) esp->esp_command, 5, 0);
+				esp->dma_setup(esp, esp->esp_command_dvma, 5, 0);
 				esp_setcount(eregs, 5, 0);
 				esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
 			}
@@ -3363,7 +3364,8 @@
 	Scsi_Cmnd *SCptr;
 	int what_next = do_intr_end;
 #ifdef CONFIG_SCSI_SUNESP
-	struct dma_registers *dregs = esp->dregs;
+	struct sparc_dma_registers *dregs = 
+		(struct sparc_dma_registers*) esp->dregs;
 #endif
 	eregs = esp->eregs;
 	SCptr = esp->current_SC;
@@ -3576,12 +3578,12 @@
 			if(!SCptr->use_sg)
 				mmu_release_scsi_one(SCptr->SCp.have_data_in,
 						     SCptr->request_bufflen,
-						     ((struct linux_sbus_device *) (esp->edev))->my_bus);
+						     ((struct linux_sbus_device *) esp->edev)->my_bus);
 			else
 				mmu_release_scsi_sgl((struct mmu_sglist *)
 						     SCptr->buffer,
 						     SCptr->use_sg - 1,
-						     ((struct linux_sbus_device *) (esp->edev))->my_bus);
+						     ((struct linux_sbus_device *) esp->edev)->my_bus);
 #endif
 			SCptr->result = (DID_RESET << 16);
 
@@ -3595,12 +3597,12 @@
 #ifdef CONFIG_SCSI_SUNESP
 					mmu_release_scsi_one(SCptr->SCp.have_data_in,
 							     SCptr->request_bufflen,
-							     ((struct linux_sbus_device *) (esp->edev))->my_bus);
+							     ((struct linux_sbus_device *) esp->edev)->my_bus);
 				else
 					mmu_release_scsi_sgl((struct mmu_sglist *)
 							     SCptr->buffer,
 							     SCptr->use_sg - 1,
-							     ((struct linux_sbus_device *) (esp->edev))->my_bus);
+							     ((struct linux_sbus_device *) esp->edev)->my_bus);
 #endif
 				SCptr->result = (DID_RESET << 16);
 
@@ -3654,16 +3656,16 @@
 #ifndef __sparc_v9__
 		if((esp->irq & 0xf) == irq) {
 #endif
-			if(DMA_IRQ_P(esp->dregs)) {
+			if(esp->dma_irq_p(esp)) {
 				again = 1;
 
-				DMA_INTSOFF(esp->dregs);
+				esp->dma_ints_off(esp);
 
 				ESPIRQ(("I%d(", esp->esp_id));
 				esp_handle(esp);
 				ESPIRQ((")"));
 
-				DMA_INTSON(esp->dregs);
+				esp->dma_ints_on(esp);
 			}
 #ifndef __sparc_v9__
 		}
@@ -3686,15 +3688,15 @@
 	/* Handle all ESP interrupts showing at this IRQ level. */
 	for_each_esp(esp) {
 		if((esp->irq & 0xf) == irq) {
-			if(DMA_IRQ_P(esp->dregs)) {
-				DMA_INTSOFF(esp->dregs);
+			if(esp->dma_irq_p(esp)) {
+				esp->dma_ints_off(esp);
 
 				ESPIRQ(("I[%d:%d](",
 					smp_processor_id(), esp->esp_id));
 				esp_handle(esp);
 				ESPIRQ((")"));
 
-				DMA_INTSON(esp->dregs);
+				esp->dma_ints_on(esp);
 				return;
 			}
 		}
diff -u --recursive -B --exclude-from=/pack/kernel/tools/lib/diff-excludes -P ../dist/linux-2.1.42-m68k/drivers/scsi/esp.h ./drivers/scsi/esp.h
--- ../dist/linux-2.1.42-m68k/drivers/scsi/esp.h	Wed Apr 16 14:58:34 1997
+++ ./drivers/scsi/esp.h	Thu Jul 17 12:23:15 1997
@@ -281,13 +281,13 @@
   int  (*dma_bytes_sent)(struct Sparc_ESP *, int);
   int  (*dma_can_transfer)(struct Sparc_ESP *, Scsi_Cmnd *);
   void (*dma_dump_state)(struct Sparc_ESP *);
-  void (*dma_init_read)(struct Sparc_ESP *, char *, int);
-  void (*dma_init_write)(struct Sparc_ESP *, char *, int);
+  void (*dma_init_read)(struct Sparc_ESP *, __u32, int);
+  void (*dma_init_write)(struct Sparc_ESP *, __u32, int);
   void (*dma_ints_off)(struct Sparc_ESP *);
   void (*dma_ints_on)(struct Sparc_ESP *);
   int  (*dma_irq_p)(struct Sparc_ESP *);
   int  (*dma_ports_p)(struct Sparc_ESP *);
-  void (*dma_setup)(struct Sparc_ESP *, char *, int, int);
+  void (*dma_setup)(struct Sparc_ESP *, __u32, int, int);
 
   /* Optional functions (i.e. may be initialized to 0) */
   void (*dma_barrier)(struct Sparc_ESP *);
@@ -517,6 +517,8 @@
 
 
 /* External functions */
+extern inline void esp_cmd(struct Sparc_ESP *esp, struct ESP_regs *eregs,
+						   unchar cmd);
 extern struct Sparc_ESP *esp_allocate(Scsi_Host_Template *, void *);
 extern void esp_initialize(struct Sparc_ESP *);
 extern void esp_intr(int, void *, struct pt_regs *);
diff -u --recursive -B --exclude-from=/pack/kernel/tools/lib/diff-excludes -P ../dist/linux-2.1.42-m68k/drivers/scsi/fastlane_esp.c ./drivers/scsi/fastlane_esp.c
--- ../dist/linux-2.1.42-m68k/drivers/scsi/fastlane_esp.c	Tue Feb 25 13:27:19 1997
+++ ./drivers/scsi/fastlane_esp.c	Thu Jul 17 12:17:38 1997
@@ -49,8 +49,8 @@
 static int  dma_can_transfer(struct Sparc_ESP *esp, Scsi_Cmnd *sp);
 static inline void dma_clear(struct Sparc_ESP *esp);
 static void dma_dump_state(struct Sparc_ESP *esp);
-static void dma_init_read(struct Sparc_ESP *esp, char *vaddress, int length);
-static void dma_init_write(struct Sparc_ESP *esp, char *vaddress, int length);
+static void dma_init_read(struct Sparc_ESP *esp, __u32 addr, int length);
+static void dma_init_write(struct Sparc_ESP *esp, __u32 addr, int length);
 static void dma_ints_off(struct Sparc_ESP *esp);
 static void dma_ints_on(struct Sparc_ESP *esp);
 static void dma_irq_exit(struct Sparc_ESP *esp);
@@ -58,7 +58,7 @@
 static void dma_led_off(struct Sparc_ESP *esp);
 static void dma_led_on(struct Sparc_ESP *esp);
 static int  dma_ports_p(struct Sparc_ESP *esp);
-static void dma_setup(struct Sparc_ESP *esp, char *addr, int count, int write);
+static void dma_setup(struct Sparc_ESP *esp, __u32 addr, int count, int write);
 
 static unsigned char ctrl_data = 0;	/* Keep backup of the stuff written
 				 * to ctrl_reg. Always write a copy
@@ -157,6 +157,7 @@
 		
 		/* Set the command buffer */
 		esp->esp_command = cmd_buffer;
+		esp->esp_command_dvma = VTOP((unsigned long) cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
 		request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, "Fastlane SCSI", esp_intr);
@@ -212,11 +213,10 @@
 		custom.intreqr, custom.intenar));
 }
 
-static void dma_init_read(struct Sparc_ESP *esp, char *vaddress, int length)
+static void dma_init_read(struct Sparc_ESP *esp, __u32 addr, int length)
 {
 	struct fastlane_dma_registers *dregs = 
 		(struct fastlane_dma_registers *) esp->dregs;
-	unsigned long addr = VTOP((unsigned long) vaddress);
 	unsigned long *t;
 	
 	cache_clear(addr, length);
@@ -232,9 +232,8 @@
 	dregs->ctrl_reg = ctrl_data;
 }
 
-static void dma_init_write(struct Sparc_ESP *esp, char *vaddress, int length)
+static void dma_init_write(struct Sparc_ESP *esp, __u32 addr, int length)
 {
-	unsigned long addr = VTOP((unsigned long) vaddress);
 	struct fastlane_dma_registers *dregs = 
 		(struct fastlane_dma_registers *) esp->dregs;
 	unsigned long *t;
@@ -341,7 +340,7 @@
 	return ((custom.intenar) & IF_PORTS);
 }
 
-static void dma_setup(struct Sparc_ESP *esp, char *addr, int count, int write)
+static void dma_setup(struct Sparc_ESP *esp, __u32 addr, int count, int write)
 {
 	/* On the Sparc, DMA_ST_WRITE means "move data from device to memory"
 	 * so when (write) is true, it actually means READ!
diff -u --recursive -B --exclude-from=/pack/kernel/tools/lib/diff-excludes -P ../dist/linux-2.1.42-m68k/drivers/scsi/sparc_esp.c ./drivers/scsi/sparc_esp.c
--- ../dist/linux-2.1.42-m68k/drivers/scsi/sparc_esp.c	Thu Jan  1 00:00:00 1970
+++ ./drivers/scsi/sparc_esp.c	Thu Jul 17 12:22:26 1997
@@ -0,0 +1,585 @@
+/* sparc_esp.c:  EnhancedScsiProcessor Sun SCSI driver code.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * Ugly generalization hacks by Jesper Skov. See "esp.c".
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/malloc.h>
+#include <linux/blk.h>
+#include <linux/proc_fs.h>
+#include <linux/stat.h>
+
+#include "scsi.h"
+#include "hosts.h"
+#include "esp.h"
+
+#include "sparc_esp.h"
+#include <asm/sbus.h>
+#include <asm/dma.h>
+#include <asm/machines.h>
+#include <asm/oplib.h>
+#include <asm/vaddrs.h>
+
+extern struct Sparc_ESP *espchain;
+
+static void dma_barrier(struct Sparc_ESP *esp);
+static int  dma_bytes_sent(struct Sparc_ESP *esp, int fifo_count);
+static int  dma_can_transfer(struct Sparc_ESP *esp, Scsi_Cmnd *sp);
+static void dma_drain(struct Sparc_ESP *esp);
+static void dma_dump_state(struct Sparc_ESP *esp);
+static void dma_init_read(struct Sparc_ESP *esp, __u32 addr, int length);
+static void dma_init_write(struct Sparc_ESP *esp, __u32 addr, int length);
+static void dma_ints_off(struct Sparc_ESP *esp);
+static void dma_ints_on(struct Sparc_ESP *esp);
+static void dma_invalidate(struct Sparc_ESP *esp);
+static void  dma_irq_entry(struct Sparc_ESP *esp);
+static void  dma_irq_exit(struct Sparc_ESP *esp);
+static int  dma_irq_p(struct Sparc_ESP *esp);
+static void dma_poll(struct Sparc_ESP *esp, unsigned char *vaddr);
+static int  dma_ports_p(struct Sparc_ESP *esp);
+static void dma_reset(struct Sparc_ESP *esp);
+static void dma_setup(struct Sparc_ESP *esp, __u32 addr, int count, int write);
+
+
+/* Detecting ESP chips on the machine.  This is the simple and easy
+ * version.
+ */
+int esp_detect(Scsi_Host_Template *tpnt)
+{
+	struct Sparc_ESP *esp, *elink;
+	struct Scsi_Host *esp_host;
+	struct linux_sbus *sbus;
+	struct linux_sbus_device *esp_edev, *esp_dev, *sbdev_iter;
+	struct ESP_regs *eregs;
+	struct sparc_dma_registers *dregs;
+	struct Linux_SBus_DMA *dma, *dlink;
+	unchar bsizes, bsizes_more;
+	int esp_node;
+
+	if(!SBus_chain)
+		panic("No SBUS in esp_detect()");
+	for_each_sbus(sbus) {
+		for_each_sbusdev(sbdev_iter, sbus) {
+			struct linux_sbus_device *espdma = 0;
+			int hme = 0;
+
+			/* Is it an esp sbus device? */
+			esp_dev = sbdev_iter;
+			if(strcmp(esp_dev->prom_name, "esp") &&
+			   strcmp(esp_dev->prom_name, "SUNW,esp")) {
+				if(!strcmp(esp_dev->prom_name, "SUNW,fas")) {
+					hme = 1;
+					espdma = esp_dev;
+				} else {
+					if(!esp_dev->child ||
+					   (strcmp(esp_dev->prom_name, "espdma") &&
+					    strcmp(esp_dev->prom_name, "dma")))
+						continue; /* nope... */
+					espdma = esp_dev;
+					esp_dev = esp_dev->child;
+					if(strcmp(esp_dev->prom_name, "esp") &&
+					   strcmp(esp_dev->prom_name, "SUNW,esp"))
+						continue; /* how can this happen? */
+				}
+			}
+
+			esp = esp_allocate(tpnt, (void *) esp_dev);
+
+			esp_host = esp->ehost;
+
+			if(hme)
+				esp_host->max_id = 16;
+			
+			/* Do command transfer with DMA */
+			esp->do_pio_cmds = 0;
+
+			/* Required 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 = &dma_init_read;
+			esp->dma_init_write = &dma_init_write;
+			esp->dma_ints_off = &dma_ints_off;
+			esp->dma_ints_on = &dma_ints_on;
+			esp->dma_irq_p = &dma_irq_p;
+			esp->dma_ports_p = &dma_ports_p;
+			esp->dma_setup = &dma_setup;
+
+			/* Optional functions */
+			esp->dma_barrier = &dma_barrier;
+			esp->dma_drain = &dma_drain;
+			esp->dma_invalidate = &dma_invalidate;
+			esp->dma_irq_entry = &dma_irq_entry;
+			esp->dma_irq_exit = &dma_irq_exit;
+			esp->dma_led_on = 0;
+			esp->dma_led_off = 0;
+			esp->dma_poll = &dma_poll;
+			esp->dma_reset = &dma_reset;
+
+			/* Get misc. prom information */
+#define ESP_IS_MY_DVMA(esp, dma)  \
+			((((struct linux_sbus_device*)(esp->edev))->my_bus == dma->SBus_dev->my_bus) && \
+			 (((struct linux_sbus_device*)(esp->edev))->slot == dma->SBus_dev->slot) && \
+			 (!strcmp(dma->SBus_dev->prom_name, "dma") || \
+			  !strcmp(dma->SBus_dev->prom_name, "espdma")))
+
+			esp_node = esp_dev->prom_node;
+			prom_getstring(esp_node, "name", esp->prom_name,
+				       sizeof(esp->prom_name));
+			esp->prom_node = esp_node;
+			if(espdma) {
+				for_each_dvma(dlink) {
+					if(dlink->SBus_dev == espdma)
+						break;
+				}
+			} else {
+				for_each_dvma(dlink) {
+					if(ESP_IS_MY_DVMA(esp, dlink) &&
+					   !dlink->allocated)
+						break;
+				}
+			}
+#undef ESP_IS_MY_DVMA
+			/* If we don't know how to handle the dvma,
+			 * do not use this device.
+			 */
+			if(!dlink){
+				printk ("Cannot find dvma for ESP%d's SCSI\n",
+					esp->esp_id);
+				scsi_unregister (esp_host);
+				continue;
+			}
+			if (dlink->allocated){
+				printk ("esp%d: can't use my espdma\n",
+					esp->esp_id);
+				scsi_unregister (esp_host);
+				continue;
+			}
+			dlink->allocated = 1;
+			dma = dlink;
+			esp->dma = (struct Linux_DMA *) dma;
+			esp->dregs = (void *) dregs = dma->regs;
+
+			esp_edev = (struct linux_sbus_device *) esp->edev;
+
+			/* Map in the ESP registers from I/O space */
+			if(!hme) {
+				prom_apply_sbus_ranges(esp_edev->my_bus, 
+									   esp_edev->reg_addrs,
+									   1, esp_edev);
+				esp->eregs = eregs = (struct ESP_regs *)
+					sparc_alloc_io(esp_edev->reg_addrs[0].phys_addr, 0,
+								   PAGE_SIZE, "ESP Registers",
+								   esp_edev->reg_addrs[0].which_io, 0x0);
+			} else {
+				/* On HME, two reg sets exist, first is DVMA,
+				 * second is ESP registers.
+				 */
+				esp->eregs = eregs = (struct ESP_regs *)
+				sparc_alloc_io(esp_edev->reg_addrs[1].phys_addr, 0,
+					       PAGE_SIZE, "ESP Registers",
+					       esp_edev->reg_addrs[1].which_io, 0x0);
+			}
+			if(!eregs)
+				panic("ESP registers unmappable");
+			esp->esp_command =
+				sparc_dvma_malloc(16, "ESP DVMA Cmd Block",
+					&esp->esp_command_dvma);
+			if(!esp->esp_command || !esp->esp_command_dvma)
+				panic("ESP DVMA transport area unmappable");
+
+			/* Set up the irq's etc. */
+			esp->ehost->io_port = 
+				esp_edev->reg_addrs[0].phys_addr;
+			esp_host->n_io_port = (unsigned char)
+				esp_edev->reg_addrs[0].reg_size;
+			esp->irq = esp_edev->irqs[0].pri;
+
+			/* Allocate the irq only if necessary */
+			for_each_esp(elink) {
+				if((elink != esp) && (esp->irq == elink->irq)) {
+					goto esp_irq_acquired; /* BASIC rulez */
+				}
+			}
+			if(request_irq(esp->irq, esp_intr, SA_SHIRQ,
+				       "Sparc ESP SCSI", NULL))
+				panic("Cannot acquire ESP irq line");
+esp_irq_acquired:
+			printk("esp%d: IRQ %d ", esp->esp_id, esp->irq);
+
+			/* Figure out our scsi ID on the bus */
+			esp->scsi_id = prom_getintdefault(esp->prom_node,
+							  "initiator-id",
+							  -1);
+			if(esp->scsi_id == -1)
+				esp->scsi_id = prom_getintdefault(esp->prom_node,
+								  "scsi-initiator-id",
+								  -1);
+			if(esp->scsi_id == -1)
+				esp->scsi_id =
+					prom_getintdefault(esp_edev->my_bus->prom_node,
+							   "scsi-initiator-id",
+							   7);
+
+			/* Check for differential SCSI-bus */
+			esp->diff = prom_getbool(esp->prom_node, "differential");
+			if(esp->diff)
+				printk("Differential ");
+
+
+			/* SCSI chip clock */
+			esp->cfreq = prom_getintdefault(esp->prom_node,
+						  "clock-frequency",
+						  -1);
+			if(esp->cfreq==-1)
+				esp->cfreq = prom_getintdefault(esp_edev->my_bus->prom_node,
+							  "clock-frequency",
+							  -1);
+
+			/* Find the burst sizes this dma/sbus/esp supports. */
+			bsizes = prom_getintdefault(esp->prom_node, "burst-sizes", 0xff);
+			bsizes &= 0xff;
+			if(espdma) {
+				bsizes_more = prom_getintdefault(
+						  espdma->prom_node,
+						  "burst-sizes", 0xff);
+				if(bsizes_more != 0xff)
+					bsizes &= bsizes_more;
+			}
+			bsizes_more = prom_getintdefault(esp_edev->my_bus->prom_node,
+							 "burst-sizes", 0xff);
+			if(bsizes_more != 0xff)
+				bsizes &= bsizes_more;
+
+			if(bsizes == 0xff || (bsizes & DMA_BURST16)==0 ||
+			   (bsizes & DMA_BURST32)==0)
+				bsizes = (DMA_BURST32 - 1);
+
+			esp->bursts = bsizes;
+
+			esp_initialize(esp);
+
+		} /* for each sbusdev */
+	} /* for each sbus */
+	printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,
+	       esps_in_use);
+	esps_running = esps_in_use;
+	return esps_in_use;
+}
+
+
+/************************************************************* DMA Functions */
+/* XXXX UGLY! : Duplicate esp_cmd here so it can remain inline in esp.c */
+static inline void esp_cmd(struct Sparc_ESP *esp, 
+						   struct ESP_regs *eregs, unchar cmd)
+{
+#ifdef DEBUG_ESP_CMDS
+	esp->espcmdlog[esp->espcmdent] = cmd;
+	esp->espcmdent = (esp->espcmdent + 1) & 31;
+#endif
+	eregs->esp_cmd = cmd;
+}
+
+static void dma_barrier(struct Sparc_ESP *esp)
+{
+	struct sparc_dma_registers *dregs =
+		(struct sparc_dma_registers *) esp->dregs;
+
+	/* XXX HME/FAS ATN deassert workaround required,
+	 * XXX no DMA flushing, only possible ESP_CMD_FLUSH
+	 * XXX to kill the fifo.
+	 */
+	if(esp->erev != fashme) {
+		while(dregs->cond_reg & DMA_PEND_READ)
+			udelay(1);
+		dregs->cond_reg &= ~(DMA_ENABLE);
+		dma_invalidate(esp);
+	} else {
+		esp_cmd(esp, esp->eregs, ESP_CMD_FLUSH);
+	}
+}
+
+/* This uses various DMA csr fields and the fifo flags count value to
+ * determine how many bytes were successfully sent/received by the ESP.
+ */
+static int dma_bytes_sent(struct Sparc_ESP *esp, int fifo_count)
+{
+	struct sparc_dma_registers *dregs = 
+		(struct sparc_dma_registers *) esp->dregs;
+
+	int rval = dregs->st_addr - esp->esp_command_dvma;
+
+	if(((struct Linux_SBus_DMA *) esp->dma)->revision == dvmarev1)
+		rval -= (4 - ((dregs->cond_reg & DMA_READ_AHEAD)>>11));
+	return rval - fifo_count;
+}
+
+static int dma_can_transfer(struct Sparc_ESP *esp, Scsi_Cmnd *sp)
+{
+	__u32 base, end, sz;
+	enum dvma_rev drev = ((struct Linux_SBus_DMA *) esp->dma)->revision;
+
+	if(drev == dvmarev3) {
+		sz = sp->SCp.this_residual;
+		if(sz > 0x1000000)
+			sz = 0x1000000;
+	} else {
+		base = ((__u32)sp->SCp.ptr);
+		base &= (0x1000000 - 1);
+		end = (base + sp->SCp.this_residual);
+		if(end > 0x1000000)
+			end = 0x1000000;
+		sz = (end - base);
+	}
+	return sz;
+}
+
+static void dma_drain(struct Sparc_ESP *esp)
+{
+	struct sparc_dma_registers *dregs =
+		(struct sparc_dma_registers *) esp->dregs;
+	enum dvma_rev drev = ((struct Linux_SBus_DMA *) esp->dma)->revision;
+
+	if(drev == dvmahme)
+		return;
+	if(dregs->cond_reg & DMA_FIFO_ISDRAIN) {
+		switch(drev) {
+		default:
+			dregs->cond_reg |= DMA_FIFO_STDRAIN;
+
+		case dvmarev3:
+		case dvmaesc1:
+			while(dregs->cond_reg & DMA_FIFO_ISDRAIN)
+				udelay(1);
+		};
+	}
+}
+
+static void dma_dump_state(struct Sparc_ESP *esp)
+{
+	struct sparc_dma_registers *dregs =
+		(struct sparc_dma_registers *) esp->dregs;
+
+	ESPLOG(("esp%d: dma -- cond_reg<%08lx> addr<%p>\n",
+		esp->esp_id, dregs->cond_reg, dregs->st_addr));
+}
+
+static void dma_flashclear(struct Sparc_ESP *esp)
+{
+	dma_drain(esp);
+	dma_invalidate(esp);
+}
+
+static void dma_init_read(struct Sparc_ESP *esp, __u32 addr, int length)
+{
+	struct sparc_dma_registers *dregs = 
+		(struct sparc_dma_registers *) esp->dregs;
+
+	dregs->cond_reg |= (DMA_ST_WRITE | DMA_ENABLE);
+	if(((struct Linux_SBus_DMA *) esp->dma)->revision == dvmaesc1)
+		dregs->cnt = 0x1000;
+	dregs->st_addr = addr;
+}
+
+static void dma_init_write(struct Sparc_ESP *esp, __u32 addr, int length)
+{
+	struct sparc_dma_registers *dregs = 
+		(struct sparc_dma_registers *) esp->dregs;
+
+	if(esp->erev == fashme) {
+		unsigned long tmp;
+
+		/* Talk about touchy hardware... */
+		tmp = dregs->cond_reg;
+		tmp |= (DMA_SCSI_DISAB | DMA_ENABLE);
+		tmp &= ~(DMA_ST_WRITE);
+		dregs->cnt = length;
+		dregs->st_addr = addr;
+		dregs->cond_reg = tmp;
+	} else {
+		/* Set up the DMA counters */
+		dregs->cond_reg = ((dregs->cond_reg & ~(DMA_ST_WRITE)) | DMA_ENABLE);
+		if(((struct Linux_SBus_DMA *) esp->dma)->revision == dvmaesc1) {
+			if(length) /* Workaround ESC gate array SBUS rerun bug. */
+				dregs->cnt = (PAGE_SIZE);
+		}
+		dregs->st_addr = addr;
+	}
+}
+
+static void dma_ints_off(struct Sparc_ESP *esp)
+{
+	DMA_INTSOFF((struct sparc_dma_registers *) esp->dregs);
+}
+
+static void dma_ints_on(struct Sparc_ESP *esp)
+{
+	DMA_INTSON((struct sparc_dma_registers *) esp->dregs);
+}
+
+static void dma_invalidate(struct Sparc_ESP *esp)
+{
+	unsigned int tmp;
+	struct sparc_dma_registers *dregs = 
+		(struct sparc_dma_registers *) esp->dregs;
+
+	if(((struct Linux_SBus_DMA *) esp->dma)->revision == dvmahme) {
+		/* SMCC can bite me. */
+		tmp = dregs->cond_reg;
+		dregs->cond_reg = DMA_RST_SCSI;
+
+		/* This would explain a lot. */
+		tmp |= (DMA_PARITY_OFF|DMA_2CLKS|DMA_SCSI_DISAB);
+
+		tmp &= ~(DMA_ENABLE|DMA_ST_WRITE);
+		dregs->cond_reg = 0;
+		dregs->cond_reg = tmp;
+	} else {
+		while(dregs->cond_reg & DMA_PEND_READ)
+			udelay(1);
+
+		tmp = dregs->cond_reg;
+		tmp &= ~(DMA_ENABLE | DMA_ST_WRITE | DMA_BCNT_ENAB);
+		tmp |= DMA_FIFO_INV;
+		dregs->cond_reg = tmp;
+		dregs->cond_reg = (tmp & ~(DMA_FIFO_INV));
+	}
+}
+
+static void dma_irq_entry(struct Sparc_ESP *esp)
+{
+	DMA_IRQ_ENTRY((struct Linux_SBus_DMA *) esp->dma, 
+				  (struct sparc_dma_registers *)esp->dregs);
+}
+
+static void dma_irq_exit(struct Sparc_ESP *esp)
+{
+	DMA_IRQ_EXIT((struct Linux_SBus_DMA *) esp->dma,
+				 (struct sparc_dma_registers *) esp->dregs);
+}
+
+static int dma_irq_p(struct Sparc_ESP *esp)
+{
+	return DMA_IRQ_P((struct sparc_dma_registers *) esp->dregs);
+}
+
+static void dma_poll(struct Sparc_ESP *esp, unsigned char *vaddr)
+{
+	if(esp->erev != fashme) {
+		dma_flashclear(esp);
+
+		/* Wait till the first bits settle. */
+		while(vaddr[0] == 0xff)
+			udelay(1);
+	} else {
+		vaddr[0] = esp->hme_fifo_workaround_buffer[0];
+		vaddr[1] = esp->hme_fifo_workaround_buffer[1];
+	}
+}	
+
+static int dma_ports_p(struct Sparc_ESP *esp)
+{
+	return (((struct sparc_dma_registers *) esp->dregs)->cond_reg 
+			& DMA_INT_ENAB);
+}
+
+/* Resetting various pieces of the ESP scsi driver chipset/buses. */
+static void dma_reset(struct Sparc_ESP *esp)
+{
+	struct sparc_dma_registers *dregs =
+		(struct sparc_dma_registers *)esp->dregs;
+	struct Linux_SBus_DMA *esp_dma = (struct Linux_SBus_DMA *) esp->dma;
+	unsigned long tmp, flags;
+	int can_do_burst16, can_do_burst32;
+
+	can_do_burst16 = esp->bursts & DMA_BURST16;
+	can_do_burst32 = esp->bursts & DMA_BURST32;
+
+	/* Punt the DVMA into a known state. */
+	if(esp_dma->revision != dvmahme) {
+		dregs->cond_reg |= DMA_RST_SCSI;
+		dregs->cond_reg &= ~(DMA_RST_SCSI);
+	}
+	switch(esp_dma->revision) {
+	case dvmahme:
+		/* This is the HME DVMA gate array. */
+
+		save_flags(flags); cli(); /* I really hate this chip. */
+
+		dregs->cond_reg = 0x08000000;   /* Reset interface to FAS */
+		dregs->cond_reg = DMA_RST_SCSI; /* Reset DVMA itself */
+
+		tmp = (DMA_PARITY_OFF|DMA_2CLKS|DMA_SCSI_DISAB|DMA_INT_ENAB);
+		tmp &= ~(DMA_ENABLE|DMA_ST_WRITE|DMA_BRST_SZ);
+
+		if(can_do_burst32)
+			tmp |= DMA_BRST32;
+
+		/* This chip is horrible. */
+		while(dregs->cond_reg & DMA_PEND_READ)
+			udelay(1);
+
+		dregs->cond_reg = 0;
+
+		dregs->cond_reg = tmp;        /* bite me */
+		restore_flags(flags);         /* ugh...  */
+		break;
+	case dvmarev2:
+		/* This is the gate array found in the sun4m
+		 * NCR SBUS I/O subsystem.
+		 */
+		if(esp->erev != esp100)
+			dregs->cond_reg |= DMA_3CLKS;
+		break;
+	case dvmarev3:
+		dregs->cond_reg &= ~(DMA_3CLKS);
+		dregs->cond_reg |= DMA_2CLKS;
+		if(can_do_burst32) {
+			dregs->cond_reg &= ~(DMA_BRST_SZ);
+			dregs->cond_reg |= DMA_BRST32;
+		}
+		break;
+	case dvmaesc1:
+		/* This is the DMA unit found on SCSI/Ether cards. */
+		dregs->cond_reg |= DMA_ADD_ENABLE;
+		dregs->cond_reg &= ~DMA_BCNT_ENAB;
+		if(!can_do_burst32 && can_do_burst16) {
+			dregs->cond_reg |= DMA_ESC_BURST;
+		} else {
+			dregs->cond_reg &= ~(DMA_ESC_BURST);
+		}
+		break;
+	default:
+		break;
+	};
+	DMA_INTSON(dregs);
+}
+
+static void dma_setup(struct Sparc_ESP *esp, __u32 addr, int count, int write)
+{
+	struct sparc_dma_registers *dregs = 
+		(struct sparc_dma_registers *) esp->dregs;
+
+	unsigned long nreg = dregs->cond_reg;
+	if(write)
+		nreg |= DMA_ST_WRITE;
+	else
+		nreg &= ~(DMA_ST_WRITE);
+	nreg |= DMA_ENABLE;
+	dregs->cond_reg = nreg;
+	if(((struct Linux_SBus_DMA *) esp->dma)->revision == dvmaesc1) {
+		/* This ESC gate array sucks! */
+		__u32 src = addr;
+		__u32 dest = src + count;
+
+		if(dest & (PAGE_SIZE - 1))
+			count = PAGE_ALIGN(count);
+		dregs->cnt = count;
+	}
+	dregs->st_addr = addr;
+}
diff -u --recursive -B --exclude-from=/pack/kernel/tools/lib/diff-excludes -P ../dist/linux-2.1.42-m68k/drivers/scsi/sparc_esp.h ./drivers/scsi/sparc_esp.h
--- ../dist/linux-2.1.42-m68k/drivers/scsi/sparc_esp.h	Thu Jan  1 00:00:00 1970
+++ ./drivers/scsi/sparc_esp.h	Thu Jul 17 12:22:26 1997
@@ -0,0 +1,53 @@
+/* sparc_esp.h: Defines and structures for the Sparc ESP (Enhanced SCSI
+¤ *		Processor) driver under Linux.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_ESP_H
+#define _SPARC_ESP_H
+
+/* For dvma controller register definitions. */
+#include <asm/dma.h>
+
+extern int esp_detect(struct SHT *);
+extern const char *esp_info(struct Scsi_Host *);
+extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+extern int esp_command(Scsi_Cmnd *);
+extern int esp_abort(Scsi_Cmnd *);
+extern int esp_reset(Scsi_Cmnd *, unsigned int);
+extern int esp_proc_info(char *buffer, char **start, off_t offset, int length,
+			 int hostno, int inout);
+
+extern struct proc_dir_entry proc_scsi_esp;
+
+
+#define DMA_PORTS_P        (dregs->cond_reg & DMA_INT_ENAB)
+
+
+
+#define SCSI_SPARC_ESP {                                                               \
+/* struct SHT *next */                                         NULL,                   \
+/* long *usage_count */                                        NULL,                   \
+/* struct proc_dir_entry *proc_dir */                          &proc_scsi_esp,         \
+/* int (*proc_info)(char *, char **, off_t, int, int, int) */  &esp_proc_info,                   \
+/* const char *name */                                         "Sun ESP 100/100a/200", \
+/* int detect(struct SHT *) */                                 esp_detect,             \
+/* int release(struct Scsi_Host *) */                          NULL,                   \
+/* const char *info(struct Scsi_Host *) */                     esp_info,               \
+/* int command(Scsi_Cmnd *) */                                 esp_command,            \
+/* int queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)) */ esp_queue,              \
+/* int abort(Scsi_Cmnd *) */                                   esp_abort,              \
+/* int reset(Scsi_Cmnd *, int) */                              esp_reset,              \
+/* int slave_attach(int, int) */                               NULL,                   \
+/* int bios_param(Disk *, kdev_t, int[]) */                    NULL,                   \
+/* int can_queue */                                            7,                     \
+/* int this_id */                                              7,                      \
+/* short unsigned int sg_tablesize */                          SG_ALL,                 \
+/* short cmd_per_lun */                                        1,                      \
+/* unsigned char present */                                    0,                      \
+/* unsigned unchecked_isa_dma:1 */                             0,                      \
+/* unsigned use_clustering:1 */                                DISABLE_CLUSTERING, }
+
+#endif /* !(_SPARC_ESP_H) */
+

