Index: arc/p_acer_pica_61.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/arc/p_acer_pica_61.c,v
retrieving revision 1.3
diff -u -r1.3 p_acer_pica_61.c
--- arc/p_acer_pica_61.c	2002/12/28 16:44:44	1.3
+++ arc/p_acer_pica_61.c	2003/01/08 17:03:01
@@ -38,16 +38,6 @@
 #include <arc/jazz/pica.h>
 #include <arc/jazz/jazziovar.h>
 
-#include "asc.h"
-#if NASC > 0
-#include <arc/jazz/ascvar.h>
-
-struct asc_config asc_acer_pica_61_conf = {
-	&asc_timing_25mhz,
-	0,
-};
-#endif
-
 /* ALI PICA 61 and some MAGNUM? */
 
 void p_acer_pica_61_init __P((void));
@@ -106,8 +96,4 @@
 
 	/* chipset-dependent jazzio bus configuration */
 	jazzio_devconfig = acer_pica_61_cpu;
-
-#if NASC > 0
-	asc_conf = &asc_acer_pica_61_conf;
-#endif
 }
Index: arc/p_ms_jazz.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/arc/p_ms_jazz.c,v
retrieving revision 1.3
diff -u -r1.3 p_ms_jazz.c
--- arc/p_ms_jazz.c	2002/12/28 16:44:44	1.3
+++ arc/p_ms_jazz.c	2003/01/08 17:03:02
@@ -39,12 +39,6 @@
 
 #include "com.h"
 
-#include "asc.h"
-#if NASC > 0
-#include <arc/jazz/ascreg.h>
-#include <arc/jazz/ascvar.h>
-#endif
-
 /* MAGNUM. NEC goes here too. */
 
 #ifndef COM_FREQ_MAGNUM
@@ -55,15 +49,6 @@
 #endif
 #endif /* COM_FREQ_MAGNUM */
 
-#if NASC > 0
-struct asc_config asc_ms_jazz_conf = {
-	&asc_timing_40mhz,
-
-	/* only if EPL is FE (Feature Enable bit for 53CF94) */
-	ASC_CNFG3_FCLK, /* clock 40MHz */
-};
-#endif
-
 void p_ms_jazz_init __P((void));
 
 struct platform platform_microsoft_jazz = {
@@ -111,10 +96,6 @@
 
 	/* jazzio bus configuration */
 	jazzio_devconfig = mips_magnum_r4000_cpu;
-
-#if NASC > 0
-	asc_conf = &asc_ms_jazz_conf;
-#endif
 
 #if NCOM > 0
 	com_freq = COM_FREQ_MAGNUM;
Index: conf/files.arc
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/conf/files.arc,v
retrieving revision 1.41
diff -u -r1.41 files.arc
--- conf/files.arc	2002/11/30 19:23:46	1.41
+++ conf/files.arc	2003/01/08 17:03:06
@@ -114,7 +114,7 @@
 device	jazzio {}
 attach	jazzio at mainbus		# optional
 file	arch/arc/jazz/jazzio.c		jazzio
-file	arch/arc/jazz/dma.c		# XXX jazzio
+#file	arch/arc/jazz/dma.c		# XXX jazzio
 file	arch/arc/jazz/jazzdmatlb.c	# XXX jazzio
 file	arch/arc/jazz/bus_dma_jazz.c	# XXX jazzio
 
@@ -160,7 +160,7 @@
 include	"dev/scsipi/files.scsipi"
 
 #	Symbios 53C94 SCSI interface driver on Jazz-Internal bus
-device	asc: scsi
+device	asc: scsi, ncr53c9x
 attach	asc at jazzio
 file	arch/arc/jazz/asc.c		asc	needs-flag
 
Index: jazz/asc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/jazz/asc.c,v
retrieving revision 1.9
diff -u -r1.9 asc.c
--- jazz/asc.c	2002/12/28 16:25:39	1.9
+++ jazz/asc.c	2003/01/08 17:03:07
@@ -1,13 +1,7 @@
-/*	$NetBSD: asc.c,v 1.9 2002/12/28 16:25:39 tsutsui Exp $	*/
-/*	$OpenBSD: asc.c,v 1.9 1998/03/16 09:38:39 pefo Exp $	*/
-/*	NetBSD: asc.c,v 1.10 1994/12/05 19:11:12 dean Exp 	*/
-
-/*-
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Ralph Campbell and Rick Macklem.
+/*	$NetBSD$	*/
+
+/*
+ * Copyright (c) 2003 Izumi Tsutsui.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -17,503 +11,101 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)asc.c	8.3 (Berkeley) 7/3/94
- */
-
-/* 
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- * 
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- * 
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
- * Carnegie Mellon requests users of this software to return to
- * 
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- * 
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-/*
- * HISTORY
- * Log:	scsi_53C94_hdw.c,v
- * Revision 2.5  91/02/05  17:45:07  mrt
- * 	Added author notices
- * 	[91/02/04  11:18:43  mrt]
- * 
- * 	Changed to use new Mach copyright
- * 	[91/02/02  12:17:20  mrt]
- * 
- * Revision 2.4  91/01/08  15:48:24  rpd
- * 	Added continuation argument to thread_block.
- * 	[90/12/27            rpd]
- * 
- * Revision 2.3  90/12/05  23:34:48  af
- * 	Recovered from pmax merge.. and from the destruction of a disk.
- * 	[90/12/03  23:40:40  af]
- * 
- * Revision 2.1.1.1  90/11/01  03:39:09  af
- * 	Created, from the DEC specs:
- * 	"PMAZ-AA TURBOchannel SCSI Module Functional Specification"
- * 	Workstation Systems Engineering, Palo Alto, CA. Aug 27, 1990.
- * 	And from the NCR data sheets
- * 	"NCR 53C94, 53C95, 53C96 Advances SCSI Controller"
- * 	[90/09/03            af]
- */
-
-/*
- *	File: scsi_53C94_hdw.h
- * 	Author: Alessandro Forin, Carnegie Mellon University
- *	Date:	9/90
- *
- *	Bottom layer of the SCSI driver: chip-dependent functions
- *
- *	This file contains the code that is specific to the NCR 53C94
- *	SCSI chip (Host Bus Adapter in SCSI parlance): probing, start
- *	operation, and interrupt routine.
- */
-
-/*
- * This layer works based on small simple 'scripts' that are installed
- * at the start of the command and drive the chip to completion.
- * The idea comes from the specs of the NCR 53C700 'script' processor.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
  *
- * There are various reasons for this, mainly
- * - Performance: identify the common (successful) path, and follow it;
- *   at interrupt time no code is needed to find the current status
- * - Code size: it should be easy to compact common operations
- * - Adaptability: the code skeleton should adapt to different chips without
- *   terrible complications.
- * - Error handling: and it is easy to modify the actions performed
- *   by the scripts to cope with strange but well identified sequences
- *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/dkstat.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/conf.h>
-#include <sys/errno.h>
 #include <sys/device.h>
+#include <sys/buf.h>
+
+#include <machine/autoconf.h>
+#include <machine/bus.h>
+
 #include <uvm/uvm_extern.h>
 
-#include <dev/scsipi/scsi_all.h>
 #include <dev/scsipi/scsipi_all.h>
+#include <dev/scsipi/scsi_all.h>
 #include <dev/scsipi/scsiconf.h>
 
-#include <mips/cache.h>
-
-#include <machine/cpu.h>
-#include <machine/autoconf.h>
-#include <machine/bus.h>
-
 #include <arc/jazz/jazziovar.h>
 #include <arc/jazz/jazzdmatlbreg.h>
+#include <arc/jazz/jazzdmatlbvar.h>
 #include <arc/jazz/dma.h>
-#include <arc/jazz/scsi.h>
-#include <arc/jazz/ascreg.h>
-#include <arc/jazz/ascvar.h>
-
 #include <arc/jazz/pica.h>
-
 
-#define	readback(a)	{ register int foo; foo = (a); }
+#include <dev/ic/ncr53c9xreg.h>
+#include <dev/ic/ncr53c9xvar.h>
 
-/*
- * In 4ns ticks.
- */
-int	asc_to_scsi_period[] = {
-	32,
-	33,
-	34,
-	35,
-	5,
-	5,
-	6,
-	7,
-	8,
-	9,
-	10,
-	11,
-	12,
-	13,
-	14,
-	15,
-	16,
-	17,
-	18,
-	19,
-	20,
-	21,
-	22,
-	23,
-	24,
-	25,
-	26,
-	27,
-	28,
-	29,
-	30,
-	31,
-};
-
-/*
- * Internal forward declarations.
- */
-struct asc_softc;
-static void asc_reset __P((struct asc_softc *, asc_regmap_t *));
-static void asc_startcmd __P((struct asc_softc *, int));
-
-#ifdef DEBUG
-int	asc_debug = 1;
-int	asc_debug_cmd;
-int	asc_debug_bn;
-int	asc_debug_sz;
-#define NLOG 16
-struct asc_log {
-	u_int	status;
-	u_char	state;
-	u_char	msg;
-	int	target;
-	int	resid;
-} asc_log[NLOG], *asc_logp = asc_log;
-#define PACK(unit, status, ss, ir) \
-	((unit << 24) | (status << 16) | (ss << 8) | ir)
-#endif
-
-/*
- * Scripts are entries in a state machine table.
- * A script has four parts: a pre-condition, an action, a command to the chip,
- * and an index into asc_scripts for the next state. The first triggers error
- * handling if not satisfied and in our case it is formed by the
- * values of the interrupt register and status register, this
- * basically captures the phase of the bus and the TC and BS
- * bits.  The action part is just a function pointer, and the
- * command is what the 53C94 should be told to do at the end
- * of the action processing.  This command is only issued and the
- * script proceeds if the action routine returns TRUE.
- * See asc_intr() for how and where this is all done.
- */
-typedef struct script {
-	int		condition;	/* expected state at interrupt time */
-	int		(*action)(struct asc_softc *, int, int, int);
-					/* extra operations */
-	int		command;	/* command to the chip */
-	struct script	*next;		/* index into asc_scripts for next state */
-} script_t;
-
-/* Matching on the condition value */
-#define	SCRIPT_MATCH(ir, csr)		((ir) | (((csr) & 0x67) << 8))
-
-
-/* forward decls of script actions */
-	/* when nothing needed */
-static int script_nop __P((struct asc_softc *, int, int, int));
-	/* all come to an end */
-static int asc_end __P((struct asc_softc *, int, int, int));
-	/* get status from target */
-static int asc_get_status __P((struct asc_softc *, int, int, int));
-	/* start reading data from target */
-static int asc_dma_in __P((struct asc_softc *, int, int, int));
-	/* cleanup after all data is read */
-static int asc_last_dma_in __P((struct asc_softc *, int, int, int));
-	/* resume data in after a message */
-static int asc_resume_in __P((struct asc_softc *, int, int, int));
-	/* resume DMA after a disconnect */
-static int asc_resume_dma_in __P((struct asc_softc *, int, int, int));
-	/* send data to target via dma */
-static int asc_dma_out __P((struct asc_softc *, int, int, int));
-	/* cleanup after all data is written */
-static int asc_last_dma_out __P((struct asc_softc *, int, int, int));
-	/* resume data out after a message */
-static int asc_resume_out __P((struct asc_softc *, int, int, int));
-	/* resume DMA after a disconnect */
-static int asc_resume_dma_out __P((struct asc_softc *, int, int, int));
-	/* negotiate sync xfer */
-static int asc_sendsync __P((struct asc_softc *, int, int, int));
-	/* negotiate sync xfer */
-static int asc_replysync __P((struct asc_softc *, int, int, int));
-	/* process a message byte */
-static int asc_msg_in __P((struct asc_softc *, int, int, int));
-	/* process an expected disconnect */
-static int asc_disconnect __P((struct asc_softc *, int, int, int));
-
-/* Define the index into asc_scripts for various state transitions */
-#define	SCRIPT_DATA_IN		0
-#define	SCRIPT_CONTINUE_IN	2
-#define	SCRIPT_DATA_OUT		3
-#define	SCRIPT_CONTINUE_OUT	5
-#define	SCRIPT_SIMPLE		6
-#define	SCRIPT_GET_STATUS	7
-#define	SCRIPT_DONE		8
-#define	SCRIPT_MSG_IN		9
-#define	SCRIPT_REPLY_SYNC	11
-#define	SCRIPT_TRY_SYNC		12
-#define	SCRIPT_DISCONNECT	15
-#define	SCRIPT_RESEL		16
-#define	SCRIPT_RESUME_IN	17
-#define	SCRIPT_RESUME_DMA_IN	18
-#define	SCRIPT_RESUME_OUT	19
-#define	SCRIPT_RESUME_DMA_OUT	20
-#define	SCRIPT_RESUME_NO_DATA	21
-
-/*
- * Scripts
- */
-script_t asc_scripts[] = {
-	/* start data in */
-	{SCRIPT_MATCH(ASC_INT_FC | ASC_INT_BS, ASC_PHASE_DATAI),	/*  0 */
-		asc_dma_in, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
-		&asc_scripts[SCRIPT_DATA_IN + 1]},
-	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_STATUS),			/*  1 */
-		asc_last_dma_in, ASC_CMD_I_COMPLETE,
-		&asc_scripts[SCRIPT_GET_STATUS]},
-
-	/* continue data in after a chunk is finished */
-	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_DATAI),			/*  2 */
-		asc_dma_in, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
-		&asc_scripts[SCRIPT_DATA_IN + 1]},
-
-	/* start data out */
-	{SCRIPT_MATCH(ASC_INT_FC | ASC_INT_BS, ASC_PHASE_DATAO),	/*  3 */
-		asc_dma_out, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
-		&asc_scripts[SCRIPT_DATA_OUT + 1]},
-	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_STATUS),			/*  4 */
-		asc_last_dma_out, ASC_CMD_I_COMPLETE,
-		&asc_scripts[SCRIPT_GET_STATUS]},
-
-	/* continue data out after a chunk is finished */
-	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_DATAO),			/*  5 */
-		asc_dma_out, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
-		&asc_scripts[SCRIPT_DATA_OUT + 1]},
-
-	/* simple command with no data transfer */
-	{SCRIPT_MATCH(ASC_INT_FC | ASC_INT_BS, ASC_PHASE_STATUS),	/*  6 */
-		script_nop, ASC_CMD_I_COMPLETE,
-		&asc_scripts[SCRIPT_GET_STATUS]},
-
-	/* get status and finish command */
-	{SCRIPT_MATCH(ASC_INT_FC, ASC_PHASE_MSG_IN),			/*  7 */
-		asc_get_status, ASC_CMD_MSG_ACPT,
-		&asc_scripts[SCRIPT_DONE]},
-	{SCRIPT_MATCH(ASC_INT_DISC, 0),					/*  8 */
-		asc_end, ASC_CMD_NOP,
-		&asc_scripts[SCRIPT_DONE]},
-
-	/* message in */
-	{SCRIPT_MATCH(ASC_INT_FC, ASC_PHASE_MSG_IN),			/*  9 */
-		asc_msg_in, ASC_CMD_MSG_ACPT,
-		&asc_scripts[SCRIPT_MSG_IN + 1]},
-	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_MSG_IN),			/* 10 */
-		script_nop, ASC_CMD_XFER_INFO,
-		&asc_scripts[SCRIPT_MSG_IN]},
-
-	/* send synchonous negotiation reply */
-	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_MSG_OUT),			/* 11 */
-		asc_replysync, ASC_CMD_XFER_INFO,
-		&asc_scripts[SCRIPT_REPLY_SYNC]},
-
-	/* try to negotiate synchonous transfer parameters */
-	{SCRIPT_MATCH(ASC_INT_FC | ASC_INT_BS, ASC_PHASE_MSG_OUT),	/* 12 */
-		asc_sendsync, ASC_CMD_XFER_INFO,
-		&asc_scripts[SCRIPT_TRY_SYNC + 1]},
-	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_MSG_IN),			/* 13 */
-		script_nop, ASC_CMD_XFER_INFO,
-		&asc_scripts[SCRIPT_MSG_IN]},
-	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_COMMAND),			/* 14 */
-		script_nop, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
-		&asc_scripts[SCRIPT_RESUME_NO_DATA]},
-
-	/* handle a disconnect */
-	{SCRIPT_MATCH(ASC_INT_DISC, ASC_PHASE_DATAO),			/* 15 */
-		asc_disconnect, ASC_CMD_ENABLE_SEL,
-		&asc_scripts[SCRIPT_RESEL]},
-
-	/* reselect sequence: this is just a placeholder so match fails */
-	{SCRIPT_MATCH(0, ASC_PHASE_MSG_IN),				/* 16 */
-		script_nop, ASC_CMD_MSG_ACPT,
-		&asc_scripts[SCRIPT_RESEL]},
-
-	/* resume data in after a message */
-	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_DATAI),			/* 17 */
-		asc_resume_in, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
-		&asc_scripts[SCRIPT_DATA_IN + 1]},
-
-	/* resume partial DMA data in after a message */
-	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_DATAI),			/* 18 */
-		asc_resume_dma_in, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
-		&asc_scripts[SCRIPT_DATA_IN + 1]},
-
-	/* resume data out after a message */
-	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_DATAO),			/* 19 */
-		asc_resume_out, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
-		&asc_scripts[SCRIPT_DATA_OUT + 1]},
-
-	/* resume partial DMA data out after a message */
-	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_DATAO),			/* 20 */
-		asc_resume_dma_out, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
-		&asc_scripts[SCRIPT_DATA_OUT + 1]},
-
-	/* resume after a message when there is no more data */
-	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_STATUS),			/* 21 */
-		script_nop, ASC_CMD_I_COMPLETE,
-		&asc_scripts[SCRIPT_GET_STATUS]},
-};
-
-/*
- * State kept for each active SCSI device.
- */
-typedef struct scsi_state {
-	script_t *script;	/* saved script while processing error */
-	struct scsi_generic cmd;/* storage for scsi command */
-	int	statusByte;	/* status byte returned during STATUS_PHASE */
-	u_int	dmaBufSize;	/* DMA buffer size */
-	int	dmalen;		/* amount to transfer in this chunk */
-	int	dmaresid;	/* amount not transfered if chunk suspended */
-	int	cmdlen;		/* length of command in cmd */
-	int	buflen;		/* total remaining amount of data to transfer */
-	vaddr_t	buf;		/* current pointer within scsicmd->buf */
-	int	flags;		/* see below */
-	int	msglen;		/* number of message bytes to read */
-	int	msgcnt;		/* number of message bytes received */
-	u_char	sync_period;	/* DMA synchronous period */
-	u_char	sync_offset;	/* DMA synchronous xfer offset or 0 if async */
-	u_char	msg_out;	/* next MSG_OUT byte to send */
-	u_char	msg_in[16];	/* buffer for multibyte messages */
-} State;
-
-/* state flags */
-#define DISCONN		0x001	/* true if currently disconnected from bus */
-#define DMA_IN_PROGRESS	0x002	/* true if data DMA started */
-#define DMA_IN		0x004	/* true if reading from SCSI device */
-#define DMA_OUT		0x010	/* true if writing to SCSI device */
-#define DID_SYNC	0x020	/* true if synchronous offset was negotiated */
-#define TRY_SYNC	0x040	/* true if try neg. synchronous offset */
-#define PARITY_ERR	0x080	/* true if parity error seen */
-
-/*
- * State kept for each active SCSI host interface (53C94).
- */
 struct asc_softc {
-	struct device	sc_dev;		/* use as a device */
-	asc_regmap_t	*regs;		/* chip address */
-	dma_softc_t	__dma;		/* stupid macro..... */
-	dma_softc_t	*dma;		/* dma control structure */
-	int		sc_id;		/* SCSI ID of this interface */
-	int		myidmask;	/* ~(1 << myid) */
-	int		state;		/* current SCSI connection state */
-	int		target;		/* target SCSI ID if busy */
-	script_t	*script;	/* next expected interrupt & action */
-	struct scsipi_xfer *cmdq[ASC_NCMD];/* Pointer to queued commands */
-	struct scsipi_xfer *cmd[ASC_NCMD];/* Pointer to current active command */
-	State		st[ASC_NCMD];	/* state info for each active command */
-	int		min_period;	/* Min transfer period clk/byte */
-	int		max_period;	/* Max transfer period clk/byte */
-	int		ccf;		/* CCF, whatever that really is? */
-	int		timeout_250;	/* 250ms timeout */
-	int		tb_ticks;	/* 4ns. ticks/tb channel ticks */
-	int		is24bit;	/* if 53CF94/96-2, 24bit address */
-	struct scsipi_channel sc_channel;
-	struct scsipi_adapter sc_adapter;
-};
+	struct ncr53c9x_softc sc_ncr53c9x;	/* glue to MI code */
 
