xref: /netbsd-src/sys/dev/isa/esp_isa.c (revision fdecd6a253f999ae92b139670d9e15cc9df4497c)
1 /*	$NetBSD: esp_isa.c,v 1.3 1997/06/06 23:43:48 thorpej Exp $	*/
2 
3 /*
4  * Copyright (c) 1997 Jason R. Thorpe.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed for the NetBSD Project
18  *	by Jason R. Thorpe.
19  * 4. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * Copyright (c) 1994 Peter Galbavy
36  * Copyright (c) 1995 Paul Kranenburg
37  * All rights reserved.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions
41  * are met:
42  * 1. Redistributions of source code must retain the above copyright
43  *    notice, this list of conditions and the following disclaimer.
44  * 2. Redistributions in binary form must reproduce the above copyright
45  *    notice, this list of conditions and the following disclaimer in the
46  *    documentation and/or other materials provided with the distribution.
47  * 3. All advertising materials mentioning features or use of this software
48  *    must display the following acknowledgement:
49  *	This product includes software developed by Peter Galbavy
50  * 4. The name of the author may not be used to endorse or promote products
51  *    derived from this software without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
54  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
55  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
56  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
57  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
58  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
59  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
61  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
62  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
63  * POSSIBILITY OF SUCH DAMAGE.
64  */
65 
66 /*
67  * Based on aic6360 by Jarle Greipsland
68  *
69  * Acknowledgements: Many of the algorithms used in this driver are
70  * inspired by the work of Julian Elischer (julian@tfs.com) and
71  * Charles Hannum (mycroft@duality.gnu.ai.mit.edu).  Thanks a million!
72  */
73 
74 /*
75  * Initial m68k mac support from Allen Briggs <briggs@macbsd.com>
76  * (basically consisting of the match, a bit of the attach, and the
77  *  "DMA" glue functions).
78  */
79 /*
80  * Copyright (c) 1994, 1996, 1997 Charles M. Hannum.  All rights reserved.
81  *
82  * Redistribution and use in source and binary forms, with or without
83  * modification, are permitted provided that the following conditions
84  * are met:
85  * 1. Redistributions of source code must retain the above copyright
86  *    notice, this list of conditions and the following disclaimer.
87  * 2. Redistributions in binary form must reproduce the above copyright
88  *    notice, this list of conditions and the following disclaimer in the
89  *    documentation and/or other materials provided with the distribution.
90  * 3. All advertising materials mentioning features or use of this software
91  *    must display the following acknowledgement:
92  *	This product includes software developed by Charles M. Hannum.
93  * 4. The name of the author may not be used to endorse or promote products
94  *    derived from this software without specific prior written permission.
95  *
96  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
97  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
98  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
99  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
100  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
101  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
102  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
103  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
105  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
106  */
107 
108 /*
109  * Copyright (c) 1997 Eric S. Hvozda (hvozda@netcom.com)
110  * All rights reserved.
111  *
112  * Redistribution and use in source and binary forms, with or without
113  * modification, are permitted provided that the following conditions
114  * are met:
115  * 1. Redistributions of source code must retain the above copyright
116  *    notice, this list of conditions and the following disclaimer.
117  * 2. Redistributions in binary form must reproduce the above copyright
118  *    notice, this list of conditions and the following disclaimer in the
119  *    documentation and/or other materials provided with the distribution.
120  * 3. All advertising materials mentioning features or use of this software
121  *    must display the following acknowledgement:
122  *      This product includes software developed by Eric S. Hvozda.
123  * 4. The name of Eric S. Hvozda may not be used to endorse or promote products
124  *    derived from this software without specific prior written permission.
125  *
126  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
127  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
128  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
129  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
130  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
131  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
132  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
133  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
134  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
135  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
136  */
137 
138 #include <sys/param.h>
139 #include <sys/systm.h>
140 #include <sys/device.h>
141 #include <sys/buf.h>
142 
143 #include <machine/bus.h>
144 #include <machine/intr.h>
145 
146 #include <scsi/scsi_all.h>
147 #include <scsi/scsiconf.h>
148 
149 #include <dev/isa/isavar.h>
150 #include <dev/isa/isadmavar.h>
151 
152 #include <dev/ic/ncr53c9xreg.h>
153 #include <dev/ic/ncr53c9xvar.h>
154 
155 #include <dev/isa/espvar.h>
156 
157 int	esp_isa_match __P((struct device *, void *, void *));
158 void	esp_isa_attach __P((struct device *, struct device *, void *));
159 
160 struct cfattach esp_isa_ca = {
161 	sizeof(struct esp_softc), esp_isa_match, esp_isa_attach
162 };
163 
164 struct cfdriver esp_cd = {
165 	NULL, "esp", DV_DULL
166 };
167 
168 struct scsi_adapter esp_switch = {
169 	ncr53c9x_scsi_cmd,
170 	minphys,		/* no max at this level; handled by DMA code */
171 	NULL,
172 	NULL,
173 };
174 
175 struct scsi_device esp_dev = {
176 	NULL,			/* Use default error handler */
177 	NULL,			/* have a queue, served by this */
178 	NULL,			/* have no async handler */
179 	NULL,			/* Use default 'done' routine */
180 };
181 
182 int esp_debug = 0;	/* ESP_SHOWTRAC | ESP_SHOWREGS | ESP_SHOWMISC */
183 
184 /*
185  * Functions and the switch for the MI code.
186  */
187 u_char	esp_read_reg __P((struct ncr53c9x_softc *, int));
188 void	esp_write_reg __P((struct ncr53c9x_softc *, int, u_char));
189 int	esp_dma_isintr __P((struct ncr53c9x_softc *));
190 void	esp_dma_reset __P((struct ncr53c9x_softc *));
191 int	esp_dma_intr __P((struct ncr53c9x_softc *));
192 int	esp_dma_setup __P((struct ncr53c9x_softc *, caddr_t *,
193 	    size_t *, int, size_t *));
194 void	esp_dma_go __P((struct ncr53c9x_softc *));
195 void	esp_dma_stop __P((struct ncr53c9x_softc *));
196 int	esp_dma_isactive __P((struct ncr53c9x_softc *));
197 
198 struct ncr53c9x_glue esp_glue = {
199 	esp_read_reg,
200 	esp_write_reg,
201 	esp_dma_isintr,
202 	esp_dma_reset,
203 	esp_dma_intr,
204 	esp_dma_setup,
205 	esp_dma_go,
206 	esp_dma_stop,
207 	esp_dma_isactive,
208 	NULL,			/* gl_clear_latched_intr */
209 };
210 
211 /*
212  * Look for the board
213  */
214 int
215 esp_find(iot, ioh, epd)
216 	bus_space_tag_t iot;
217 	bus_space_handle_t ioh;
218 	struct esp_probe_data *epd;
219 {
220 	u_int vers;
221 	u_int p1;
222 	u_int p2;
223 	u_int jmp;
224 
225 	ESP_TRACE(("[esp_find] "));
226 
227 	/* reset card before we probe? */
228 
229 	/*
230 	 * Switch to the PIO regs and look for the bit pattern
231 	 * we expect...
232 	 */
233 	bus_space_write_1(iot, ioh, NCR_CFG4,
234 		NCRCFG4_CRS1 | bus_space_read_1(iot, ioh, NCR_CFG4));
235 
236 #define SIG_MASK 0x87
237 #define REV_MASK 0x70
238 #define	M1	 0x02
239 #define	M2	 0x05
240 #define ISNCR	 0x80
241 #define ISESP406 0x40
242 
243 	vers = bus_space_read_1(iot, ioh, NCR_SIGNTR);
244 	p1 = bus_space_read_1(iot, ioh, NCR_SIGNTR) & SIG_MASK;
245 	p2 = bus_space_read_1(iot, ioh, NCR_SIGNTR) & SIG_MASK;
246 
247 	ESP_MISC(("%s: 0x%0x 0x%0x 0x%0x\n", epd->sc_dev.dv_xname,
248 	    vers, p1, p2));
249 
250 	if (!((p1 == M1 && p2 == M2) || (p1 == M2 && p2 == M1)))
251 		return 0;
252 
253 	/* Ok, what is it? */
254 	epd->sc_isncr = (vers & ISNCR);
255 	epd->sc_rev = ((vers & REV_MASK) == ISESP406) ?
256 	    NCR_VARIANT_ESP406 : NCR_VARIANT_FAS408;
257 
258 	/* What do the jumpers tell us? */
259 	jmp = bus_space_read_1(iot, ioh, NCR_JMP);
260 
261 	epd->sc_msize = (jmp & NCRJMP_ROMSZ) ? 0x4000 : 0x8000;
262 	epd->sc_parity = jmp & NCRJMP_J2;
263 	epd->sc_sync = jmp & NCRJMP_J4;
264 	epd->sc_id = (jmp & NCRJMP_J3) ? 7 : 6;
265 	switch (jmp & (NCRJMP_J0 | NCRJMP_J1)) {
266 		case NCRJMP_J0 | NCRJMP_J1:
267 			epd->sc_irq = 11;
268 			break;
269 		case NCRJMP_J0:
270 			epd->sc_irq = 10;
271 			break;
272 		case NCRJMP_J1:
273 			epd->sc_irq = 15;
274 			break;
275 		default:
276 			epd->sc_irq = 12;
277 			break;
278 	}
279 
280 	bus_space_write_1(iot, ioh, NCR_CFG4,
281 		~NCRCFG4_CRS1 & bus_space_read_1(iot, ioh, NCR_CFG4));
282 
283 	/* Try to set NCRESPCFG3_FCLK, some FAS408's don't support
284 	 * NCRESPCFG3_FCLK even though it is documented.  A bad
285 	 * batch of chips perhaps?
286 	 */
287 	bus_space_write_1(iot, ioh, NCR_ESPCFG3,
288 	    bus_space_read_1(iot, ioh, NCR_ESPCFG3) | NCRESPCFG3_FCLK);
289 	epd->sc_isfast = bus_space_read_1(iot, ioh, NCR_ESPCFG3)
290 	    & NCRESPCFG3_FCLK;
291 
292 	return 1;
293 }
294 
295 void
296 esp_init(esc, epd)
297 	struct esp_softc *esc;
298 	struct esp_probe_data *epd;
299 {
300 	struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
301 
302 	ESP_TRACE(("[esp_init] "));
303 
304 	/*
305 	 * Set up the glue for MI code early; we use some of it here.
306 	 */
307 	sc->sc_glue = &esp_glue;
308 
309 	sc->sc_rev = epd->sc_rev;
310 	sc->sc_id = epd->sc_id;
311 
312 	/* If we could set NCRESPCFG3_FCLK earlier, we can really move */
313 	sc->sc_cfg3 = NCR_READ_REG(sc, NCR_ESPCFG3);
314 	if ((epd->sc_rev == NCR_VARIANT_FAS408) && epd->sc_isfast) {
315 		sc->sc_freq = 40;
316 		sc->sc_cfg3 |= NCRESPCFG3_FCLK;
317 	}
318 	else
319 		sc->sc_freq = 24;
320 
321 	/* Setup the register defaults */
322 	sc->sc_cfg1 = sc->sc_id;
323 	if (epd->sc_parity)
324 		sc->sc_cfg1 |= NCRCFG1_PARENB;
325 	sc->sc_cfg2 = NCRCFG2_SCSI2;
326 	sc->sc_cfg3 |= NCRESPCFG3_IDM | NCRESPCFG3_FSCSI;
327 
328 	/*
329 	 * This is the value used to start sync negotiations
330 	 * Note that the NCR register "SYNCTP" is programmed
331 	 * in "clocks per byte", and has a minimum value of 4.
332 	 * The SCSI period used in negotiation is one-fourth
333 	 * of the time (in nanoseconds) needed to transfer one byte.
334 	 * Since the chip's clock is given in MHz, we have the following
335 	 * formula: 4 * period = (1000 / freq) * 4
336 	 */
337 	if (epd->sc_sync)
338 	{
339 #ifdef DIAGNOSTIC
340 		printf("%s: sync requested, but not supported; will do async\n",
341 		    sc->sc_dev.dv_xname);
342 #endif
343 		epd->sc_sync = 0;
344 	}
345 
346 	sc->sc_minsync = 0;
347 
348 	/* Really no limit, but since we want to fit into the TCR... */
349 	sc->sc_maxxfer = 64 * 1024;
350 }
351 
352 /*
353  * Check the slots looking for a board we recognise
354  * If we find one, note it's address (slot) and call
355  * the actual probe routine to check it out.
356  */
357 int
358 esp_isa_match(parent, match, aux)
359 	struct device *parent;
360 	void *match, *aux;
361 {
362 	struct ncr53c9x_softc *sc = match;
363 	struct isa_attach_args *ia = aux;
364 	bus_space_tag_t iot = ia->ia_iot;
365 	bus_space_handle_t ioh;
366 	struct esp_probe_data epd;
367 	int rv;
368 
369 	ESP_TRACE(("[esp_isa_match] "));
370 
371 	if (ia->ia_iobase != 0x230 && ia->ia_iobase != 0x330) {
372 #ifdef DIAGNOSTIC
373 		printf("%s: invalid iobase 0x%0x, device not configured\n",
374 		    sc->sc_dev.dv_xname, ia->ia_iobase);
375 #endif
376 		return 0;
377 	}
378 
379 	if (bus_space_map(iot, ia->ia_iobase, ESP_ISA_IOSIZE, 0, &ioh)) {
380 #ifdef DIAGNOSTIC
381 		printf("%s: bus_space_map() failed!\n", sc->sc_dev.dv_xname);
382 #endif
383 		return 0;
384 	}
385 
386 	epd.sc_dev = sc->sc_dev;
387 	rv = esp_find(iot, ioh, &epd);
388 
389 	bus_space_unmap(iot, ioh, ESP_ISA_IOSIZE);
390 
391 	if (rv) {
392 		if (ia->ia_irq != IRQUNK && ia->ia_irq != epd.sc_irq) {
393 #ifdef DIAGNOSTIC
394 		printf("%s: configured IRQ (%0d) does not match board IRQ (%0d), device not configured\n",
395 		    sc->sc_dev.dv_xname, ia->ia_irq, epd.sc_irq);
396 #endif
397 			return 0;
398 		}
399 		ia->ia_irq = epd.sc_irq;
400 		ia->ia_msize = 0;
401 		ia->ia_iosize = ESP_ISA_IOSIZE;
402 	}
403 	return (rv);
404 }
405 
406 /*
407  * Attach this instance, and then all the sub-devices
408  */
409 void
410 esp_isa_attach(parent, self, aux)
411 	struct device *parent, *self;
412 	void *aux;
413 {
414 	struct isa_attach_args *ia = aux;
415 	struct esp_softc *esc = (void *)self;
416 	struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
417 	bus_space_tag_t iot = ia->ia_iot;
418 	bus_space_handle_t ioh;
419 	struct esp_probe_data epd;
420 	isa_chipset_tag_t ic = ia->ia_ic;
421 
422 	printf("\n");
423 	ESP_TRACE(("[esp_isa_attach] "));
424 
425 	if (bus_space_map(iot, ia->ia_iobase, ESP_ISA_IOSIZE, 0, &ioh))
426 		panic("espattach: bus_space_map failed");
427 
428 	epd.sc_dev = sc->sc_dev;
429 	if (!esp_find(iot, ioh, &epd))
430 		panic("espattach: esp_find failed");
431 
432 	if (ia->ia_drq != DRQUNK)
433 		isa_dmacascade(parent, ia->ia_drq);
434 
435 	esc->sc_ih = isa_intr_establish(ic, ia->ia_irq, IST_EDGE, IPL_BIO,
436 	    (int (*)(void *))ncr53c9x_intr, esc);
437 	if (esc->sc_ih == NULL) {
438 		printf("%s: couldn't establish interrupt\n",
439 		    sc->sc_dev.dv_xname);
440 		return;
441 	}
442 
443 	esp_init(esc, &epd);
444 
445 	esc->sc_ioh = ioh;
446 	esc->sc_iot = iot;
447 
448 	printf("%s:%ssync,%sparity\n", sc->sc_dev.dv_xname,
449 	    epd.sc_sync ? " " : " no ", epd.sc_parity ? " " : " no ");
450 	printf("%s", sc->sc_dev.dv_xname);
451 
452 	/*
453 	 * Now try to attach all the sub-devices
454 	 */
455 	ncr53c9x_attach(sc, &esp_switch, &esp_dev);
456 }
457 
458 /*
459  * Glue functions.
460  */
461 u_char
462 esp_read_reg(sc, reg)
463 	struct ncr53c9x_softc *sc;
464 	int reg;
465 {
466 	struct esp_softc *esc = (struct esp_softc *)sc;
467 	u_char v;
468 
469 	v =  bus_space_read_1(esc->sc_iot, esc->sc_ioh, reg);
470 
471 	ESP_REGS(("[esp_read_reg CRS%c 0x%02x=0x%02x] ",
472 	    (bus_space_read_1(esc->sc_iot, esc->sc_ioh, NCR_CFG4) &
473 	    NCRCFG4_CRS1) ? '1' : '0', reg, v));
474 
475 	return v;
476 }
477 
478 void
479 esp_write_reg(sc, reg, val)
480 	struct ncr53c9x_softc *sc;
481 	int reg;
482 	u_char val;
483 {
484 	struct esp_softc *esc = (struct esp_softc *)sc;
485 	u_char v = val;
486 
487 	if (reg == NCR_CMD && v == (NCRCMD_TRANS|NCRCMD_DMA)) {
488 		v = NCRCMD_TRANS;
489 	}
490 
491 	ESP_REGS(("[esp_write_reg CRS%c 0x%02x=0x%02x] ",
492 	    (bus_space_read_1(esc->sc_iot, esc->sc_ioh, NCR_CFG4) &
493 	    NCRCFG4_CRS1) ? '1' : '0', reg, v));
494 
495 	bus_space_write_1(esc->sc_iot, esc->sc_ioh, reg, v);
496 }
497 
498 int
499 esp_dma_isintr(sc)
500 	struct ncr53c9x_softc *sc;
501 {
502 	ESP_TRACE(("[esp_dma_isintr] "));
503 
504 	return NCR_READ_REG(sc, NCR_STAT) & NCRSTAT_INT;
505 }
506 
507 void
508 esp_dma_reset(sc)
509 	struct ncr53c9x_softc *sc;
510 {
511 	struct esp_softc *esc = (struct esp_softc *)sc;
512 
513 	ESP_TRACE(("[esp_dma_reset] "));
514 
515 	esc->sc_active = 0;
516 	esc->sc_tc = 0;
517 }
518 
519 int
520 esp_dma_intr(sc)
521 	struct ncr53c9x_softc *sc;
522 {
523 	struct esp_softc *esc = (struct esp_softc *)sc;
524 	u_char	*p;
525 	u_int	espphase, espstat, espintr;
526 	int	cnt;
527 
528 	ESP_TRACE(("[esp_dma_intr] "));
529 
530 	if (esc->sc_active == 0) {
531 		printf("%s: dma_intr--inactive DMA\n", sc->sc_dev.dv_xname);
532 		return -1;
533 	}
534 
535 	if ((sc->sc_espintr & NCRINTR_BS) == 0) {
536 		esc->sc_active = 0;
537 		return 0;
538 	}
539 
540 	cnt = *esc->sc_pdmalen;
541 	if (*esc->sc_pdmalen == 0) {
542 		printf("%s: data interrupt, but no count left\n",
543 		    sc->sc_dev.dv_xname);
544 	}
545 
546 	p = *esc->sc_dmaaddr;
547 	espphase = sc->sc_phase;
548 	espstat = (u_int) sc->sc_espstat;
549 	espintr = (u_int) sc->sc_espintr;
550 	do {
551 		if (esc->sc_datain) {
552 			*p++ = NCR_READ_REG(sc, NCR_FIFO);
553 			cnt--;
554 			if (espphase == DATA_IN_PHASE) {
555 				NCR_WRITE_REG(sc, NCR_CMD, NCRCMD_TRANS);
556 			} else {
557 				esc->sc_active = 0;
558 			}
559 	 	} else {
560 			if (   (espphase == DATA_OUT_PHASE)
561 			    || (espphase == MESSAGE_OUT_PHASE)) {
562 				NCR_WRITE_REG(sc, NCR_FIFO, *p++);
563 				cnt--;
564 				NCR_WRITE_REG(sc, NCR_CMD, NCRCMD_TRANS);
565 			} else {
566 				esc->sc_active = 0;
567 			}
568 		}
569 
570 		if (esc->sc_active) {
571 			while (!(NCR_READ_REG(sc, NCR_STAT) & 0x80));
572 			espstat = NCR_READ_REG(sc, NCR_STAT);
573 			espintr = NCR_READ_REG(sc, NCR_INTR);
574 			espphase = (espintr & NCRINTR_DIS)
575 				    ? /* Disconnected */ BUSFREE_PHASE
576 				    : espstat & PHASE_MASK;
577 		}
578 	} while (esc->sc_active && espintr);
579 	sc->sc_phase = espphase;
580 	sc->sc_espstat = (u_char) espstat;
581 	sc->sc_espintr = (u_char) espintr;
582 	*esc->sc_dmaaddr = p;
583 	*esc->sc_pdmalen = cnt;
584 
585 	if (*esc->sc_pdmalen == 0) {
586 		esc->sc_tc = NCRSTAT_TC;
587 	}
588 	sc->sc_espstat |= esc->sc_tc;
589 	return 0;
590 }
591 
592 int
593 esp_dma_setup(sc, addr, len, datain, dmasize)
594 	struct ncr53c9x_softc *sc;
595 	caddr_t *addr;
596 	size_t *len;
597 	int datain;
598 	size_t *dmasize;
599 {
600 	struct esp_softc *esc = (struct esp_softc *)sc;
601 
602 	ESP_TRACE(("[esp_dma_setup] "));
603 
604 	esc->sc_dmaaddr = addr;
605 	esc->sc_pdmalen = len;
606 	esc->sc_datain = datain;
607 	esc->sc_dmasize = *dmasize;
608 	esc->sc_tc = 0;
609 
610 	return 0;
611 }
612 
613 void
614 esp_dma_go(sc)
615 	struct ncr53c9x_softc *sc;
616 {
617 	struct esp_softc *esc = (struct esp_softc *)sc;
618 
619 	ESP_TRACE(("[esp_dma_go] "));
620 
621 	esc->sc_active = 1;
622 }
623 
624 void
625 esp_dma_stop(sc)
626 	struct ncr53c9x_softc *sc;
627 {
628 	ESP_TRACE(("[esp_dma_stop] "));
629 }
630 
631 int
632 esp_dma_isactive(sc)
633 	struct ncr53c9x_softc *sc;
634 {
635 	struct esp_softc *esc = (struct esp_softc *)sc;
636 
637 	ESP_TRACE(("[esp_dma_isactive] "));
638 
639 	return esc->sc_active;
640 }
641