esp.c revision 1.27
1/*	$NetBSD: esp.c,v 1.27 2000/12/29 21:31:44 briggs 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 * All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 *    notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 *    notice, this list of conditions and the following disclaimer in the
45 *    documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 *    must display the following acknowledgement:
48 *	This product includes software developed by Peter Galbavy
49 * 4. The name of the author may not be used to endorse or promote products
50 *    derived from this software without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
54 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
56 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
58 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
60 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
61 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
62 * POSSIBILITY OF SUCH DAMAGE.
63 */
64
65/*
66 * Based on aic6360 by Jarle Greipsland
67 *
68 * Acknowledgements: Many of the algorithms used in this driver are
69 * inspired by the work of Julian Elischer (julian@tfs.com) and
70 * Charles Hannum (mycroft@duality.gnu.ai.mit.edu).  Thanks a million!
71 */
72
73/*
74 * Initial m68k mac support from Allen Briggs <briggs@macbsd.com>
75 * (basically consisting of the match, a bit of the attach, and the
76 *  "DMA" glue functions).
77 */
78
79#include <sys/types.h>
80#include <sys/param.h>
81#include <sys/systm.h>
82#include <sys/kernel.h>
83#include <sys/errno.h>
84#include <sys/ioctl.h>
85#include <sys/device.h>
86#include <sys/buf.h>
87#include <sys/proc.h>
88#include <sys/user.h>
89#include <sys/queue.h>
90
91#include <dev/scsipi/scsi_all.h>
92#include <dev/scsipi/scsipi_all.h>
93#include <dev/scsipi/scsiconf.h>
94#include <dev/scsipi/scsi_message.h>
95
96#include <machine/cpu.h>
97#include <machine/bus.h>
98#include <machine/param.h>
99
100#include <dev/ic/ncr53c9xreg.h>
101#include <dev/ic/ncr53c9xvar.h>
102
103#include <machine/viareg.h>
104
105#include <mac68k/obio/espvar.h>
106#include <mac68k/obio/obiovar.h>
107
108void	espattach	__P((struct device *, struct device *, void *));
109int	espmatch	__P((struct device *, struct cfdata *, void *));
110
111/* Linkup to the rest of the kernel */
112struct cfattach esp_ca = {
113	sizeof(struct esp_softc), espmatch, espattach
114};
115
116/*
117 * Functions and the switch for the MI code.
118 */
119u_char	esp_read_reg __P((struct ncr53c9x_softc *, int));
120void	esp_write_reg __P((struct ncr53c9x_softc *, int, u_char));
121int	esp_dma_isintr __P((struct ncr53c9x_softc *));
122void	esp_dma_reset __P((struct ncr53c9x_softc *));
123int	esp_dma_intr __P((struct ncr53c9x_softc *));
124int	esp_dma_setup __P((struct ncr53c9x_softc *, caddr_t *,
125	    size_t *, int, size_t *));
126void	esp_dma_go __P((struct ncr53c9x_softc *));
127void	esp_dma_stop __P((struct ncr53c9x_softc *));
128int	esp_dma_isactive __P((struct ncr53c9x_softc *));
129void	esp_quick_write_reg __P((struct ncr53c9x_softc *, int, u_char));
130int	esp_quick_dma_intr __P((struct ncr53c9x_softc *));
131int	esp_quick_dma_setup __P((struct ncr53c9x_softc *, caddr_t *,
132	    size_t *, int, size_t *));
133void	esp_quick_dma_go __P((struct ncr53c9x_softc *));
134
135void	esp_intr __P((void *sc));
136void	esp_dualbus_intr __P((void *sc));
137static struct esp_softc		*esp0 = NULL, *esp1 = NULL;
138
139static __inline__ int esp_dafb_have_dreq __P((struct esp_softc *esc));
140static __inline__ int esp_iosb_have_dreq __P((struct esp_softc *esc));
141int (*esp_have_dreq) __P((struct esp_softc *esc));
142
143struct ncr53c9x_glue esp_glue = {
144	esp_read_reg,
145	esp_write_reg,
146	esp_dma_isintr,
147	esp_dma_reset,
148	esp_dma_intr,
149	esp_dma_setup,
150	esp_dma_go,
151	esp_dma_stop,
152	esp_dma_isactive,
153	NULL,			/* gl_clear_latched_intr */
154};
155
156int
157espmatch(parent, cf, aux)
158	struct device *parent;
159	struct cfdata *cf;
160	void *aux;
161{
162	int	found = 0;
163
164	if ((cf->cf_unit == 0) && mac68k_machine.scsi96) {
165		found = 1;
166	}
167	if ((cf->cf_unit == 1) && mac68k_machine.scsi96_2) {
168		found = 1;
169	}
170
171	return found;
172}
173
174/*
175 * Attach this instance, and then all the sub-devices
176 */
177void
178espattach(parent, self, aux)
179	struct device *parent, *self;
180	void *aux;
181{
182	struct obio_attach_args *oa = (struct obio_attach_args *)aux;
183	extern vaddr_t		SCSIBase;
184	struct esp_softc	*esc = (void *)self;
185	struct ncr53c9x_softc	*sc = &esc->sc_ncr53c9x;
186	int			quick = 0;
187	unsigned long		reg_offset;
188
189	reg_offset = SCSIBase - IOBase;
190	esc->sc_tag = oa->oa_tag;
191	/*
192	 * For Wombat, Primus and Optimus motherboards, DREQ is
193	 * visible on bit 0 of the IOSB's emulated VIA2 vIFR (and
194	 * the scsi registers are offset 0x1000 bytes from IOBase).
195	 *
196	 * For the Q700/900/950 it's at f9800024 for bus 0 and
197	 * f9800028 for bus 1 (900/950).  For these machines, that is also
198	 * a (12-bit) configuration register for DAFB's control of the
199	 * pseudo-DMA timing.  The default value is 0x1d1.
200	 */
201	esp_have_dreq = esp_dafb_have_dreq;
202	if (sc->sc_dev.dv_unit == 0) {
203		if (reg_offset == 0x10000) {
204			quick = 1;
205			esp_have_dreq = esp_iosb_have_dreq;
206		} else if (reg_offset == 0x18000) {
207			quick = 0;
208		} else {
209			if (bus_space_map(esc->sc_tag, 0xf9800024,
210					  4, 0, &esc->sc_bsh)) {
211				printf("failed to map 4 at 0xf9800024.\n");
212			} else {
213				quick = 1;
214				bus_space_write_4(esc->sc_tag,
215						  esc->sc_bsh, 0, 0x1d1);
216			}
217		}
218	} else {
219		if (bus_space_map(esc->sc_tag, 0xf9800028,
220				  4, 0, &esc->sc_bsh)) {
221			printf("failed to map 4 at 0xf9800028.\n");
222		} else {
223			quick = 1;
224			bus_space_write_4(esc->sc_tag, esc->sc_bsh, 0, 0x1d1);
225		}
226	}
227	if (quick) {
228		esp_glue.gl_write_reg = esp_quick_write_reg;
229		esp_glue.gl_dma_intr = esp_quick_dma_intr;
230		esp_glue.gl_dma_setup = esp_quick_dma_setup;
231		esp_glue.gl_dma_go = esp_quick_dma_go;
232	}
233
234	/*
235	 * Set up the glue for MI code early; we use some of it here.
236	 */
237	sc->sc_glue = &esp_glue;
238
239	/*
240	 * Save the regs
241	 */
242	if (sc->sc_dev.dv_unit == 0) {
243		esp0 = esc;
244
245		esc->sc_reg = (volatile u_char *) SCSIBase;
246		via2_register_irq(VIA2_SCSIIRQ, esp_intr, esc);
247		esc->irq_mask = V2IF_SCSIIRQ;
248		if (reg_offset == 0x10000) {
249			/* From the Q650 developer's note */
250			sc->sc_freq = 16500000;
251		} else {
252			sc->sc_freq = 25000000;
253		}
254
255		if (esp_glue.gl_dma_go == esp_quick_dma_go) {
256			printf(" (quick)");
257		}
258	} else {
259		esp1 = esc;
260
261		esc->sc_reg = (volatile u_char *) SCSIBase + 0x402;
262		via2_register_irq(VIA2_SCSIIRQ, esp_dualbus_intr, NULL);
263		esc->irq_mask = 0;
264		sc->sc_freq = 25000000;
265
266		if (esp_glue.gl_dma_go == esp_quick_dma_go) {
267			printf(" (quick)");
268		}
269	}
270
271	printf(": address %p", esc->sc_reg);
272
273	sc->sc_id = 7;
274
275	/* gimme Mhz */
276	sc->sc_freq /= 1000000;
277
278	/*
279	 * It is necessary to try to load the 2nd config register here,
280	 * to find out what rev the esp chip is, else the esp_reset
281	 * will not set up the defaults correctly.
282	 */
283	sc->sc_cfg1 = sc->sc_id; /* | NCRCFG1_PARENB; */
284	sc->sc_cfg2 = NCRCFG2_SCSI2;
285	sc->sc_cfg3 = 0;
286	sc->sc_rev = NCR_VARIANT_NCR53C96;
287
288	/*
289	 * This is the value used to start sync negotiations
290	 * Note that the NCR register "SYNCTP" is programmed
291	 * in "clocks per byte", and has a minimum value of 4.
292	 * The SCSI period used in negotiation is one-fourth
293	 * of the time (in nanoseconds) needed to transfer one byte.
294	 * Since the chip's clock is given in MHz, we have the following
295	 * formula: 4 * period = (1000 / freq) * 4
296	 */
297	sc->sc_minsync = 1000 / sc->sc_freq;
298
299	/* We need this to fit into the TCR... */
300	sc->sc_maxxfer = 64 * 1024;
301
302	if (!quick) {
303		sc->sc_minsync = 0;	/* No synchronous xfers w/o DMA */
304		sc->sc_maxxfer = 8 * 1024;
305	}
306
307	/*
308	 * Configure interrupts.
309	 */
310	if (esc->irq_mask) {
311		via2_reg(vPCR) = 0x22;
312		via2_reg(vIFR) = esc->irq_mask;
313		via2_reg(vIER) = 0x80 | esc->irq_mask;
314	}
315
316	/*
317	 * Now try to attach all the sub-devices
318	 */
319	ncr53c9x_attach(sc, NULL, NULL);
320}
321
322/*
323 * Glue functions.
324 */
325
326u_char
327esp_read_reg(sc, reg)
328	struct ncr53c9x_softc *sc;
329	int reg;
330{
331	struct esp_softc *esc = (struct esp_softc *)sc;
332
333	return esc->sc_reg[reg * 16];
334}
335
336void
337esp_write_reg(sc, reg, val)
338	struct ncr53c9x_softc *sc;
339	int reg;
340	u_char val;
341{
342	struct esp_softc *esc = (struct esp_softc *)sc;
343	u_char	v = val;
344
345	if (reg == NCR_CMD && v == (NCRCMD_TRANS|NCRCMD_DMA)) {
346		v = NCRCMD_TRANS;
347	}
348	esc->sc_reg[reg * 16] = v;
349}
350
351void
352esp_dma_stop(sc)
353	struct ncr53c9x_softc *sc;
354{
355}
356
357int
358esp_dma_isactive(sc)
359	struct ncr53c9x_softc *sc;
360{
361	struct esp_softc *esc = (struct esp_softc *)sc;
362
363	return esc->sc_active;
364}
365
366int
367esp_dma_isintr(sc)
368	struct ncr53c9x_softc *sc;
369{
370	struct esp_softc *esc = (struct esp_softc *)sc;
371
372	return esc->sc_reg[NCR_STAT * 16] & 0x80;
373}
374
375void
376esp_dma_reset(sc)
377	struct ncr53c9x_softc *sc;
378{
379	struct esp_softc *esc = (struct esp_softc *)sc;
380
381	esc->sc_active = 0;
382	esc->sc_tc = 0;
383}
384
385int
386esp_dma_intr(sc)
387	struct ncr53c9x_softc *sc;
388{
389	struct esp_softc *esc = (struct esp_softc *)sc;
390	volatile u_char *cmdreg, *intrreg, *statreg, *fiforeg;
391	u_char	*p;
392	u_int	espphase, espstat, espintr;
393	int	cnt, s;
394
395	if (esc->sc_active == 0) {
396		printf("dma_intr--inactive DMA\n");
397		return -1;
398	}
399
400	if ((sc->sc_espintr & NCRINTR_BS) == 0) {
401		esc->sc_active = 0;
402		return 0;
403	}
404
405	cnt = esc->sc_dmasize;
406	if (esc->sc_dmasize == 0) {
407		printf("data interrupt, but no count left.");
408	}
409
410	p = *esc->sc_dmaaddr;
411	espphase = sc->sc_phase;
412	espstat = (u_int) sc->sc_espstat;
413	espintr = (u_int) sc->sc_espintr;
414	cmdreg = esc->sc_reg + NCR_CMD * 16;
415	fiforeg = esc->sc_reg + NCR_FIFO * 16;
416	statreg = esc->sc_reg + NCR_STAT * 16;
417	intrreg = esc->sc_reg + NCR_INTR * 16;
418	do {
419		if (esc->sc_datain) {
420			*p++ = *fiforeg;
421			cnt--;
422			if (espphase == DATA_IN_PHASE) {
423				*cmdreg = NCRCMD_TRANS;
424			} else {
425				esc->sc_active = 0;
426			}
427	 	} else {
428			if (   (espphase == DATA_OUT_PHASE)
429			    || (espphase == MESSAGE_OUT_PHASE)) {
430				*fiforeg = *p++;
431				cnt--;
432				*cmdreg = NCRCMD_TRANS;
433			} else {
434				esc->sc_active = 0;
435			}
436		}
437
438		if (esc->sc_active) {
439			while (!(*statreg & 0x80));
440			s = splhigh();
441			espstat = *statreg;
442			espintr = *intrreg;
443			espphase = (espintr & NCRINTR_DIS)
444				    ? /* Disconnected */ BUSFREE_PHASE
445				    : espstat & PHASE_MASK;
446			splx(s);
447		}
448	} while (esc->sc_active && (espintr & NCRINTR_BS));
449	sc->sc_phase = espphase;
450	sc->sc_espstat = (u_char) espstat;
451	sc->sc_espintr = (u_char) espintr;
452	*esc->sc_dmaaddr = p;
453	esc->sc_dmasize = cnt;
454
455	if (esc->sc_dmasize == 0) {
456		esc->sc_tc = NCRSTAT_TC;
457	}
458	sc->sc_espstat |= esc->sc_tc;
459	return 0;
460}
461
462int
463esp_dma_setup(sc, addr, len, datain, dmasize)
464	struct ncr53c9x_softc *sc;
465	caddr_t *addr;
466	size_t *len;
467	int datain;
468	size_t *dmasize;
469{
470	struct esp_softc *esc = (struct esp_softc *)sc;
471
472	esc->sc_dmaaddr = addr;
473	esc->sc_dmalen = len;
474	esc->sc_datain = datain;
475	esc->sc_dmasize = *dmasize;
476	esc->sc_tc = 0;
477
478	return 0;
479}
480
481void
482esp_dma_go(sc)
483	struct ncr53c9x_softc *sc;
484{
485	struct esp_softc *esc = (struct esp_softc *)sc;
486
487	if (esc->sc_datain == 0) {
488		esc->sc_reg[NCR_FIFO * 16] = **esc->sc_dmaaddr;
489		(*esc->sc_dmalen)--;
490		(*esc->sc_dmaaddr)++;
491	}
492	esc->sc_active = 1;
493}
494
495void
496esp_quick_write_reg(sc, reg, val)
497	struct ncr53c9x_softc *sc;
498	int reg;
499	u_char val;
500{
501	struct esp_softc *esc = (struct esp_softc *)sc;
502
503	esc->sc_reg[reg * 16] = val;
504}
505
506#if DEBUG
507int mac68k_esp_debug=0;
508#endif
509
510int
511esp_quick_dma_intr(sc)
512	struct ncr53c9x_softc *sc;
513{
514	struct esp_softc *esc = (struct esp_softc *)sc;
515	int trans=0, resid=0;
516
517	if (esc->sc_active == 0)
518		panic("dma_intr--inactive DMA\n");
519
520	esc->sc_active = 0;
521
522	if (esc->sc_dmasize == 0) {
523		int	res;
524
525		res = NCR_READ_REG(sc, NCR_TCL);
526		res += NCR_READ_REG(sc, NCR_TCM) << 8;
527		printf("dmaintr: DMA xfer of zero xferred %d\n", res);
528		return 0;
529	}
530
531	if ((sc->sc_espstat & NCRSTAT_TC) == 0) {
532		resid += NCR_READ_REG(sc, NCR_TCL);
533		resid += NCR_READ_REG(sc, NCR_TCM) << 8;
534		if (resid == 0)
535			resid = 65536;
536	}
537
538	trans = esc->sc_dmasize - resid;
539	if (trans < 0) {
540		printf("dmaintr: trans < 0????");
541		trans = *esc->sc_dmalen;
542	}
543
544	NCR_DMA(("dmaintr: trans %d, resid %d.\n", trans, resid));
545#if DEBUG
546	if (mac68k_esp_debug) {
547		printf("eqd_intr: trans %d, resid %d.\n", trans, resid);
548	}
549#endif
550	*esc->sc_dmaaddr += trans;
551	*esc->sc_dmalen -= trans;
552
553	return 0;
554}
555
556int
557esp_quick_dma_setup(sc, addr, len, datain, dmasize)
558	struct ncr53c9x_softc *sc;
559	caddr_t *addr;
560	size_t *len;
561	int datain;
562	size_t *dmasize;
563{
564	struct esp_softc *esc = (struct esp_softc *)sc;
565
566	esc->sc_dmaaddr = addr;
567	esc->sc_dmalen = len;
568
569	if (*len & 1) {
570		esc->sc_pad = 1;
571	} else {
572		esc->sc_pad = 0;
573	}
574
575	esc->sc_datain = datain;
576	esc->sc_dmasize = *dmasize;
577
578#if DIAGNOSTIC
579	if (esc->sc_dmasize == 0) {
580		printf("esp_quick_dma_setup called with %lx, %lx, %d, %lx\n",
581		    (long) *addr, (long) *len, datain, (long) esc->sc_dmasize);
582	}
583#endif
584#if DEBUG
585	if (mac68k_esp_debug) {
586	printf("eqd_setup: addr %lx, len %lx, in? %d, dmasize %lx\n",
587	    (long) *addr, (long) *len, datain, (long) esc->sc_dmasize);
588	}
589#endif
590
591	return 0;
592}
593
594static __inline__ int
595esp_dafb_have_dreq(esc)
596	struct esp_softc *esc;
597{
598	return (*(volatile u_int32_t *)(esc->sc_bsh.base) & 0x200);
599}
600
601static __inline__ int
602esp_iosb_have_dreq(esc)
603	struct esp_softc *esc;
604{
605	return (via2_reg(vIFR) & V2IF_SCSIDRQ);
606}
607
608static volatile int espspl=-1;
609
610/*
611 * Apple "DMA" is weird.
612 *
613 * Basically, the CPU acts like the DMA controller.  The DREQ/ off the
614 * chip goes to a register that we've mapped at attach time (on the
615 * IOSB or DAFB, depending on the machine).  Apple also provides some
616 * space for which the memory controller handshakes data to/from the
617 * NCR chip with the DACK/ line.  This space appears to be mapped over
618 * and over, every 4 bytes, but only the lower 16 bits are valid (but
619 * reading the upper 16 bits will handshake DACK/ just fine, so if you
620 * read *u_int16_t++ = *u_int16_t++ in a loop, you'll get
621 * <databyte><databyte>0xff0xff<databyte><databyte>0xff0xff...
622 *
623 * When you're attempting to read or write memory to this DACK/ed space,
624 * and the NCR is not ready for some timeout period, the system will
625 * generate a bus error.  This might be for one of several reasons:
626 *
627 *	1) (on write) The FIFO is full and is not draining.
628 *	2) (on read) The FIFO is empty and is not filling.
629 *	3) An interrupt condition has occurred.
630 *	4) Anything else?
631 *
632 * So if a bus error occurs, we first turn off the nofault bus error handler,
633 * then we check for an interrupt (which would render the first two
634 * possibilities moot).  If there's no interrupt, check for a DREQ/.  If we
635 * have that, then attempt to resume stuffing (or unstuffing) the FIFO.  If
636 * neither condition holds, pause briefly and check again.
637 *
638 * NOTE!!!  In order to make allowances for the hardware structure of
639 *          the mac, spl values in here are hardcoded!!!!!!!!!
640 *          This is done to allow serial interrupts to get in during
641 *          scsi transfers.  This is ugly.
642 */
643void
644esp_quick_dma_go(sc)
645	struct ncr53c9x_softc *sc;
646{
647	struct esp_softc *esc = (struct esp_softc *)sc;
648	extern long mac68k_a2_fromfault;
649	extern int *nofault;
650	label_t faultbuf;
651	u_int16_t volatile *pdma;
652	u_int16_t *addr;
653	int		len, res;
654	u_short		cnt32, cnt2;
655	u_char volatile *statreg;
656
657	esc->sc_active = 1;
658
659	espspl = splhigh();
660
661	addr = (u_int16_t *) *esc->sc_dmaaddr;
662	len  = esc->sc_dmasize;
663
664restart_dmago:
665#if DEBUG
666	if (mac68k_esp_debug) {
667		printf("eqdg: a %lx, l %lx, in? %d ... ",
668		    (long) addr, (long) len, esc->sc_datain);
669	}
670#endif
671	nofault = (int *) &faultbuf;
672	if (setjmp((label_t *) nofault)) {
673		int	i=0;
674
675		nofault = (int *) 0;
676#if DEBUG
677		if (mac68k_esp_debug) {
678			printf("be\n");
679		}
680#endif
681		/*
682		 * Bus error...
683		 * So, we first check for an interrupt.  If we have
684		 * one, go handle it.  Next we check for DREQ/.  If
685		 * we have it, then we restart the transfer.  If
686		 * neither, then loop until we get one or the other.
687		 */
688		statreg = esc->sc_reg + NCR_STAT * 16;
689		for (;;) {
690			spl2();		/* Give serial a chance... */
691			splhigh();	/* That's enough... */
692
693			if (*statreg & 0x80) {
694				goto gotintr;
695			}
696
697			if (esp_have_dreq(esc)) {
698				/*
699				 * Get the length from the address
700				 * differential.
701				 */
702				addr = (u_int16_t *) mac68k_a2_fromfault;
703				len = esc->sc_dmasize -
704				    ((long) addr - (long) *esc->sc_dmaaddr);
705
706				if (esc->sc_datain == 0) {
707					/*
708					 * Let the FIFO drain before we read
709					 * the transfer count.
710					 * Do we need to do this?
711					 * Can we do this?
712					 */
713					while (NCR_READ_REG(sc, NCR_FFLAG)
714					    & 0x1f);
715					/*
716					 * Get the length from the transfer
717					 * counters.
718					 */
719					res = NCR_READ_REG(sc, NCR_TCL);
720					res += NCR_READ_REG(sc, NCR_TCM) << 8;
721					/*
722					 * If they don't agree,
723					 * adjust accordingly.
724					 */
725					while (res > len) {
726						len+=2; addr--;
727					}
728					if (res != len) {
729						panic("esp_quick_dma_go: res %d != len %d\n",
730							res, len);
731					}
732				}
733				break;
734			}
735
736			DELAY(1);
737			if (i++ > 1000000)
738				panic("esp_dma_go: Bus error, but no condition!  Argh!");
739		}
740		goto restart_dmago;
741	}
742
743	len &= ~1;
744
745	statreg = esc->sc_reg + NCR_STAT * 16;
746	pdma = (u_int16_t *) (esc->sc_reg + 0x100);
747
748	/*
749	 * These loops are unrolled into assembly for two reasons:
750	 * 1) We can make sure that they are as efficient as possible, and
751	 * 2) (more importantly) we need the address that we are reading
752	 *    from or writing to to be in a2.
753	 */
754	cnt32 = len / 32;
755	cnt2 = (len % 32) / 2;
756	if (esc->sc_datain == 0) {
757		/* while (cnt32--) { 16 instances of *pdma = *addr++; } */
758		/* while (cnt2--) { *pdma = *addr++; } */
759		__asm __volatile ("
760				movl %1, %%a2
761				movl %2, %%a3
762				movw %3, %%d2
763				cmpw #0, %%d2
764				beq  2f
765				subql #1, %%d2
766			1:	movw %%a2@+,%%a3@; movw %%a2@+,%%a3@
767				movw %%a2@+,%%a3@; movw %%a2@+,%%a3@
768				movw %%a2@+,%%a3@; movw %%a2@+,%%a3@
769				movw %%a2@+,%%a3@; movw %%a2@+,%%a3@
770				movw %%a2@+,%%a3@; movw %%a2@+,%%a3@
771				movw %%a2@+,%%a3@; movw %%a2@+,%%a3@
772				movw %%a2@+,%%a3@; movw %%a2@+,%%a3@
773				movw %%a2@+,%%a3@; movw %%a2@+,%%a3@
774				movw #8704,%%sr
775				movw #9728,%%sr
776				dbra %%d2, 1b
777			2:	movw %4, %%d2
778				cmpw #0, %%d2
779				beq  4f
780				subql #1, %%d2
781			3:	movw %%a2@+,%%a3@
782				dbra %%d2, 3b
783			4:	movl %%a2, %0"
784			: "=g" (addr)
785			: "0" (addr), "g" (pdma), "g" (cnt32), "g" (cnt2)
786			: "a2", "a3", "d2");
787		if (esc->sc_pad) {
788			unsigned char	*c;
789			c = (unsigned char *) addr;
790			/* Wait for DREQ */
791			while (!esp_have_dreq(esc)) {
792				if (*statreg & 0x80) {
793					nofault = (int *) 0;
794					goto gotintr;
795				}
796			}
797			*(unsigned char *)pdma = *c;
798		}
799	} else {
800		/* while (cnt32--) { 16 instances of *addr++ = *pdma; } */
801		/* while (cnt2--) { *addr++ = *pdma; } */
802		__asm __volatile ("
803				movl %1, %%a2
804				movl %2, %%a3
805				movw %3, %%d2
806				cmpw #0, %%d2
807				beq  6f
808				subql #1, %%d2
809			5:	movw %%a3@,%%a2@+; movw %%a3@,%%a2@+
810				movw %%a3@,%%a2@+; movw %%a3@,%%a2@+
811				movw %%a3@,%%a2@+; movw %%a3@,%%a2@+
812				movw %%a3@,%%a2@+; movw %%a3@,%%a2@+
813				movw %%a3@,%%a2@+; movw %%a3@,%%a2@+
814				movw %%a3@,%%a2@+; movw %%a3@,%%a2@+
815				movw %%a3@,%%a2@+; movw %%a3@,%%a2@+
816				movw %%a3@,%%a2@+; movw %%a3@,%%a2@+
817				movw #8704,%%sr
818				movw #9728,%%sr
819				dbra %%d2, 5b
820			6:	movw %4, %%d2
821				cmpw #0, %%d2
822				beq  8f
823				subql #1, %%d2
824			7:	movw %%a3@,%%a2@+
825				dbra %%d2, 7b
826			8:	movl %%a2, %0"
827			: "=g" (addr)
828			: "0" (addr), "g" (pdma), "g" (cnt32), "g" (cnt2)
829			: "a2", "a3", "d2");
830		if (esc->sc_pad) {
831			unsigned char	*c;
832			c = (unsigned char *) addr;
833			/* Wait for DREQ */
834			while (!esp_have_dreq(esc)) {
835				if (*statreg & 0x80) {
836					nofault = (int *) 0;
837					goto gotintr;
838				}
839			}
840			*c = *(unsigned char *)pdma;
841		}
842	}
843
844	nofault = (int *) 0;
845
846	/*
847	 * If we have not received an interrupt yet, we should shortly,
848	 * and we can't prevent it, so return and wait for it.
849	 */
850	if ((*statreg & 0x80) == 0) {
851#if DEBUG
852		if (mac68k_esp_debug) {
853			printf("g.\n");
854		}
855#endif
856		if (espspl != -1) splx(espspl); espspl = -1;
857		return;
858	}
859
860gotintr:
861#if DEBUG
862	if (mac68k_esp_debug) {
863		printf("g!\n");
864	}
865#endif
866	ncr53c9x_intr(sc);
867	if (espspl != -1) splx(espspl); espspl = -1;
868}
869
870void
871esp_intr(sc)
872	void *sc;
873{
874	struct esp_softc *esc = (struct esp_softc *)sc;
875
876	if (esc->sc_reg[NCR_STAT * 16] & 0x80) {
877		ncr53c9x_intr((struct ncr53c9x_softc *) esp0);
878	}
879}
880
881void
882esp_dualbus_intr(sc)
883	void *sc;
884{
885	if (esp0 && (esp0->sc_reg[NCR_STAT * 16] & 0x80)) {
886		ncr53c9x_intr((struct ncr53c9x_softc *) esp0);
887	}
888
889	if (esp1 && (esp1->sc_reg[NCR_STAT * 16] & 0x80)) {
890		ncr53c9x_intr((struct ncr53c9x_softc *) esp1);
891	}
892}
893