-#define	ASC_STATE_IDLE		0	/* idle state */
-#define	ASC_STATE_BUSY		1	/* selecting or currently connected */
-#define ASC_STATE_TARGET	2	/* currently selected as target */
-#define ASC_STATE_RESEL		3	/* currently waiting for reselect */
-
-typedef struct asc_softc *asc_softc_t;
-
-struct asc_timing {
-	int		min_period;	/* Min transfer period clk/byte */
-	int		max_period;	/* Max transfer period clk/byte */
-	int		ccf;		/* CCF, whatever that really is? */
-	int		timeout_250;	/* 250ms timeout */
-	int		tb_ticks;	/* 4ns. ticks/tb channel ticks */
-}	asc_timing_40mhz = {
-		ASC_MIN_PERIOD40,
-		ASC_MAX_PERIOD40,
-		ASC_CCF(40),
-		ASC_TIMEOUT_250(40, 8 /* exception for ASC_CCF(40) (== 0) */),
-		6, /* 6.25 */
-},	asc_timing_25mhz = {
-		ASC_MIN_PERIOD25,
-		ASC_MAX_PERIOD25,
-		ASC_CCF(25),
-		ASC_TIMEOUT_250(25, ASC_CCF(25)),
-		10,
-},	asc_timing_12mhz = {
-		ASC_MIN_PERIOD12,
-		ASC_MAX_PERIOD12,
-		ASC_CCF(13),
-		ASC_TIMEOUT_250(13, ASC_CCF(13)),
-		20,
+	bus_space_tag_t sc_iot;		/* bus space tag */
+	bus_space_handle_t sc_ioh;	/* bus space handle */
+	bus_space_handle_t sc_dmaioh;	/* bus space handle for DMAC */
+
+	bus_dma_tag_t sc_dmat;		/* DMA tag */
+	bus_dmamap_t sc_dmamap;		/* DMA map for transfers */
+
+	int     sc_active;              /* DMA state */
+	int     sc_datain;              /* DMA Data Direction */
+	size_t  sc_dmasize;             /* DMA size */
+	char    **sc_dmaaddr;           /* DMA address */
+	size_t  *sc_dmalen;             /* DMA length */
 };
 
-struct asc_config *asc_conf = NULL;
-
 /*
  * Autoconfiguration data for config.
  */
-int	ascmatch __P((struct device *, struct cfdata *, void *));
-void	ascattach __P((struct device *, struct device *, void *));
-
-int	asc_doprobe __P((void *, int, int, struct device *));
+int asc_match(struct device *, struct cfdata *, void *);
+void asc_attach(struct device *, struct device *, void *);
 
 CFATTACH_DECL(asc, sizeof(struct asc_softc),
-    ascmatch, ascattach, NULL, NULL);
+    asc_match, asc_attach, NULL, NULL);
 
 /*
- *  Glue to the machine dependent scsi
+ *  Functions and the switch for the MI code.
  */
-void asc_scsipi_request __P((struct scsipi_channel *,
-				scsipi_adapter_req_t, void *));
-
-static int asc_intr __P((void *));
-static void asc_poll __P((struct asc_softc *, int));
-#ifdef DEBUG
-static void asc_DumpLog __P((char *));
-#endif
+u_char asc_read_reg(struct ncr53c9x_softc *, int);
+void asc_write_reg(struct ncr53c9x_softc *, int, u_char);
+int asc_dma_isintr(struct ncr53c9x_softc *);
+void asc_dma_reset(struct ncr53c9x_softc *);
+int asc_dma_intr(struct ncr53c9x_softc *);
+int asc_dma_setup(struct ncr53c9x_softc *, caddr_t *, size_t *, int, size_t *);
+void asc_dma_go(struct ncr53c9x_softc *);
+void asc_dma_stop(struct ncr53c9x_softc *);
+int asc_dma_isactive(struct ncr53c9x_softc *);
+
+struct ncr53c9x_glue asc_glue = {
+	asc_read_reg,
+	asc_write_reg,
+	asc_dma_isintr,
+	asc_dma_reset,
+	asc_dma_intr,
+	asc_dma_setup,
+	asc_dma_go,
+	asc_dma_stop,
+	asc_dma_isactive,
+	NULL			/* gl_clear_latched_intr */
+};
 
 /*
  * Match driver based on name
  */
 int
-ascmatch(parent, match, aux)
+asc_match(parent, match, aux)
 	struct device *parent;
 	struct cfdata *match;
 	void *aux;
@@ -526,1530 +118,321 @@
 }
 
 void
