xref: /netbsd-src/sys/arch/next68k/dev/esp.c (revision 4472dbe5e3bd91ef2540bada7a7ca7384627ff9b)
1 /*	$NetBSD: esp.c,v 1.27 2000/06/05 07:59:51 nisimura Exp $	*/
2 
3 /*-
4  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
9  * Simulation Facility, NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	This product includes software developed by the NetBSD
22  *	Foundation, Inc. and its contributors.
23  * 4. Neither the name of The NetBSD Foundation nor the names of its
24  *    contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 /*
41  * Copyright (c) 1994 Peter Galbavy
42  * All rights reserved.
43  *
44  * Redistribution and use in source and binary forms, with or without
45  * modification, are permitted provided that the following conditions
46  * are met:
47  * 1. Redistributions of source code must retain the above copyright
48  *    notice, this list of conditions and the following disclaimer.
49  * 2. Redistributions in binary form must reproduce the above copyright
50  *    notice, this list of conditions and the following disclaimer in the
51  *    documentation and/or other materials provided with the distribution.
52  * 3. All advertising materials mentioning features or use of this software
53  *    must display the following acknowledgement:
54  *	This product includes software developed by Peter Galbavy
55  * 4. The name of the author may not be used to endorse or promote products
56  *    derived from this software without specific prior written permission.
57  *
58  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
59  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
60  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
61  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
62  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
63  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
64  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
66  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
67  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
68  * POSSIBILITY OF SUCH DAMAGE.
69  */
70 
71 /*
72  * Based on aic6360 by Jarle Greipsland
73  *
74  * Acknowledgements: Many of the algorithms used in this driver are
75  * inspired by the work of Julian Elischer (julian@tfs.com) and
76  * Charles Hannum (mycroft@duality.gnu.ai.mit.edu).  Thanks a million!
77  */
78 
79 /*
80  * Grabbed from the sparc port at revision 1.73 for the NeXT.
81  * Darrin B. Jewell <dbj@netbsd.org>  Sat Jul  4 15:41:32 1998
82  */
83 
84 #include <sys/types.h>
85 #include <sys/param.h>
86 #include <sys/systm.h>
87 #include <sys/kernel.h>
88 #include <sys/errno.h>
89 #include <sys/ioctl.h>
90 #include <sys/device.h>
91 #include <sys/buf.h>
92 #include <sys/proc.h>
93 #include <sys/user.h>
94 #include <sys/queue.h>
95 
96 #include <dev/scsipi/scsi_all.h>
97 #include <dev/scsipi/scsipi_all.h>
98 #include <dev/scsipi/scsiconf.h>
99 #include <dev/scsipi/scsi_message.h>
100 
101 #include <machine/bus.h>
102 #include <machine/autoconf.h>
103 #include <machine/cpu.h>
104 
105 #include <dev/ic/ncr53c9xreg.h>
106 #include <dev/ic/ncr53c9xvar.h>
107 
108 #include <next68k/next68k/isr.h>
109 
110 #include <next68k/dev/nextdmareg.h>
111 #include <next68k/dev/nextdmavar.h>
112 
113 #include "espreg.h"
114 #include "espvar.h"
115 
116 #ifdef DEBUG
117 #define ESP_DEBUG
118 #endif
119 
120 #ifdef ESP_DEBUG
121 int esp_debug = 0;
122 #define DPRINTF(x) if (esp_debug) printf x;
123 #else
124 #define DPRINTF(x)
125 #endif
126 
127 
128 void	espattach_intio	__P((struct device *, struct device *, void *));
129 int	espmatch_intio	__P((struct device *, struct cfdata *, void *));
130 
131 /* DMA callbacks */
132 bus_dmamap_t esp_dmacb_continue __P((void *arg));
133 void esp_dmacb_completed __P((bus_dmamap_t map, void *arg));
134 void esp_dmacb_shutdown __P((void *arg));
135 
136 #ifdef ESP_DEBUG
137 char esp_dma_dump[5*1024] = "";
138 struct ncr53c9x_softc *esp_debug_sc = 0;
139 void esp_dma_store __P((struct ncr53c9x_softc *sc));
140 void esp_dma_print __P((struct ncr53c9x_softc *sc));
141 int esp_dma_nest = 0;
142 #endif
143 
144 
145 /* Linkup to the rest of the kernel */
146 struct cfattach esp_ca = {
147 	sizeof(struct esp_softc), espmatch_intio, espattach_intio
148 };
149 
150 /*
151  * Functions and the switch for the MI code.
152  */
153 u_char	esp_read_reg __P((struct ncr53c9x_softc *, int));
154 void	esp_write_reg __P((struct ncr53c9x_softc *, int, u_char));
155 int	esp_dma_isintr __P((struct ncr53c9x_softc *));
156 void	esp_dma_reset __P((struct ncr53c9x_softc *));
157 int	esp_dma_intr __P((struct ncr53c9x_softc *));
158 int	esp_dma_setup __P((struct ncr53c9x_softc *, caddr_t *,
159 	    size_t *, int, size_t *));
160 void	esp_dma_go __P((struct ncr53c9x_softc *));
161 void	esp_dma_stop __P((struct ncr53c9x_softc *));
162 int	esp_dma_isactive __P((struct ncr53c9x_softc *));
163 
164 struct ncr53c9x_glue esp_glue = {
165 	esp_read_reg,
166 	esp_write_reg,
167 	esp_dma_isintr,
168 	esp_dma_reset,
169 	esp_dma_intr,
170 	esp_dma_setup,
171 	esp_dma_go,
172 	esp_dma_stop,
173 	esp_dma_isactive,
174 	NULL,			/* gl_clear_latched_intr */
175 };
176 
177 #ifdef ESP_DEBUG
178 #define XCHR(x) "0123456789abcdef"[(x) & 0xf]
179 static void
180 esp_hex_dump(unsigned char *pkt, size_t len)
181 {
182 	size_t i, j;
183 
184 	printf("00000000 ");
185 	for(i=0; i<len; i++) {
186 		printf("%c%c ", XCHR(pkt[i]>>4), XCHR(pkt[i]));
187 		if ((i+1) % 16 == 8) {
188 			printf(" ");
189 		}
190 		if ((i+1) % 16 == 0) {
191 			printf(" %c", '|');
192 			for(j=0; j<16; j++) {
193 				printf("%c", pkt[i-15+j]>=32 && pkt[i-15+j]<127?pkt[i-15+j]:'.');
194 			}
195 			printf("%c\n%c%c%c%c%c%c%c%c  ", '|',
196 					XCHR((i+1)>>28),XCHR((i+1)>>24),XCHR((i+1)>>20),XCHR((i+1)>>16),
197 					XCHR((i+1)>>12), XCHR((i+1)>>8), XCHR((i+1)>>4), XCHR(i+1));
198 		}
199 	}
200 	printf("\n");
201 }
202 #endif
203 
204 int
205 espmatch_intio(parent, cf, aux)
206 	struct device *parent;
207 	struct cfdata *cf;
208 	void *aux;
209 {
210   /* should probably probe here */
211   /* Should also probably set up data from config */
212 
213 	return(1);
214 }
215 
216 void
217 espattach_intio(parent, self, aux)
218 	struct device *parent, *self;
219 	void *aux;
220 {
221 	struct esp_softc *esc = (void *)self;
222 	struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
223 
224 #ifdef ESP_DEBUG
225 	esp_debug_sc = sc;
226 #endif
227 
228 	esc->sc_bst = NEXT68K_INTIO_BUS_SPACE;
229 	if (bus_space_map(esc->sc_bst, NEXT_P_SCSI,
230 			ESP_DEVICE_SIZE, 0, &esc->sc_bsh)) {
231     panic("\n%s: can't map ncr53c90 registers",
232 				sc->sc_dev.dv_xname);
233 	}
234 
235 	sc->sc_id = 7;
236 	sc->sc_freq = 20;							/* Mhz */
237 
238 	/*
239 	 * Set up glue for MI code early; we use some of it here.
240 	 */
241 	sc->sc_glue = &esp_glue;
242 
243 	/*
244 	 * XXX More of this should be in ncr53c9x_attach(), but
245 	 * XXX should we really poke around the chip that much in
246 	 * XXX the MI code?  Think about this more...
247 	 */
248 
249 	/*
250 	 * It is necessary to try to load the 2nd config register here,
251 	 * to find out what rev the esp chip is, else the ncr53c9x_reset
252 	 * will not set up the defaults correctly.
253 	 */
254 	sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
255 	sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE;
256 	sc->sc_cfg3 = NCRCFG3_CDB;
257 	NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
258 
259 	if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
260 	    (NCRCFG2_SCSI2 | NCRCFG2_RPE)) {
261 		sc->sc_rev = NCR_VARIANT_ESP100;
262 	} else {
263 		sc->sc_cfg2 = NCRCFG2_SCSI2;
264 		NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
265 		sc->sc_cfg3 = 0;
266 		NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
267 		sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK);
268 		NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
269 		if (NCR_READ_REG(sc, NCR_CFG3) !=
270 		    (NCRCFG3_CDB | NCRCFG3_FCLK)) {
271 			sc->sc_rev = NCR_VARIANT_ESP100A;
272 		} else {
273 			/* NCRCFG2_FE enables > 64K transfers */
274 			sc->sc_cfg2 |= NCRCFG2_FE;
275 			sc->sc_cfg3 = 0;
276 			NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
277 			sc->sc_rev = NCR_VARIANT_ESP200;
278 		}
279 	}
280 
281 	/*
282 	 * XXX minsync and maxxfer _should_ be set up in MI code,
283 	 * XXX but it appears to have some dependency on what sort
284 	 * XXX of DMA we're hooked up to, etc.
285 	 */
286 
287 	/*
288 	 * This is the value used to start sync negotiations
289 	 * Note that the NCR register "SYNCTP" is programmed
290 	 * in "clocks per byte", and has a minimum value of 4.
291 	 * The SCSI period used in negotiation is one-fourth
292 	 * of the time (in nanoseconds) needed to transfer one byte.
293 	 * Since the chip's clock is given in MHz, we have the following
294 	 * formula: 4 * period = (1000 / freq) * 4
295 	 */
296 	sc->sc_minsync = 1000 / sc->sc_freq;
297 
298 	/*
299 	 * Alas, we must now modify the value a bit, because it's
300 	 * only valid when can switch on FASTCLK and FASTSCSI bits
301 	 * in config register 3...
302 	 */
303 	switch (sc->sc_rev) {
304 	case NCR_VARIANT_ESP100:
305 		sc->sc_maxxfer = 64 * 1024;
306 		sc->sc_minsync = 0;	/* No synch on old chip? */
307 		break;
308 
309 	case NCR_VARIANT_ESP100A:
310 		sc->sc_maxxfer = 64 * 1024;
311 		/* Min clocks/byte is 5 */
312 		sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
313 		break;
314 
315 	case NCR_VARIANT_ESP200:
316 		sc->sc_maxxfer = 16 * 1024 * 1024;
317 		/* XXX - do actually set FAST* bits */
318 		break;
319 	}
320 
321 	/* @@@ Some ESP_DCTL bits probably need setting */
322 	NCR_WRITE_REG(sc, ESP_DCTL,
323 			ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_RESET);
324 	DELAY(10);
325 	DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
326 	NCR_WRITE_REG(sc, ESP_DCTL, ESPDCTL_20MHZ | ESPDCTL_INTENB);
327 	DELAY(10);
328 	DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
329 
330 	/* Set up SCSI DMA */
331 	{
332 		esc->sc_scsi_dma.nd_bst = NEXT68K_INTIO_BUS_SPACE;
333 
334 		if (bus_space_map(esc->sc_scsi_dma.nd_bst, NEXT_P_SCSI_CSR,
335 				sizeof(struct dma_dev),0, &esc->sc_scsi_dma.nd_bsh)) {
336 			panic("\n%s: can't map scsi DMA registers",
337 					sc->sc_dev.dv_xname);
338 		}
339 
340 		esc->sc_scsi_dma.nd_intr = NEXT_I_SCSI_DMA;
341 		esc->sc_scsi_dma.nd_shutdown_cb  = &esp_dmacb_shutdown;
342 		esc->sc_scsi_dma.nd_continue_cb  = &esp_dmacb_continue;
343 		esc->sc_scsi_dma.nd_completed_cb = &esp_dmacb_completed;
344 		esc->sc_scsi_dma.nd_cb_arg       = sc;
345 		nextdma_config(&esc->sc_scsi_dma);
346 		nextdma_init(&esc->sc_scsi_dma);
347 
348 #if 0
349 		/* Turn on target selection using the `dma' method */
350 		ncr53c9x_dmaselect = 1;
351 #else
352 		ncr53c9x_dmaselect = 0;
353 #endif
354 
355 		esc->sc_datain = -1;
356 		esc->sc_dmaaddr = 0;
357 		esc->sc_dmalen  = 0;
358 		esc->sc_dmasize = 0;
359 
360 		esc->sc_loaded = 0;
361 
362 		esc->sc_begin = 0;
363 		esc->sc_begin_size = 0;
364 
365 		{
366 			int error;
367 			if ((error = bus_dmamap_create(esc->sc_scsi_dma.nd_dmat,
368 					sc->sc_maxxfer, sc->sc_maxxfer/NBPG, sc->sc_maxxfer,
369 					0, BUS_DMA_ALLOCNOW, &esc->sc_main_dmamap)) != 0) {
370 				panic("%s: can't create main i/o DMA map, error = %d",
371 						sc->sc_dev.dv_xname,error);
372 			}
373 		}
374 		esc->sc_main = 0;
375 		esc->sc_main_size = 0;
376 
377 		{
378 			int error;
379 			if ((error = bus_dmamap_create(esc->sc_scsi_dma.nd_dmat,
380 					ESP_DMA_TAILBUFSIZE,
381 					1, ESP_DMA_TAILBUFSIZE,
382 					0, BUS_DMA_ALLOCNOW, &esc->sc_tail_dmamap)) != 0) {
383 				panic("%s: can't create tail i/o DMA map, error = %d",
384 						sc->sc_dev.dv_xname,error);
385 			}
386 		}
387 		esc->sc_tail = 0;
388 		esc->sc_tail_size = 0;
389 
390 	}
391 
392 	/* Establish interrupt channel */
393 	isrlink_autovec(ncr53c9x_intr, sc, NEXT_I_IPL(NEXT_I_SCSI), 0);
394 	INTR_ENABLE(NEXT_I_SCSI);
395 
396 	/* register interrupt stats */
397 	evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
398 	    sc->sc_dev.dv_xname, "intr");
399 
400 	/* Do the common parts of attachment. */
401 	ncr53c9x_attach(sc, NULL, NULL);
402 }
403 
404 /*
405  * Glue functions.
406  */
407 
408 u_char
409 esp_read_reg(sc, reg)
410 	struct ncr53c9x_softc *sc;
411 	int reg;
412 {
413 	struct esp_softc *esc = (struct esp_softc *)sc;
414 
415 	return(bus_space_read_1(esc->sc_bst, esc->sc_bsh, reg));
416 }
417 
418 void
419 esp_write_reg(sc, reg, val)
420 	struct ncr53c9x_softc *sc;
421 	int reg;
422 	u_char val;
423 {
424 	struct esp_softc *esc = (struct esp_softc *)sc;
425 
426 	bus_space_write_1(esc->sc_bst, esc->sc_bsh, reg, val);
427 }
428 
429 int
430 esp_dma_isintr(sc)
431 	struct ncr53c9x_softc *sc;
432 {
433 	struct esp_softc *esc = (struct esp_softc *)sc;
434 
435 	int r = (INTR_OCCURRED(NEXT_I_SCSI));
436 
437 	if (r) {
438 
439 		{
440 			int flushcount;
441 			int s;
442 			s = spldma();
443 
444 			flushcount = 0;
445 
446 #ifdef ESP_DEBUG
447 			esp_dma_nest++;
448 #endif
449 
450 			DPRINTF(("esp_dma_isintr = 0x%b\n",
451 					(*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)),NEXT_INTR_BITS));
452 
453 			while (esp_dma_isactive(sc)) {
454 				flushcount++;
455 
456 #ifdef DIAGNOSTIC
457 				r = (INTR_OCCURRED(NEXT_I_SCSI));
458 				if (!r) panic("esp intr enabled but dma failed to flush");
459 #endif
460 #ifdef DIAGNOSTIC
461 #if 0
462 				if ((esc->sc_loaded & (ESP_LOADED_TAIL/* |ESP_UNLOADED_MAIN */))
463 						!= (ESP_LOADED_TAIL /* |ESP_UNLOADED_MAIN */)) {
464 					if (esc->sc_datain) {
465 						NCR_WRITE_REG(sc, ESP_DCTL,
466 								ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
467 					} else {
468 						NCR_WRITE_REG(sc, ESP_DCTL,
469 								ESPDCTL_20MHZ | ESPDCTL_INTENB);
470 					}
471 					next_dma_print(&esc->sc_scsi_dma);
472 					esp_dma_print(sc);
473 					printf("%s: unexpected flush: tc=0x%06x\n",
474 							sc->sc_dev.dv_xname,
475 							(((sc->sc_cfg2 & NCRCFG2_FE)
476 									? NCR_READ_REG(sc, NCR_TCH) : 0)<<16)|
477 							(NCR_READ_REG(sc, NCR_TCM)<<8)|
478 							NCR_READ_REG(sc, NCR_TCL));
479 					ncr53c9x_readregs(sc);
480 					printf("%s: readregs[intr=%02x,stat=%02x,step=%02x]\n",
481 							sc->sc_dev.dv_xname,
482 							sc->sc_espintr, sc->sc_espstat, sc->sc_espstep);
483 					panic("%s: flushing flushing non-tail dma\n",
484 							sc->sc_dev.dv_xname);
485 				}
486 #endif
487 #endif
488 				DPRINTF(("%s: flushing dma, count = %d\n", sc->sc_dev.dv_xname,flushcount));
489 				if (esc->sc_datain) {
490 					NCR_WRITE_REG(sc, ESP_DCTL,
491 							ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD | ESPDCTL_FLUSH);
492 					DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
493 					NCR_WRITE_REG(sc, ESP_DCTL,
494 							ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD);
495 				} else {
496 					NCR_WRITE_REG(sc, ESP_DCTL,
497 							ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_FLUSH);
498 					DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
499 					NCR_WRITE_REG(sc, ESP_DCTL,
500 							ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD);
501 				}
502 				DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
503 
504 				{
505 					int nr;
506 					nr = nextdma_intr(&esc->sc_scsi_dma);
507 					if (nr) {
508 						DPRINTF(("nextma_intr = %d\n",nr));
509 #ifdef DIAGNOSTIC
510 #if 0
511 						if (flushcount > 16) {
512 							printf("%s: unexpected flushcount %d\n",sc->sc_dev.dv_xname,flushcount);
513 						}
514 #endif
515 #endif
516 #ifdef DIAGNOSTIC
517 #if 0
518 						if (esp_dma_isactive(sc)) {
519 							esp_dma_print(sc);
520 							printf("%s: dma still active after a flush with count %d\n",
521 									sc->sc_dev.dv_xname,flushcount);
522 
523 						}
524 #endif
525 #endif
526 						flushcount = 0;
527 					}
528 				}
529 			}
530 
531 #ifdef ESP_DEBUG
532 			esp_dma_nest--;
533 #endif
534 
535 			splx(s);
536 		}
537 
538 #ifdef DIAGNOSTIC
539 		r = (INTR_OCCURRED(NEXT_I_SCSI));
540 		if (!r) panic("esp intr not enabled after dma flush");
541 #endif
542 
543 		/* Clear the DMAMOD bit in the DCTL register, since if this
544 		 * routine returns true, then the ncr53c9x_intr handler will
545 		 * be called and needs access to the scsi registers.
546 		 */
547 		if (esc->sc_datain) {
548 			NCR_WRITE_REG(sc, ESP_DCTL,
549 					ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
550 		} else {
551 			NCR_WRITE_REG(sc, ESP_DCTL,
552 					ESPDCTL_20MHZ | ESPDCTL_INTENB);
553 		}
554 		DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
555 
556 	}
557 
558 	return (r);
559 }
560 
561 void
562 esp_dma_reset(sc)
563 	struct ncr53c9x_softc *sc;
564 {
565 	struct esp_softc *esc = (struct esp_softc *)sc;
566 
567 	DPRINTF(("esp dma reset\n"));
568 
569 #ifdef ESP_DEBUG
570 	if (esp_debug) {
571 		printf("  *intrstat = 0x%b\n",
572 				(*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)),NEXT_INTR_BITS);
573 		printf("  *intrmask = 0x%b\n",
574 				(*(volatile u_long *)IIOV(NEXT_P_INTRMASK)),NEXT_INTR_BITS);
575 	}
576 #endif
577 
578 	/* Clear the DMAMOD bit in the DCTL register: */
579 	NCR_WRITE_REG(sc, ESP_DCTL,
580 			ESPDCTL_20MHZ | ESPDCTL_INTENB);
581 	DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
582 
583 	nextdma_reset(&esc->sc_scsi_dma);
584 
585 	esc->sc_datain = -1;
586 	esc->sc_dmaaddr = 0;
587 	esc->sc_dmalen  = 0;
588 	esc->sc_dmasize = 0;
589 
590 	esc->sc_loaded = 0;
591 
592 	esc->sc_begin = 0;
593 	esc->sc_begin_size = 0;
594 
595 	if (esc->sc_main_dmamap->dm_mapsize) {
596 		bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap);
597 	}
598 	esc->sc_main = 0;
599 	esc->sc_main_size = 0;
600 
601 	if (esc->sc_tail_dmamap->dm_mapsize) {
602 		bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap);
603 	}
604 	esc->sc_tail = 0;
605 	esc->sc_tail_size = 0;
606 }
607 
608 int
609 esp_dma_intr(sc)
610 	struct ncr53c9x_softc *sc;
611 {
612 #ifdef DIAGNOSTIC
613 	panic("%s: esp_dma_intr shouldn't be invoked.\n", sc->sc_dev.dv_xname);
614 #endif
615 
616 	return -1;
617 }
618 
619 /* it appears that:
620  * addr and len arguments to this need to be kept up to date
621  * with the status of the transfter.
622  * the dmasize of this is the actual length of the transfer
623  * request, which is guaranteed to be less than maxxfer.
624  * (len may be > maxxfer)
625  */
626 
627 int
628 esp_dma_setup(sc, addr, len, datain, dmasize)
629 	struct ncr53c9x_softc *sc;
630 	caddr_t *addr;
631 	size_t *len;
632 	int datain;
633 	size_t *dmasize;
634 {
635 	struct esp_softc *esc = (struct esp_softc *)sc;
636 
637 #ifdef DIAGNOSTIC
638 #ifdef ESP_DEBUG
639 	/* if this is a read DMA, pre-fill the buffer with 0xdeadbeef
640 	 * to identify bogus reads
641 	 */
642 	if (datain) {
643 		int *v = (int *)(*addr);
644 		int i;
645 		for(i=0;i<((*len)/4);i++) v[i] = 0xdeadbeef;
646 		v = (int *)(&(esc->sc_tailbuf[0]));
647 		for(i=0;i<((sizeof(esc->sc_tailbuf)/4));i++) v[i] = 0xdeaffeed;
648 	} else {
649 		int *v;
650 		int i;
651 		v = (int *)(&(esc->sc_tailbuf[0]));
652 		for(i=0;i<((sizeof(esc->sc_tailbuf)/4));i++) v[i] = 0xfeeb1eed;
653 	}
654 #endif
655 #endif
656 
657 	DPRINTF(("esp_dma_setup(0x%08lx,0x%08lx,0x%08lx)\n",*addr,*len,*dmasize));
658 
659 #if 0
660 #ifdef DIAGNOSTIC /* @@@ this is ok sometimes. verify that we handle it ok
661 									 * and then remove this check
662 									 */
663 	if (*len != *dmasize) {
664 		panic("esp dmalen 0x%lx != size 0x%lx",*len,*dmasize);
665 	}
666 #endif
667 #endif
668 
669 #ifdef DIAGNOSTIC
670 	if ((esc->sc_datain != -1) ||
671 			(esc->sc_main_dmamap->dm_mapsize != 0) ||
672 			(esc->sc_tail_dmamap->dm_mapsize != 0) ||
673 			(esc->sc_dmasize != 0)) {
674 		panic("%s: map already loaded in esp_dma_setup\n"
675 				"\tdatain = %d\n\tmain_mapsize=%d\n\tail_mapsize=%d\n\tdmasize = %d",
676 				sc->sc_dev.dv_xname, esc->sc_datain,
677 				esc->sc_main_dmamap->dm_mapsize,
678 				esc->sc_tail_dmamap->dm_mapsize,
679 				esc->sc_dmasize);
680 	}
681 #endif
682 
683 	/* we are sometimes asked to dma zero  bytes, that's easy */
684 	if (*dmasize <= 0) {
685 		return(0);
686 	}
687 
688 	/* Save these in case we have to abort DMA */
689 	esc->sc_datain   = datain;
690 	esc->sc_dmaaddr  = addr;
691 	esc->sc_dmalen   = len;
692 	esc->sc_dmasize  = *dmasize;
693 
694 	esc->sc_loaded = 0;
695 
696 #define DMA_SCSI_ALIGNMENT 16
697 #define DMA_SCSI_ALIGN(type, addr)	\
698 	((type)(((unsigned)(addr)+DMA_SCSI_ALIGNMENT-1) \
699 		&~(DMA_SCSI_ALIGNMENT-1)))
700 #define DMA_SCSI_ALIGNED(addr) \
701 	(((unsigned)(addr)&(DMA_SCSI_ALIGNMENT-1))==0)
702 
703 	{
704 		size_t slop_bgn_size; /* # bytes to be fifo'd at beginning */
705 		size_t slop_end_size; /* # bytes to be transferred in tail buffer */
706 
707 		{
708 			u_long bgn = (u_long)(*esc->sc_dmaaddr);
709 			u_long end = (u_long)(*esc->sc_dmaaddr+esc->sc_dmasize);
710 
711 			slop_bgn_size = DMA_SCSI_ALIGNMENT-(bgn % DMA_SCSI_ALIGNMENT);
712 			if (slop_bgn_size == DMA_SCSI_ALIGNMENT) slop_bgn_size = 0;
713 			slop_end_size = (end % DMA_ENDALIGNMENT);
714 		}
715 
716 		/* Force a minimum slop end size. This ensures that write
717 		 * requests will overrun, as required to get completion interrupts.
718 		 * In addition, since the tail buffer is guaranteed to be mapped
719 		 * in a single dma segment, the overrun won't accidentally
720 		 * end up in its own segment.
721 		 */
722 		if (!esc->sc_datain) {
723 #if 0
724 			slop_end_size += ESP_DMA_MAXTAIL;
725 #else
726 			slop_end_size += 0x10;
727 #endif
728 		}
729 
730 		/* Check to make sure we haven't counted extra slop
731 		 * as would happen for a very short dma buffer, also
732 		 * for short buffers, just stuff the entire thing in the tail
733 		 */
734 		if ((slop_bgn_size+slop_end_size >= esc->sc_dmasize)
735 #if 0
736 				|| (esc->sc_dmasize <= ESP_DMA_MAXTAIL)
737 #endif
738 				)
739 		{
740  			slop_bgn_size = 0;
741 			slop_end_size = esc->sc_dmasize;
742 		}
743 
744 		/* initialize the fifo buffer */
745 		if (slop_bgn_size) {
746 			esc->sc_begin = *esc->sc_dmaaddr;
747 			esc->sc_begin_size = slop_bgn_size;
748 		} else {
749 			esc->sc_begin = 0;
750 			esc->sc_begin_size = 0;
751 		}
752 
753 		/* Load the normal DMA map */
754 		{
755 			esc->sc_main      = *esc->sc_dmaaddr+slop_bgn_size;
756 			esc->sc_main_size = (esc->sc_dmasize)-(slop_end_size+slop_bgn_size);
757 
758 			if (esc->sc_main_size) {
759 				int error;
760 				error = bus_dmamap_load(esc->sc_scsi_dma.nd_dmat,
761 						esc->sc_main_dmamap,
762 						esc->sc_main, esc->sc_main_size,
763 						NULL, BUS_DMA_NOWAIT);
764 				if (error) {
765 					panic("%s: can't load main dma map. error = %d, addr=0x%08x, size=0x%08x",
766 							sc->sc_dev.dv_xname, error,esc->sc_main,esc->sc_main_size);
767 				}
768 #if 0
769 				bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap,
770 						0, esc->sc_main_dmamap->dm_mapsize,
771 						(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
772 #endif
773 			} else {
774 				esc->sc_main = 0;
775 			}
776 		}
777 
778 		/* Load the tail DMA map */
779 		if (slop_end_size) {
780 			esc->sc_tail      = DMA_ENDALIGN(caddr_t,esc->sc_tailbuf+slop_end_size)-slop_end_size;
781 			/* If the beginning of the tail is not correctly aligned,
782 			 * we have no choice but to align the start, which might then unalign the end.
783 			 */
784 			esc->sc_tail      = DMA_SCSI_ALIGN(caddr_t,esc->sc_tail);
785 			/* So therefore, we change the tail size to be end aligned again. */
786 			esc->sc_tail_size = DMA_ENDALIGN(caddr_t,esc->sc_tail+slop_end_size)-esc->sc_tail;
787 
788 			/* @@@ next dma overrun lossage */
789 			if (!esc->sc_datain) {
790 				esc->sc_tail_size += ESP_DMA_OVERRUN;
791 			}
792 
793 			{
794 				int error;
795 				error = bus_dmamap_load(esc->sc_scsi_dma.nd_dmat,
796 						esc->sc_tail_dmamap,
797 						esc->sc_tail, esc->sc_tail_size,
798 						NULL, BUS_DMA_NOWAIT);
799 				if (error) {
800 					panic("%s: can't load tail dma map. error = %d, addr=0x%08x, size=0x%08x",
801 							sc->sc_dev.dv_xname, error,esc->sc_tail,esc->sc_tail_size);
802 				}
803 #if 0
804 				bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap,
805 						0, esc->sc_tail_dmamap->dm_mapsize,
806 						(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
807 #endif
808 			}
809 		}
810 	}
811 
812 	return (0);
813 }
814 
815 #ifdef ESP_DEBUG
816 /* For debugging */
817 void
818 esp_dma_store(sc)
819 	struct ncr53c9x_softc *sc;
820 {
821 	struct esp_softc *esc = (struct esp_softc *)sc;
822 	char *p = &esp_dma_dump[0];
823 
824 	p += sprintf(p,"%s: sc_datain=%d\n",sc->sc_dev.dv_xname,esc->sc_datain);
825 	p += sprintf(p,"%s: sc_loaded=0x%08x\n",sc->sc_dev.dv_xname,esc->sc_loaded);
826 
827 	if (esc->sc_dmaaddr) {
828 		p += sprintf(p,"%s: sc_dmaaddr=0x%08lx\n",sc->sc_dev.dv_xname,*esc->sc_dmaaddr);
829 	} else {
830 		p += sprintf(p,"%s: sc_dmaaddr=NULL\n",sc->sc_dev.dv_xname);
831 	}
832 	if (esc->sc_dmalen) {
833 		p += sprintf(p,"%s: sc_dmalen=0x%08lx\n",sc->sc_dev.dv_xname,*esc->sc_dmalen);
834 	} else {
835 		p += sprintf(p,"%s: sc_dmalen=NULL\n",sc->sc_dev.dv_xname);
836 	}
837 	p += sprintf(p,"%s: sc_dmasize=0x%08x\n",sc->sc_dev.dv_xname,esc->sc_dmasize);
838 
839 	p += sprintf(p,"%s: sc_begin = 0x%08x, sc_begin_size = 0x%08x\n",
840 			sc->sc_dev.dv_xname, esc->sc_begin, esc->sc_begin_size);
841 	p += sprintf(p,"%s: sc_main = 0x%08x, sc_main_size = 0x%08x\n",
842 			sc->sc_dev.dv_xname, esc->sc_main, esc->sc_main_size);
843 	{
844 		int i;
845 		bus_dmamap_t map = esc->sc_main_dmamap;
846 		p += sprintf(p,"%s: sc_main_dmamap. mapsize = 0x%08x, nsegs = %d\n",
847 				sc->sc_dev.dv_xname, map->dm_mapsize, map->dm_nsegs);
848 		for(i=0;i<map->dm_nsegs;i++) {
849 			p += sprintf(p,"%s: map->dm_segs[%d]->ds_addr = 0x%08x, len = 0x%08x\n",
850 			sc->sc_dev.dv_xname, i, map->dm_segs[i].ds_addr, map->dm_segs[i].ds_len);
851 		}
852 	}
853 	p += sprintf(p,"%s: sc_tail = 0x%08x, sc_tail_size = 0x%08x\n",
854 			sc->sc_dev.dv_xname, esc->sc_tail, esc->sc_tail_size);
855 	{
856 		int i;
857 		bus_dmamap_t map = esc->sc_tail_dmamap;
858 		p += sprintf(p,"%s: sc_tail_dmamap. mapsize = 0x%08x, nsegs = %d\n",
859 				sc->sc_dev.dv_xname, map->dm_mapsize, map->dm_nsegs);
860 		for(i=0;i<map->dm_nsegs;i++) {
861 			p += sprintf(p,"%s: map->dm_segs[%d]->ds_addr = 0x%08x, len = 0x%08x\n",
862 			sc->sc_dev.dv_xname, i, map->dm_segs[i].ds_addr, map->dm_segs[i].ds_len);
863 		}
864 	}
865 }
866 
867 void
868 esp_dma_print(sc)
869 	struct ncr53c9x_softc *sc;
870 {
871 	esp_dma_store(sc);
872 	printf("%s",esp_dma_dump);
873 }
874 #endif
875 
876 void
877 esp_dma_go(sc)
878 	struct ncr53c9x_softc *sc;
879 {
880 	struct esp_softc *esc = (struct esp_softc *)sc;
881 
882 	DPRINTF(("%s: esp_dma_go(datain = %d)\n",
883 			sc->sc_dev.dv_xname, esc->sc_datain));
884 
885 #ifdef ESP_DEBUG
886 	if (esp_debug) esp_dma_print(sc);
887 	else esp_dma_store(sc);
888 #endif
889 
890 #ifdef ESP_DEBUG
891 	{
892 		int n = NCR_READ_REG(sc, NCR_FFLAG);
893 		DPRINTF(("%s: fifo size = %d, seq = 0x%x\n",
894 				sc->sc_dev.dv_xname,
895 				n & NCRFIFO_FF, (n & NCRFIFO_SS)>>5));
896 	}
897 #endif
898 
899 	/* zero length dma transfers are boring */
900 	if (esc->sc_dmasize == 0) {
901 		return;
902 	}
903 
904 #if defined(DIAGNOSTIC)
905   if ((esc->sc_begin_size == 0) &&
906 			(esc->sc_main_dmamap->dm_mapsize == 0) &&
907 			(esc->sc_tail_dmamap->dm_mapsize == 0)) {
908 		esp_dma_print(sc);
909 		panic("%s: No DMA requested!",sc->sc_dev.dv_xname);
910 	}
911 #endif
912 
913 	/* Stuff the fifo with the begin buffer */
914 	if (esc->sc_datain) {
915 		int i;
916 		DPRINTF(("%s: FIFO read of %d bytes:",
917 				sc->sc_dev.dv_xname,esc->sc_begin_size));
918 		for(i=0;i<esc->sc_begin_size;i++) {
919 			esc->sc_begin[i]=NCR_READ_REG(sc, NCR_FIFO);
920 			DPRINTF((" %02x",esc->sc_begin[i]&0xff));
921 		}
922 		DPRINTF(("\n"));
923 	} else {
924 		int i;
925 		DPRINTF(("%s: FIFO write of %d bytes:",
926 				sc->sc_dev.dv_xname,esc->sc_begin_size));
927 		for(i=0;i<esc->sc_begin_size;i++) {
928 			NCR_WRITE_REG(sc, NCR_FIFO, esc->sc_begin[i]);
929 			DPRINTF((" %02x",esc->sc_begin[i]&0xff));
930 		}
931 		DPRINTF(("\n"));
932 	}
933 
934 	/* if we are a dma write cycle, copy the end slop */
935 	if (esc->sc_datain == 0) {
936 		memcpy(esc->sc_tail,
937 				(*esc->sc_dmaaddr+esc->sc_begin_size+esc->sc_main_size),
938 				(esc->sc_dmasize-(esc->sc_begin_size+esc->sc_main_size)));
939 	}
940 
941 	if (esc->sc_main_dmamap->dm_mapsize) {
942 		bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap,
943 				0, esc->sc_main_dmamap->dm_mapsize,
944 				(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
945 	}
946 
947 	if (esc->sc_tail_dmamap->dm_mapsize) {
948 		bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap,
949 				0, esc->sc_tail_dmamap->dm_mapsize,
950 				(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
951 	}
952 
953 	nextdma_start(&esc->sc_scsi_dma,
954 			(esc->sc_datain ? DMACSR_SETREAD : DMACSR_SETWRITE));
955 
956 	if (esc->sc_datain) {
957 		NCR_WRITE_REG(sc, ESP_DCTL,
958 				ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD);
959 	} else {
960 		NCR_WRITE_REG(sc, ESP_DCTL,
961 				ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD);
962 	}
963 	DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
964 }
965 
966 void
967 esp_dma_stop(sc)
968 	struct ncr53c9x_softc *sc;
969 {
970 	panic("Not yet implemented");
971 }
972 
973 int
974 esp_dma_isactive(sc)
975 	struct ncr53c9x_softc *sc;
976 {
977 	struct esp_softc *esc = (struct esp_softc *)sc;
978 	int r = !nextdma_finished(&esc->sc_scsi_dma);
979 	DPRINTF(("esp_dma_isactive = %d\n",r));
980 	return(r);
981 }
982 
983 /****************************************************************/
984 
985 /* Internal dma callback routines */
986 bus_dmamap_t
987 esp_dmacb_continue(arg)
988 	void *arg;
989 {
990 	struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
991 	struct esp_softc *esc = (struct esp_softc *)sc;
992 
993 	DPRINTF(("%s: dma continue\n",sc->sc_dev.dv_xname));
994 
995 #ifdef DIAGNOSTIC
996 	if ((esc->sc_datain < 0) || (esc->sc_datain > 1)) {
997 		panic("%s: map not loaded in dma continue callback, datain = %d",
998 				sc->sc_dev.dv_xname,esc->sc_datain);
999 	}
1000 #endif
1001 
1002 	if ((!(esc->sc_loaded & ESP_LOADED_MAIN)) &&
1003 			(esc->sc_main_dmamap->dm_mapsize)) {
1004 			DPRINTF(("%s: Loading main map\n",sc->sc_dev.dv_xname));
1005 #if 0
1006 			bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap,
1007 					0, esc->sc_main_dmamap->dm_mapsize,
1008 					(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
1009 #endif
1010 			esc->sc_loaded |= ESP_LOADED_MAIN;
1011 			return(esc->sc_main_dmamap);
1012 	}
1013 
1014 	if ((!(esc->sc_loaded & ESP_LOADED_TAIL)) &&
1015 			(esc->sc_tail_dmamap->dm_mapsize)) {
1016 			DPRINTF(("%s: Loading tail map\n",sc->sc_dev.dv_xname));
1017 #if 0
1018 			bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap,
1019 					0, esc->sc_tail_dmamap->dm_mapsize,
1020 					(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
1021 #endif
1022 			esc->sc_loaded |= ESP_LOADED_TAIL;
1023 			return(esc->sc_tail_dmamap);
1024 	}
1025 
1026 	DPRINTF(("%s: not loading map\n",sc->sc_dev.dv_xname));
1027 	return(0);
1028 }
1029 
1030 
1031 void
1032 esp_dmacb_completed(map, arg)
1033 	bus_dmamap_t map;
1034 	void *arg;
1035 {
1036 	struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
1037 	struct esp_softc *esc = (struct esp_softc *)sc;
1038 
1039 	DPRINTF(("%s: dma completed\n",sc->sc_dev.dv_xname));
1040 
1041 #ifdef DIAGNOSTIC
1042 	if ((esc->sc_datain < 0) || (esc->sc_datain > 1)) {
1043 		panic("%s: invalid dma direction in completed callback, datain = %d",
1044 				sc->sc_dev.dv_xname,esc->sc_datain);
1045 	}
1046 #endif
1047 
1048 	if (map == esc->sc_main_dmamap) {
1049 #ifdef DIAGNOSTIC
1050 		if ((esc->sc_loaded & ESP_UNLOADED_MAIN) ||
1051 				!(esc->sc_loaded & ESP_LOADED_MAIN)) {
1052 			panic("%s: unexpected completed call for main map\n",sc->sc_dev.dv_xname);
1053 		}
1054 #endif
1055 		esc->sc_loaded |= ESP_UNLOADED_MAIN;
1056 	} else if (map == esc->sc_tail_dmamap) {
1057 #ifdef DIAGNOSTIC
1058 		if ((esc->sc_loaded & ESP_UNLOADED_TAIL) ||
1059 				!(esc->sc_loaded & ESP_LOADED_TAIL)) {
1060 			panic("%s: unexpected completed call for tail map\n",sc->sc_dev.dv_xname);
1061 		}
1062 #endif
1063 		esc->sc_loaded |= ESP_UNLOADED_TAIL;
1064 	}
1065 #ifdef DIAGNOSTIC
1066 	 else {
1067 		panic("%s: unexpected completed map", sc->sc_dev.dv_xname);
1068 	}
1069 #endif
1070 
1071 #ifdef ESP_DEBUG
1072 	if (esp_debug) {
1073 		if (map == esc->sc_main_dmamap) {
1074 			printf("%s: completed main map\n",sc->sc_dev.dv_xname);
1075 		} else if (map == esc->sc_tail_dmamap) {
1076 			printf("%s: completed tail map\n",sc->sc_dev.dv_xname);
1077 		}
1078 	}
1079 #endif
1080 
1081 #if 0
1082 	if ((map == esc->sc_tail_dmamap) ||
1083 			((esc->sc_tail_size == 0) && (map == esc->sc_main_dmamap))) {
1084 
1085 		/* Clear the DMAMOD bit in the DCTL register to give control
1086 		 * back to the scsi chip.
1087 		 */
1088 		if (esc->sc_datain) {
1089 			NCR_WRITE_REG(sc, ESP_DCTL,
1090 					ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
1091 		} else {
1092 			NCR_WRITE_REG(sc, ESP_DCTL,
1093 					ESPDCTL_20MHZ | ESPDCTL_INTENB);
1094 		}
1095 		DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
1096 	}
1097 #endif
1098 
1099 
1100 #if 0
1101 	bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, map,
1102 			0, map->dm_mapsize,
1103 			(esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
1104 #endif
1105 
1106 }
1107 
1108 void
1109 esp_dmacb_shutdown(arg)
1110 	void *arg;
1111 {
1112 	struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
1113 	struct esp_softc *esc = (struct esp_softc *)sc;
1114 
1115 	DPRINTF(("%s: dma shutdown\n",sc->sc_dev.dv_xname));
1116 
1117 #if 0
1118 	{
1119 		/* Clear the DMAMOD bit in the DCTL register to give control
1120 		 * back to the scsi chip.
1121 		 */
1122 		if (esc->sc_datain) {
1123 			NCR_WRITE_REG(sc, ESP_DCTL,
1124 					ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
1125 		} else {
1126 			NCR_WRITE_REG(sc, ESP_DCTL,
1127 					ESPDCTL_20MHZ | ESPDCTL_INTENB);
1128 		}
1129 		DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
1130 	}
1131 #endif
1132 
1133 	DPRINTF(("%s: esp_dma_nest == %d\n",sc->sc_dev.dv_xname,esp_dma_nest));
1134 
1135 	/* Stuff the end slop into fifo */
1136 
1137 #ifdef ESP_DEBUG
1138 	if (esp_debug) {
1139 
1140 		int n = NCR_READ_REG(sc, NCR_FFLAG);
1141 		DPRINTF(("%s: fifo size = %d, seq = 0x%x\n",
1142 				sc->sc_dev.dv_xname,n & NCRFIFO_FF, (n & NCRFIFO_SS)>>5));
1143 	}
1144 #endif
1145 
1146 	if (esc->sc_main_dmamap->dm_mapsize) {
1147 		bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap,
1148 			0, esc->sc_main_dmamap->dm_mapsize,
1149 				(esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
1150 		bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap);
1151 	}
1152 
1153 	if (esc->sc_tail_dmamap->dm_mapsize) {
1154 		bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap,
1155 			0, esc->sc_tail_dmamap->dm_mapsize,
1156 				(esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
1157 		bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap);
1158 	}
1159 
1160 	/* copy the tail dma buffer data for read transfers */
1161 	if (esc->sc_datain == 1) {
1162 		memcpy((*esc->sc_dmaaddr+esc->sc_begin_size+esc->sc_main_size),
1163 				esc->sc_tail,
1164 				(esc->sc_dmasize-(esc->sc_begin_size+esc->sc_main_size)));
1165 	}
1166 
1167 #ifdef ESP_DEBUG
1168 	if (esp_debug) {
1169 		printf("%s: dma_shutdown: addr=0x%08lx,len=0x%08lx,size=0x%08lx\n",
1170 				sc->sc_dev.dv_xname,
1171 				*esc->sc_dmaaddr, *esc->sc_dmalen, esc->sc_dmasize);
1172 		if (esp_debug > 10) {
1173 			esp_hex_dump(*(esc->sc_dmaaddr),esc->sc_dmasize);
1174 			printf("%s: tail=0x%08lx,tailbuf=0x%08lx,tail_size=0x%08lx\n",
1175 					sc->sc_dev.dv_xname,
1176 					esc->sc_tail, &(esc->sc_tailbuf[0]), esc->sc_tail_size);
1177 			esp_hex_dump(&(esc->sc_tailbuf[0]),sizeof(esc->sc_tailbuf));
1178 		}
1179 	}
1180 #endif
1181 
1182 	*(esc->sc_dmaaddr) += esc->sc_dmasize;
1183 	*(esc->sc_dmalen)  -= esc->sc_dmasize;
1184 
1185 	esc->sc_main = 0;
1186 	esc->sc_main_size = 0;
1187 	esc->sc_tail = 0;
1188 	esc->sc_tail_size = 0;
1189 
1190 	esc->sc_datain = -1;
1191 	esc->sc_dmaaddr = 0;
1192 	esc->sc_dmalen  = 0;
1193 	esc->sc_dmasize = 0;
1194 
1195 	esc->sc_loaded = 0;
1196 
1197 	esc->sc_begin = 0;
1198 	esc->sc_begin_size = 0;
1199 
1200 #ifdef ESP_DEBUG
1201 	if (esp_debug) {
1202 		printf("  *intrstat = 0x%b\n",
1203 				(*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)),NEXT_INTR_BITS);
1204 		printf("  *intrmask = 0x%b\n",
1205 				(*(volatile u_long *)IIOV(NEXT_P_INTRMASK)),NEXT_INTR_BITS);
1206 	}
1207 #endif
1208 }
1209