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