-ascattach(parent, self, aux)
+asc_attach(parent, self, aux)
 	struct device *parent;
 	struct device *self;
 	void *aux;
 {
 	struct jazzio_attach_args *ja = aux;
-	asc_softc_t asc = (void *)self;
-	asc_regmap_t *regs;
-	int id, s, i;
-	int bufsiz;
+	struct asc_softc *asc = (void *)self;
+	struct ncr53c9x_softc *sc = &asc->sc_ncr53c9x;
+	bus_space_tag_t iot;
 
+#if 0
+	/* Need info from platform dependent config?? */
 	if (asc_conf == NULL)
 		panic("asc_conf isn't initialized");
+#endif
 
-	/*
-	 * Initialize hw descriptor, cache some pointers
-	 */
-	asc->regs = (asc_regmap_t *)ja->ja_addr;	/* XXX */
+	sc->sc_glue = &asc_glue;
 
-	/*
-	 * Set up machine dependencies.
-	 * 1) how to do dma
-	 * 2) timing based on chip clock frequency
-	 */
-#if 1	/*XXX check if code handles 0 as 64k */
-	bufsiz = 63 * 1024;
-#else
-	bufsiz = 64 * 1024;
-#endif
-	asc->dma = &asc->__dma;
-	asc_dma_init(asc->dma);
+	asc->sc_iot = iot = ja->ja_bust;
+	asc->sc_dmat = ja->ja_dmat;
 
-	/*
-	 * Now for timing.
-	 */
-	asc->min_period = asc_conf->ac_timing->min_period;
-	asc->max_period = asc_conf->ac_timing->max_period;
-	asc->ccf = asc_conf->ac_timing->ccf;
-	asc->timeout_250 = asc_conf->ac_timing->timeout_250;
-	asc->tb_ticks = asc_conf->ac_timing->tb_ticks;
+	if (bus_space_map(iot, ja->ja_addr, 0x10 /*XXX*/, 0, &asc->sc_ioh)) {
+		printf(": unable to map I/O space\n");
+		return;
+	}
 
-	asc->state = ASC_STATE_IDLE;
-	asc->target = -1;
+	if (bus_space_map(iot, R4030_SYS_DMA0_REGS, R4030_DMA_RANGE,
+	    0, &asc->sc_dmaioh)) {
+		printf(": unable to map dma I/O space\n");
+		goto out1;
+	}
 
-	regs = asc->regs;
+	if (bus_dmamap_create(asc->sc_dmat, MAXPHYS, 1, MAXPHYS, 0,
+	    BUS_DMA_ALLOCNOW|BUS_DMA_NOWAIT, &asc->sc_dmamap)) {
+		printf(": unable to create DMA map\n");
+		goto out2;
+	}
 
 	/*
-	 * Reset chip, fully.  Note that interrupts are already enabled.
+	 * XXX More of this should be in ncr53c9x_attach(), but
+	 * XXX should we really poke around the chip that much in
+	 * XXX the MI code?  Think about this more...
 	 */
-	s = splbio();
 
-	/* preserve our ID for now */
-	asc->sc_id = regs->asc_cnfg1 & ASC_CNFG1_MY_BUS_ID;
-	asc->myidmask = ~(1 << asc->sc_id);
+	/*
+	 * Set up static configuration info.
+	 */
+	sc->sc_id = 7; /* XXX should be taken from ARC BIOS */
+	sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
 
 	/* identify 53CF9x-2 or not */
-	regs->asc_cmd = ASC_CMD_RESET;
-	wbflush(); DELAY(25);
-	regs->asc_cmd = ASC_CMD_DMA | ASC_CMD_NOP;
-	wbflush(); DELAY(25);
-	regs->asc_cnfg2 = ASC_CNFG2_FE;
-	wbflush(); DELAY(25);
-	regs->asc_cmd = ASC_CMD_DMA | ASC_CMD_NOP;
-	wbflush(); DELAY(25);
-	asc->is24bit = regs->asc_id == ASC_ID_53CF94;
-
-	asc_reset(asc, regs);
+	asc_write_reg(sc, NCR_CMD, NCRCMD_RSTCHIP);
+	DELAY(25);
+	asc_write_reg(sc, NCR_CMD, NCRCMD_DMA | NCRCMD_NOP);
+	DELAY(25);
+	asc_write_reg(sc, NCR_CFG2, NCRCFG2_FE);
+	DELAY(25);
+	asc_write_reg(sc, NCR_CMD, NCRCMD_DMA | NCRCMD_NOP);
+	DELAY(25);
+	if (asc_read_reg(sc, NCR_TCH) == 0xa2 /*XXX*/) {
+		sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_FE;
+		sc->sc_cfg3 = NCRF9XCFG3_IDM | NCRF9XCFG3_FCLK;
+		sc->sc_features = NCR_F_FASTSCSI;
+		sc->sc_cfg3_fscsi = NCRF9XCFG3_FSCSI;
+		sc->sc_freq = 40; /* MHz */
+		sc->sc_maxxfer = 16 * 1024 * 1024;
+	} else {
+		sc->sc_freq = 25; /* MHz */
+		sc->sc_maxxfer = 64 * 1024;
+	}
 
 	/*
-	 * Our SCSI id on the bus.
-	 * The user can set this via the prom on 3maxen/picaen.
-	 * If this changes it is easy to fix: make a default that
-	 * can be changed as boot arg.
+	 * XXX minsync and maxxfer _should_ be set up in MI code,
+	 * XXX but it appears to have some dependency on what sort
+	 * XXX of DMA we're hooked up to, etc.
 	 */
-#ifdef	unneeded
-	regs->asc_cnfg1 = (regs->asc_cnfg1 & ~ASC_CNFG1_MY_BUS_ID) |
-			      (scsi_initiator_id[unit] & 0x7);
-	asc->sc_id = regs->asc_cnfg1 & ASC_CNFG1_MY_BUS_ID;
-#endif
-	id = asc->sc_id;
-	splx(s);
 
 	/*
-	 * Give each target its DMA buffer region.
-	 * The buffer address is the same for all targets,
-	 * the allocated dma viritual scatter/gather space.
+	 * This is the value used to start sync negotiations
+	 * Note that the NCR register "SYNCTP" is programmed
+	 * in "clocks per byte", and has a minimum value of 4.
+	 * The SCSI period used in negotiation is one-fourth
+	 * of the time (in nanoseconds) needed to transfer one byte.
+	 * Since the chip's clock is given in MHz, we have the following
+	 * formula: 4 * period = (1000 / freq) * 4
 	 */
-	for (i = 0; i < ASC_NCMD; i++) {
-		asc->st[i].dmaBufSize = bufsiz;
-	}
+	sc->sc_minsync = 1000 / sc->sc_freq;
 
-	/*
-	 * Set up interrupt handler.
-         */
-	jazzio_intr_establish(ja->ja_intr, asc_intr, (void *)asc);
-
-	printf(": %s, target %d\n", asc->is24bit ? "NCR53CF9X-2" : "NCR53C94",
-	    id);
-
-	asc->sc_adapter.adapt_dev = &asc->sc_dev;
-	asc->sc_adapter.adapt_nchannels = 1;
-	asc->sc_adapter.adapt_openings = 7;
-	asc->sc_adapter.adapt_max_periph = 1;
-	asc->sc_adapter.adapt_ioctl = NULL;
-	asc->sc_adapter.adapt_minphys = minphys;
-	asc->sc_adapter.adapt_request = asc_scsipi_request;
-
-	memset(&asc->sc_channel, 0, sizeof(asc->sc_channel));
-	asc->sc_channel.chan_adapter = &asc->sc_adapter;
-	asc->sc_channel.chan_bustype = &scsi_bustype;
-	asc->sc_channel.chan_channel = 0;
-	asc->sc_channel.chan_ntargets = 8;
-	asc->sc_channel.chan_nluns = 8;
-	asc->sc_channel.chan_id = asc->sc_id;
+	/* establish interrupt */
+	jazzio_intr_establish(ja->ja_intr, ncr53c9x_intr, asc);
 
-	/*
-	 * Now try to attach all the sub devices.
-	 */
-	config_found(self, &asc->sc_channel, scsiprint);
+	/* Do the common parts of attachment. */
+	sc->sc_adapter.adapt_minphys = minphys;
+	sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request;
+	ncr53c9x_attach(sc);
+
+	/* Turn on target selection using the `dma' method */
+	sc->sc_features |= NCR_F_DMASELECT;
+	return;
+
+ out2:
+	bus_space_unmap(iot, asc->sc_dmaioh, R4030_DMA_RANGE);
+ out1:
+	bus_space_unmap(iot, asc->sc_ioh, 0x20/*XXX*/);
 }
 
 /*
- * Start activity on a SCSI device.
- * We maintain information on each device separately since devices can
- * connect/disconnect during an operation.
+ * Glue functions.
  */
