xref: /netbsd-src/sys/arch/next68k/dev/esp.c (revision 1ca5c1b28139779176bd5c13ad7c5f25c0bcd5f8)
1 /*	$NetBSD: esp.c,v 1.35 2001/05/23 02:14:07 chs 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 				DD_SIZE,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 		sc->sc_features |= NCR_F_DMASELECT;
351 #endif
352 
353 		esc->sc_datain = -1;
354 		esc->sc_dmaaddr = 0;
355 		esc->sc_dmalen  = 0;
356 		esc->sc_dmasize = 0;
357 
358 		esc->sc_loaded = 0;
359 
360 		esc->sc_begin = 0;
361 		esc->sc_begin_size = 0;
362 
363 		{
364 			int error;
365 			if ((error = bus_dmamap_create(esc->sc_scsi_dma.nd_dmat,
366 					sc->sc_maxxfer, sc->sc_maxxfer/NBPG+1, sc->sc_maxxfer,
367 					0, BUS_DMA_ALLOCNOW, &esc->sc_main_dmamap)) != 0) {
368 				panic("%s: can't create main i/o DMA map, error = %d",
369 						sc->sc_dev.dv_xname,error);
370 			}
371 		}
372 		esc->sc_main = 0;
373 		esc->sc_main_size = 0;
374 
375 		{
376 			int error;
377 			if ((error = bus_dmamap_create(esc->sc_scsi_dma.nd_dmat,
378 					ESP_DMA_TAILBUFSIZE,
379 					1, ESP_DMA_TAILBUFSIZE,
380 					0, BUS_DMA_ALLOCNOW, &esc->sc_tail_dmamap)) != 0) {
381 				panic("%s: can't create tail i/o DMA map, error = %d",
382 						sc->sc_dev.dv_xname,error);
383 			}
384 		}
385 		esc->sc_tail = 0;
386 		esc->sc_tail_size = 0;
387 
388 	}
389 
390 	/* Establish interrupt channel */
391 	isrlink_autovec(ncr53c9x_intr, sc, NEXT_I_IPL(NEXT_I_SCSI), 0);
392 	INTR_ENABLE(NEXT_I_SCSI);
393 
394 	/* register interrupt stats */
395 	evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
396 	    sc->sc_dev.dv_xname, "intr");
397 
398 	/* Do the common parts of attachment. */
399 	ncr53c9x_attach(sc);
400 }
401 
402 /*
403  * Glue functions.
404  */
405 
406 u_char
407 esp_read_reg(sc, reg)
408 	struct ncr53c9x_softc *sc;
409 	int reg;
410 {
411 	struct esp_softc *esc = (struct esp_softc *)sc;
412 
413 	return(bus_space_read_1(esc->sc_bst, esc->sc_bsh, reg));
414 }
415 
416 void
417 esp_write_reg(sc, reg, val)
418 	struct ncr53c9x_softc *sc;
419 	int reg;
420 	u_char val;
421 {
422 	struct esp_softc *esc = (struct esp_softc *)sc;
423 
424 	bus_space_write_1(esc->sc_bst, esc->sc_bsh, reg, val);
425 }
426 
427 int
428 esp_dma_isintr(sc)
429 	struct ncr53c9x_softc *sc;
430 {
431 	struct esp_softc *esc = (struct esp_softc *)sc;
432 
433 	int r = (INTR_OCCURRED(NEXT_I_SCSI));
434 
435 	if (r) {
436 
437 		{
438 			int flushcount;
439 			int s;
440 			s = spldma();
441 
442 			flushcount = 0;
443 
444 #ifdef ESP_DEBUG
445 			esp_dma_nest++;
446 
447 			if (esp_debug) {
448 				char sbuf[256];
449 
450 				bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)),
451 						 NEXT_INTR_BITS, sbuf, sizeof(sbuf));
452 				printf("esp_dma_isintr = 0x%s\n", sbuf);
453 			}
454 #endif
455 
456 			while (esp_dma_isactive(sc)) {
457 				flushcount++;
458 
459 #ifdef DIAGNOSTIC
460 				r = (INTR_OCCURRED(NEXT_I_SCSI));
461 				if (!r) panic("esp intr enabled but dma failed to flush");
462 #endif
463 #ifdef DIAGNOSTIC
464 #if 0
465 				if ((esc->sc_loaded & (ESP_LOADED_TAIL/* |ESP_UNLOADED_MAIN */))
466 						!= (ESP_LOADED_TAIL /* |ESP_UNLOADED_MAIN */)) {
467 					if (esc->sc_datain) {
468 						NCR_WRITE_REG(sc, ESP_DCTL,
469 								ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
470 					} else {
471 						NCR_WRITE_REG(sc, ESP_DCTL,
472 								ESPDCTL_20MHZ | ESPDCTL_INTENB);
473 					}
474 					next_dma_print(&esc->sc_scsi_dma);
475 					esp_dma_print(sc);
476 					printf("%s: unexpected flush: tc=0x%06x\n",
477 							sc->sc_dev.dv_xname,
478 							(((sc->sc_cfg2 & NCRCFG2_FE)
479 									? NCR_READ_REG(sc, NCR_TCH) : 0)<<16)|
480 							(NCR_READ_REG(sc, NCR_TCM)<<8)|
481 							NCR_READ_REG(sc, NCR_TCL));
482 					ncr53c9x_readregs(sc);
483 					printf("%s: readregs[intr=%02x,stat=%02x,step=%02x]\n",
484 							sc->sc_dev.dv_xname,
485 							sc->sc_espintr, sc->sc_espstat, sc->sc_espstep);
486 					panic("%s: flushing flushing non-tail dma\n",
487 							sc->sc_dev.dv_xname);
488 				}
489 #endif
490 #endif
491 				DPRINTF(("%s: flushing dma, count = %d\n", sc->sc_dev.dv_xname,flushcount));
492 				if (esc->sc_datain) {
493 					NCR_WRITE_REG(sc, ESP_DCTL,
494 							ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD | ESPDCTL_FLUSH);
495 					DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
496 					NCR_WRITE_REG(sc, ESP_DCTL,
497 							ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD);
498 				} else {
499 					NCR_WRITE_REG(sc, ESP_DCTL,
500 							ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_FLUSH);
501 					DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
502 					NCR_WRITE_REG(sc, ESP_DCTL,
503 							ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD);
504 				}
505 				DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
506 
507 				{
508 					int nr;
509 					nr = nextdma_intr(&esc->sc_scsi_dma);
510 					if (nr) {
511 						DPRINTF(("nextma_intr = %d\n",nr));
512 #ifdef DIAGNOSTIC
513 						if (flushcount > 4) {
514 							printf("%s: unexpected flushcount %d\n",sc->sc_dev.dv_xname,flushcount);
515 						}
516 #endif
517 #ifdef DIAGNOSTIC
518 #if 0
519 						if (esp_dma_isactive(sc)) {
520 							esp_dma_print(sc);
521 							printf("%s: dma still active after a flush with count %d\n",
522 									sc->sc_dev.dv_xname,flushcount);
523 
524 						}
525 #endif
526 #endif
527 						flushcount = 0;
528 					}
529 				}
530 			}
531 
532 #ifdef ESP_DEBUG
533 			esp_dma_nest--;
534 #endif
535 
536 			splx(s);
537 		}
538 
539 #ifdef DIAGNOSTIC
540 		r = (INTR_OCCURRED(NEXT_I_SCSI));
541 		if (!r) panic("esp intr not enabled after dma flush");
542 #endif
543 
544 		/* Clear the DMAMOD bit in the DCTL register, since if this
545 		 * routine returns true, then the ncr53c9x_intr handler will
546 		 * be called and needs access to the scsi registers.
547 		 */
548 		if (esc->sc_datain) {
549 			NCR_WRITE_REG(sc, ESP_DCTL,
550 					ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
551 		} else {
552 			NCR_WRITE_REG(sc, ESP_DCTL,
553 					ESPDCTL_20MHZ | ESPDCTL_INTENB);
554 		}
555 		DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
556 
557 	}
558 
559 	return (r);
560 }
561 
562 void
563 esp_dma_reset(sc)
564 	struct ncr53c9x_softc *sc;
565 {
566 	struct esp_softc *esc = (struct esp_softc *)sc;
567 
568 	DPRINTF(("esp dma reset\n"));
569 
570 #ifdef ESP_DEBUG
571 	if (esp_debug) {
572 		char sbuf[256];
573 
574 		bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)),
575 				 NEXT_INTR_BITS, sbuf, sizeof(sbuf));
576 		printf("  *intrstat = 0x%s\n", sbuf);
577 
578 		bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRMASK)),
579 				 NEXT_INTR_BITS, sbuf, sizeof(sbuf));
580 		printf("  *intrmask = 0x%s\n", sbuf);
581 	}
582 #endif
583 
584 	/* Clear the DMAMOD bit in the DCTL register: */
585 	NCR_WRITE_REG(sc, ESP_DCTL,
586 			ESPDCTL_20MHZ | ESPDCTL_INTENB);
587 	DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
588 
589 	nextdma_reset(&esc->sc_scsi_dma);
590 
591 	esc->sc_datain = -1;
592 	esc->sc_dmaaddr = 0;
593 	esc->sc_dmalen  = 0;
594 	esc->sc_dmasize = 0;
595 
596 	esc->sc_loaded = 0;
597 
598 	esc->sc_begin = 0;
599 	esc->sc_begin_size = 0;
600 
601 	if (esc->sc_main_dmamap->dm_mapsize) {
602 		bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap);
603 	}
604 	esc->sc_main = 0;
605 	esc->sc_main_size = 0;
606 
607 	if (esc->sc_tail_dmamap->dm_mapsize) {
608 		bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap);
609 	}
610 	esc->sc_tail = 0;
611 	esc->sc_tail_size = 0;
612 }
613 
614 int
615 esp_dma_intr(sc)
616 	struct ncr53c9x_softc *sc;
617 {
618 #ifdef DIAGNOSTIC
619 	panic("%s: esp_dma_intr shouldn't be invoked.\n", sc->sc_dev.dv_xname);
620 #endif
621 
622 	return -1;
623 }
624 
625 /* it appears that:
626  * addr and len arguments to this need to be kept up to date
627  * with the status of the transfter.
628  * the dmasize of this is the actual length of the transfer
629  * request, which is guaranteed to be less than maxxfer.
630  * (len may be > maxxfer)
631  */
632 
633 int
634 esp_dma_setup(sc, addr, len, datain, dmasize)
635 	struct ncr53c9x_softc *sc;
636 	caddr_t *addr;
637 	size_t *len;
638 	int datain;
639 	size_t *dmasize;
640 {
641 	struct esp_softc *esc = (struct esp_softc *)sc;
642 
643 #ifdef DIAGNOSTIC
644 #ifdef ESP_DEBUG
645 	/* if this is a read DMA, pre-fill the buffer with 0xdeadbeef
646 	 * to identify bogus reads
647 	 */
648 	if (datain) {
649 		int *v = (int *)(*addr);
650 		int i;
651 		for(i=0;i<((*len)/4);i++) v[i] = 0xdeadbeef;
652 		v = (int *)(&(esc->sc_tailbuf[0]));
653 		for(i=0;i<((sizeof(esc->sc_tailbuf)/4));i++) v[i] = 0xdeaffeed;
654 	} else {
655 		int *v;
656 		int i;
657 		v = (int *)(&(esc->sc_tailbuf[0]));
658 		for(i=0;i<((sizeof(esc->sc_tailbuf)/4));i++) v[i] = 0xfeeb1eed;
659 	}
660 #endif
661 #endif
662 
663 	DPRINTF(("esp_dma_setup(%p,0x%08x,0x%08x)\n",*addr,*len,*dmasize));
664 
665 #if 0
666 #ifdef DIAGNOSTIC /* @@@ this is ok sometimes. verify that we handle it ok
667 									 * and then remove this check
668 									 */
669 	if (*len != *dmasize) {
670 		panic("esp dmalen 0x%lx != size 0x%lx",*len,*dmasize);
671 	}
672 #endif
673 #endif
674 
675 #ifdef DIAGNOSTIC
676 	if ((esc->sc_datain != -1) ||
677 			(esc->sc_main_dmamap->dm_mapsize != 0) ||
678 			(esc->sc_tail_dmamap->dm_mapsize != 0) ||
679 			(esc->sc_dmasize != 0)) {
680 		panic("%s: map already loaded in esp_dma_setup\n"
681 				"\tdatain = %d\n\tmain_mapsize=%ld\n\tail_mapsize=%ld\n\tdmasize = %d",
682 				sc->sc_dev.dv_xname, esc->sc_datain,
683 				esc->sc_main_dmamap->dm_mapsize,
684 				esc->sc_tail_dmamap->dm_mapsize,
685 				esc->sc_dmasize);
686 	}
687 #endif
688 
689 	/* we are sometimes asked to dma zero  bytes, that's easy */
690 	if (*dmasize <= 0) {
691 		return(0);
692 	}
693 
694 	/* Save these in case we have to abort DMA */
695 	esc->sc_datain   = datain;
696 	esc->sc_dmaaddr  = addr;
697 	esc->sc_dmalen   = len;
698 	esc->sc_dmasize  = *dmasize;
699 
700 	esc->sc_loaded = 0;
701 
702 #define DMA_SCSI_ALIGNMENT 16
703 #define DMA_SCSI_ALIGN(type, addr)	\
704 	((type)(((unsigned)(addr)+DMA_SCSI_ALIGNMENT-1) \
705 		&~(DMA_SCSI_ALIGNMENT-1)))
706 #define DMA_SCSI_ALIGNED(addr) \
707 	(((unsigned)(addr)&(DMA_SCSI_ALIGNMENT-1))==0)
708 
709 	{
710 		size_t slop_bgn_size; /* # bytes to be fifo'd at beginning */
711 		size_t slop_end_size; /* # bytes to be transferred in tail buffer */
712 
713 		{
714 			u_long bgn = (u_long)(*esc->sc_dmaaddr);
715 			u_long end = (u_long)(*esc->sc_dmaaddr+esc->sc_dmasize);
716 
717 			slop_bgn_size = DMA_SCSI_ALIGNMENT-(bgn % DMA_SCSI_ALIGNMENT);
718 			if (slop_bgn_size == DMA_SCSI_ALIGNMENT) slop_bgn_size = 0;
719 			slop_end_size = (end % DMA_ENDALIGNMENT);
720 		}
721 
722 		/* Force a minimum slop end size. This ensures that write
723 		 * requests will overrun, as required to get completion interrupts.
724 		 * In addition, since the tail buffer is guaranteed to be mapped
725 		 * in a single dma segment, the overrun won't accidentally
726 		 * end up in its own segment.
727 		 */
728 		if (!esc->sc_datain) {
729 #if 0
730 			slop_end_size += ESP_DMA_MAXTAIL;
731 #else
732 			slop_end_size += 0x10;
733 #endif
734 		}
735 
736 		/* Check to make sure we haven't counted extra slop
737 		 * as would happen for a very short dma buffer, also
738 		 * for short buffers, just stuff the entire thing in the tail
739 		 */
740 		if ((slop_bgn_size+slop_end_size >= esc->sc_dmasize)
741 #if 0
742 				|| (esc->sc_dmasize <= ESP_DMA_MAXTAIL)
743 #endif
744 				)
745 		{
746  			slop_bgn_size = 0;
747 			slop_end_size = esc->sc_dmasize;
748 		}
749 
750 		/* initialize the fifo buffer */
751 		if (slop_bgn_size) {
752 			esc->sc_begin = *esc->sc_dmaaddr;
753 			esc->sc_begin_size = slop_bgn_size;
754 		} else {
755 			esc->sc_begin = 0;
756 			esc->sc_begin_size = 0;
757 		}
758 
759 		/* Load the normal DMA map */
760 		{
761 			esc->sc_main      = *esc->sc_dmaaddr+slop_bgn_size;
762 			esc->sc_main_size = (esc->sc_dmasize)-(slop_end_size+slop_bgn_size);
763 
764 			if (esc->sc_main_size) {
765 				int error;
766 				error = bus_dmamap_load(esc->sc_scsi_dma.nd_dmat,
767 						esc->sc_main_dmamap,
768 						esc->sc_main, esc->sc_main_size,
769 						NULL, BUS_DMA_NOWAIT);
770 				if (error) {
771 #ifdef ESP_DEBUG
772 					printf("%s: esc->sc_main_dmamap->_dm_size = %ld\n",
773 							sc->sc_dev.dv_xname,esc->sc_main_dmamap->_dm_size);
774 					printf("%s: esc->sc_main_dmamap->_dm_segcnt = %d\n",
775 							sc->sc_dev.dv_xname,esc->sc_main_dmamap->_dm_segcnt);
776 					printf("%s: esc->sc_main_dmamap->_dm_maxsegsz = %ld\n",
777 							sc->sc_dev.dv_xname,esc->sc_main_dmamap->_dm_maxsegsz);
778 					printf("%s: esc->sc_main_dmamap->_dm_boundary = %ld\n",
779 							sc->sc_dev.dv_xname,esc->sc_main_dmamap->_dm_boundary);
780 					esp_dma_print(sc);
781 #endif
782 					panic("%s: can't load main dma map. error = %d, addr=%p, size=0x%08x",
783 							sc->sc_dev.dv_xname, error,esc->sc_main,esc->sc_main_size);
784 				}
785 #if 0
786 				bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap,
787 						0, esc->sc_main_dmamap->dm_mapsize,
788 						(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
789 				esc->sc_main_dmamap->dm_xfer_len = 0;
790 #endif
791 			} else {
792 				esc->sc_main = 0;
793 			}
794 		}
795 
796 		/* Load the tail DMA map */
797 		if (slop_end_size) {
798 			esc->sc_tail      = DMA_ENDALIGN(caddr_t,esc->sc_tailbuf+slop_end_size)-slop_end_size;
799 			/* If the beginning of the tail is not correctly aligned,
800 			 * we have no choice but to align the start, which might then unalign the end.
801 			 */
802 			esc->sc_tail      = DMA_SCSI_ALIGN(caddr_t,esc->sc_tail);
803 			/* So therefore, we change the tail size to be end aligned again. */
804 			esc->sc_tail_size = DMA_ENDALIGN(caddr_t,esc->sc_tail+slop_end_size)-esc->sc_tail;
805 
806 			/* @@@ next dma overrun lossage */
807 			if (!esc->sc_datain) {
808 				esc->sc_tail_size += ESP_DMA_OVERRUN;
809 			}
810 
811 			{
812 				int error;
813 				error = bus_dmamap_load(esc->sc_scsi_dma.nd_dmat,
814 						esc->sc_tail_dmamap,
815 						esc->sc_tail, esc->sc_tail_size,
816 						NULL, BUS_DMA_NOWAIT);
817 				if (error) {
818 					panic("%s: can't load tail dma map. error = %d, addr=%p, size=0x%08x",
819 							sc->sc_dev.dv_xname, error,esc->sc_tail,esc->sc_tail_size);
820 				}
821 #if 0
822 				bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap,
823 						0, esc->sc_tail_dmamap->dm_mapsize,
824 						(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
825 				esc->sc_tail_dmamap->dm_xfer_len = 0;
826 #endif
827 			}
828 		}
829 	}
830 
831 	return (0);
832 }
833 
834 #ifdef ESP_DEBUG
835 /* For debugging */
836 void
837 esp_dma_store(sc)
838 	struct ncr53c9x_softc *sc;
839 {
840 	struct esp_softc *esc = (struct esp_softc *)sc;
841 	char *p = &esp_dma_dump[0];
842 
843 	p += sprintf(p,"%s: sc_datain=%d\n",sc->sc_dev.dv_xname,esc->sc_datain);
844 	p += sprintf(p,"%s: sc_loaded=0x%08x\n",sc->sc_dev.dv_xname,esc->sc_loaded);
845 
846 	if (esc->sc_dmaaddr) {
847 		p += sprintf(p,"%s: sc_dmaaddr=%p\n",sc->sc_dev.dv_xname,*esc->sc_dmaaddr);
848 	} else {
849 		p += sprintf(p,"%s: sc_dmaaddr=NULL\n",sc->sc_dev.dv_xname);
850 	}
851 	if (esc->sc_dmalen) {
852 		p += sprintf(p,"%s: sc_dmalen=0x%08x\n",sc->sc_dev.dv_xname,*esc->sc_dmalen);
853 	} else {
854 		p += sprintf(p,"%s: sc_dmalen=NULL\n",sc->sc_dev.dv_xname);
855 	}
856 	p += sprintf(p,"%s: sc_dmasize=0x%08x\n",sc->sc_dev.dv_xname,esc->sc_dmasize);
857 
858 	p += sprintf(p,"%s: sc_begin = %p, sc_begin_size = 0x%08x\n",
859 			sc->sc_dev.dv_xname, esc->sc_begin, esc->sc_begin_size);
860 	p += sprintf(p,"%s: sc_main = %p, sc_main_size = 0x%08x\n",
861 			sc->sc_dev.dv_xname, esc->sc_main, esc->sc_main_size);
862 	{
863 		int i;
864 		bus_dmamap_t map = esc->sc_main_dmamap;
865 		p += sprintf(p,"%s: sc_main_dmamap. mapsize = 0x%08lx, nsegs = %d\n",
866 				sc->sc_dev.dv_xname, map->dm_mapsize, map->dm_nsegs);
867 		for(i=0;i<map->dm_nsegs;i++) {
868 			p += sprintf(p,"%s: map->dm_segs[%d].ds_addr = 0x%08lx, len = 0x%08lx\n",
869 			sc->sc_dev.dv_xname, i, map->dm_segs[i].ds_addr, map->dm_segs[i].ds_len);
870 		}
871 	}
872 	p += sprintf(p,"%s: sc_tail = %p, sc_tail_size = 0x%08x\n",
873 			sc->sc_dev.dv_xname, esc->sc_tail, esc->sc_tail_size);
874 	{
875 		int i;
876 		bus_dmamap_t map = esc->sc_tail_dmamap;
877 		p += sprintf(p,"%s: sc_tail_dmamap. mapsize = 0x%08lx, nsegs = %d\n",
878 				sc->sc_dev.dv_xname, map->dm_mapsize, map->dm_nsegs);
879 		for(i=0;i<map->dm_nsegs;i++) {
880 			p += sprintf(p,"%s: map->dm_segs[%d].ds_addr = 0x%08lx, len = 0x%08lx\n",
881 			sc->sc_dev.dv_xname, i, map->dm_segs[i].ds_addr, map->dm_segs[i].ds_len);
882 		}
883 	}
884 }
885 
886 void
887 esp_dma_print(sc)
888 	struct ncr53c9x_softc *sc;
889 {
890 	esp_dma_store(sc);
891 	printf("%s",esp_dma_dump);
892 }
893 #endif
894 
895 void
896 esp_dma_go(sc)
897 	struct ncr53c9x_softc *sc;
898 {
899 	struct esp_softc *esc = (struct esp_softc *)sc;
900 
901 	DPRINTF(("%s: esp_dma_go(datain = %d)\n",
902 			sc->sc_dev.dv_xname, esc->sc_datain));
903 
904 #ifdef ESP_DEBUG
905 	if (esp_debug) esp_dma_print(sc);
906 	else esp_dma_store(sc);
907 #endif
908 
909 #ifdef ESP_DEBUG
910 	{
911 		int n = NCR_READ_REG(sc, NCR_FFLAG);
912 		DPRINTF(("%s: fifo size = %d, seq = 0x%x\n",
913 				sc->sc_dev.dv_xname,
914 				n & NCRFIFO_FF, (n & NCRFIFO_SS)>>5));
915 	}
916 #endif
917 
918 	/* zero length dma transfers are boring */
919 	if (esc->sc_dmasize == 0) {
920 		return;
921 	}
922 
923 #if defined(DIAGNOSTIC)
924   if ((esc->sc_begin_size == 0) &&
925 			(esc->sc_main_dmamap->dm_mapsize == 0) &&
926 			(esc->sc_tail_dmamap->dm_mapsize == 0)) {
927 		esp_dma_print(sc);
928 		panic("%s: No DMA requested!",sc->sc_dev.dv_xname);
929 	}
930 #endif
931 
932 	/* Stuff the fifo with the begin buffer */
933 	if (esc->sc_datain) {
934 		int i;
935 		DPRINTF(("%s: FIFO read of %d bytes:",
936 				sc->sc_dev.dv_xname,esc->sc_begin_size));
937 		for(i=0;i<esc->sc_begin_size;i++) {
938 			esc->sc_begin[i]=NCR_READ_REG(sc, NCR_FIFO);
939 			DPRINTF((" %02x",esc->sc_begin[i]&0xff));
940 		}
941 		DPRINTF(("\n"));
942 	} else {
943 		int i;
944 		DPRINTF(("%s: FIFO write of %d bytes:",
945 				sc->sc_dev.dv_xname,esc->sc_begin_size));
946 		for(i=0;i<esc->sc_begin_size;i++) {
947 			NCR_WRITE_REG(sc, NCR_FIFO, esc->sc_begin[i]);
948 			DPRINTF((" %02x",esc->sc_begin[i]&0xff));
949 		}
950 		DPRINTF(("\n"));
951 	}
952 
953 	/* if we are a dma write cycle, copy the end slop */
954 	if (esc->sc_datain == 0) {
955 		memcpy(esc->sc_tail,
956 				(*esc->sc_dmaaddr+esc->sc_begin_size+esc->sc_main_size),
957 				(esc->sc_dmasize-(esc->sc_begin_size+esc->sc_main_size)));
958 	}
959 
960 	if (esc->sc_main_dmamap->dm_mapsize) {
961 		bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap,
962 				0, esc->sc_main_dmamap->dm_mapsize,
963 				(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
964 		esc->sc_main_dmamap->dm_xfer_len = 0;
965 	}
966 
967 	if (esc->sc_tail_dmamap->dm_mapsize) {
968 		bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap,
969 				0, esc->sc_tail_dmamap->dm_mapsize,
970 				(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
971 		esc->sc_tail_dmamap->dm_xfer_len = 0;
972 	}
973 
974 	nextdma_start(&esc->sc_scsi_dma,
975 			(esc->sc_datain ? DMACSR_SETREAD : DMACSR_SETWRITE));
976 
977 	if (esc->sc_datain) {
978 		NCR_WRITE_REG(sc, ESP_DCTL,
979 				ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD);
980 	} else {
981 		NCR_WRITE_REG(sc, ESP_DCTL,
982 				ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD);
983 	}
984 	DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
985 }
986 
987 void
988 esp_dma_stop(sc)
989 	struct ncr53c9x_softc *sc;
990 {
991 	struct esp_softc *esc = (struct esp_softc *)sc;
992 	next_dma_print(&esc->sc_scsi_dma);
993 	esp_dma_print(sc);
994 	panic("%s: stop not yet implemented\n",sc->sc_dev.dv_xname);
995 }
996 
997 int
998 esp_dma_isactive(sc)
999 	struct ncr53c9x_softc *sc;
1000 {
1001 	struct esp_softc *esc = (struct esp_softc *)sc;
1002 	int r = !nextdma_finished(&esc->sc_scsi_dma);
1003 	DPRINTF(("esp_dma_isactive = %d\n",r));
1004 	return(r);
1005 }
1006 
1007 /****************************************************************/
1008 
1009 /* Internal dma callback routines */
1010 bus_dmamap_t
1011 esp_dmacb_continue(arg)
1012 	void *arg;
1013 {
1014 	struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
1015 	struct esp_softc *esc = (struct esp_softc *)sc;
1016 
1017 	DPRINTF(("%s: dma continue\n",sc->sc_dev.dv_xname));
1018 
1019 #ifdef DIAGNOSTIC
1020 	if ((esc->sc_datain < 0) || (esc->sc_datain > 1)) {
1021 		panic("%s: map not loaded in dma continue callback, datain = %d",
1022 				sc->sc_dev.dv_xname,esc->sc_datain);
1023 	}
1024 #endif
1025 
1026 	if ((!(esc->sc_loaded & ESP_LOADED_MAIN)) &&
1027 			(esc->sc_main_dmamap->dm_mapsize)) {
1028 			DPRINTF(("%s: Loading main map\n",sc->sc_dev.dv_xname));
1029 #if 0
1030 			bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap,
1031 					0, esc->sc_main_dmamap->dm_mapsize,
1032 					(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
1033 			esc->sc_main_dmamap->dm_xfer_len = 0;
1034 #endif
1035 			esc->sc_loaded |= ESP_LOADED_MAIN;
1036 			return(esc->sc_main_dmamap);
1037 	}
1038 
1039 	if ((!(esc->sc_loaded & ESP_LOADED_TAIL)) &&
1040 			(esc->sc_tail_dmamap->dm_mapsize)) {
1041 			DPRINTF(("%s: Loading tail map\n",sc->sc_dev.dv_xname));
1042 #if 0
1043 			bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap,
1044 					0, esc->sc_tail_dmamap->dm_mapsize,
1045 					(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
1046 			esc->sc_tail_dmamap->dm_xfer_len = 0;
1047 #endif
1048 			esc->sc_loaded |= ESP_LOADED_TAIL;
1049 			return(esc->sc_tail_dmamap);
1050 	}
1051 
1052 	DPRINTF(("%s: not loading map\n",sc->sc_dev.dv_xname));
1053 	return(0);
1054 }
1055 
1056 
1057 void
1058 esp_dmacb_completed(map, arg)
1059 	bus_dmamap_t map;
1060 	void *arg;
1061 {
1062 	struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
1063 	struct esp_softc *esc = (struct esp_softc *)sc;
1064 
1065 	DPRINTF(("%s: dma completed\n",sc->sc_dev.dv_xname));
1066 
1067 #ifdef DIAGNOSTIC
1068 	if ((esc->sc_datain < 0) || (esc->sc_datain > 1)) {
1069 		panic("%s: invalid dma direction in completed callback, datain = %d",
1070 				sc->sc_dev.dv_xname,esc->sc_datain);
1071 	}
1072 #endif
1073 
1074 #if defined(DIAGNOSTIC) && 0
1075 	{
1076 		int i;
1077 		for(i=0;i<map->dm_nsegs;i++) {
1078 			if (map->dm_xfer_len != map->dm_mapsize) {
1079 				printf("%s: map->dm_mapsize = %d\n", sc->sc_dev.dv_xname,map->dm_mapsize);
1080 				printf("%s: map->dm_nsegs = %d\n", sc->sc_dev.dv_xname,map->dm_nsegs);
1081 				printf("%s: map->dm_xfer_len = %d\n", sc->sc_dev.dv_xname,map->dm_xfer_len);
1082 				for(i=0;i<map->dm_nsegs;i++) {
1083 					printf("%s: map->dm_segs[%d].ds_addr = 0x%08lx\n",
1084 							sc->sc_dev.dv_xname,i,map->dm_segs[i].ds_addr);
1085 					printf("%s: map->dm_segs[%d].ds_len = %d\n",
1086 							sc->sc_dev.dv_xname,i,map->dm_segs[i].ds_len);
1087 				}
1088 				panic("%s: incomplete dma transfer\n",sc->sc_dev.dv_xname);
1089 			}
1090 		}
1091 	}
1092 #endif
1093 
1094 	if (map == esc->sc_main_dmamap) {
1095 #ifdef DIAGNOSTIC
1096 		if ((esc->sc_loaded & ESP_UNLOADED_MAIN) ||
1097 				!(esc->sc_loaded & ESP_LOADED_MAIN)) {
1098 			panic("%s: unexpected completed call for main map\n",sc->sc_dev.dv_xname);
1099 		}
1100 #endif
1101 		esc->sc_loaded |= ESP_UNLOADED_MAIN;
1102 	} else if (map == esc->sc_tail_dmamap) {
1103 #ifdef DIAGNOSTIC
1104 		if ((esc->sc_loaded & ESP_UNLOADED_TAIL) ||
1105 				!(esc->sc_loaded & ESP_LOADED_TAIL)) {
1106 			panic("%s: unexpected completed call for tail map\n",sc->sc_dev.dv_xname);
1107 		}
1108 #endif
1109 		esc->sc_loaded |= ESP_UNLOADED_TAIL;
1110 	}
1111 #ifdef DIAGNOSTIC
1112 	 else {
1113 		panic("%s: unexpected completed map", sc->sc_dev.dv_xname);
1114 	}
1115 #endif
1116 
1117 #ifdef ESP_DEBUG
1118 	if (esp_debug) {
1119 		if (map == esc->sc_main_dmamap) {
1120 			printf("%s: completed main map\n",sc->sc_dev.dv_xname);
1121 		} else if (map == esc->sc_tail_dmamap) {
1122 			printf("%s: completed tail map\n",sc->sc_dev.dv_xname);
1123 		}
1124 	}
1125 #endif
1126 
1127 #if 0
1128 	if ((map == esc->sc_tail_dmamap) ||
1129 			((esc->sc_tail_size == 0) && (map == esc->sc_main_dmamap))) {
1130 
1131 		/* Clear the DMAMOD bit in the DCTL register to give control
1132 		 * back to the scsi chip.
1133 		 */
1134 		if (esc->sc_datain) {
1135 			NCR_WRITE_REG(sc, ESP_DCTL,
1136 					ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
1137 		} else {
1138 			NCR_WRITE_REG(sc, ESP_DCTL,
1139 					ESPDCTL_20MHZ | ESPDCTL_INTENB);
1140 		}
1141 		DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
1142 	}
1143 #endif
1144 
1145 
1146 #if 0
1147 	bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, map,
1148 			0, map->dm_mapsize,
1149 			(esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
1150 #endif
1151 
1152 }
1153 
1154 void
1155 esp_dmacb_shutdown(arg)
1156 	void *arg;
1157 {
1158 	struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
1159 	struct esp_softc *esc = (struct esp_softc *)sc;
1160 	bus_size_t xfer_len = 0;
1161 
1162 	DPRINTF(("%s: dma shutdown\n",sc->sc_dev.dv_xname));
1163 
1164 #if 0
1165 	{
1166 		/* Clear the DMAMOD bit in the DCTL register to give control
1167 		 * back to the scsi chip.
1168 		 */
1169 		if (esc->sc_datain) {
1170 			NCR_WRITE_REG(sc, ESP_DCTL,
1171 					ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
1172 		} else {
1173 			NCR_WRITE_REG(sc, ESP_DCTL,
1174 					ESPDCTL_20MHZ | ESPDCTL_INTENB);
1175 		}
1176 		DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
1177 	}
1178 #endif
1179 
1180 	DPRINTF(("%s: esp_dma_nest == %d\n",sc->sc_dev.dv_xname,esp_dma_nest));
1181 
1182 	/* Stuff the end slop into fifo */
1183 
1184 #ifdef ESP_DEBUG
1185 	if (esp_debug) {
1186 
1187 		int n = NCR_READ_REG(sc, NCR_FFLAG);
1188 		DPRINTF(("%s: fifo size = %d, seq = 0x%x\n",
1189 				sc->sc_dev.dv_xname,n & NCRFIFO_FF, (n & NCRFIFO_SS)>>5));
1190 	}
1191 #endif
1192 
1193 	xfer_len += esc->sc_begin_size;
1194 
1195 	if (esc->sc_main_dmamap->dm_mapsize) {
1196 		xfer_len += esc->sc_main_dmamap->dm_xfer_len;
1197 		bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap,
1198 			0, esc->sc_main_dmamap->dm_mapsize,
1199 				(esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
1200 		bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap);
1201 	}
1202 
1203 	if (esc->sc_tail_dmamap->dm_mapsize) {
1204 		xfer_len += esc->sc_tail_dmamap->dm_xfer_len;
1205 		bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap,
1206 			0, esc->sc_tail_dmamap->dm_mapsize,
1207 				(esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
1208 		bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap);
1209 	}
1210 
1211 	/* truncate in case tail overran */
1212 	if (xfer_len > esc->sc_dmasize) {
1213 		xfer_len = esc->sc_dmasize;
1214 	}
1215 
1216 	/* copy the tail dma buffer data for read transfers */
1217 	if (esc->sc_datain == 1) {
1218 		memcpy((*esc->sc_dmaaddr+esc->sc_begin_size+esc->sc_main_size),
1219 				esc->sc_tail,
1220 				(esc->sc_dmasize-(esc->sc_begin_size+esc->sc_main_size)));
1221 	}
1222 
1223 #ifdef ESP_DEBUG
1224 	if (esp_debug) {
1225 		printf("%s: dma_shutdown: addr=%p,len=0x%08x,size=0x%08x\n",
1226 				sc->sc_dev.dv_xname,
1227 				*esc->sc_dmaaddr, *esc->sc_dmalen, esc->sc_dmasize);
1228 		if (esp_debug > 10) {
1229 			esp_hex_dump(*(esc->sc_dmaaddr),esc->sc_dmasize);
1230 			printf("%s: tail=%p,tailbuf=%p,tail_size=0x%08x\n",
1231 					sc->sc_dev.dv_xname,
1232 					esc->sc_tail, &(esc->sc_tailbuf[0]), esc->sc_tail_size);
1233 			esp_hex_dump(&(esc->sc_tailbuf[0]),sizeof(esc->sc_tailbuf));
1234 		}
1235 	}
1236 #endif
1237 
1238 #if 0
1239 	KASSERT(xfer_len == esc->sc_dmasize);
1240 #endif
1241 
1242 	*(esc->sc_dmaaddr) += xfer_len;
1243 	*(esc->sc_dmalen)  -= xfer_len;
1244 
1245 	esc->sc_main = 0;
1246 	esc->sc_main_size = 0;
1247 	esc->sc_tail = 0;
1248 	esc->sc_tail_size = 0;
1249 
1250 	esc->sc_datain = -1;
1251 	esc->sc_dmaaddr = 0;
1252 	esc->sc_dmalen  = 0;
1253 	esc->sc_dmasize = 0;
1254 
1255 	esc->sc_loaded = 0;
1256 
1257 	esc->sc_begin = 0;
1258 	esc->sc_begin_size = 0;
1259 
1260 #ifdef ESP_DEBUG
1261 	if (esp_debug) {
1262 		char sbuf[256];
1263 
1264 		bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)),
1265 				 NEXT_INTR_BITS, sbuf, sizeof(sbuf));
1266 		printf("  *intrstat = 0x%s\n", sbuf);
1267 
1268 		bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRMASK)),
1269 				 NEXT_INTR_BITS, sbuf, sizeof(sbuf));
1270 		printf("  *intrmask = 0x%s\n", sbuf);
1271 	}
1272 #endif
1273 }
1274