esp.c revision 1.59 1 /* $NetBSD: esp.c,v 1.59 2021/02/22 04:24:41 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 /*
80 * AV DMA support from Michael Zucca (mrz5149 (at) acm.org)
81 */
82
83 #include <sys/cdefs.h>
84 __KERNEL_RCSID(0, "$NetBSD: esp.c,v 1.59 2021/02/22 04:24:41 rin Exp $");
85
86 #include <sys/types.h>
87 #include <sys/param.h>
88 #include <sys/buf.h>
89 #include <sys/bus.h>
90 #include <sys/device.h>
91
92 #include <uvm/uvm_extern.h>
93
94 #include <dev/scsipi/scsiconf.h>
95
96 #include <dev/ic/ncr53c9xreg.h>
97 #include <dev/ic/ncr53c9xvar.h>
98
99 #include <machine/cpu.h>
100 #include <machine/psc.h>
101 #include <machine/viareg.h>
102
103 #include <mac68k/obio/espvar.h>
104 #include <mac68k/obio/obiovar.h>
105
106 static int espmatch(device_t, cfdata_t, void *);
107 static void espattach(device_t, device_t, void *);
108
109 /* Linkup to the rest of the kernel */
110 CFATTACH_DECL_NEW(esp, sizeof(struct esp_softc),
111 espmatch, espattach, NULL, NULL);
112
113 /*
114 * Functions and the switch for the MI code.
115 */
116 static uint8_t esp_read_reg(struct ncr53c9x_softc *, int);
117 static void esp_write_reg(struct ncr53c9x_softc *, int, uint8_t);
118 static int esp_dma_isintr(struct ncr53c9x_softc *);
119 static void esp_dma_reset(struct ncr53c9x_softc *);
120 static int esp_dma_intr(struct ncr53c9x_softc *);
121 static int esp_dma_setup(struct ncr53c9x_softc *, uint8_t **, size_t *,
122 int, size_t *);
123 static void esp_dma_go(struct ncr53c9x_softc *);
124 static void esp_dma_stop(struct ncr53c9x_softc *);
125 static int esp_dma_isactive(struct ncr53c9x_softc *);
126 static void esp_quick_write_reg(struct ncr53c9x_softc *, int, uint8_t);
127 static int esp_quick_dma_intr(struct ncr53c9x_softc *);
128 static int esp_quick_dma_setup(struct ncr53c9x_softc *, uint8_t **,
129 size_t *, int, size_t *);
130 static void esp_quick_dma_go(struct ncr53c9x_softc *);
131
132 static void esp_av_write_reg(struct ncr53c9x_softc *, int, uint8_t);
133 static void esp_av_dma_reset(struct ncr53c9x_softc *);
134 static int esp_av_dma_intr(struct ncr53c9x_softc *);
135 static int esp_av_pio_intr(struct ncr53c9x_softc *);
136 static int esp_av_dma_setup(struct ncr53c9x_softc *, uint8_t **, size_t *,
137 int, size_t *);
138 static void esp_av_dma_go(struct ncr53c9x_softc *);
139 static void esp_av_dma_stop(struct ncr53c9x_softc *);
140
141 static void esp_intr(void *);
142 static void esp_dualbus_intr(void *);
143
144 static int esp_dafb_have_dreq(struct esp_softc *);
145 static int esp_iosb_have_dreq(struct esp_softc *);
146 int (*esp_have_dreq)(struct esp_softc *);
147
148 static struct esp_softc *esp0, *esp1;
149
150 static struct ncr53c9x_glue esp_glue = {
151 .gl_read_reg = esp_read_reg,
152 .gl_write_reg = esp_write_reg,
153 .gl_dma_isintr = esp_dma_isintr,
154 .gl_dma_reset = esp_dma_reset,
155 .gl_dma_intr = esp_dma_intr,
156 .gl_dma_setup = esp_dma_setup,
157 .gl_dma_go = esp_dma_go,
158 .gl_dma_stop = esp_dma_stop,
159 .gl_dma_isactive = esp_dma_isactive,
160 .gl_clear_latched_intr = NULL,
161 };
162
163 static int
164 espmatch(device_t parent, cfdata_t cf, void *aux)
165 {
166 struct obio_attach_args *oa = aux;
167
168 if (oa->oa_addr == 0 && mac68k_machine.scsi96)
169 return 1;
170 if (oa->oa_addr == 1 && mac68k_machine.scsi96_2)
171 return 1;
172 return 0;
173 }
174
175 /*
176 * Attach this instance, and then all the sub-devices
177 */
178 static void
179 espattach(device_t parent, device_t self, void *aux)
180 {
181 struct esp_softc *esc = device_private(self);
182 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
183 struct obio_attach_args *oa = aux;
184 bus_addr_t addr;
185 unsigned long reg_offset;
186 int quick = 0, avdma = 0;
187 uint8_t irq_mask; /* mask for clearing IRQ */
188 extern vaddr_t SCSIBase;
189
190 sc->sc_dev = self;
191
192 reg_offset = SCSIBase - IOBase;
193
194 /*
195 * For Wombat, Primus and Optimus motherboards, DREQ is
196 * visible on bit 0 of the IOSB's emulated VIA2 vIFR (and
197 * the scsi registers are offset 0x1000 bytes from IOBase).
198 *
199 * For the Q700/900/950 it's at f9800024 for bus 0 and
200 * f9800028 for bus 1 (900/950). For these machines, that is also
201 * a (12-bit) configuration register for DAFB's control of the
202 * pseudo-DMA timing. The default value is 0x1d1.
203 */
204 if (oa->oa_addr == 0) {
205 if (reg_offset == 0x10000) {
206 quick = 1;
207 esp_have_dreq = esp_iosb_have_dreq;
208 } else if (reg_offset == 0x18000)
209 avdma = 1;
210 else {
211 addr = 0xf9800024;
212 goto dafb_dreq;
213 }
214 } else {
215 bus_space_tag_t bst;
216 bus_space_handle_t bsh;
217
218 addr = 0xf9800028;
219
220 dafb_dreq: bst = oa->oa_tag;
221 if (bus_space_map(bst, addr, 4, 0, &bsh))
222 aprint_error(": failed to map 4 at 0x%lx.\n", addr);
223 else {
224 quick = 1;
225 esp_have_dreq = esp_dafb_have_dreq;
226 esc->sc_dreqreg = (volatile uint32_t *)
227 bus_space_vaddr(bst, bsh);
228 *esc->sc_dreqreg = 0x1d1;
229 }
230 }
231
232 if (quick) {
233 esp_glue.gl_write_reg = esp_quick_write_reg;
234 esp_glue.gl_dma_intr = esp_quick_dma_intr;
235 esp_glue.gl_dma_setup = esp_quick_dma_setup;
236 esp_glue.gl_dma_go = esp_quick_dma_go;
237 } else if (avdma) {
238 esp_glue.gl_write_reg = esp_av_write_reg;
239 esp_glue.gl_dma_reset = esp_av_dma_reset;
240 esp_glue.gl_dma_intr = esp_av_dma_intr;
241 esp_glue.gl_dma_setup = esp_av_dma_setup;
242 esp_glue.gl_dma_go = esp_av_dma_go;
243 esp_glue.gl_dma_stop = esp_av_dma_stop;
244 }
245
246 /*
247 * Set up the glue for MI code early; we use some of it here.
248 */
249 sc->sc_glue = &esp_glue;
250
251 /*
252 * Save the regs
253 */
254 if (oa->oa_addr == 0) {
255 esp0 = esc;
256
257 esc->sc_reg = (volatile uint8_t *)SCSIBase;
258 via2_register_irq(VIA2_SCSIIRQ, esp_intr, esc);
259 irq_mask = V2IF_SCSIIRQ;
260 if (reg_offset == 0x10000) {
261 /* From the Q650 developer's note */
262 sc->sc_freq = 16500000;
263 } else
264 sc->sc_freq = 25000000;
265
266 if (quick)
267 aprint_normal(" (quick)");
268 else if (avdma)
269 aprint_normal(" (avdma)");
270 } else {
271 esp1 = esc;
272
273 esc->sc_reg = (volatile uint8_t *)SCSIBase + 0x402;
274 via2_register_irq(VIA2_SCSIIRQ, esp_dualbus_intr, NULL);
275 irq_mask = 0;
276 sc->sc_freq = 25000000;
277
278 if (quick)
279 printf(" (quick)");
280 }
281
282 aprint_normal(": address %p", esc->sc_reg);
283
284 sc->sc_id = 7;
285
286 /* gimme MHz */
287 sc->sc_freq /= 1000000;
288
289 /*
290 * It is necessary to try to load the 2nd config register here,
291 * to find out what rev the esp chip is, else the esp_reset
292 * will not set up the defaults correctly.
293 */
294 sc->sc_cfg1 = sc->sc_id; /* | NCRCFG1_PARENB; */
295 sc->sc_cfg2 = NCRCFG2_SCSI2;
296 if (avdma) {
297 sc->sc_cfg3 = NCRCFG3_CDB;
298 sc->sc_rev = NCR_VARIANT_NCR53C94;
299 } else {
300 sc->sc_cfg3 = 0;
301 sc->sc_rev = NCR_VARIANT_NCR53C96;
302 }
303
304 /*
305 * This is the value used to start sync negotiations
306 * Note that the NCR register "SYNCTP" is programmed
307 * in "clocks per byte", and has a minimum value of 4.
308 * The SCSI period used in negotiation is one-fourth
309 * of the time (in nanoseconds) needed to transfer one byte.
310 * Since the chip's clock is given in MHz, we have the following
311 * formula: 4 * period = (1000 / freq) * 4
312 */
313 sc->sc_minsync = 1000 / sc->sc_freq;
314
315 /* We need this to fit into the TCR... */
316 sc->sc_maxxfer = 64 * 1024;
317
318 switch (current_mac_model->machineid) {
319 case MACH_MACQ630:
320 /* XXX on LC630 64k xfer causes timeout error */
321 sc->sc_maxxfer = 63 * 1024;
322 break;
323 }
324
325 if (!quick) {
326 /*
327 * No synchronous xfers w/o DMA.
328 *
329 * XXXRO
330 * Also disable synchronous xfers for avdma for now,
331 * by which some disks cannot be read.
332 */
333 sc->sc_minsync = 0;
334 }
335
336 if (!quick && !avdma)
337 sc->sc_maxxfer = 8 * 1024;
338
339 /*
340 * Configure interrupts.
341 */
342 if (irq_mask) {
343 via2_reg(vPCR) = 0x22;
344 via2_reg(vIFR) = irq_mask;
345 via2_reg(vIER) = 0x80 | irq_mask;
346 }
347
348 /*
349 * Setup for AV DMA
350 */
351 if (avdma) {
352 bus_dma_segment_t osegs, isegs;
353 int orsegs, irsegs;
354
355 esc->sc_rset = 0;
356 esc->sc_pio = 0;
357 esc->sc_dmat = oa->oa_dmat;
358
359 if (bus_dmamap_create(esc->sc_dmat, sc->sc_maxxfer,
360 sc->sc_maxxfer / NBPG + 1, sc->sc_maxxfer, 0,
361 BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &esc->sc_dmap)) {
362 printf("failed to create DMA map.\n");
363 return;
364 }
365
366 /*
367 * Allocate memory which is friendly to the DMA engine
368 * (16-byte aligned) for use as the SCSI message buffers.
369 *
370 * XXX
371 * We need two buffers here. Since bus_dmamem_map(9) for
372 * m68k round size into NBPG.
373 */
374 if (bus_dmamem_alloc(esc->sc_dmat, NBPG, 16, NBPG,
375 &osegs, 1, &orsegs, BUS_DMA_NOWAIT)) {
376 printf("failed to allocate omess buffer.\n");
377 goto out1;
378 }
379 if (bus_dmamem_map(esc->sc_dmat, &osegs, orsegs,
380 NCR_MAX_MSG_LEN, (void **)&sc->sc_omess,
381 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) {
382 printf("failed to map omess buffer.\n");
383 goto out2;
384 }
385
386 if (bus_dmamem_alloc(esc->sc_dmat, NBPG, 16, NBPG,
387 &isegs, 1, &irsegs, BUS_DMA_NOWAIT)) {
388 printf("failed to allocate imess buffer.\n");
389 goto out3;
390 }
391 if (bus_dmamem_map(esc->sc_dmat, &isegs, irsegs,
392 NCR_MAX_MSG_LEN + 1, (void **)&sc->sc_imess,
393 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) {
394 printf("failed to map imess buffer.\n");
395
396 bus_dmamem_free(esc->sc_dmat, &isegs, irsegs);
397 out3: bus_dmamem_unmap(esc->sc_dmat, sc->sc_omess, NBPG);
398 out2: bus_dmamem_free(esc->sc_dmat, &osegs, orsegs);
399 out1: bus_dmamap_destroy(esc->sc_dmat, esc->sc_dmap);
400 return;
401 }
402 }
403
404 /*
405 * Now try to attach all the sub-devices
406 */
407 sc->sc_adapter.adapt_minphys = minphys;
408 sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request;
409 ncr53c9x_attach(sc);
410 }
411
412 /*
413 * Glue functions.
414 */
415
416 static uint8_t
417 esp_read_reg(struct ncr53c9x_softc *sc, int reg)
418 {
419 struct esp_softc *esc = (struct esp_softc *)sc;
420
421 return esc->sc_reg[reg * 16];
422 }
423
424 static void
425 esp_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t val)
426 {
427 struct esp_softc *esc = (struct esp_softc *)sc;
428 uint8_t v = val;
429
430 if (reg == NCR_CMD && v == (NCRCMD_TRANS|NCRCMD_DMA)) {
431 v = NCRCMD_TRANS;
432 }
433 esc->sc_reg[reg * 16] = v;
434 }
435
436 static void
437 esp_dma_stop(struct ncr53c9x_softc *sc)
438 {
439 }
440
441 static int
442 esp_dma_isactive(struct ncr53c9x_softc *sc)
443 {
444 struct esp_softc *esc = (struct esp_softc *)sc;
445
446 return esc->sc_active;
447 }
448
449 static int
450 esp_dma_isintr(struct ncr53c9x_softc *sc)
451 {
452 struct esp_softc *esc = (struct esp_softc *)sc;
453
454 return esc->sc_reg[NCR_STAT * 16] & NCRSTAT_INT;
455 }
456
457 static void
458 esp_dma_reset(struct ncr53c9x_softc *sc)
459 {
460 struct esp_softc *esc = (struct esp_softc *)sc;
461
462 esc->sc_active = 0;
463 esc->sc_tc = 0;
464 }
465
466 static int
467 esp_dma_intr(struct ncr53c9x_softc *sc)
468 {
469 struct esp_softc *esc = (struct esp_softc *)sc;
470 volatile uint8_t *cmdreg, *intrreg, *statreg, *fiforeg;
471 uint8_t *p;
472 u_int espphase, espstat, espintr;
473 int cnt, s;
474
475 if (esc->sc_active == 0) {
476 printf("dma_intr--inactive DMA\n");
477 return -1;
478 }
479
480 if ((sc->sc_espintr & NCRINTR_BS) == 0) {
481 esc->sc_active = 0;
482 return 0;
483 }
484
485 cnt = *esc->sc_dmalen;
486 if (*esc->sc_dmalen == 0) {
487 printf("data interrupt, but no count left.\n");
488 }
489
490 p = *esc->sc_dmaaddr;
491 espphase = sc->sc_phase;
492 espstat = (u_int)sc->sc_espstat;
493 espintr = (u_int)sc->sc_espintr;
494 cmdreg = esc->sc_reg + NCR_CMD * 16;
495 fiforeg = esc->sc_reg + NCR_FIFO * 16;
496 statreg = esc->sc_reg + NCR_STAT * 16;
497 intrreg = esc->sc_reg + NCR_INTR * 16;
498 do {
499 if (esc->sc_datain) {
500 *p++ = *fiforeg;
501 cnt--;
502 if (espphase == DATA_IN_PHASE) {
503 *cmdreg = NCRCMD_TRANS;
504 } else {
505 esc->sc_active = 0;
506 }
507 } else {
508 if ( (espphase == DATA_OUT_PHASE)
509 || (espphase == MESSAGE_OUT_PHASE)) {
510 *fiforeg = *p++;
511 cnt--;
512 *cmdreg = NCRCMD_TRANS;
513 } else {
514 esc->sc_active = 0;
515 }
516 }
517
518 if (esc->sc_active) {
519 while (!(*statreg & 0x80));
520 s = splhigh();
521 espstat = *statreg;
522 espintr = *intrreg;
523 espphase = (espintr & NCRINTR_DIS)
524 ? /* Disconnected */ BUSFREE_PHASE
525 : espstat & PHASE_MASK;
526 splx(s);
527 }
528 } while (esc->sc_active && (espintr & NCRINTR_BS));
529 sc->sc_phase = espphase;
530 sc->sc_espstat = (uint8_t)espstat;
531 sc->sc_espintr = (uint8_t)espintr;
532 *esc->sc_dmaaddr = p;
533 *esc->sc_dmalen = cnt;
534
535 if (*esc->sc_dmalen == 0) {
536 esc->sc_tc = NCRSTAT_TC;
537 }
538 sc->sc_espstat |= esc->sc_tc;
539 return 0;
540 }
541
542 static int
543 esp_dma_setup(struct ncr53c9x_softc *sc, uint8_t **addr, size_t *len,
544 int datain, size_t *dmasize)
545 {
546 struct esp_softc *esc = (struct esp_softc *)sc;
547
548 esc->sc_dmaaddr = addr;
549 esc->sc_dmalen = len;
550 esc->sc_datain = datain;
551 esc->sc_dmasize = *dmasize;
552 esc->sc_tc = 0;
553
554 return 0;
555 }
556
557 static void
558 esp_dma_go(struct ncr53c9x_softc *sc)
559 {
560 struct esp_softc *esc = (struct esp_softc *)sc;
561
562 if (esc->sc_datain == 0) {
563 esc->sc_reg[NCR_FIFO * 16] = **esc->sc_dmaaddr;
564 (*esc->sc_dmalen)--;
565 (*esc->sc_dmaaddr)++;
566 }
567 esc->sc_active = 1;
568 }
569
570 static void
571 esp_quick_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t val)
572 {
573 struct esp_softc *esc = (struct esp_softc *)sc;
574
575 esc->sc_reg[reg * 16] = val;
576 }
577
578 #if DEBUG
579 int mac68k_esp_debug=0;
580 #endif
581
582 static int
583 esp_quick_dma_intr(struct ncr53c9x_softc *sc)
584 {
585 struct esp_softc *esc = (struct esp_softc *)sc;
586 int trans=0, resid=0;
587
588 if (esc->sc_active == 0)
589 panic("dma_intr--inactive DMA");
590
591 esc->sc_active = 0;
592
593 if (esc->sc_dmasize == 0) {
594 int res;
595
596 res = NCR_READ_REG(sc, NCR_TCL);
597 res += NCR_READ_REG(sc, NCR_TCM) << 8;
598 /* This can happen in the case of a TRPAD operation */
599 /* Pretend that it was complete */
600 sc->sc_espstat |= NCRSTAT_TC;
601 #if DEBUG
602 if (mac68k_esp_debug) {
603 printf("dmaintr: DMA xfer of zero xferred %d\n",
604 65536 - res);
605 }
606 #endif
607 return 0;
608 }
609
610 if ((sc->sc_espstat & NCRSTAT_TC) == 0) {
611 if (esc->sc_datain == 0) {
612 resid = NCR_READ_REG(sc, NCR_FFLAG) & 0x1f;
613 #if DEBUG
614 if (mac68k_esp_debug) {
615 printf("Write FIFO residual %d bytes\n", resid);
616 }
617 #endif
618 }
619 resid += NCR_READ_REG(sc, NCR_TCL);
620 resid += NCR_READ_REG(sc, NCR_TCM) << 8;
621 if (resid == 0)
622 resid = 65536;
623 }
624
625 trans = esc->sc_dmasize - resid;
626 if (trans < 0) {
627 printf("dmaintr: trans < 0????\n");
628 trans = *esc->sc_dmalen;
629 }
630
631 NCR_DMA(("dmaintr: trans %d, resid %d.\n", trans, resid));
632 #if DEBUG
633 if (mac68k_esp_debug) {
634 printf("eqd_intr: trans %d, resid %d.\n", trans, resid);
635 }
636 #endif
637 *esc->sc_dmaaddr += trans;
638 *esc->sc_dmalen -= trans;
639
640 return 0;
641 }
642
643 static int
644 esp_quick_dma_setup(struct ncr53c9x_softc *sc, uint8_t **addr, size_t *len,
645 int datain, size_t *dmasize)
646 {
647 struct esp_softc *esc = (struct esp_softc *)sc;
648
649 esc->sc_dmaaddr = addr;
650 esc->sc_dmalen = len;
651
652 if (*len & 1) {
653 esc->sc_pad = 1;
654 } else {
655 esc->sc_pad = 0;
656 }
657
658 esc->sc_datain = datain;
659 esc->sc_dmasize = *dmasize;
660
661 #if DIAGNOSTIC
662 if (esc->sc_dmasize == 0) {
663 /* This can happen in the case of a TRPAD operation */
664 }
665 #endif
666 #if DEBUG
667 if (mac68k_esp_debug) {
668 printf("eqd_setup: addr %lx, len %lx, in? %d, dmasize %lx\n",
669 (long) *addr, (long) *len, datain, (long) esc->sc_dmasize);
670 }
671 #endif
672
673 return 0;
674 }
675
676 static int
677 esp_dafb_have_dreq(struct esp_softc *esc)
678 {
679
680 return *esc->sc_dreqreg & 0x200;
681 }
682
683 static int
684 esp_iosb_have_dreq(struct esp_softc *esc)
685 {
686
687 return via2_reg(vIFR) & V2IF_SCSIDRQ;
688 }
689
690 static volatile int espspl = -1;
691
692 /*
693 * Apple "DMA" is weird.
694 *
695 * Basically, the CPU acts like the DMA controller. The DREQ/ off the
696 * chip goes to a register that we've mapped at attach time (on the
697 * IOSB or DAFB, depending on the machine). Apple also provides some
698 * space for which the memory controller handshakes data to/from the
699 * NCR chip with the DACK/ line. This space appears to be mapped over
700 * and over, every 4 bytes, but only the lower 16 bits are valid (but
701 * reading the upper 16 bits will handshake DACK/ just fine, so if you
702 * read *uint16_t++ = *uint16_t++ in a loop, you'll get
703 * <databyte><databyte>0xff0xff<databyte><databyte>0xff0xff...
704 *
705 * When you're attempting to read or write memory to this DACK/ed space,
706 * and the NCR is not ready for some timeout period, the system will
707 * generate a bus error. This might be for one of several reasons:
708 *
709 * 1) (on write) The FIFO is full and is not draining.
710 * 2) (on read) The FIFO is empty and is not filling.
711 * 3) An interrupt condition has occurred.
712 * 4) Anything else?
713 *
714 * So if a bus error occurs, we first turn off the nofault bus error handler,
715 * then we check for an interrupt (which would render the first two
716 * possibilities moot). If there's no interrupt, check for a DREQ/. If we
717 * have that, then attempt to resume stuffing (or unstuffing) the FIFO. If
718 * neither condition holds, pause briefly and check again.
719 *
720 * NOTE!!! In order to make allowances for the hardware structure of
721 * the mac, spl values in here are hardcoded!!!!!!!!!
722 * This is done to allow serial interrupts to get in during
723 * scsi transfers. This is ugly.
724 */
725 static void
726 esp_quick_dma_go(struct ncr53c9x_softc *sc)
727 {
728 struct esp_softc *esc = (struct esp_softc *)sc;
729 extern long mac68k_a2_fromfault;
730 extern int *nofault;
731 label_t faultbuf;
732 uint16_t volatile *pdma;
733 uint16_t *addr;
734 int len, res;
735 uint16_t cnt32, cnt2;
736 volatile uint8_t *statreg;
737
738 esc->sc_active = 1;
739
740 espspl = splhigh();
741
742 addr = (uint16_t *)*esc->sc_dmaaddr;
743 len = esc->sc_dmasize;
744
745 restart_dmago:
746 #if DEBUG
747 if (mac68k_esp_debug) {
748 printf("eqdg: a %lx, l %lx, in? %d ... ",
749 (long) addr, (long) len, esc->sc_datain);
750 }
751 #endif
752 nofault = (int *)&faultbuf;
753 if (setjmp((label_t *)nofault)) {
754 int i = 0;
755
756 nofault = NULL;
757 #if DEBUG
758 if (mac68k_esp_debug) {
759 printf("be\n");
760 }
761 #endif
762 /*
763 * Bus error...
764 * So, we first check for an interrupt. If we have
765 * one, go handle it. Next we check for DREQ/. If
766 * we have it, then we restart the transfer. If
767 * neither, then loop until we get one or the other.
768 */
769 statreg = esc->sc_reg + NCR_STAT * 16;
770 for (;;) {
771 spl2(); /* Give serial a chance... */
772 splhigh(); /* That's enough... */
773
774 if (*statreg & 0x80) {
775 goto gotintr;
776 }
777
778 if (esp_have_dreq(esc)) {
779 /*
780 * Get the remaining length from the address
781 * differential.
782 */
783 addr = (uint16_t *)mac68k_a2_fromfault;
784 len = esc->sc_dmasize -
785 ((long)addr - (long)*esc->sc_dmaaddr);
786
787 if (esc->sc_datain == 0) {
788 /*
789 * Let the FIFO drain before we read
790 * the transfer count.
791 * Do we need to do this?
792 * Can we do this?
793 */
794 while (NCR_READ_REG(sc, NCR_FFLAG)
795 & 0x1f);
796 /*
797 * Get the length from the transfer
798 * counters.
799 */
800 res = NCR_READ_REG(sc, NCR_TCL);
801 res += NCR_READ_REG(sc, NCR_TCM) << 8;
802 /*
803 * If they don't agree,
804 * adjust accordingly.
805 */
806 while (res > len) {
807 len+=2; addr--;
808 }
809 if (res != len) {
810 panic("%s: res %d != len %d",
811 __func__, res, len);
812 }
813 }
814 break;
815 }
816
817 DELAY(1);
818 if (i++ > 1000000)
819 panic("%s: Bus error, but no condition! Argh!",
820 __func__);
821 }
822 goto restart_dmago;
823 }
824
825 len &= ~1;
826
827 statreg = esc->sc_reg + NCR_STAT * 16;
828 pdma = (volatile uint16_t *)(esc->sc_reg + 0x100);
829
830 /*
831 * These loops are unrolled into assembly for two reasons:
832 * 1) We can make sure that they are as efficient as possible, and
833 * 2) (more importantly) we need the address that we are reading
834 * from or writing to to be in a2.
835 */
836 cnt32 = len / 32;
837 cnt2 = (len % 32) / 2;
838 if (esc->sc_datain == 0) {
839 /* while (cnt32--) { 16 instances of *pdma = *addr++; } */
840 /* while (cnt2--) { *pdma = *addr++; } */
841 __asm volatile (
842 " movl %1, %%a2 \n"
843 " movl %2, %%a3 \n"
844 " movw %3, %%d2 \n"
845 " cmpw #0, %%d2 \n"
846 " beq 2f \n"
847 " subql #1, %%d2 \n"
848 "1: movw %%a2@+,%%a3@; movw %%a2@+,%%a3@ \n"
849 " movw %%a2@+,%%a3@; movw %%a2@+,%%a3@ \n"
850 " movw %%a2@+,%%a3@; movw %%a2@+,%%a3@ \n"
851 " movw %%a2@+,%%a3@; movw %%a2@+,%%a3@ \n"
852 " movw %%a2@+,%%a3@; movw %%a2@+,%%a3@ \n"
853 " movw %%a2@+,%%a3@; movw %%a2@+,%%a3@ \n"
854 " movw %%a2@+,%%a3@; movw %%a2@+,%%a3@ \n"
855 " movw %%a2@+,%%a3@; movw %%a2@+,%%a3@ \n"
856 " movw #8704,%%sr \n"
857 " movw #9728,%%sr \n"
858 " dbra %%d2, 1b \n"
859 "2: movw %4, %%d2 \n"
860 " cmpw #0, %%d2 \n"
861 " beq 4f \n"
862 " subql #1, %%d2 \n"
863 "3: movw %%a2@+,%%a3@ \n"
864 " dbra %%d2, 3b \n"
865 "4: movl %%a2, %0"
866 : "=g" (addr)
867 : "0" (addr), "g" (pdma), "g" (cnt32), "g" (cnt2)
868 : "a2", "a3", "d2");
869 if (esc->sc_pad) {
870 volatile uint8_t *c;
871 c = (volatile uint8_t *) addr;
872 /* Wait for DREQ */
873 while (!esp_have_dreq(esc)) {
874 if (*statreg & 0x80) {
875 nofault = NULL;
876 goto gotintr;
877 }
878 }
879 *(volatile int8_t *)pdma = *c;
880 }
881 } else {
882 /* while (cnt32--) { 16 instances of *addr++ = *pdma; } */
883 /* while (cnt2--) { *addr++ = *pdma; } */
884 __asm volatile (
885 " movl %1, %%a2 \n"
886 " movl %2, %%a3 \n"
887 " movw %3, %%d2 \n"
888 " cmpw #0, %%d2 \n"
889 " beq 6f \n"
890 " subql #1, %%d2 \n"
891 "5: movw %%a3@,%%a2@+; movw %%a3@,%%a2@+ \n"
892 " movw %%a3@,%%a2@+; movw %%a3@,%%a2@+ \n"
893 " movw %%a3@,%%a2@+; movw %%a3@,%%a2@+ \n"
894 " movw %%a3@,%%a2@+; movw %%a3@,%%a2@+ \n"
895 " movw %%a3@,%%a2@+; movw %%a3@,%%a2@+ \n"
896 " movw %%a3@,%%a2@+; movw %%a3@,%%a2@+ \n"
897 " movw %%a3@,%%a2@+; movw %%a3@,%%a2@+ \n"
898 " movw %%a3@,%%a2@+; movw %%a3@,%%a2@+ \n"
899 " movw #8704,%%sr \n"
900 " movw #9728,%%sr \n"
901 " dbra %%d2, 5b \n"
902 "6: movw %4, %%d2 \n"
903 " cmpw #0, %%d2 \n"
904 " beq 8f \n"
905 " subql #1, %%d2 \n"
906 "7: movw %%a3@,%%a2@+ \n"
907 " dbra %%d2, 7b \n"
908 "8: movl %%a2, %0"
909 : "=g" (addr)
910 : "0" (addr), "g" (pdma), "g" (cnt32), "g" (cnt2)
911 : "a2", "a3", "d2");
912 if (esc->sc_pad) {
913 volatile uint8_t *c;
914 c = (volatile int8_t *)addr;
915 /* Wait for DREQ */
916 while (!esp_have_dreq(esc)) {
917 if (*statreg & 0x80) {
918 nofault = NULL;
919 goto gotintr;
920 }
921 }
922 *c = *(volatile uint8_t *)pdma;
923 }
924 }
925
926 nofault = NULL;
927
928 /*
929 * If we have not received an interrupt yet, we should shortly,
930 * and we can't prevent it, so return and wait for it.
931 */
932 if ((*statreg & 0x80) == 0) {
933 #if DEBUG
934 if (mac68k_esp_debug) {
935 printf("g.\n");
936 }
937 #endif
938 if (espspl != -1)
939 splx(espspl);
940 espspl = -1;
941 return;
942 }
943
944 gotintr:
945 #if DEBUG
946 if (mac68k_esp_debug) {
947 printf("g!\n");
948 }
949 #endif
950 /*
951 * We have been called from the MI ncr53c9x_intr() handler,
952 * which protects itself against multiple invocation with a
953 * lock. Follow the example of ncr53c9x_poll().
954 */
955 mutex_exit(&sc->sc_lock);
956 ncr53c9x_intr(sc);
957 mutex_enter(&sc->sc_lock);
958 if (espspl != -1)
959 splx(espspl);
960 espspl = -1;
961 }
962
963 static void
964 esp_intr(void *sc)
965 {
966 struct esp_softc *esc = (struct esp_softc *)sc;
967
968 if (esc->sc_reg[NCR_STAT * 16] & 0x80) {
969 ncr53c9x_intr((struct ncr53c9x_softc *)esp0);
970 }
971 }
972
973 static void
974 esp_dualbus_intr(void *sc)
975 {
976 if (esp0 && (esp0->sc_reg[NCR_STAT * 16] & 0x80)) {
977 ncr53c9x_intr((struct ncr53c9x_softc *)esp0);
978 }
979
980 if (esp1 && (esp1->sc_reg[NCR_STAT * 16] & 0x80)) {
981 ncr53c9x_intr((struct ncr53c9x_softc *)esp1);
982 }
983 }
984
985 static void
986 esp_av_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t val)
987 {
988 struct esp_softc *esc = (struct esp_softc *)sc;
989 uint8_t v;
990
991 if (esc->sc_pio && reg == NCR_CMD && val == (NCRCMD_TRANS|NCRCMD_DMA))
992 v = NCRCMD_TRANS;
993 else
994 v = val;
995 esc->sc_reg[reg * 16] = v;
996 }
997
998 static void
999 esp_av_dma_reset(struct ncr53c9x_softc *sc)
1000 {
1001 struct esp_softc *esc = (struct esp_softc *)sc;
1002 uint32_t res;
1003
1004 if(esc->sc_active && !esc->sc_pio)
1005 stop_psc_dma(PSC_DMA_CHANNEL_SCSI, esc->sc_rset, &res,
1006 esc->sc_datain);
1007
1008 esc->sc_active = esc->sc_tc = 0;
1009 }
1010
1011 static int
1012 esp_av_dma_intr(struct ncr53c9x_softc *sc)
1013 {
1014 struct esp_softc *esc = (struct esp_softc *)sc;
1015 uint32_t resid;
1016 int trans, fifo_count;
1017
1018 KASSERT(esc->sc_active);
1019
1020 /* Deal with any PIO transfers */
1021 if (esc->sc_pio)
1022 return esp_av_pio_intr(sc);
1023
1024 #if DEBUG
1025 int tc_size;
1026 tc_size = NCR_READ_REG(sc, NCR_TCM);
1027 tc_size <<= 8;
1028 tc_size |= NCR_READ_REG(sc, NCR_TCL);
1029 printf("[av_dma_intr: intr 0x%x stat 0x%x tc 0x%x dmasize %zu]\n",
1030 sc->sc_espintr, sc->sc_espstat, tc_size, esc->sc_dmasize);
1031 #endif
1032
1033 esc->sc_active = 0;
1034
1035 if (esc->sc_dmasize == 0) {
1036 /* A "Transfer Pad" operation completed */
1037 return 0;
1038 }
1039
1040 if ((sc->sc_espintr & NCRINTR_BS) && (sc->sc_espstat & NCRSTAT_TC)) {
1041 /* Wait for engine to finish the transfer */
1042 wait_psc_dma(PSC_DMA_CHANNEL_SCSI, esc->sc_rset, &resid);
1043 #if DEBUG
1044 printf("[av_dma_intr: DMA %s done]\n", esc->sc_datain ?
1045 "read" : "write");
1046 #endif
1047 }
1048
1049 /* Halt the DMA engine */
1050 stop_psc_dma(PSC_DMA_CHANNEL_SCSI, esc->sc_rset, &resid,
1051 esc->sc_datain);
1052
1053 bus_dmamap_sync(esc->sc_dmat, esc->sc_dmap, 0, esc->sc_dmasize,
1054 esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1055 bus_dmamap_unload(esc->sc_dmat, esc->sc_dmap);
1056
1057 /* On read, bytes in the FIFO count as residual */
1058 if (esc->sc_datain) {
1059 fifo_count = (int)(NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF);
1060 resid += fifo_count;
1061 if (fifo_count) {
1062 /*
1063 * Flush those bytes since we don't know
1064 * what state they were in.
1065 */
1066 NCRCMD(sc, NCRCMD_FLUSH);
1067 #if DEBUG
1068 printf("[av_dma_intr: flushed %d bytes from FIFO]\n",
1069 fifo_count) ;
1070 #endif
1071 }
1072 }
1073
1074 trans = esc->sc_dmasize - resid;
1075 if (trans < 0) {
1076 /*
1077 * XXXRO
1078 * This situation can happen in perfectly normal operation
1079 * if the ESP is reselected while using DMA to select
1080 * another target. As such, don't print the warning.
1081 */
1082 #if DEBUG
1083 printf("[av_dma_intr: xfer (%d) > req (%zu)]\n",
1084 trans, esc->sc_dmasize);
1085 #endif
1086 trans = esc->sc_dmasize;
1087 }
1088
1089 #if DEBUG
1090 printf("[av_dma_intr: DMA %s of %d bytes done with %u residual]\n",
1091 esc->sc_datain ? "read" : "write", trans, resid);
1092 #endif
1093
1094 *esc->sc_dmalen -= trans;
1095 *esc->sc_dmaaddr += trans;
1096
1097 return 0;
1098 }
1099
1100 static int
1101 esp_av_pio_intr(struct ncr53c9x_softc *sc)
1102 {
1103 struct esp_softc *esc = (struct esp_softc *)sc;
1104 int espphase, cnt, s;
1105 uint8_t espstat, espintr;
1106 volatile uint8_t *cmdreg, *intrreg, *statreg, *fiforeg;
1107 uint8_t *p;
1108
1109 #if DEBUG
1110 printf("[av_pio_intr: intr 0x%x stat 0x%x]\n", sc->sc_espintr,
1111 sc->sc_espstat);
1112 #endif
1113
1114 if ((sc->sc_espintr & NCRINTR_BS) == 0) {
1115 esc->sc_active = 0;
1116 return 0;
1117 }
1118
1119 cnt = esc->sc_dmasize;
1120 #if DEBUG
1121 /*
1122 * XXXRO
1123 * Is this possible?
1124 */
1125 if (cnt == 0)
1126 printf("data interrupt, but no count left.\n");
1127 #endif
1128
1129 p = *esc->sc_dmaaddr;
1130 espphase = sc->sc_phase;
1131 espstat = sc->sc_espstat;
1132 espintr = sc->sc_espintr;
1133 cmdreg = esc->sc_reg + NCR_CMD * 16;
1134 fiforeg = esc->sc_reg + NCR_FIFO * 16;
1135 statreg = esc->sc_reg + NCR_STAT * 16;
1136 intrreg = esc->sc_reg + NCR_INTR * 16;
1137 do {
1138 if (esc->sc_datain) {
1139 *p++ = *fiforeg;
1140 cnt--;
1141 if (espphase == DATA_IN_PHASE)
1142 *cmdreg = NCRCMD_TRANS;
1143 else
1144 esc->sc_active = 0;
1145 } else {
1146 if ((espphase == DATA_OUT_PHASE) ||
1147 (espphase == MESSAGE_OUT_PHASE)) {
1148 *fiforeg = *p++;
1149 cnt--;
1150 *cmdreg = NCRCMD_TRANS;
1151 } else
1152 esc->sc_active = 0;
1153 }
1154
1155 if (esc->sc_active) {
1156 while (!(*statreg & NCRSTAT_INT));
1157 s = splhigh();
1158 espstat = *statreg;
1159 espintr = *intrreg;
1160 if (espintr & NCRINTR_DIS)
1161 espphase = BUSFREE_PHASE; /* disconnected */
1162 else
1163 espphase = espstat & PHASE_MASK;
1164 splx(s);
1165 }
1166 } while (cnt > 0 /* XXXRO not present in esp_dma_intr() */ &&
1167 esc->sc_active && (espintr & NCRINTR_BS));
1168
1169 /* XXXRO */
1170 KASSERT(cnt >= 0);
1171
1172 sc->sc_phase = espphase;
1173 sc->sc_espstat = espstat;
1174 sc->sc_espintr = espintr;
1175 *esc->sc_dmaaddr = p;
1176 *esc->sc_dmalen -= esc->sc_dmasize - cnt;
1177
1178 if (cnt == 0) {
1179 /* XXXRO */
1180 esc->sc_active = 0;
1181 esc->sc_tc = NCRSTAT_TC;
1182 }
1183
1184 sc->sc_espstat |= esc->sc_tc;
1185
1186 #if DEBUG
1187 printf("[av_pio_intr: PIO %s of %d bytes done %d residual]\n",
1188 esc->sc_datain ? "read" : "write", esc->sc_dmasize - cnt, cnt) ;
1189 #endif
1190
1191 return 0;
1192 }
1193
1194 static int
1195 esp_av_dma_setup(struct ncr53c9x_softc *sc, uint8_t **addr, size_t *len,
1196 int datain, size_t *dmasize)
1197 {
1198 struct esp_softc *esc = (struct esp_softc *)sc;
1199 size_t round_bytes;
1200
1201 esc->sc_dmaaddr = addr;
1202 esc->sc_dmalen = len;
1203 esc->sc_datain = datain;
1204
1205 /*
1206 * XXXRO
1207 * No need to set up DMA in `Transfer Pad' operation.
1208 */
1209 if (*dmasize == 0) {
1210 esc->sc_dmasize = 0;
1211 return 0;
1212 }
1213
1214 /*
1215 * Do short transfers of 16 bytes or less using PIO.
1216 */
1217 if (*dmasize <= 16) {
1218 esc->sc_pio = 1;
1219 esc->sc_tc = 0;
1220 esc->sc_dmasize = *dmasize;
1221 #ifdef DEBUG
1222 printf("[av_dma_setup: short PIO "
1223 "req %zu act %zu v %p p 0x%x %s]\n",
1224 *len, esc->sc_dmasize, *esc->sc_dmaaddr,
1225 kvtop(*esc->sc_dmaaddr), esc->sc_datain ?
1226 "read" : "write");
1227 #endif
1228 return 0;
1229 }
1230
1231 /*
1232 * Ensure the transfer is on a 16-byte aligned boundary for
1233 * the DMA engine by doing PIO to the next 16-byte boundary.
1234 */
1235 if ((uintptr_t)*addr & 0xf) {
1236 esc->sc_pio = 1;
1237 esc->sc_tc = 0;
1238
1239 round_bytes = 16 - ((uintptr_t)*addr & 0xf);
1240
1241 /* Try to optimize for fewer interrrupts */
1242 if (*dmasize > 16 + round_bytes)
1243 esc->sc_dmasize = round_bytes;
1244 else
1245 esc->sc_dmasize = *dmasize;
1246
1247 #ifdef DEBUG
1248 printf("[av_dma_setup: round PIO "
1249 "req %zu act %zu v %p p 0x%x %s]\n",
1250 *len, esc->sc_dmasize, *esc->sc_dmaaddr,
1251 kvtop(*esc->sc_dmaaddr), esc->sc_datain ?
1252 "read" : "write");
1253 #endif
1254
1255 return 0;
1256 }
1257
1258 /*
1259 * The DMA engine seems to like to move data in multiples of
1260 * 16 bytes. So if there are any trailing bytes, we move them
1261 * using PIO.
1262 */
1263 if(*dmasize & 0xf) {
1264 #ifdef DEBUG
1265 printf("[av_dma_setup: trimming %zu trailing bytes from DMA]\n",
1266 *dmasize & 0xf);
1267 #endif
1268 *dmasize -= *dmasize & 0xf;
1269 }
1270
1271 /*
1272 * At this point the data is acceptable for a DMA transaction.
1273 */
1274 esc->sc_pio = 0;
1275
1276 bus_dmamap_load(esc->sc_dmat, esc->sc_dmap, *esc->sc_dmaaddr,
1277 *dmasize, NULL, BUS_DMA_NOWAIT);
1278
1279 /*
1280 * The DMA engine can only transfer one contiguous segment at a time.
1281 */
1282 *dmasize = esc->sc_dmap->dm_segs[0].ds_len;
1283 esc->sc_dmasize = *dmasize;
1284
1285 bus_dmamap_sync(esc->sc_dmat, esc->sc_dmap, 0, esc->sc_dmasize,
1286 esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
1287
1288 /*
1289 * We must start a DMA before the device is ready to transfer
1290 * data or the DMA engine gets confused and thinks it has to
1291 * do a write when it should really do a read.
1292 *
1293 * Doing this here also seems to work fine for DMA writes.
1294 */
1295 #ifdef DEBUG
1296 printf("[av_dma_setup: DMA req %zu act %zu v %p p 0x%lx %s]\n",
1297 *len, esc->sc_dmasize, *esc->sc_dmaaddr,
1298 esc->sc_dmap->dm_segs[0].ds_addr, esc->sc_datain ?
1299 "read" : "write");
1300 #endif
1301 start_psc_dma(PSC_DMA_CHANNEL_SCSI, &esc->sc_rset,
1302 esc->sc_dmap->dm_segs[0].ds_addr,
1303 esc->sc_dmasize & ~0x1UL, esc->sc_datain);
1304
1305 return 0;
1306 }
1307
1308 static void
1309 esp_av_dma_go(struct ncr53c9x_softc *sc)
1310 {
1311 struct esp_softc *esc = (struct esp_softc *)sc;
1312
1313 /*
1314 * XXXRO
1315 * No DMA transfer in Transfer Pad operation
1316 */
1317 if (esc->sc_dmasize == 0)
1318 return;
1319
1320 if (esc->sc_pio && esc->sc_datain == 0) {
1321 NCR_WRITE_REG(sc, NCR_FIFO, **esc->sc_dmaaddr);
1322 (*esc->sc_dmaaddr)++;
1323 (*esc->sc_dmalen)--;
1324 esc->sc_dmasize--;
1325 }
1326 esc->sc_active = 1;
1327 }
1328
1329 static void
1330 esp_av_dma_stop(struct ncr53c9x_softc *sc)
1331 {
1332 struct esp_softc *esc = (struct esp_softc *)sc;
1333 uint32_t res;
1334
1335 if (esc->sc_active && !esc->sc_pio)
1336 stop_psc_dma(PSC_DMA_CHANNEL_SCSI, esc->sc_rset, &res,
1337 esc->sc_datain);
1338
1339 bus_dmamap_unload(esc->sc_dmat, esc->sc_dmap);
1340
1341 esc->sc_active = esc->sc_tc = 0;
1342 }
1343
1344