-void
-asc_scsipi_request(chan, req, arg)
-	struct scsipi_channel *chan;
-	scsipi_adapter_req_t req;
-	void *arg;
-{
-	struct scsipi_xfer *xs;
-	struct scsipi_periph *periph;
-	struct asc_softc *asc = (void *)chan->chan_adapter->adapt_dev;
-	int dontqueue, s;
-
-	switch (req) {
-	case ADAPTER_REQ_RUN_XFER:
-		xs = arg;
-		periph = xs->xs_periph;
 
-		dontqueue = xs->xs_control & XS_CTL_POLL;
-
-		/*
-		 *  Flush caches for any data buffer
-		 */
-		if(xs->datalen != 0) {
-			mips_dcache_wbinv_range((vaddr_t)xs->data, xs->datalen);
-		}
-		/*
-		 *  The hack on the next few lines are to avoid buffers
-		 *  mapped to UADDR. Realloc to the kva uarea address.
-		 */
-		if((u_int)(xs->data) >= UADDR) {
-			xs->data = ((u_int)(xs->data) & ~UADDR) + (u_char *)(curproc->p_addr);
-		}
-
-		s = splbio();
-		asc->cmd[periph->periph_target] = xs;
-
-		/*
-		 *  Going to launch.
-		 *  Make a local copy of the command and some pointers.
-		 */
-		asc_startcmd(asc, periph->periph_target);
+u_char
+asc_read_reg(sc, reg)
+	struct ncr53c9x_softc *sc;
+	int reg;
+{
+	struct asc_softc *asc = (struct asc_softc *)sc;
 
-		/*
-		 *  If in startup, interrupts not usable yet.
-		 */
-		if(dontqueue) {
-			asc_poll(asc,periph->periph_target);
-		}
-		splx(s);
-		return;
-	case ADAPTER_REQ_GROW_RESOURCES:
-		/* XXX Not supported. */
-		return;
-	case ADAPTER_REQ_SET_XFER_MODE:
-		/* XXX Not supported. */
-		return;
-	}
+	return bus_space_read_1(asc->sc_iot, asc->sc_ioh, reg);
 }
 
 void
-asc_poll(asc, target)
-	struct asc_softc *asc;
-	int target;
+asc_write_reg(sc, reg, val)
+	struct ncr53c9x_softc *sc;
+	int reg;
+	u_char val;
 {
-	struct scsipi_xfer *scsicmd = asc->cmd[target];
-	int count = scsicmd->timeout * 10;
+	struct asc_softc *asc = (struct asc_softc *)sc;
 
-	while(count) {
-		if(asc->regs->asc_status &ASC_CSR_INT) {
-			asc_intr(asc);
-		}
-		if(scsicmd->xs_status & XS_STS_DONE)
-			break;
-		DELAY(5);
-		count--;
-	}
-	if(count == 0) {
-		scsicmd->error = XS_TIMEOUT;
-		asc_end(asc, 0, 0, 0);
-	}
+	bus_space_write_1(asc->sc_iot, asc->sc_ioh, reg, val);
 }
 
-static void
-asc_reset(asc, regs)
-	asc_softc_t asc;
-	asc_regmap_t *regs;
+int
+asc_dma_isintr(sc)
+	struct ncr53c9x_softc *sc;
 {
 
-	/*
-	 * Reset chip and wait till done
-	 */
-	regs->asc_cmd = ASC_CMD_RESET;
-	wbflush(); DELAY(25);
-
-	/* spec says this is needed after reset */
-	regs->asc_cmd = ASC_CMD_NOP;
-	wbflush(); DELAY(25);
-
-	/*
-	 * Set up various chip parameters
-	 */
-	regs->asc_ccf = asc->ccf;
-	wbflush(); DELAY(25);
-	regs->asc_sel_timo = asc->timeout_250;
-	/* restore our ID */
-	regs->asc_cnfg1 = asc->sc_id | ASC_CNFG1_P_CHECK;
-	/* include ASC_CNFG2_SCSI2 if you want to allow SCSI II commands */
-	regs->asc_cnfg2 = /* ASC_CNFG2_RFB | ASC_CNFG2_SCSI2 | */ ASC_CNFG2_EPL;
-	regs->asc_cnfg3 = asc_conf->ac_cnfg3;
-	/* zero anything else */
-	ASC_TC_PUT(regs, 0, asc->is24bit);
-	regs->asc_syn_p = asc->min_period;
-	regs->asc_syn_o = 0;	/* async for now */
-	wbflush();
+	return asc_read_reg(sc, NCR_STAT) & NCRSTAT_INT;
 }
 
-/*
- * Start a SCSI command on a target.
- */
-static void
-asc_startcmd(asc, target)
-	asc_softc_t asc;
-	int target;
+void
+asc_dma_reset(sc)
+	struct ncr53c9x_softc *sc;
 {
-	asc_regmap_t *regs;
-	State *state;
-	struct scsipi_xfer *scsicmd;
-	int i, len;
-
-	/*
-	 * See if another target is currently selected on this SCSI bus.
-	 */
-	if (asc->target >= 0)
-		return;
-
-	regs = asc->regs;
-
-	/*
-	 * If a reselection is in progress, it is Ok to ignore it since
-	 * the ASC will automatically cancel the command and flush
-	 * the FIFO if the ASC is reselected before the command starts.
-	 * If we try to use ASC_CMD_DISABLE_SEL, we can hang the system if
-	 * a reselect occurs before starting the command.
-	 */
-
-	asc->state = ASC_STATE_BUSY;
-	asc->target = target;
-
-	/* cache some pointers */
-	scsicmd = asc->cmd[target];
-	state = &asc->st[target];
-
-	/*
-	 * Init the chip and target state.
-	 */
-	state->flags = state->flags & DID_SYNC;
-	state->script = (script_t *)0;
-	state->msg_out = SCSI_NO_OP;
-
-	/*
-	 * Set up for DMA of command output. Also need to flush cache.
-	 */
-	bcopy(scsicmd->cmd, &state->cmd, scsicmd->cmdlen);
-	state->cmdlen = scsicmd->cmdlen;
-	state->buf = (vaddr_t)scsicmd->data;
-	state->buflen = scsicmd->datalen;
-	len = state->cmdlen;
-	state->dmalen = len;
-	
-#ifdef DEBUG
-	if (asc_debug > 1) {
-		printf("asc_startcmd: %s target %d cmd %x len %d\n",
-			asc->sc_dev.dv_xname, target,
-			state->cmd.opcode, state->buflen);
-	}
-#endif
-
-	/* check for simple SCSI command with no data transfer */
-	if (scsicmd->xs_control & XS_CTL_DATA_OUT) {
-		asc->script = &asc_scripts[SCRIPT_DATA_OUT];
-		state->flags |= DMA_OUT;
-	}
-	else if (scsicmd->xs_control & XS_CTL_DATA_IN) {
-		asc->script = &asc_scripts[SCRIPT_DATA_IN];
-		state->flags |= DMA_IN;
-	}
-	else if (state->buflen == 0) {
-		/* check for sync negotiation */
-		if ((scsicmd->xs_status & /* SCSICMD_USE_SYNC */ 0) &&
-		    !(state->flags & DID_SYNC)) {
-			asc->script = &asc_scripts[SCRIPT_TRY_SYNC];
-			state->flags |= TRY_SYNC;
-		} else
-			asc->script = &asc_scripts[SCRIPT_SIMPLE];
-		state->buf = (vaddr_t)0;
-	}
-
-#ifdef DEBUG
-	asc_debug_cmd = state->cmd.opcode;
-	if (state->cmd.opcode == SCSI_READ_EXT) {
-		asc_debug_bn = (state->cmd.bytes[1] << 24) |
-			(state->cmd.bytes[2] << 16) |
-			(state->cmd.bytes[3] << 8) |
-			 state->cmd.bytes[4];
-		asc_debug_sz = (state->cmd.bytes[6] << 8) | state->cmd.bytes[7];
-	}
-	asc_logp->status = PACK(asc->sc_dev.dv_unit, 0, 0, asc_debug_cmd);
-	asc_logp->target = asc->target;
-	asc_logp->state = asc->script - asc_scripts;
-	asc_logp->msg = SCSI_DIS_REC_IDENTIFY;
-	asc_logp->resid = scsicmd->datalen;
-	if (++asc_logp >= &asc_log[NLOG])
-		asc_logp = asc_log;
-#endif
-
-	/* preload the FIFO with the message and command to be sent */
-	regs->asc_fifo = SCSI_DIS_REC_IDENTIFY |
-	    (scsicmd->xs_periph->periph_lun & 0x07);
+	struct asc_softc *asc = (struct asc_softc *)sc;
 
-	for( i = 0; i < len; i++ ) {
-		regs->asc_fifo = ((caddr_t)&state->cmd)[i];
-	}
-	ASC_TC_PUT(regs, 0, asc->is24bit);
-	readback(regs->asc_cmd);
-	regs->asc_cmd = ASC_CMD_DMA;
-	readback(regs->asc_cmd);
-
-	regs->asc_dbus_id = target;
-	readback(regs->asc_dbus_id);
-	regs->asc_syn_p = state->sync_period;
-	readback(regs->asc_syn_p);
-	regs->asc_syn_o = state->sync_offset;
-	readback(regs->asc_syn_o);
-
-/*XXX PEFO */
-/* we are not using sync transfer now, need to check this if we will */
-
-	if (state->flags & TRY_SYNC)
-		regs->asc_cmd = ASC_CMD_SEL_ATN_STOP;
-	else
-		regs->asc_cmd = ASC_CMD_SEL_ATN;
-	readback(regs->asc_cmd);
+	/* halt DMA */
+	bus_space_write_4(asc->sc_iot, asc->sc_dmaioh, R4030_DMA_ENAB, 0);
+	bus_space_write_4(asc->sc_iot, asc->sc_dmaioh, R4030_DMA_MODE, 0);
 }
 
-/*
- * Interrupt routine
- *	Take interrupts from the chip
- *
- * Implementation:
- *	Move along the current command's script if
- *	all is well, invoke error handler if not.
- */
 int
-asc_intr(sc)
-	void *sc;
+asc_dma_intr(sc)
+	struct ncr53c9x_softc *sc;
 {
-	asc_softc_t asc = sc;
-	asc_regmap_t *regs = asc->regs;
-	State *state;
-	script_t *scpt;
-	int ss, ir, status;
-
-	/* collect ephemeral information */
-	status = regs->asc_status;
-	ss = regs->asc_ss;
-
-	if ((status & ASC_CSR_INT) == 0) /* Make shure it's a real interrupt */
-		 return(0);
-
-	ir = regs->asc_intr;	/* this resets the previous two */
-	scpt = asc->script;
-
-#ifdef DEBUG
-	asc_logp->status = PACK(asc->sc_dev.dv_unit, status, ss, ir);
-	asc_logp->target = (asc->state == ASC_STATE_BUSY) ? asc->target : -1;
-	asc_logp->state = scpt - asc_scripts;
-	asc_logp->msg = -1;
-	asc_logp->resid = 0;
-	if (++asc_logp >= &asc_log[NLOG])
-		asc_logp = asc_log;
-	if (asc_debug > 2)
-		printf("asc_intr: status %x ss %x ir %x cond %d:%x\n",
-			status, ss, ir, scpt - asc_scripts, scpt->condition);
-#endif
+	struct asc_softc *asc = (struct asc_softc *)sc;
+	int datain, resid, trans;
 
-	/* check the expected state */
-	if (SCRIPT_MATCH(ir, status) == scpt->condition) {
-		/*
-		 * Perform the appropriate operation, then proceed.
-		 */
-		if ((*scpt->action)(asc, status, ss, ir)) {
-			regs->asc_cmd = scpt->command;
-			readback(regs->asc_cmd);
-			asc->script = scpt->next;
-		}
-		goto done;
-	}
+	datain = asc->sc_datain;
 
-	/*
-	 * Check for parity error.
-	 * Hardware will automatically set ATN
-	 * to request the device for a MSG_OUT phase.
-	 */
-	if (status & ASC_CSR_PE) {
-		printf("%s: SCSI device %d: incomming parity error seen\n",
-			asc->sc_dev.dv_xname, asc->target);
-		asc->st[asc->target].flags |= PARITY_ERR;
-	}
-
-	/*
-	 * Check for gross error.
-	 * Probably a bug in a device driver.
-	 */
-	if (status & ASC_CSR_GE) {
-		printf("%s: SCSI device %d: gross error\n",
-			asc->sc_dev.dv_xname, asc->target);
-		goto abort;
-	}
-
-	/* check for message in or out */
-	if ((ir & ~ASC_INT_FC) == ASC_INT_BS) {
-		register int len, fifo;
-
-		state = &asc->st[asc->target];
-		switch (ASC_PHASE(status)) {
-		case ASC_PHASE_DATAI:
-		case ASC_PHASE_DATAO:
-			ASC_TC_GET(regs, len);
-			fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
-			printf("asc_intr: data overrun: buflen %d dmalen %d tc %d fifo %d\n",
-				state->buflen, state->dmalen, len, fifo);
-			goto abort;
-
-		case ASC_PHASE_MSG_IN:
-			break;
-
-		case ASC_PHASE_MSG_OUT:
-			/*
-			 * Check for parity error.
-			 * Hardware will automatically set ATN
-			 * to request the device for a MSG_OUT phase.
-			 */
-			if (state->flags & PARITY_ERR) {
-				state->flags &= ~PARITY_ERR;
-				state->msg_out = SCSI_MESSAGE_PARITY_ERROR;
-				/* reset message in counter */
-				state->msglen = 0;
-			} else
-				state->msg_out = SCSI_NO_OP;
-			regs->asc_fifo = state->msg_out;
-			regs->asc_cmd = ASC_CMD_XFER_INFO;
-			readback(regs->asc_cmd);
-			goto done;
-
-		case ASC_PHASE_STATUS:
-			/* probably an error in the SCSI command */
-			asc->script = &asc_scripts[SCRIPT_GET_STATUS];
-			regs->asc_cmd = ASC_CMD_I_COMPLETE;
-			readback(regs->asc_cmd);
-			goto done;
-
-		default:
-			goto abort;
-		}
-
-		if (state->script)
-			goto abort;
-
-		/*
-		 * OK, message coming in clean up whatever is going on.
-		 * Get number of bytes left to transfered from byte counter
-		 * counter decrements when data is trf on the SCSI bus
-		 */
-		ASC_TC_GET(regs, len);
-		fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
-		/* flush any data in the FIFO */
-		if (fifo && !(state->flags & DMA_IN_PROGRESS)) {
-printf("asc_intr: fifo flush %d len %d fifo %x\n", fifo, len, regs->asc_fifo);
-			regs->asc_cmd = ASC_CMD_FLUSH;
-			readback(regs->asc_cmd);
-			DELAY(2);
-		}
-		else if (fifo && state->flags & DMA_IN_PROGRESS) {	
-			if (state->flags & DMA_OUT) {
-				len += fifo; /* Bytes dma'ed but not sent */
-			}
-			else if (state->flags & DMA_IN) {
-				printf("asc_intr: IN: dmalen %d len %d fifo %d\n",
-					state->dmalen, len, fifo); /* XXX */
-			}
-			regs->asc_cmd = ASC_CMD_FLUSH;
-			readback(regs->asc_cmd);
-			DELAY(2);
-		}
-		if (len && (state->flags & DMA_IN_PROGRESS)) {
-			/* save number of bytes still to be sent or received */
-			state->dmaresid = len;
-			state->flags &= ~DMA_IN_PROGRESS;
-			ASC_TC_PUT(regs, 0, asc->is24bit);
-#ifdef DEBUG
-			if (asc_logp == asc_log)
-				asc_log[NLOG - 1].resid = len;
-			else
-				asc_logp[-1].resid = len;
-#endif
-			/* setup state to resume to */
-			if (state->flags & DMA_IN) {
-				/*
-				 * Since the ASC_CNFG3_SRB bit of the
-				 * cnfg3 register bit is not set,
-				 * we just transferred an extra byte.
-				 * Since we can't resume on an odd byte
-				 * boundary, we copy the valid data out
-				 * and resume DMA at the start address.
-				 */
-				if (len & 1) {
-					printf("asc_intr: msg in len %d (fifo %d)\n",
-						len, fifo); /* XXX */
-					len = state->dmalen - len;
-					goto do_in;
-				}
-				state->script =
-					&asc_scripts[SCRIPT_RESUME_DMA_IN];
-			} else if (state->flags & DMA_OUT)
-				state->script =
-					&asc_scripts[SCRIPT_RESUME_DMA_OUT];
-			else
-				state->script = asc->script;
-		} else if (state->flags & DMA_IN) {
-			if (len) {
-#ifdef DEBUG
-				printf("asc_intr: 1: bn %d len %d (fifo %d)\n",
-					asc_debug_bn, len, fifo); /* XXX */
-#endif
-				goto abort;
-			}
-			/* setup state to resume to */
-			if (state->flags & DMA_IN_PROGRESS) {
-				len = state->dmalen;
-				state->flags &= ~DMA_IN_PROGRESS;
-			do_in:
-				DMA_END(asc->dma);
-				state->buf += len;
-				state->buflen -= len;
-			}
-			if (state->buflen)
-				state->script =
-				    &asc_scripts[SCRIPT_RESUME_IN];
-			else
-				state->script =
-				    &asc_scripts[SCRIPT_RESUME_NO_DATA];
-		} else if (state->flags & DMA_OUT) {
-			if (len) {
-				printf("asc_intr: 2: len %d (fifo %d)\n", len,
-					fifo); /* XXX */
-/* XXX THEO */
-#if 1 
-				regs->asc_cmd = ASC_CMD_FLUSH;
-				readback(regs->asc_cmd);
-				DELAY(2);
-				len = 0;
-#else                                   
-				goto abort;
-#endif
-			}
-			/*
-			 * If this is the last chunk, the next expected
-			 * state is to get status.
-			 */
-			if (state->flags & DMA_IN_PROGRESS) {
-				state->flags &= ~DMA_IN_PROGRESS;
-				DMA_END(asc->dma);
-				len = state->dmalen;
-				state->buf += len;
-				state->buflen -= len;
-			}
-			if (state->buflen)
-				state->script =
-				    &asc_scripts[SCRIPT_RESUME_OUT];
-			else
-				state->script =
-				    &asc_scripts[SCRIPT_RESUME_NO_DATA];
-		} else if (asc->script == &asc_scripts[SCRIPT_SIMPLE])
-			state->script = &asc_scripts[SCRIPT_RESUME_NO_DATA];
-		else
-			state->script = asc->script;
-
-		/* setup to receive a message */
-		asc->script = &asc_scripts[SCRIPT_MSG_IN];
-		state->msglen = 0;
-		regs->asc_cmd = ASC_CMD_XFER_INFO;
-		readback(regs->asc_cmd);
-		goto done;
-	}
-
-	/* check for SCSI bus reset */
-	if (ir & ASC_INT_RESET) {
-		register int i;
-
-		printf("%s: SCSI bus reset!!\n", asc->sc_dev.dv_xname);
-		/* need to flush any pending commands */
-		for (i = 0; i < ASC_NCMD; i++) {
-			if (!asc->cmd[i])
-				continue;
-			asc->cmd[i]->error = XS_DRIVER_STUFFUP;
-			asc_end(asc, 0, 0, 0);
-		}
-		/* rearbitrate synchronous offset */
-		for (i = 0; i < ASC_NCMD; i++) {
-			asc->st[i].sync_offset = 0;
-			asc->st[i].flags = 0;
-		}
-		asc->target = -1;
-		return(1);
-	}
-
-	/* check for command errors */
-	if (ir & ASC_INT_ILL)
-		goto abort;
-
-	/* check for disconnect */
-	if (ir & ASC_INT_DISC) {
-		state = &asc->st[asc->target];
-		switch (asc->script - asc_scripts) {
-		case SCRIPT_DONE:
-		case SCRIPT_DISCONNECT:
-			/*
-			 * Disconnects can happen normally when the
-			 * command is complete with the phase being
-			 * either ASC_PHASE_DATAO or ASC_PHASE_MSG_IN.
-			 * The SCRIPT_MATCH() only checks for one phase
-			 * so we can wind up here.
-			 * Perform the appropriate operation, then proceed.
-			 */
-			if ((*scpt->action)(asc, status, ss, ir)) {
-				regs->asc_cmd = scpt->command;
-				readback(regs->asc_cmd);
-				asc->script = scpt->next;
-			}
-			goto done;
-
-		case SCRIPT_TRY_SYNC:
-		case SCRIPT_SIMPLE:
-		case SCRIPT_DATA_IN:
-		case SCRIPT_DATA_OUT: /* one of the starting scripts */
-			if (ASC_SS(ss) == 0) {
-				/* device did not respond */
-				if (regs->asc_flags & ASC_FLAGS_FIFO_CNT) {
-					regs->asc_cmd = ASC_CMD_FLUSH;
-					readback(regs->asc_cmd);
-				}
-				asc->cmd[asc->target]->error = XS_SELTIMEOUT;
-				asc_end(asc, status, ss, ir);
-				return(1);
-			}
-			/* FALLTHROUGH */
-
-		default:
-			printf("%s: SCSI device %d: unexpected disconnect\n",
-				asc->sc_dev.dv_xname, asc->target);
-#ifdef DEBUG
-			asc_DumpLog("asc_disc");
-#endif
-			/*
-			 * On rare occasions my RZ24 does a disconnect during
-			 * data in phase and the following seems to keep it
-			 * happy.
-			 * XXX Should a scsi disk ever do this??
-			 */
-			asc->script = &asc_scripts[SCRIPT_RESEL];
-			asc->state = ASC_STATE_RESEL;
-			state->flags |= DISCONN;
-			regs->asc_cmd = ASC_CMD_ENABLE_SEL;
-			readback(regs->asc_cmd);
-			return(1);
-		}
-	}
-
-	/* check for reselect */
-	if (ir & ASC_INT_RESEL) {
-		unsigned fifo, id, msg;
-
-		fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
-		if (fifo < 2)
-			goto abort;
-		/* read unencoded SCSI ID and convert to binary */
-		msg = regs->asc_fifo & asc->myidmask;
-		for (id = 0; (msg & 1) == 0; id++)
-			msg >>= 1;
-		/* read identify message */
-		msg = regs->asc_fifo;
-#ifdef DEBUG
-		if (asc_logp == asc_log)
-			asc_log[NLOG - 1].msg = msg;
-		else
-			asc_logp[-1].msg = msg;
+#ifdef DIAGNOSTIC
+	/* This is an "assertion" :) */
+	if (asc->sc_active == 0)
+		panic("asc_dma_intr: DMA wasn't active");
 #endif
-		asc->state = ASC_STATE_BUSY;
-		asc->target = id;
-		state = &asc->st[id];
-		asc->script = state->script;
-		state->script = (script_t *)0;
-		if (!(state->flags & DISCONN))
-			goto abort;
-		state->flags &= ~DISCONN;
-		regs->asc_syn_p = state->sync_period;
-		regs->asc_syn_o = state->sync_offset;
-		regs->asc_cmd = ASC_CMD_MSG_ACPT;
-		readback(regs->asc_cmd);
-		goto done;
-	}
-
-	/* check if we are being selected as a target */
-	if (ir & (ASC_INT_SEL | ASC_INT_SEL_ATN))
-		goto abort;
 
-	/*
-	 * 'ir' must be just ASC_INT_FC.
-	 * This is normal if canceling an ASC_ENABLE_SEL.
-	 */
-
-done:
-	wbflush();
-	/*
-	 * If the next interrupt comes in immediatly the interrupt
-	 * dispatcher (which we are returning to) will catch it
-	 * before returning to the interrupted code.
-	 */
-	return(1);
+	/* DMA has stopped */
 
-abort:
-#ifdef DEBUG
-	asc_DumpLog("asc_intr");
-#endif
-	panic("asc_intr");
-	return(1);
-}
+	asc->sc_active = 0;
 
-/*
- * All the many little things that the interrupt
- * routine might switch to.
- */
+	if (asc->sc_dmasize == 0) {
+		/* A "Transfer Pad" operation complete */
+		NCR_DMA(("dmaintr: discarded %d bytes (tcl=%d, tcm=%d)\n",
+		    NCR_READ_REG(sc, NCR_TCL) |
+		    (NCR_READ_REG(sc, NCR_TCM) << 8),
+		    NCR_READ_REG(sc, NCR_TCL),
+		    NCR_READ_REG(sc, NCR_TCM)));
 
-/* ARGSUSED */
-static int
-script_nop(asc, status, ss, ir)
-	asc_softc_t asc;
-	int status, ss, ir;
-{
-	return (1);
-}
+		return 0;
+	}
 
-/* ARGSUSED */
-static int
-asc_get_status(asc, status, ss, ir)
-	register asc_softc_t asc;
-	register int status, ss, ir;
-{
-	register asc_regmap_t *regs = asc->regs;
-	register int data;
+	resid = 0;
 
 	/*
-	 * Get the last two bytes in the FIFO.
+	 * If a transfer onto the SCSI bus gets interrupted by the device
+	 * (e.g. for a SAVEPOINTER message), the data in the FIFO counts
+	 * as residual since the ESP counter registers get decremented as
+	 * bytes are clocked into the FIFO.
 	 */
-	if ((data = regs->asc_flags & ASC_FLAGS_FIFO_CNT) != 2) {
-		printf("asc_get_status: cmdreg %x, fifo cnt %d\n",
-		       regs->asc_cmd, data); /* XXX */
-#ifdef DEBUG
-		asc_DumpLog("get_status"); /* XXX */
-#endif
-		if (data < 2) {
-			asc->regs->asc_cmd = ASC_CMD_MSG_ACPT;
-			readback(asc->regs->asc_cmd);
-			return (0);
-		}
-		do {
-			data = regs->asc_fifo;
-		} while ((regs->asc_flags & ASC_FLAGS_FIFO_CNT) > 2);
+	if (!datain &&
+	    (resid = (asc_read_reg(sc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
+		NCR_DMA(("asc_dma_intr: empty asc FIFO of %d ", resid));
 	}
-
-	/* save the status byte */
-	asc->st[asc->target].statusByte = data = regs->asc_fifo;
-#ifdef DEBUG
-	if (asc_logp == asc_log)
-		asc_log[NLOG - 1].msg = data;
-	else
-		asc_logp[-1].msg = data;
-#endif
-
-	/* get the (presumed) command_complete message */
-	if ((data = regs->asc_fifo) == SCSI_COMMAND_COMPLETE)
-		return (1);
-
-#ifdef DEBUG
-	printf("asc_get_status: status %x cmd %x\n",
-		asc->st[asc->target].statusByte, data);
-	asc_DumpLog("asc_get_status");
-#endif
-	return (0);
-}
 
-/* ARGSUSED */
-static int
-asc_end(asc, status, ss, ir)
-	asc_softc_t asc;
-	int status, ss, ir;
-{
-	struct scsipi_xfer *scsicmd;
-	struct scsipi_periph *periph;
-	State *state;
-	int i, target;
-
-	asc->state = ASC_STATE_IDLE;
-	target = asc->target;
-	asc->target = -1;
-	scsicmd = asc->cmd[target];
-	periph = scsicmd->xs_periph;
-	asc->cmd[target] = (struct scsipi_xfer *)0;
-	state = &asc->st[target];
-
-#ifdef DEBUG
-	if (asc_debug > 1) {
-		printf("asc_end: %s target %d cmd %x err %d resid %d\n",
-			asc->sc_dev.dv_xname, target,
-			state->cmd.opcode, scsicmd->error, state->buflen);
+#if 0
+	if ((sc->sc_espstat & NCRSTAT_TC) == 0) {
+		/* XXX need to drain residual data in FIFO? */
 	}
 #endif
-#ifdef DIAGNOSTIC
-	if (target < 0 || !scsicmd)
-		panic("asc_end");
-#endif
 
-	/* look for disconnected devices */
-	for (i = 0; i < ASC_NCMD; i++) {
-		if (!asc->cmd[i] || !(asc->st[i].flags & DISCONN))
-			continue;
-		asc->regs->asc_cmd = ASC_CMD_ENABLE_SEL;
-		readback(asc->regs->asc_cmd);
-		asc->state = ASC_STATE_RESEL;
-		asc->script = &asc_scripts[SCRIPT_RESEL];
-		break;
-	}
+	/* halt DMA */
+	bus_space_write_4(asc->sc_iot, asc->sc_dmaioh, R4030_DMA_COUNT, 0);
+	bus_space_write_4(asc->sc_iot, asc->sc_dmaioh, R4030_DMA_ENAB, 0);
+	bus_space_write_4(asc->sc_iot, asc->sc_dmaioh, R4030_DMA_MODE, 0);
 
-	if(scsicmd->error == XS_NOERROR) {
-		if((state->statusByte & ST_MASK) == SCSI_CHECK) {
-			scsicmd->status = state->statusByte;
-			scsicmd->error = XS_BUSY;
-		}
-	}
+	bus_dmamap_sync(asc->sc_dmat, asc->sc_dmamap,
+	    0, asc->sc_dmamap->dm_mapsize,
+	    datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
+	bus_dmamap_unload(asc->sc_dmat, asc->sc_dmamap);
 
-	scsicmd->resid = state->buflen;
+	trans = asc->sc_dmasize - resid;
 
-	/*
-	 * Look for another device that is ready.
-	 * May want to keep last one started and increment for fairness
-	 * rather than always starting at zero.
-	 */
-	for (i = 0; i < ASC_NCMD; i++) {
-		/* don't restart a disconnected command */
-		if (!asc->cmd[i] || (asc->st[i].flags & DISCONN))
-			continue;
-		asc_startcmd(asc, i);
-		break;
-	}
-
-	/* signal device driver that the command is done */
-	scsipi_done(scsicmd);
-
-	return (0);
-}
-
-/* ARGSUSED */
-static int
-asc_dma_in(asc, status, ss, ir)
-	register asc_softc_t asc;
-	register int status, ss, ir;
-{
-	register asc_regmap_t *regs = asc->regs;
-	register State *state = &asc->st[asc->target];
-	register int len;
-
-	/* check for previous chunk in buffer */
-	if (state->flags & DMA_IN_PROGRESS) {
+	if (trans < 0) {		/* transfered < 0 ? */
+#if 0
 		/*
-		 * Only count bytes that have been copied to memory.
-		 * There may be some bytes in the FIFO if synchonous transfers
-		 * are in progress.
+		 * This situation can happen in perfectly normal operation
+		 * if the ESP is reselected while using DMA to select
+		 * another target.  As such, don't print the warning.
 		 */
-		DMA_END(asc->dma);
-		ASC_TC_GET(regs, len);
-		len = state->dmalen - len;
-		state->buf += len;
-		state->buflen -= len;
-	}
-
-	/* setup to start reading the next chunk */
-	len = state->buflen;
-#ifdef DEBUG
-	if (asc_logp == asc_log)
-		asc_log[NLOG - 1].resid = len;
-	else
-		asc_logp[-1].resid = len;
-#endif
-	if (len > state->dmaBufSize)
-		len = state->dmaBufSize;
-	state->dmalen = len;
-	DMA_START(asc->dma, (caddr_t)state->buf, len, DMA_FROM_DEV);
-	ASC_TC_PUT(regs, len, asc->is24bit);
-#ifdef DEBUG
-	if (asc_debug > 2)
-		printf("asc_dma_in: buflen %d, len %d\n", state->buflen, len);
-#endif
-
-	/* check for next chunk */
-	state->flags |= DMA_IN_PROGRESS;
-	if (len != state->buflen) {
-		regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
-		readback(regs->asc_cmd);
-		asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
-		return (0);
-	}
-	return (1);
-}
-
-/* ARGSUSED */
-static int
-asc_last_dma_in(asc, status, ss, ir)
-	register asc_softc_t asc;
-	register int status, ss, ir;
-{
-	register asc_regmap_t *regs = asc->regs;
-	register State *state = &asc->st[asc->target];
-	register int len, fifo;
-
-	DMA_END(asc->dma);
-	ASC_TC_GET(regs, len);
-	fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
-#ifdef DEBUG
-	if (asc_debug > 2)
-		printf("asc_last_dma_in: buflen %d dmalen %d tc %d fifo %d\n",
-			state->buflen, state->dmalen, len, fifo);
-#endif
-	if (fifo) {
-		/* device must be trying to send more than we expect */
-		regs->asc_cmd = ASC_CMD_FLUSH;
-		readback(regs->asc_cmd);
-	}
-	state->flags &= ~DMA_IN_PROGRESS;
-	len = state->dmalen - len;
-	state->buflen -= len;
-
-	return (1);
-}
-
-/* ARGSUSED */
-static int
-asc_resume_in(asc, status, ss, ir)
-	register asc_softc_t asc;
-	register int status, ss, ir;
-{
-	register asc_regmap_t *regs = asc->regs;
-	register State *state = &asc->st[asc->target];
-	register int len;
-
-	/* setup to start reading the next chunk */
-	len = state->buflen;
-#ifdef DEBUG
-	if (asc_logp == asc_log)
-		asc_log[NLOG - 1].resid = len;
-	else
-		asc_logp[-1].resid = len;
-#endif
-	if (len > state->dmaBufSize)
-		len = state->dmaBufSize;
-	state->dmalen = len;
-#ifdef DEBUG
-	if (asc_logp == asc_log)
-		asc_log[NLOG - 1].resid = len;
-	else
-		asc_logp[-1].resid = len;
-#endif
-	DMA_START(asc->dma, (caddr_t)state->buf, len, DMA_FROM_DEV);
-	ASC_TC_PUT(regs, len, asc->is24bit);
-#ifdef DEBUG
-	if (asc_debug > 2)
-		printf("asc_resume_in: buflen %d, len %d\n", state->buflen,
-			len);
-#endif
-
-	/* check for next chunk */
-	state->flags |= DMA_IN_PROGRESS;
-	if (len != state->buflen) {
-		regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
-		readback(regs->asc_cmd);
-		asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
-		return (0);
-	}
-	return (1);
-}
-
-/* ARGSUSED */
-static int
-asc_resume_dma_in(asc, status, ss, ir)
-	register asc_softc_t asc;
-	register int status, ss, ir;
-{
-	register asc_regmap_t *regs = asc->regs;
-	register State *state = &asc->st[asc->target];
-	register int len, off;
-
-	/* setup to finish reading the current chunk */
-	len = state->dmaresid;
-	off = state->dmalen - len;
-	if ((off & 1) && state->sync_offset) {
-		printf("asc_resume_dma_in: odd xfer dmalen %d len %d off %d\n",
-			state->dmalen, len, off); /* XXX */
-		regs->asc_res_fifo = ((u_char *)state->buf)[off];
-/*XXX Need to flush cache ? */
-	}
-	DMA_START(asc->dma, (caddr_t)state->buf + off, len, DMA_FROM_DEV);
-	ASC_TC_PUT(regs, len, asc->is24bit);
-#ifdef DEBUG
-	if (asc_debug > 2)
-		printf("asc_resume_dma_in: buflen %d dmalen %d len %d off %d\n",
-			state->dmalen, state->buflen, len, off);
-#endif
-
-	/* check for next chunk */
-	state->flags |= DMA_IN_PROGRESS;
-	if (state->dmalen != state->buflen) {
-		regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
-		readback(regs->asc_cmd);
-		asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
-		return (0);
-	}
-	return (1);
-}
-
-/* ARGSUSED */
-static int
-asc_dma_out(asc, status, ss, ir)
-	register asc_softc_t asc;
-	register int status, ss, ir;
-{
-	register asc_regmap_t *regs = asc->regs;
-	register State *state = &asc->st[asc->target];
-	register int len, fifo;
-
-	if (state->flags & DMA_IN_PROGRESS) {
-		/* check to be sure previous chunk was finished */
-		ASC_TC_GET(regs, len);
-		fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
-		if (len || fifo)
-			printf("asc_dma_out: buflen %d dmalen %d tc %d fifo %d\n",
-				state->buflen, state->dmalen, len, fifo); /* XXX */
-		len += fifo;
-		len = state->dmalen - len;
-		state->buf += len;
-		state->buflen -= len;
-	}
-
-	/* setup for this chunk */
-	len = state->buflen;
-#ifdef DEBUG
-	if (asc_logp == asc_log)
-		asc_log[NLOG - 1].resid = len;
-	else
-		asc_logp[-1].resid = len;
-#endif
-	if (len > state->dmaBufSize)
-		len = state->dmaBufSize;
-	state->dmalen = len;
-	DMA_START(asc->dma, (caddr_t)state->buf, len, DMA_TO_DEV);
-	ASC_TC_PUT(regs, len, asc->is24bit);
-#ifdef DEBUG
-	if (asc_debug > 2)
-		printf("asc_dma_out: buflen %d, len %d\n", state->buflen, len);
+		printf("%s: xfer (%d) > req (%d)\n",
+		    sc->sc_dev.dv_xname, trans, asc->sc_dmasize);
 #endif
-
-	/* check for next chunk */
-	state->flags |= DMA_IN_PROGRESS;
-	if (len != state->buflen) {
-		regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
-		readback(regs->asc_cmd);
-		asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
-		return (0);
+		trans = asc->sc_dmasize;
 	}
-	return (1);
-}
+	NCR_DMA(("dmaintr: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n",
+	    NCR_READ_REG(sc, NCR_TCL),
+	    NCR_READ_REG(sc, NCR_TCM),
+	    (sc->sc_cfg2 & NCRCFG2_FE) ? NCR_READ_REG(sc, NCR_TCH) : 0,
+	    trans, resid));
 
-/* ARGSUSED */
-static int
-asc_last_dma_out(asc, status, ss, ir)
-	register asc_softc_t asc;
-	register int status, ss, ir;
-{
-	register asc_regmap_t *regs = asc->regs;
-	register State *state = &asc->st[asc->target];
-	register int len, fifo;
-
-	ASC_TC_GET(regs, len);
-	fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
-#ifdef DEBUG
-	if (asc_debug > 2)
-		printf("asc_last_dma_out: buflen %d dmalen %d tc %d fifo %d\n",
-			state->buflen, state->dmalen, len, fifo);
-#endif
-	if (fifo) {
-		len += fifo;
-		regs->asc_cmd = ASC_CMD_FLUSH;
-		readback(regs->asc_cmd);
-	}
-	state->flags &= ~DMA_IN_PROGRESS;
-	len = state->dmalen - len;
-	state->buflen -= len;
-	return (1);
-}
+	*asc->sc_dmalen -= trans;
+	*asc->sc_dmaaddr += trans;
 
-/* ARGSUSED */
-static int
-asc_resume_out(asc, status, ss, ir)
-	register asc_softc_t asc;
-	register int status, ss, ir;
-{
-	register asc_regmap_t *regs = asc->regs;
-	register State *state = &asc->st[asc->target];
-	register int len;
-
-	/* setup for this chunk */
-	len = state->buflen;
-#ifdef DEBUG
-	if (asc_logp == asc_log)
-		asc_log[NLOG - 1].resid = len;
-	else
-		asc_logp[-1].resid = len;
-#endif
-	if (len > state->dmaBufSize)
-		len = state->dmaBufSize;
-	state->dmalen = len;
-#ifdef DEBUG
- 	if (asc_logp == asc_log)
-		asc_log[NLOG - 1].resid = len;
-	else
-		asc_logp[-1].resid = len;
-#endif
-	DMA_START(asc->dma, (caddr_t)state->buf, len, DMA_TO_DEV);
-	ASC_TC_PUT(regs, len, asc->is24bit);
-#ifdef DEBUG
-	if (asc_debug > 2)
-		printf("asc_resume_out: buflen %d, len %d\n", state->buflen,
-			len);
-#endif
-
-	/* check for next chunk */
-	state->flags |= DMA_IN_PROGRESS;
-	if (len != state->buflen) {
-		regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
-		readback(regs->asc_cmd);
-		asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
-		return (0);
-	}
-	return (1);
+	return 0;
 }
 
-/* ARGSUSED */
-static int
-asc_resume_dma_out(asc, status, ss, ir)
-	register asc_softc_t asc;
-	register int status, ss, ir;
-{
-	register asc_regmap_t *regs = asc->regs;
-	register State *state = &asc->st[asc->target];
-	register int len, off;
-
-	/* setup to finish writing this chunk */
-	len = state->dmaresid;
-	off = state->dmalen - len;
-	if (off & 1) {
-		printf("asc_resume_dma_out: odd xfer dmalen %d len %d off %d\n",
-			state->dmalen, len, off); /* XXX */
-		regs->asc_fifo = ((u_char *)state->buf)[off];
-/*XXX Need to flush Cache ? */
-		off++;
-		len--;
-	}
-	DMA_START(asc->dma, (caddr_t)state->buf + off, len, DMA_TO_DEV);
-	ASC_TC_PUT(regs, len, asc->is24bit);
-#ifdef DEBUG
-	if (asc_debug > 2)
-		printf("asc_resume_dma_out: buflen %d dmalen %d len %d off %d\n",
-			state->dmalen, state->buflen, len, off);
-#endif
+int
+asc_dma_setup(sc, addr, len, datain, dmasize)
+	struct ncr53c9x_softc *sc;
+	caddr_t *addr;
+	size_t *len;
+	int datain;
+	size_t *dmasize;
+{
+	struct asc_softc *asc = (struct asc_softc *)sc;
+
+	/* halt DMA */
+	bus_space_write_4(asc->sc_iot, asc->sc_dmaioh, R4030_DMA_ENAB, 0);
+	bus_space_write_4(asc->sc_iot, asc->sc_dmaioh, R4030_DMA_MODE, 0);
+
+	asc->sc_dmaaddr = addr;
+	asc->sc_dmalen = len;
+	asc->sc_dmasize = *dmasize;
+	asc->sc_datain = datain;
+
+	/*
+	 * No need to set up DMA in `Transfer Pad' operation.
+	 */
+	if (*dmasize == 0)
+		return 0;
+
+	bus_dmamap_load(asc->sc_dmat, asc->sc_dmamap, *addr, *len, NULL,
+	    ((sc->sc_nexus->xs->xs_control & XS_CTL_NOSLEEP) ?
+	    BUS_DMA_NOWAIT : BUS_DMA_WAITOK) | BUS_DMA_STREAMING |
+	    (datain ? BUS_DMA_READ : BUS_DMA_WRITE));
+	bus_dmamap_sync(asc->sc_dmat, asc->sc_dmamap,
+	    0, asc->sc_dmamap->dm_mapsize,
+	    datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
 
-	/* check for next chunk */
-	state->flags |= DMA_IN_PROGRESS;
-	if (state->dmalen != state->buflen) {
-		regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
-		readback(regs->asc_cmd);
-		asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
-		return (0);
-	}
-	return (1);
+	return 0;
 }
 
-/* ARGSUSED */
-static int
-asc_sendsync(asc, status, ss, ir)
-	register asc_softc_t asc;
-	register int status, ss, ir;
+void
+asc_dma_go(sc)
+	struct ncr53c9x_softc *sc;
 {
-	register asc_regmap_t *regs = asc->regs;
-	register State *state = &asc->st[asc->target];
+	struct asc_softc *asc = (struct asc_softc *)sc;
 
-	/* send the extended synchronous negotiation message */
-	regs->asc_fifo = SCSI_EXTENDED_MSG;
-	wbflush();
-	regs->asc_fifo = 3;
-	wbflush();
-	regs->asc_fifo = SCSI_SYNCHRONOUS_XFER;
-	wbflush();
-	regs->asc_fifo = SCSI_MIN_PERIOD;
-	wbflush();
-	regs->asc_fifo = ASC_MAX_OFFSET;
-	/* state to resume after we see the sync reply message */
-	state->script = asc->script + 2;
-	state->msglen = 0;
-	return (1);
-}
+	/* No DMA transfer in Transfer Pad operation */
+	if (asc->sc_dmasize == 0)
+		return;
 
-/* ARGSUSED */
-static int
-asc_replysync(asc, status, ss, ir)
-	register asc_softc_t asc;
-	register int status, ss, ir;
-{
-	register asc_regmap_t *regs = asc->regs;
-	register State *state = &asc->st[asc->target];
+	/* load transfer parameters */
+	bus_space_write_4(asc->sc_iot, asc->sc_dmaioh,
+	    R4030_DMA_ADDR, asc->sc_dmamap->dm_segs[0].ds_addr);
+	bus_space_write_4(asc->sc_iot, asc->sc_dmaioh,
+	    R4030_DMA_COUNT, asc->sc_dmamap->dm_segs[0].ds_len);
+	bus_space_write_4(asc->sc_iot, asc->sc_dmaioh,
+	    R4030_DMA_MODE, R4030_DMA_MODE_160NS | R4030_DMA_MODE_16);
+
+	/* start DMA */
+	bus_space_write_4(asc->sc_iot, asc->sc_dmaioh,
+	    R4030_DMA_ENAB, R4030_DMA_ENAB_RUN |
+	    (asc->sc_datain ? R4030_DMA_ENAB_READ : R4030_DMA_ENAB_WRITE));
 
-#ifdef DEBUG
-	if (asc_debug > 2)
-		printf("asc_replysync: %x %x\n",
-			asc_to_scsi_period[state->sync_period] * asc->tb_ticks,
-			state->sync_offset);
-#endif
-	/* send synchronous transfer in response to a request */
-	regs->asc_fifo = SCSI_EXTENDED_MSG;
-	wbflush();
-	regs->asc_fifo = 3;
-	wbflush();
-	regs->asc_fifo = SCSI_SYNCHRONOUS_XFER;
-	wbflush();
-	regs->asc_fifo = asc_to_scsi_period[state->sync_period] * asc->tb_ticks;
-	wbflush();
-	regs->asc_fifo = state->sync_offset;
-	regs->asc_cmd = ASC_CMD_XFER_INFO;
-	readback(regs->asc_cmd);
-
-	/* return to the appropriate script */
-	if (!state->script) {
-#ifdef DEBUG
-		asc_DumpLog("asc_replsync");
-#endif
-		panic("asc_replysync");
-	}
-	asc->script = state->script;
-	state->script = (script_t *)0;
-	return (0);
+	asc->sc_active = 1;
 }
 
-/* ARGSUSED */
-static int
-asc_msg_in(asc, status, ss, ir)
-	register asc_softc_t asc;
-	register int status, ss, ir;
+void
+asc_dma_stop(sc)
+	struct ncr53c9x_softc *sc;
 {
-	register asc_regmap_t *regs = asc->regs;
-	register State *state = &asc->st[asc->target];
-	register int msg;
-	int i;
-
-	/* read one message byte */
-	msg = regs->asc_fifo;
-#ifdef DEBUG
-	if (asc_logp == asc_log)
-		asc_log[NLOG - 1].msg = msg;
-	else
-		asc_logp[-1].msg = msg;
-#endif
-
-	/* check for multi-byte message */
-	if (state->msglen != 0) {
-		/* first byte is the message length */
-		if (state->msglen < 0) {
-			state->msglen = msg;
-			return (1);
-		}
-		if (state->msgcnt >= state->msglen)
-			goto abort;
-		state->msg_in[state->msgcnt++] = msg;
-
-		/* did we just read the last byte of the message? */
-		if (state->msgcnt != state->msglen)
-			return (1);
-
-		/* process an extended message */
-#ifdef DEBUG
-		if (asc_debug > 2)
-			printf("asc_msg_in: msg %x %x %x\n",
-				state->msg_in[0],
-				state->msg_in[1],
-				state->msg_in[2]);
-#endif
-		switch (state->msg_in[0]) {
-		case SCSI_SYNCHRONOUS_XFER:
-			state->flags |= DID_SYNC;
-			state->sync_offset = state->msg_in[2];
-
-			/* convert SCSI period to ASC period */
-			i = state->msg_in[1] / asc->tb_ticks;
-			if (i < asc->min_period)
-				i = asc->min_period;
-			else if (i >= asc->max_period) {
-				/* can't do sync transfer, period too long */
-				printf("%s: SCSI device %d: sync xfer period too long (%d)\n",
-					asc->sc_dev.dv_xname, asc->target, i);
-				i = asc->max_period;
-				state->sync_offset = 0;
-			}
-			if ((i * asc->tb_ticks) != state->msg_in[1])
-				i++;
-			state->sync_period = i & 0x1F;
-
-			/*
-			 * If this is a request, check minimums and
-			 * send back an acknowledge.
-			 */
-			if (!(state->flags & TRY_SYNC)) {
-				regs->asc_cmd = ASC_CMD_SET_ATN;
-				readback(regs->asc_cmd);
-
-				if (state->sync_period < asc->min_period)
-					state->sync_period =
-						asc->min_period;
-				if (state->sync_offset > ASC_MAX_OFFSET)
-					state->sync_offset =
-						ASC_MAX_OFFSET;
-				asc->script = &asc_scripts[SCRIPT_REPLY_SYNC];
-				regs->asc_syn_p = state->sync_period;
-				readback(regs->asc_syn_p);
-				regs->asc_syn_o = state->sync_offset;
-				readback(regs->asc_syn_o);
-				regs->asc_cmd = ASC_CMD_MSG_ACPT;
-				readback(regs->asc_cmd);
-				return (0);
-			}
-
-			regs->asc_syn_p = state->sync_period;
-			readback(regs->asc_syn_p);
-			regs->asc_syn_o = state->sync_offset;
-			readback(regs->asc_syn_o);
-			goto done;
-
-		default:
-			printf("%s: SCSI device %d: rejecting extended message 0x%x\n",
-				 asc->sc_dev.dv_xname, asc->target,
-				state->msg_in[0]);
-			goto reject;
-		}
-	}
-
-	/* process first byte of a message */
-#ifdef DEBUG
-	if (asc_debug > 2)
-		printf("asc_msg_in: msg %x\n", msg);
-#endif
-	switch (msg) {
-#if 0
-	case SCSI_MESSAGE_REJECT:
-		printf(" did not like SYNCH xfer "); /* XXX */
-		state->flags |= DID_SYNC;
-		regs->asc_cmd = ASC_CMD_MSG_ACPT;
-		readback(regs->asc_cmd);
-		status = asc_wait(regs, ASC_CSR_INT);
-		ir = regs->asc_intr;
-		/* some just break out here, some dont */
-		if (ASC_PHASE(status) == ASC_PHASE_MSG_OUT) {
-			regs->asc_fifo = SCSI_ABORT;
-			regs->asc_cmd = ASC_CMD_XFER_INFO;
-			readback(regs->asc_cmd);
-			status = asc_wait(regs, ASC_CSR_INT);
-			ir = regs->asc_intr;
-		}
-		if (ir & ASC_INT_DISC) {
-			asc_end(asc, status, 0, ir);
-			return (0);
-		}
-		goto status;
-#endif /* 0 */
-
-	case SCSI_EXTENDED_MSG: /* read an extended message */
-		/* setup to read message length next */
-		state->msglen = -1;
-		state->msgcnt = 0;
-		return (1);
-
-	case SCSI_NO_OP:
-		break;
-
-	case SCSI_SAVE_DATA_POINTER:
-		/* expect another message */
-		return (1);
-
-	case SCSI_RESTORE_POINTERS:
-		/*
-		 * Need to do the following if resuming synchonous data in
-		 * on an odd byte boundary.
-		regs->asc_cnfg2 |= ASC_CNFG2_RFB;
-		 */
-		break;
+	struct asc_softc *asc = (struct asc_softc *)sc;
 
-	case SCSI_DISCONNECT:
-		if (state->flags & DISCONN)
-			goto abort;
-		state->flags |= DISCONN;
-		regs->asc_cmd = ASC_CMD_MSG_ACPT;
-		readback(regs->asc_cmd);
-		asc->script = &asc_scripts[SCRIPT_DISCONNECT];
-		return (0);
-
-	default:
-		printf("%s: SCSI device %d: rejecting message 0x%x\n",
-			asc->sc_dev.dv_xname, asc->target, msg);
-	reject:
-		/* request a message out before acknowledging this message */
-		state->msg_out = SCSI_MESSAGE_REJECT;
-		regs->asc_cmd = ASC_CMD_SET_ATN;
-		readback(regs->asc_cmd);
-	}
+	/* halt DMA */
+	bus_space_write_4(asc->sc_iot, asc->sc_dmaioh, R4030_DMA_ENAB, 0);
+	bus_space_write_4(asc->sc_iot, asc->sc_dmaioh, R4030_DMA_MODE, 0);
 
-done:
-	/* return to original script */
-	regs->asc_cmd = ASC_CMD_MSG_ACPT;
-	readback(regs->asc_cmd);
-	if (!state->script) {
-	abort:
-#ifdef DEBUG
-		asc_DumpLog("asc_msg_in");
-#endif
-		panic("asc_msg_in");
-	}
-	asc->script = state->script;
-	state->script = (script_t *)0;
-	return (0);
+	asc->sc_active = 0;
 }
 
-/* ARGSUSED */
-static int
-asc_disconnect(asc, status, ss, ir)
-	asc_softc_t asc;
-	int status, ss, ir;
-{
-#ifdef DIAGNOSTIC
-	if (!(asc->st[asc->target].flags & DISCONN)) {
-		printf("asc_disconnect: device %d: DISCONN not set!\n",
-			asc->target);
-	}
-#endif /* DIAGNOSTIC */
-	asc->target = -1;
-	asc->state = ASC_STATE_RESEL;
-	return (1);
-}
-
-#ifdef DEBUG
-/*
- * Dump the log buffer.
- */
-static void
-asc_DumpLog(str)
-	char *str;
+int
+asc_dma_isactive(sc)
+	struct ncr53c9x_softc *sc;
 {
-	register struct asc_log *lp;
-	register u_int status;
+	struct asc_softc *asc = (struct asc_softc *)sc;
 
-	printf("asc: %s: cmd %x bn %d cnt %d\n", str, asc_debug_cmd,
-		asc_debug_bn, asc_debug_sz);
-	lp = asc_logp;
-	do {
-		status = lp->status;
-		printf("asc%d tgt %d status %x ss %x ir %x cond %d:%x msg %x resid %d\n",
-			status >> 24,
-			lp->target,
-			(status >> 16) & 0xFF,
-			(status >> 8) & 0xFF,
-			status & 0XFF,
-			lp->state,
-			asc_scripts[lp->state].condition,
-			lp->msg, lp->resid);
-		if (++lp >= &asc_log[NLOG])
-			lp = asc_log;
-	} while (lp != asc_logp);
+	return asc->sc_active;
 }
-#endif	/* DEBUG */
Index: jazz/bus_dma_jazz.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/jazz/bus_dma_jazz.c,v
retrieving revision 1.4
diff -u -r1.4 bus_dma_jazz.c
--- jazz/bus_dma_jazz.c	2001/11/14 18:15:15	1.4
+++ jazz/bus_dma_jazz.c	2003/01/08 17:03:08
@@ -39,11 +39,19 @@
 #include <arc/jazz/jazzdmatlbreg.h>
 #include <arc/jazz/jazzdmatlbvar.h>
 
+typedef struct jazz_tlbmap {
+	struct jazz_dma_pte *ptebase;
+	bus_addr_t vaddr;
+} *jazz_tlbmap_t;
+
 static int	jazz_bus_dmamap_alloc_sgmap __P((bus_dma_tag_t,
 		    bus_dma_segment_t *, int, bus_size_t, struct proc *, int));
 static void	jazz_bus_dmamap_free_sgmap __P((bus_dma_tag_t,
 		    bus_dma_segment_t *, int));
 
+int	jazz_bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int,
+	    bus_size_t, bus_size_t, int, bus_dmamap_t *));
+void	jazz_bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
 int	jazz_bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
 	    bus_size_t, struct proc *, int));
 int	jazz_bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t,
@@ -62,6 +70,8 @@
 {
 	_bus_dma_tag_init(t);
 
+	t->_dmamap_create = jazz_bus_dmamap_create;
+	t->_dmamap_destroy = jazz_bus_dmamap_destroy;
 	t->_dmamap_load = jazz_bus_dmamap_load;
 	t->_dmamap_load_mbuf = jazz_bus_dmamap_load_mbuf;
 	t->_dmamap_load_uio = jazz_bus_dmamap_load_uio;
@@ -117,6 +127,83 @@
 	}
 }
 
+
+/*
+ * function to create a DMA map. If BUS_DMA_ALLOCNOW is specified and
+ * nsegments is 1, allocate jazzdmatlb here, too.
+ */
+int
+jazz_bus_dmamap_create(t, size, nsegments, maxsegsz, boundary, flags, dmamp)
+	bus_dma_tag_t t;
+	bus_size_t size;
+	int nsegments;
+	bus_size_t maxsegsz;
+	bus_size_t boundary;
+	int flags;
+	bus_dmamap_t *dmamp;
+{
+	struct arc_bus_dmamap *map;
+	jazz_tlbmap_t tlbmap;
+	int error, npte;
+
+	if ((flags & BUS_DMA_ALLOCNOW) == 0)
+		return (_bus_dmamap_create(t, size, nsegments, maxsegsz,
+		    boundary, flags, dmamp));
+
+	if (nsegments > 1)
+		/* BUS_DMA_ALLOCNOW is allowd only with one segment for now. */
+		return (ENOMEM);
+
+	tlbmap = malloc(sizeof(struct jazz_tlbmap), M_DMAMAP,
+	    (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK);
+	if (tlbmap == NULL)
+		return (ENOMEM);
+
+	npte = jazz_dma_page_round(maxsegsz) / JAZZ_DMA_PAGE_SIZE + 1; 
+	tlbmap->ptebase =
+	    jazz_dmatlb_alloc(npte, boundary, flags, &tlbmap->vaddr);
+	if (tlbmap->ptebase == NULL) {
+		free(tlbmap, M_DMAMAP);
+		return (ENOMEM);
+	}
+
+	error = _bus_dmamap_create(t, size, nsegments, maxsegsz, boundary,
+	    flags, dmamp);
+	if (error != 0) {
+		jazz_dmatlb_free(tlbmap->vaddr, npte);
+		free(tlbmap, M_DMAMAP);
+		return (error);
+	}
+	map = *dmamp;
+	map->_dm_cookie = (void *)tlbmap;
+
+	return (0);
+}
+
+/*
+ * function to destroy a DMA map. If BUS_DMA_ALLOCNOW is specified,
+ * free jazzdmatlb, too.
+ */
+void
+jazz_bus_dmamap_destroy(t, map)
+	bus_dma_tag_t t;
+	bus_dmamap_t map;
+{
+
+	if ((map->_dm_flags & BUS_DMA_ALLOCNOW) != 0) {
+		jazz_tlbmap_t tlbmap;
+		int npte;
+
+		tlbmap = (jazz_tlbmap_t)map->_dm_cookie;
+		npte = jazz_dma_page_round(map->_dm_maxsegsz) /
+		    JAZZ_DMA_PAGE_SIZE + 1;
+		jazz_dmatlb_free(tlbmap->vaddr, npte);
+		free(tlbmap, M_DMAMAP);
+	}
+
+	_bus_dmamap_destroy(t, map);
+}
+
 /*
  * function for loading a direct-mapped DMA map with a linear buffer.
  */
@@ -129,8 +216,26 @@
 	struct proc *p;
 	int flags;
 {
-	int error = _bus_dmamap_load(t, map, buf, buflen, p, flags);
+	int error;
+
+	if ((map->_dm_flags & BUS_DMA_ALLOCNOW) != 0) {
+		jazz_tlbmap_t tlbmap;
+		bus_size_t off;
+
+		tlbmap = (jazz_tlbmap_t)map->_dm_cookie;
+		off = jazz_dma_page_offs(buf);
+		jazz_dmatlb_map_va(p, (vaddr_t)buf, buflen, tlbmap->ptebase);
+
+		map->dm_segs[0].ds_addr = tlbmap->vaddr + off;
+		map->dm_segs[0].ds_len = buflen;
+		map->dm_segs[0]._ds_vaddr = (vaddr_t)buf;
+		map->dm_mapsize = buflen;
+		map->dm_nsegs = 1;
 
+		return (0);
+	}
+
+	error = _bus_dmamap_load(t, map, buf, buflen, p, flags);
 	if (error == 0) {
 		error = jazz_bus_dmamap_alloc_sgmap(t, map->dm_segs,
 		    map->dm_nsegs, map->_dm_boundary, p, flags);
@@ -148,8 +253,12 @@
 	struct mbuf *m0;
 	int flags;
 {
-	int error = _bus_dmamap_load_mbuf(t, map, m0, flags);
+	int error;
+
+	if ((map->_dm_flags & BUS_DMA_ALLOCNOW) != 0)
+		return (ENODEV); /* XXX which errno is better? */
 
+	error = _bus_dmamap_load_mbuf(t, map, m0, flags);
 	if (error == 0) {
 		error = jazz_bus_dmamap_alloc_sgmap(t, map->dm_segs,
 		    map->dm_nsegs, map->_dm_boundary, NULL, flags);
@@ -167,8 +276,12 @@
 	struct uio *uio;
 	int flags;
 {
-	int error = jazz_bus_dmamap_load_uio(t, map, uio, flags);
+	int error;
 
+	if ((map->_dm_flags & BUS_DMA_ALLOCNOW) != 0)
+		return (ENODEV); /* XXX which errno is better? */
+
+	error = jazz_bus_dmamap_load_uio(t, map, uio, flags);
 	if (error == 0) {
 		error = jazz_bus_dmamap_alloc_sgmap(t, map->dm_segs,
 		    map->dm_nsegs, map->_dm_boundary,
@@ -190,8 +303,12 @@
 	bus_size_t size;
 	int flags;
 {
-	int error = _bus_dmamap_load_raw(t, map, segs, nsegs, size, flags);
+	int error;
+
+	if ((map->_dm_flags & BUS_DMA_ALLOCNOW) != 0)
+		return (ENODEV); /* XXX which errno is better? */
 
+	error = _bus_dmamap_load_raw(t, map, segs, nsegs, size, flags);
 	if (error == 0) {
 		error = jazz_bus_dmamap_alloc_sgmap(t, map->dm_segs,
 		    map->dm_nsegs, map->_dm_boundary, NULL, flags);
@@ -207,6 +324,13 @@
 	bus_dma_tag_t t;
 	bus_dmamap_t map;
 {
+	if ((map->_dm_flags & BUS_DMA_ALLOCNOW) != 0) {
+		map->dm_mapsize = 0;
+		map->dm_nsegs = 0;
+		map->_dm_flags &= ~BUS_DMA_ALLOCNOW;
+		return;
+	}
+
 	jazz_bus_dmamap_free_sgmap(t, map->dm_segs, map->dm_nsegs);
 	_bus_dmamap_unload(t, map);
 }
Index: jazz/dma.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/jazz/dma.h,v
retrieving revision 1.2
diff -u -r1.2 dma.h
--- jazz/dma.h	2001/07/24 16:26:53	1.2
+++ jazz/dma.h	2003/01/08 17:03:08
@@ -34,83 +34,34 @@
 /*
  *  Hardware dma registers.
  */
-typedef volatile struct {
-	int32_t		dma_mode;
-	int32_t		pad1;
-	int32_t		dma_enab;
-	int32_t		pad2;
-	int32_t		dma_count;
-	int32_t		pad3;
-	int32_t		dma_addr;
-	int32_t		pad4;
-} DmaReg, *pDmaReg;
 
-#define	R4030_DMA_MODE_40NS	0x00	/* Device dma timing */
-#define	R4030_DMA_MODE_80NS	0x01	/* Device dma timing */
-#define	R4030_DMA_MODE_120NS	0x02	/* Device dma timing */
-#define	R4030_DMA_MODE_160NS	0x03	/* Device dma timing */
-#define	R4030_DMA_MODE_200NS	0x04	/* Device dma timing */
-#define	R4030_DMA_MODE_240NS	0x05	/* Device dma timing */
-#define	R4030_DMA_MODE_280NS	0x06	/* Device dma timing */
-#define	R4030_DMA_MODE_320NS	0x07	/* Device dma timing */
-#define	R4030_DMA_MODE_8		0x08	/* Device 8 bit  */
-#define	R4030_DMA_MODE_16	0x10	/* Device 16 bit */
-#define	R4030_DMA_MODE_32	0x18	/* Device 32 bit */
-#define	R4030_DMA_MODE_INT	0x20	/* Interrupt when done */
-#define	R4030_DMA_MODE_BURST	0x40	/* Burst mode (Rev 2 only) */
-#define R4030_DMA_MODE_FAST	0x80	/* Fast dma cycle (Rev 2 only) */
-#define R4030_DMA_MODE		0xff	/* Mode register bits */
-#define DMA_DIR_WRITE		0x100	/* Software direction status */
-#define DMA_DIR_READ		0x000	/* Software direction status */
+#define R4030_DMA_MODE		0x00
+#define  R4030_DMA_MODE_40NS	0x00	/* Device dma timing */
+#define  R4030_DMA_MODE_80NS	0x01	/* Device dma timing */
+#define  R4030_DMA_MODE_120NS	0x02	/* Device dma timing */
+#define  R4030_DMA_MODE_160NS	0x03	/* Device dma timing */
+#define  R4030_DMA_MODE_200NS	0x04	/* Device dma timing */
+#define  R4030_DMA_MODE_240NS	0x05	/* Device dma timing */
+#define  R4030_DMA_MODE_280NS	0x06	/* Device dma timing */
+#define  R4030_DMA_MODE_320NS	0x07	/* Device dma timing */
+#define  R4030_DMA_MODE_8	0x08	/* Device 8 bit  */
+#define  R4030_DMA_MODE_16	0x10	/* Device 16 bit */
+#define  R4030_DMA_MODE_32	0x18	/* Device 32 bit */
+#define  R4030_DMA_MODE_INT	0x20	/* Interrupt when done */
+#define  R4030_DMA_MODE_BURST	0x40	/* Burst mode (Rev 2 only) */
+#define  R4030_DMA_MODE_FAST	0x80	/* Fast dma cycle (Rev 2 only) */
+
+#define R4030_DMA_ENAB		0x08
+#define  R4030_DMA_ENAB_RUN	0x0001	/* Enable dma */
+#define  R4030_DMA_ENAB_READ	0x0000	/* Read from device */
+#define  R4030_DMA_ENAB_WRITE	0x0002	/* Write to device */
+#define  R4030_DMA_ENAB_TC_IE	0x0100	/* Terminal count int enable */
+#define  R4030_DMA_ENAB_ME_IE	0x0200	/* Memory error int enable */
+#define  R4030_DMA_ENAB_TL_IE	0x0400	/* Translation limit int enable */
 
-#define	R4030_DMA_ENAB_RUN	0x01	/* Enable dma */
-#define	R4030_DMA_ENAB_READ	0x00	/* Read from device */
-#define	R4030_DMA_ENAB_WRITE	0x02	/* Write to device */
-#define	R4030_DMA_ENAB_TC_IE	0x100	/* Terminal count int enable */
-#define	R4030_DMA_ENAB_ME_IE	0x200	/* Memory error int enable */
-#define	R4030_DMA_ENAB_TL_IE	0x400	/* Translation limit int enable */
+#define R4030_DMA_COUNT	0x10
+#define  R4030_DMA_COUNT_MASK	0x000fffff /* Byte count mask */
 
-#define	R4030_DMA_COUNT_MASK	0x000fffff /* Byte count mask */
+#define	R4030_DMA_ADDR	0x18
 
-/*
- *  Structure used to control dma.
- */
-
-typedef struct dma_softc {
-	struct device	sc_dev;		/* use as a device */
-	struct esp_softc *sc_esp;
-	bus_addr_t	dma_va;		/* Viritual address for transfer */
-	int		mode;		/* Mode register value and direction */
-	jazz_dma_pte_t	*pte_base;	/* Pointer to dma tlb array */
-	int		pte_size;	/* Size of pte allocated pte array */
-	pDmaReg		dma_reg;	/* Pointer to dma registers */
-	int		sc_active;	/* Active flag */
-	void (*reset)(struct dma_softc *);	/* Reset routine pointer */
-	void (*enintr)(struct dma_softc *);	/* Int enab routine pointer */
-	void (*map)(struct dma_softc *, char *, size_t, int);
-						/* Map a dma viritual area */
-	void (*start)(struct dma_softc *, caddr_t, size_t, int);
-						/* Start routine pointer */
-	int (*isintr)(struct dma_softc *);	/* Int check routine pointer */
-	int (*intr)(struct dma_softc *);	/* Interrupt routine pointer */
-	void (*end)(struct dma_softc *);	/* Interrupt routine pointer */
-} dma_softc_t;
-
-#define	DMA_TO_DEV	0
-#define	DMA_FROM_DEV	1
-
-#define	DMA_RESET(r)		((r->reset)(r))
-#define	DMA_START(a, b, c, d)	((a->start)(a, b, c, d))
-#define	DMA_MAP(a, b, c, d)	((a->map)(a, b, c, d))
-#define	DMA_INTR(r)		((r->intr)(r))
-#define	DMA_DRAIN(r)
-#define	DMA_END(r)		((r->end)(r))
-
-void picaDmaInit __P((void));
-void picaDmaTLBAlloc __P((dma_softc_t *));
-void picaDmaTLBFree __P((dma_softc_t *));
-void picaDmaMap __P((struct dma_softc *, char *, size_t, int));
-void picaDmaStart __P((struct dma_softc *, char *, size_t, int));
-void picaDmaFlush __P((struct dma_softc *, char *, size_t, int));
-void asc_dma_init __P((struct dma_softc *));
-void fdc_dma_init __P((struct dma_softc *));
+#define	R4030_DMA_RANGE	0x20
Index: jazz/fdc_jazzio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/jazz/fdc_jazzio.c,v
retrieving revision 1.5
diff -u -r1.5 fdc_jazzio.c
--- jazz/fdc_jazzio.c	2002/12/28 16:25:39	1.5
+++ jazz/fdc_jazzio.c	2003/01/08 17:03:09
@@ -80,23 +80,15 @@
 #include <sys/systm.h>
 #include <sys/callout.h>
 #include <sys/device.h>
-#include <sys/buf.h>
-#include <sys/queue.h>
 
-#include <mips/cache.h>
-
 #include <machine/autoconf.h>
 #include <machine/bus.h>
-#include <machine/cpu.h>
 
-#include <arc/jazz/jazzdmatlbreg.h>
 #include <arc/jazz/fdreg.h>
 #include <arc/jazz/fdcvar.h>
 #include <arc/jazz/jazziovar.h>
 #include <arc/jazz/dma.h>
 
-#include "locators.h"
-
 /* controller driver configuration */
 int fdc_jazzio_probe(struct device *, struct cfdata *, void *);
 void fdc_jazzio_attach(struct device *, struct device *, void *);
@@ -111,8 +103,11 @@
 	struct fdc_softc sc_fdc;	/* base fdc device */
 
 	bus_space_handle_t sc_baseioh;	/* base I/O handle */
-	struct dma_softc __dma;
-	struct dma_softc *dma;
+
+	bus_dma_tag_t sc_dmat;		/* bus dma tag */
+	bus_dmamap_t sc_dmamap;		/* bus dma map */
+	bus_space_handle_t sc_dmaioh;	/* dma I/O handle */
+	int sc_datain;			/* data direction */
 };
 
 CFATTACH_DECL(fdc_jazzio, sizeof(struct fdc_jazzio_softc),
@@ -175,13 +170,12 @@
 
 	fdc->sc_iot = ja->ja_bust;
 
-	fdc->sc_maxiosize = 4096; /* XXX */
+	fdc->sc_maxiosize = MAXPHYS;
 	fdc->sc_dma_start = fdc_jazzio_dma_start;
 	fdc->sc_dma_abort = fdc_jazzio_dma_abort;
 	fdc->sc_dma_done = fdc_jazzio_dma_done;
 
-	jsc->dma = &jsc->__dma;
-	fdc_dma_init(jsc->dma);
+	jsc->sc_dmat = ja->ja_dmat;
 
 	if (bus_space_map(fdc->sc_iot, ja->ja_addr,
 	    FDC_OFFSET + FDC_NPORT, 0, &jsc->sc_baseioh)) {
@@ -192,16 +186,32 @@
 	if (bus_space_subregion(fdc->sc_iot, jsc->sc_baseioh,
 	    FDC_OFFSET, FDC_NPORT, &fdc->sc_ioh)) {
 		printf(": unable to subregion I/O space\n");
-		bus_space_unmap(fdc->sc_iot, jsc->sc_baseioh,
-		    FDC_OFFSET + FDC_NPORT);
-		return;
+		goto out_unmap1;
 	}
 
+	if (bus_space_map(fdc->sc_iot, jazzio_conf->jc_fdcdmareg,
+	    R4030_DMA_RANGE, 0, &jsc->sc_dmaioh)) {
+		printf(": unable to map dma I/O space\n");
+		goto out_unmap1;
+	}
+
+	if (bus_dmamap_create(jsc->sc_dmat, MAXPHYS, 1, MAXPHYS, 0,
+	    BUS_DMA_ALLOCNOW|BUS_DMA_NOWAIT, &jsc->sc_dmamap)) {
+		printf(": unable to create DMA map\n");
+		goto out_unmap2;
+	}
+
 	printf("\n");
 
 	jazzio_intr_establish(ja->ja_intr, fdcintr, fdc);
 
 	fdcattach(fdc);
+	return;
+
+ out_unmap2:
+	bus_space_unmap(fdc->sc_iot, jsc->sc_dmaioh, R4030_DMA_RANGE);
+ out_unmap1:
+	bus_space_unmap(fdc->sc_iot, jsc->sc_baseioh, FDC_OFFSET + FDC_NPORT);
 }
 
 void
@@ -213,8 +223,31 @@
 {
 	struct fdc_jazzio_softc *jsc = (void *)fdc;
 
-	mips_dcache_wbinv_range((vaddr_t)addr, (vsize_t)size);
-	DMA_START(jsc->dma, addr, size, datain ? DMA_FROM_DEV : DMA_TO_DEV);
+	/* halt DMA */
+	bus_space_write_4(fdc->sc_iot, jsc->sc_dmaioh, R4030_DMA_ENAB, 0);
+	bus_space_write_4(fdc->sc_iot, jsc->sc_dmaioh, R4030_DMA_MODE, 0);
+
+	jsc->sc_datain = datain;
+
+	bus_dmamap_load(jsc->sc_dmat, jsc->sc_dmamap, addr, size, NULL,
+	    BUS_DMA_NOWAIT | BUS_DMA_STREAMING |
+	    (datain ? BUS_DMA_READ : BUS_DMA_WRITE));
+	bus_dmamap_sync(jsc->sc_dmat, jsc->sc_dmamap,
+	    0, jsc->sc_dmamap->dm_mapsize,
+	    datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
+	/* load new transfer parameters */
+	bus_space_write_4(fdc->sc_iot, jsc->sc_dmaioh,
+	    R4030_DMA_ADDR, jsc->sc_dmamap->dm_segs[0].ds_addr);
+	bus_space_write_4(fdc->sc_iot, jsc->sc_dmaioh,
+	    R4030_DMA_COUNT, jsc->sc_dmamap->dm_segs[0].ds_len);
+	bus_space_write_4(fdc->sc_iot, jsc->sc_dmaioh,
+	    R4030_DMA_MODE, R4030_DMA_MODE_160NS | R4030_DMA_MODE_8);
+
+	/* start DMA */
+	bus_space_write_4(fdc->sc_iot, jsc->sc_dmaioh,
+	    R4030_DMA_ENAB, R4030_DMA_ENAB_RUN |
+	    (datain ? R4030_DMA_ENAB_READ : R4030_DMA_ENAB_WRITE));
 }
 
 void
@@ -223,7 +256,9 @@
 {
 	struct fdc_jazzio_softc *jsc = (void *)fdc;
 
-	DMA_RESET(jsc->dma);
+	/* halt DMA */
+	bus_space_write_4(fdc->sc_iot, jsc->sc_dmaioh, R4030_DMA_ENAB, 0);
+	bus_space_write_4(fdc->sc_iot, jsc->sc_dmaioh, R4030_DMA_MODE, 0);
 }
 
 void
@@ -232,5 +267,13 @@
 {
 	struct fdc_jazzio_softc *jsc = (void *)fdc;
 
-	DMA_END(jsc->dma);
+	/* halt DMA */
+	bus_space_write_4(fdc->sc_iot, jsc->sc_dmaioh, R4030_DMA_COUNT, 0);
+	bus_space_write_4(fdc->sc_iot, jsc->sc_dmaioh, R4030_DMA_ENAB, 0);
+	bus_space_write_4(fdc->sc_iot, jsc->sc_dmaioh, R4030_DMA_MODE, 0);
+
+	bus_dmamap_sync(jsc->sc_dmat, jsc->sc_dmamap,
+	    0, jsc->sc_dmamap->dm_mapsize,
+	    jsc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
+	bus_dmamap_unload(jsc->sc_dmat, jsc->sc_dmamap);
 }
Index: jazz/jazzio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/jazz/jazzio.c,v
retrieving revision 1.8
diff -u -r1.8 jazzio.c
--- jazz/jazzio.c	2003/01/01 00:32:05	1.8
+++ jazz/jazzio.c	2003/01/08 17:03:09
@@ -42,6 +42,7 @@
 #include <arc/jazz/jazziovar.h>
 #include <arc/jazz/pica.h>
 #include <arc/jazz/jazzdmatlbreg.h>
+#include <arc/jazz/jazzdmatlbvar.h>
 #include <arc/jazz/dma.h>
 #include <arc/jazz/pckbc_jazzioreg.h>
 
@@ -145,8 +146,8 @@
 
 	sc->sc_bus.ab_dv = (struct device *)sc;
 
-	/* Initialize PICA Dma */
-	picaDmaInit();
+	/* Initialize jazzio dma mapping register area and pool */
+	jazz_dmatlb_init(&jazzio_bus, jazzio_conf->jc_dmatlbreg);
 
 	/* Create bus_dma_tag */
 	jazz_bus_dma_tag_init(&sc->sc_dmat);