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