1 /* $NetBSD: esp.c,v 1.67 2023/02/03 23:17:49 tsutsui Exp $ */
2
3 /*-
4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
9 * Simulation Facility, NASA Ames Research Center.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * Copyright (c) 1994 Peter Galbavy
35 * All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software
46 * must display the following acknowledgement:
47 * This product includes software developed by Peter Galbavy
48 * 4. The name of the author may not be used to endorse or promote products
49 * derived from this software without specific prior written permission.
50 *
51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
52 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
55 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
56 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
57 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
60 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
61 * POSSIBILITY OF SUCH DAMAGE.
62 */
63
64 /*
65 * Based on aic6360 by Jarle Greipsland
66 *
67 * Acknowledgements: Many of the algorithms used in this driver are
68 * inspired by the work of Julian Elischer (julian@tfs.com) and
69 * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million!
70 */
71
72 /*
73 * Grabbed from the sparc port at revision 1.73 for the NeXT.
74 * Darrin B. Jewell <dbj@NetBSD.org> Sat Jul 4 15:41:32 1998
75 */
76
77 #include <sys/cdefs.h>
78 __KERNEL_RCSID(0, "$NetBSD: esp.c,v 1.67 2023/02/03 23:17:49 tsutsui Exp $");
79
80 #include <sys/types.h>
81 #include <sys/param.h>
82 #include <sys/systm.h>
83 #include <sys/kernel.h>
84 #include <sys/errno.h>
85 #include <sys/ioctl.h>
86 #include <sys/device.h>
87 #include <sys/buf.h>
88 #include <sys/proc.h>
89 #include <sys/queue.h>
90
91 #include <uvm/uvm_extern.h>
92
93 #include <dev/scsipi/scsi_all.h>
94 #include <dev/scsipi/scsipi_all.h>
95 #include <dev/scsipi/scsiconf.h>
96 #include <dev/scsipi/scsi_message.h>
97
98 #include <machine/bus.h>
99 #include <machine/autoconf.h>
100 #include <machine/cpu.h>
101
102 #include <dev/ic/ncr53c9xreg.h>
103 #include <dev/ic/ncr53c9xvar.h>
104
105 #include <next68k/next68k/isr.h>
106
107 #include <next68k/dev/intiovar.h>
108 #include <next68k/dev/nextdmareg.h>
109 #include <next68k/dev/nextdmavar.h>
110
111 #include <next68k/dev/espreg.h>
112 #include <next68k/dev/espvar.h>
113
114 #ifdef DEBUG
115 #undef ESP_DEBUG
116 #endif
117
118 #ifdef ESP_DEBUG
119 int esp_debug = 0;
120 #define DPRINTF(x) if (esp_debug) printf x;
121 #define NDTRACEIF(x) if (10) do {x;} while (0)
122 #else
123 #define DPRINTF(x)
124 #define NDTRACEIF(x)
125 #endif
126 #define PRINTF(x) printf x;
127
128
129 static int espmatch_intio(device_t, cfdata_t, void *);
130 static void espattach_intio(device_t, device_t, void *);
131
132 /* DMA callbacks */
133 static bus_dmamap_t esp_dmacb_continue(void *);
134 static void esp_dmacb_completed(bus_dmamap_t, void *);
135 static void esp_dmacb_shutdown(void *);
136
137 static void findchannel_defer(device_t);
138
139 #ifdef ESP_DEBUG
140 char esp_dma_dump[5*1024] = "";
141 struct ncr53c9x_softc *esp_debug_sc = 0;
142 void esp_dma_store(struct ncr53c9x_softc *);
143 void esp_dma_print(struct ncr53c9x_softc *);
144 int esp_dma_nest = 0;
145 int esptraceshow;
146 #endif
147
148
149 /* Linkup to the rest of the kernel */
150 CFATTACH_DECL_NEW(esp, sizeof(struct esp_softc),
151 espmatch_intio, espattach_intio, NULL, NULL);
152
153 static int attached = 0;
154
155 /*
156 * Functions and the switch for the MI code.
157 */
158 static uint8_t esp_read_reg(struct ncr53c9x_softc *, int);
159 static void esp_write_reg(struct ncr53c9x_softc *, int, uint8_t);
160 static int esp_dma_isintr(struct ncr53c9x_softc *);
161 static void esp_dma_reset(struct ncr53c9x_softc *);
162 static int esp_dma_intr(struct ncr53c9x_softc *);
163 static int esp_dma_setup(struct ncr53c9x_softc *, uint8_t **, size_t *, int,
164 size_t *);
165 static void esp_dma_go(struct ncr53c9x_softc *);
166 static void esp_dma_stop(struct ncr53c9x_softc *);
167 static int esp_dma_isactive(struct ncr53c9x_softc *);
168
169 static int doze(volatile int);
170
171 static struct ncr53c9x_glue esp_glue = {
172 .gl_read_reg = esp_read_reg,
173 .gl_write_reg = esp_write_reg,
174 .gl_dma_isintr = esp_dma_isintr,
175 .gl_dma_reset = esp_dma_reset,
176 .gl_dma_intr = esp_dma_intr,
177 .gl_dma_setup = esp_dma_setup,
178 .gl_dma_go = esp_dma_go,
179 .gl_dma_stop = esp_dma_stop,
180 .gl_dma_isactive = esp_dma_isactive,
181 .gl_clear_latched_intr = NULL
182 };
183
184 #define nd_bsr4(reg) \
185 bus_space_read_4(nsc->sc_bst, nsc->sc_bsh, (reg))
186 #define nd_bsw4(reg, val) \
187 bus_space_write_4(nsc->sc_bst, nsc->sc_bsh, (reg), (val))
188
189 #ifdef ESP_DEBUG
190 #define XCHR(x) hexdigits[(x) & 0xf]
191 static void
esp_hex_dump(unsigned char * pkt,size_t len)192 esp_hex_dump(unsigned char *pkt, size_t len)
193 {
194 size_t i, j;
195
196 printf("00000000 ");
197 for(i = 0; i < len; i++) {
198 printf("%c%c ", XCHR(pkt[i] >> 4), XCHR(pkt[i]));
199 if ((i + 1) % 16 == 8) {
200 printf(" ");
201 }
202 if ((i + 1) % 16 == 0) {
203 printf(" %c", '|');
204 for(j = 0; j < 16; j++) {
205 printf("%c", pkt[i - 15 + j] >= 32 &&
206 pkt[i - 15 + j] < 127 ?
207 pkt[i - 15 + j] : '.');
208 }
209 printf("%c\n%c%c%c%c%c%c%c%c ", '|',
210 XCHR((i + 1) >> 28), XCHR((i + 1) >> 24),
211 XCHR((i + 1) >> 20), XCHR((i + 1) >> 16),
212 XCHR((i + 1) >> 12), XCHR((i + 1) >> 8),
213 XCHR((i + 1) >> 4), XCHR(i + 1));
214 }
215 }
216 printf("\n");
217 }
218 #endif
219
220 static int
espmatch_intio(device_t parent,cfdata_t cf,void * aux)221 espmatch_intio(device_t parent, cfdata_t cf, void *aux)
222 {
223 struct intio_attach_args *ia = aux;
224
225 if (attached)
226 return 0;
227
228 ia->ia_addr = (void *)NEXT_P_SCSI;
229
230 return 1;
231 }
232
233 static void
findchannel_defer(device_t self)234 findchannel_defer(device_t self)
235 {
236 struct esp_softc *esc = device_private(self);
237 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
238 int error;
239
240 if (esc->sc_dma == NULL) {
241 aprint_normal("%s", device_xname(sc->sc_dev));
242 esc->sc_dma = nextdma_findchannel("scsi");
243 if (esc->sc_dma == NULL)
244 panic("%s: can't find DMA channel",
245 device_xname(sc->sc_dev));
246 }
247
248 nextdma_setconf(esc->sc_dma, shutdown_cb, &esp_dmacb_shutdown);
249 nextdma_setconf(esc->sc_dma, continue_cb, &esp_dmacb_continue);
250 nextdma_setconf(esc->sc_dma, completed_cb, &esp_dmacb_completed);
251 nextdma_setconf(esc->sc_dma, cb_arg, sc);
252
253 error = bus_dmamap_create(esc->sc_dma->sc_dmat,
254 sc->sc_maxxfer, sc->sc_maxxfer / PAGE_SIZE + 1, sc->sc_maxxfer,
255 0, BUS_DMA_ALLOCNOW, &esc->sc_main_dmamap);
256 if (error != 0) {
257 panic("%s: can't create main i/o DMA map, error = %d",
258 device_xname(sc->sc_dev), error);
259 }
260
261 error = bus_dmamap_create(esc->sc_dma->sc_dmat,
262 ESP_DMA_TAILBUFSIZE, 1, ESP_DMA_TAILBUFSIZE,
263 0, BUS_DMA_ALLOCNOW, &esc->sc_tail_dmamap);
264 if (error != 0) {
265 panic("%s: can't create tail i/o DMA map, error = %d",
266 device_xname(sc->sc_dev), error);
267 }
268
269 #if 0
270 /* Turn on target selection using the `DMA' method */
271 sc->sc_features |= NCR_F_DMASELECT;
272 #endif
273
274 /* Do the common parts of attachment. */
275 sc->sc_adapter.adapt_minphys = minphys;
276 sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request;
277 ncr53c9x_attach(sc);
278
279 /* Establish interrupt channel */
280 isrlink_autovec(ncr53c9x_intr, sc, NEXT_I_IPL(NEXT_I_SCSI), 0, NULL);
281 INTR_ENABLE(NEXT_I_SCSI);
282
283 /* register interrupt stats */
284 evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
285 device_xname(sc->sc_dev), "intr");
286
287 aprint_normal_dev(sc->sc_dev, "using DMA channel %s\n",
288 device_xname(esc->sc_dma->sc_dev));
289 }
290
291 static void
espattach_intio(device_t parent,device_t self,void * aux)292 espattach_intio(device_t parent, device_t self, void *aux)
293 {
294 struct esp_softc *esc = device_private(self);
295 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
296 struct intio_attach_args *ia = aux;
297
298 sc->sc_dev = self;
299
300 #ifdef ESP_DEBUG
301 esp_debug_sc = sc;
302 #endif
303
304 esc->sc_bst = ia->ia_bst;
305 if (bus_space_map(esc->sc_bst, NEXT_P_SCSI,
306 ESP_DEVICE_SIZE, 0, &esc->sc_bsh)) {
307 aprint_normal("\n");
308 panic("%s: can't map ncr53c90 registers",
309 device_xname(self));
310 }
311
312 sc->sc_id = 7;
313 sc->sc_freq = 20; /* MHz */
314
315 /*
316 * Set up glue for MI code early; we use some of it here.
317 */
318 sc->sc_glue = &esp_glue;
319
320 /*
321 * XXX More of this should be in ncr53c9x_attach(), but
322 * XXX should we really poke around the chip that much in
323 * XXX the MI code? Think about this more...
324 */
325
326 /*
327 * It is necessary to try to load the 2nd config register here,
328 * to find out what rev the esp chip is, else the ncr53c9x_reset
329 * will not set up the defaults correctly.
330 */
331 sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
332 sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE;
333 sc->sc_cfg3 = NCRCFG3_CDB;
334 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
335
336 if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
337 (NCRCFG2_SCSI2 | NCRCFG2_RPE)) {
338 sc->sc_rev = NCR_VARIANT_ESP100;
339 } else {
340 sc->sc_cfg2 = NCRCFG2_SCSI2;
341 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
342 sc->sc_cfg3 = 0;
343 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
344 sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK);
345 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
346 if (NCR_READ_REG(sc, NCR_CFG3) !=
347 (NCRCFG3_CDB | NCRCFG3_FCLK)) {
348 sc->sc_rev = NCR_VARIANT_ESP100A;
349 } else {
350 /* NCRCFG2_FE enables > 64K transfers */
351 sc->sc_cfg2 |= NCRCFG2_FE;
352 sc->sc_cfg3 = 0;
353 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
354 sc->sc_rev = NCR_VARIANT_ESP200;
355 }
356 }
357
358 /*
359 * XXX minsync and maxxfer _should_ be set up in MI code,
360 * XXX but it appears to have some dependency on what sort
361 * XXX of DMA we're hooked up to, etc.
362 */
363
364 /*
365 * This is the value used to start sync negotiations
366 * Note that the NCR register "SYNCTP" is programmed
367 * in "clocks per byte", and has a minimum value of 4.
368 * The SCSI period used in negotiation is one-fourth
369 * of the time (in nanoseconds) needed to transfer one byte.
370 * Since the chip's clock is given in MHz, we have the following
371 * formula: 4 * period = (1000 / freq) * 4
372 */
373 sc->sc_minsync = /* 1000 / sc->sc_freq */ 0;
374
375 /*
376 * Alas, we must now modify the value a bit, because it's
377 * only valid when can switch on FASTCLK and FASTSCSI bits
378 * in config register 3...
379 */
380 switch (sc->sc_rev) {
381 case NCR_VARIANT_ESP100:
382 sc->sc_maxxfer = 64 * 1024;
383 sc->sc_minsync = 0; /* No synch on old chip? */
384 break;
385
386 case NCR_VARIANT_ESP100A:
387 sc->sc_maxxfer = 64 * 1024;
388 /* Min clocks/byte is 5 */
389 sc->sc_minsync = /* ncr53c9x_cpb2stp(sc, 5) */ 0;
390 break;
391
392 case NCR_VARIANT_ESP200:
393 sc->sc_maxxfer = 16 * 1024 * 1024;
394 /* XXX - do actually set FAST* bits */
395 break;
396 }
397
398 /* @@@ Some ESP_DCTL bits probably need setting */
399 NCR_WRITE_REG(sc, ESP_DCTL,
400 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_RESET);
401 DELAY(10);
402 DPRINTF(("esp dctl is 0x%02x\n", NCR_READ_REG(sc,ESP_DCTL)));
403 NCR_WRITE_REG(sc, ESP_DCTL, ESPDCTL_16MHZ | ESPDCTL_INTENB);
404 DELAY(10);
405 DPRINTF(("esp dctl is 0x%02x\n", NCR_READ_REG(sc, ESP_DCTL)));
406
407 esc->sc_dma = nextdma_findchannel("scsi");
408 if (esc->sc_dma != NULL) {
409 findchannel_defer(self);
410 } else {
411 aprint_normal("\n");
412 config_defer(self, findchannel_defer);
413 }
414
415 attached = 1;
416 }
417
418 /*
419 * Glue functions.
420 */
421
422 static uint8_t
esp_read_reg(struct ncr53c9x_softc * sc,int reg)423 esp_read_reg(struct ncr53c9x_softc *sc, int reg)
424 {
425 struct esp_softc *esc = (struct esp_softc *)sc;
426
427 return bus_space_read_1(esc->sc_bst, esc->sc_bsh, reg);
428 }
429
430 static void
esp_write_reg(struct ncr53c9x_softc * sc,int reg,uint8_t val)431 esp_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t val)
432 {
433 struct esp_softc *esc = (struct esp_softc *)sc;
434
435 bus_space_write_1(esc->sc_bst, esc->sc_bsh, reg, val);
436 }
437
438 volatile uint32_t save1;
439
440 #define xADDR 0x0211a000
441 static int
doze(volatile int c)442 doze(volatile int c)
443 {
444 #if 0
445 static int tmp1;
446 #endif
447 uint32_t tmp1;
448 volatile uint8_t tmp2;
449 volatile uint8_t *reg = (volatile uint8_t *)IIOV(xADDR);
450
451 if (c > 244)
452 return 0;
453 if (c == 0)
454 return 0;
455 #if 0
456 ((*(volatile u_long *)IIOV(NEXT_P_INTRMASK)) &= (~NEXT_I_BIT(x)));
457 #endif
458 (*reg) = 0;
459 (*reg) = 0;
460 do {
461 save1 = (*reg);
462 tmp2 = *(reg + 3);
463 tmp1 = tmp2;
464 } while (tmp1 <= c);
465 return 0;
466 }
467
468 static int
esp_dma_isintr(struct ncr53c9x_softc * sc)469 esp_dma_isintr(struct ncr53c9x_softc *sc)
470 {
471 struct esp_softc *esc = (struct esp_softc *)sc;
472
473 if (INTR_OCCURRED(NEXT_I_SCSI)) {
474 NDTRACEIF(ndtrace_addc('i'));
475 NCR_WRITE_REG(sc, ESP_DCTL,
476 ESPDCTL_16MHZ | ESPDCTL_INTENB |
477 (esc->sc_datain ? ESPDCTL_DMARD : 0));
478 return 1;
479 } else {
480 return 0;
481 }
482 }
483
484 static int
esp_dma_intr(struct ncr53c9x_softc * sc)485 esp_dma_intr(struct ncr53c9x_softc *sc)
486 {
487 struct esp_softc *esc = (struct esp_softc *)sc;
488 struct nextdma_softc *nsc = esc->sc_dma;
489 struct nextdma_status *stat = &nsc->sc_stat;
490 int r = (INTR_OCCURRED(NEXT_I_SCSI));
491 int flushcount;
492
493 r = 1;
494
495 NDTRACEIF(ndtrace_addc('I'));
496 if (r) {
497 #if 0
498 printf("esp_dma_isintr start\n");
499 #endif
500 {
501 int s = spldma();
502 void *ndmap = stat->nd_map;
503 int ndidx = stat->nd_idx;
504 splx(s);
505
506 flushcount = 0;
507
508 #ifdef ESP_DEBUG
509 #if 0
510 esp_dma_nest++;
511 #endif
512
513 if (esp_debug) {
514 char sbuf[256];
515
516 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS,
517 (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)));
518
519 printf("esp_dma_isintr = %s\n", sbuf);
520 }
521 #endif
522
523 mutex_exit(&sc->sc_lock); /* for nextdma intr */
524 while (!nextdma_finished(nsc)) {
525 NDTRACEIF(ndtrace_addc('w'));
526 NDTRACEIF(
527 ndtrace_printf("f%dm%dl%dw",
528 NCR_READ_REG(sc, NCR_FFLAG) &
529 NCRFIFO_FF,
530 NCR_READ_REG((sc), NCR_TCM),
531 NCR_READ_REG((sc), NCR_TCL));
532 );
533 if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF)
534 flushcount = 5;
535 NCR_WRITE_REG(sc, ESP_DCTL,
536 ESPDCTL_16MHZ | ESPDCTL_INTENB |
537 ESPDCTL_DMAMOD |
538 (esc->sc_datain ? ESPDCTL_DMARD : 0));
539
540 s = spldma();
541 while (ndmap == stat->nd_map &&
542 ndidx == stat->nd_idx &&
543 (nd_bsr4(DD_CSR) & 0x08000000) == 0 &&
544 ++flushcount < 5) {
545 splx(s);
546 NDTRACEIF(ndtrace_addc('F'));
547 NCR_WRITE_REG(sc, ESP_DCTL,
548 ESPDCTL_FLUSH | ESPDCTL_16MHZ |
549 ESPDCTL_INTENB | ESPDCTL_DMAMOD |
550 (esc->sc_datain ?
551 ESPDCTL_DMARD : 0));
552 doze(0x32);
553 NCR_WRITE_REG(sc, ESP_DCTL,
554 ESPDCTL_16MHZ | ESPDCTL_INTENB |
555 ESPDCTL_DMAMOD |
556 (esc->sc_datain ?
557 ESPDCTL_DMARD : 0));
558 doze(0x32);
559 s = spldma();
560 }
561 NDTRACEIF(ndtrace_addc('0' + flushcount));
562 if (flushcount > 4) {
563 int next;
564 int onext = 0;
565
566 splx(s);
567 DPRINTF(("DMA reset\n"));
568 while (((next = nd_bsr4(DD_NEXT)) !=
569 (nd_bsr4(DD_LIMIT) & 0x7FFFFFFF)) &&
570 onext != next) {
571 onext = next;
572 DELAY(50);
573 }
574 NDTRACEIF(ndtrace_addc('R'));
575 NCR_WRITE_REG(sc, ESP_DCTL,
576 ESPDCTL_16MHZ | ESPDCTL_INTENB);
577 NDTRACEIF(
578 ndtrace_printf(
579 "ff:%d tcm:%d tcl:%d ",
580 NCR_READ_REG(sc, NCR_FFLAG)
581 & NCRFIFO_FF,
582 NCR_READ_REG((sc), NCR_TCM),
583 NCR_READ_REG((sc),
584 NCR_TCL));
585 );
586 s = spldma();
587 nextdma_reset(nsc);
588 splx(s);
589 goto out;
590 }
591 splx(s);
592
593 #ifdef DIAGNOSTIC
594 if (flushcount > 4) {
595 NDTRACEIF(ndtrace_addc('+'));
596 printf("%s: unexpected flushcount"
597 " %d on %s\n",
598 device_xname(sc->sc_dev),
599 flushcount,
600 esc->sc_datain ? "read" : "write");
601 }
602 #endif
603
604 if (!nextdma_finished(nsc)) {
605 NDTRACEIF(ndtrace_addc('1'));
606 }
607 flushcount = 0;
608 s = spldma();
609 ndmap = stat->nd_map;
610 ndidx = stat->nd_idx;
611 splx(s);
612
613 }
614 out:
615 mutex_enter(&sc->sc_lock); /* for nextdma intr */
616
617 #ifdef ESP_DEBUG
618 #if 0
619 esp_dma_nest--;
620 #endif
621 #endif
622
623 }
624
625 doze(0x32);
626 NCR_WRITE_REG(sc, ESP_DCTL,
627 ESPDCTL_16MHZ | ESPDCTL_INTENB |
628 (esc->sc_datain ? ESPDCTL_DMARD : 0));
629 NDTRACEIF(ndtrace_addc('b'));
630
631 while (esc->sc_datain != -1)
632 DELAY(50);
633
634 if (esc->sc_dmaaddr) {
635 bus_size_t xfer_len = 0;
636 int resid;
637
638 NCR_WRITE_REG(sc, ESP_DCTL,
639 ESPDCTL_16MHZ | ESPDCTL_INTENB);
640 if (stat->nd_exception == 0) {
641 resid = NCR_READ_REG((sc), NCR_TCL) +
642 (NCR_READ_REG((sc), NCR_TCM) << 8);
643 if (resid) {
644 resid += (NCR_READ_REG(sc, NCR_FFLAG) &
645 NCRFIFO_FF);
646 #ifdef ESP_DEBUG
647 if (NCR_READ_REG(sc, NCR_FFLAG) &
648 NCRFIFO_FF)
649 if ((NCR_READ_REG(sc,
650 NCR_FFLAG) & NCRFIFO_FF) !=
651 16 ||
652 NCR_READ_REG((sc),
653 NCR_TCL) != 240)
654 esptraceshow++;
655 #endif
656 }
657 xfer_len = esc->sc_dmasize - resid;
658 } else {
659 #define ncr53c9x_sched_msgout(m) \
660 do { \
661 NCR_MISC(("ncr53c9x_sched_msgout %x %d", m, __LINE__)); \
662 NCRCMD(sc, NCRCMD_SETATN); \
663 sc->sc_flags |= NCR_ATN; \
664 sc->sc_msgpriq |= (m); \
665 } while (0)
666 int i;
667
668 xfer_len = 0;
669 if (esc->sc_begin)
670 xfer_len += esc->sc_begin_size;
671 if (esc->sc_main_dmamap)
672 xfer_len +=
673 esc->sc_main_dmamap->dm_xfer_len;
674 if (esc->sc_tail_dmamap)
675 xfer_len +=
676 esc->sc_tail_dmamap->dm_xfer_len;
677 resid = 0;
678 printf("X\n");
679 for (i = 0; i < 16; i++) {
680 NCR_WRITE_REG(sc, ESP_DCTL,
681 ESPDCTL_FLUSH | ESPDCTL_16MHZ |
682 ESPDCTL_INTENB |
683 (esc->sc_datain ?
684 ESPDCTL_DMARD : 0));
685 NCR_WRITE_REG(sc, ESP_DCTL,
686 ESPDCTL_16MHZ | ESPDCTL_INTENB |
687 (esc->sc_datain ?
688 ESPDCTL_DMARD : 0));
689 }
690 #if 0
691 printf("ff:%02x tcm:%d tcl:%d esp_dstat:%02x"
692 " stat:%02x step: %02x intr:%02x"
693 " new stat:%02X\n",
694 NCR_READ_REG(sc, NCR_FFLAG),
695 NCR_READ_REG((sc), NCR_TCM),
696 NCR_READ_REG((sc), NCR_TCL),
697 NCR_READ_REG(sc, ESP_DSTAT),
698 sc->sc_espstat, sc->sc_espstep,
699 sc->sc_espintr,
700 NCR_READ_REG(sc, NCR_STAT));
701 printf("sc->sc_state: %x sc->sc_phase: %x"
702 " sc->sc_espstep:%x sc->sc_prevphase:%x"
703 " sc->sc_flags:%x\n",
704 sc->sc_state, sc->sc_phase, sc->sc_espstep,
705 sc->sc_prevphase, sc->sc_flags);
706 #endif
707 #if 0
708 sc->sc_flags &= ~NCR_ICCS;
709 #endif
710 sc->sc_nexus->flags |= ECB_ABORT;
711 if (sc->sc_phase == MESSAGE_IN_PHASE) {
712 #if 0
713 ncr53c9x_sched_msgout(SEND_ABORT);
714 #endif
715 ncr53c9x_abort(sc, sc->sc_nexus);
716 } else if (sc->sc_phase != STATUS_PHASE) {
717 printf("ATTENTION!!! "
718 "not message/status phase: %d\n",
719 sc->sc_phase);
720 }
721 }
722
723 NDTRACEIF(ndtrace_printf("f%dm%dl%ds%dx%dr%dS",
724 NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF,
725 NCR_READ_REG((sc), NCR_TCM),
726 NCR_READ_REG((sc), NCR_TCL),
727 esc->sc_dmasize, (int)xfer_len, resid);
728 );
729
730 *esc->sc_dmaaddr += xfer_len;
731 *esc->sc_dmalen -= xfer_len;
732 esc->sc_dmaaddr = 0;
733 esc->sc_dmalen = 0;
734 esc->sc_dmasize = 0;
735 }
736
737 NDTRACEIF(ndtrace_addc('B'));
738 sc->sc_espstat = NCR_READ_REG(sc, NCR_STAT) |
739 (sc->sc_espstat & NCRSTAT_INT);
740
741 DPRINTF(("esp dctl is 0x%02x\n", NCR_READ_REG(sc, ESP_DCTL)));
742 #if 0
743 printf("esp_dma_isintr DONE\n");
744 #endif
745 }
746
747 return r;
748 }
749
750 static void
esp_dma_reset(struct ncr53c9x_softc * sc)751 esp_dma_reset(struct ncr53c9x_softc *sc)
752 {
753 struct esp_softc *esc = (struct esp_softc *)sc;
754
755 DPRINTF(("esp DMA reset\n"));
756
757 #ifdef ESP_DEBUG
758 if (esp_debug) {
759 char sbuf[256];
760
761 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS,
762 (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)));
763 printf(" *intrstat = %s\n", sbuf);
764
765 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS,
766 (*(volatile u_long *)IIOV(NEXT_P_INTRMASK)));
767 printf(" *intrmask = %s\n", sbuf);
768 }
769 #endif
770
771 #if 0
772 /* Clear the DMAMOD bit in the DCTL register: */
773 NCR_WRITE_REG(sc, ESP_DCTL, ESPDCTL_16MHZ | ESPDCTL_INTENB);
774 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
775 #endif
776
777 nextdma_reset(esc->sc_dma);
778 nextdma_init(esc->sc_dma);
779
780 esc->sc_datain = -1;
781 esc->sc_dmaaddr = 0;
782 esc->sc_dmalen = 0;
783 esc->sc_dmasize = 0;
784
785 esc->sc_loaded = 0;
786
787 esc->sc_begin = 0;
788 esc->sc_begin_size = 0;
789
790 if (esc->sc_main_dmamap->dm_mapsize) {
791 bus_dmamap_unload(esc->sc_dma->sc_dmat, esc->sc_main_dmamap);
792 }
793 esc->sc_main = 0;
794 esc->sc_main_size = 0;
795
796 if (esc->sc_tail_dmamap->dm_mapsize) {
797 bus_dmamap_unload(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap);
798 }
799 esc->sc_tail = 0;
800 esc->sc_tail_size = 0;
801 }
802
803 /*
804 * it appears that:
805 * addr and len arguments to this need to be kept up to date
806 * with the status of the transfter.
807 * the dmasize of this is the actual length of the transfer
808 * request, which is guaranteed to be less than maxxfer.
809 * (len may be > maxxfer)
810 */
811
812 static int
esp_dma_setup(struct ncr53c9x_softc * sc,uint8_t ** addr,size_t * len,int datain,size_t * dmasize)813 esp_dma_setup(struct ncr53c9x_softc *sc, uint8_t **addr, size_t *len,
814 int datain, size_t *dmasize)
815 {
816 struct esp_softc *esc = (struct esp_softc *)sc;
817
818 NDTRACEIF(ndtrace_addc('h'));
819 #ifdef DIAGNOSTIC
820 #ifdef ESP_DEBUG
821 /*
822 * if this is a read DMA, pre-fill the buffer with 0xdeadbeef
823 * to identify bogus reads
824 */
825 if (datain) {
826 int *v = (int *)(*addr);
827 int i;
828 for (i = 0; i < ((*len) / 4); i++)
829 v[i] = 0xdeadbeef;
830 v = (int *)(&(esc->sc_tailbuf[0]));
831 for (i = 0; i < ((sizeof(esc->sc_tailbuf) / 4)); i++)
832 v[i] = 0xdeafbeef;
833 } else {
834 int *v;
835 int i;
836 v = (int *)(&(esc->sc_tailbuf[0]));
837 for (i = 0; i < ((sizeof(esc->sc_tailbuf) / 4)); i++)
838 v[i] = 0xfeeb1eed;
839 }
840 #endif
841 #endif
842
843 DPRINTF(("esp_dma_setup(%p,0x%08x,0x%08x)\n", *addr, *len, *dmasize));
844
845 #if 0
846 #ifdef DIAGNOSTIC
847 /*
848 * @@@ this is ok sometimes. verify that we handle it ok
849 * and then remove this check
850 */
851 if (*len != *dmasize) {
852 panic("esp dmalen 0x%lx != size 0x%lx", *len, *dmasize);
853 }
854 #endif
855 #endif
856
857 #ifdef DIAGNOSTIC
858 if ((esc->sc_datain != -1) ||
859 (esc->sc_main_dmamap->dm_mapsize != 0) ||
860 (esc->sc_tail_dmamap->dm_mapsize != 0) ||
861 (esc->sc_dmasize != 0)) {
862 panic("%s: map already loaded in esp_dma_setup"
863 "\tdatain = %d\n\tmain_mapsize=%ld\n"
864 "\tail_mapsize=%ld\n\tdmasize = %d",
865 device_xname(sc->sc_dev), esc->sc_datain,
866 esc->sc_main_dmamap->dm_mapsize,
867 esc->sc_tail_dmamap->dm_mapsize,
868 esc->sc_dmasize);
869 }
870 #endif
871
872 /* we are sometimes asked to DMA zero bytes, that's easy */
873 if (*dmasize <= 0) {
874 return 0;
875 }
876
877 if (*dmasize > ESP_MAX_DMASIZE)
878 *dmasize = ESP_MAX_DMASIZE;
879
880 /* Save these in case we have to abort DMA */
881 esc->sc_datain = datain;
882 esc->sc_dmaaddr = addr;
883 esc->sc_dmalen = len;
884 esc->sc_dmasize = *dmasize;
885
886 esc->sc_loaded = 0;
887
888 #define DMA_SCSI_ALIGNMENT 16
889 #define DMA_SCSI_ALIGN(type, addr) \
890 ((type)(((unsigned int)(addr) + DMA_SCSI_ALIGNMENT - 1) \
891 & ~(DMA_SCSI_ALIGNMENT-1)))
892 #define DMA_SCSI_ALIGNED(addr) \
893 (((unsigned int)(addr) & (DMA_SCSI_ALIGNMENT - 1)) == 0)
894
895 {
896 size_t slop_bgn_size; /* # bytes to be fifo'd at beginning */
897 size_t slop_end_size; /* # bytes to be transferred in
898 tail buffer */
899
900 {
901 u_long bgn = (u_long)(*esc->sc_dmaaddr);
902 u_long end = bgn + esc->sc_dmasize;
903
904 slop_bgn_size =
905 DMA_SCSI_ALIGNMENT - (bgn % DMA_SCSI_ALIGNMENT);
906 if (slop_bgn_size == DMA_SCSI_ALIGNMENT)
907 slop_bgn_size = 0;
908 slop_end_size = end % DMA_ENDALIGNMENT;
909 }
910
911 /*
912 * Force a minimum slop end size. This ensures that write
913 * requests will overrun, as required to get completion
914 * interrupts.
915 * In addition, since the tail buffer is guaranteed to be mapped
916 * in a single DMA segment, the overrun won't accidentally
917 * end up in its own segment.
918 */
919 if (!esc->sc_datain) {
920 #if 0
921 slop_end_size += ESP_DMA_MAXTAIL;
922 #else
923 slop_end_size += 0x10;
924 #endif
925 }
926
927 /*
928 * Check to make sure we haven't counted extra slop
929 * as would happen for a very short DMA buffer, also
930 * for short buffers, just stuff the entire thing in the tail
931 */
932 if ((slop_bgn_size+slop_end_size >= esc->sc_dmasize)
933 #if 0
934 || (esc->sc_dmasize <= ESP_DMA_MAXTAIL)
935 #endif
936 ) {
937 slop_bgn_size = 0;
938 slop_end_size = esc->sc_dmasize;
939 }
940
941 /* initialize the fifo buffer */
942 if (slop_bgn_size != 0) {
943 esc->sc_begin = *esc->sc_dmaaddr;
944 esc->sc_begin_size = slop_bgn_size;
945 } else {
946 esc->sc_begin = 0;
947 esc->sc_begin_size = 0;
948 }
949
950 #if 1
951 /* Load the normal DMA map */
952 {
953 esc->sc_main = *esc->sc_dmaaddr;
954 esc->sc_main += slop_bgn_size;
955 esc->sc_main_size =
956 (esc->sc_dmasize) - (slop_end_size + slop_bgn_size);
957
958 if (esc->sc_main_size != 0) {
959 int error;
960
961 if (!esc->sc_datain ||
962 DMA_ENDALIGNED(esc->sc_main_size +
963 slop_end_size)) {
964 KASSERT(DMA_SCSI_ALIGNMENT ==
965 DMA_ENDALIGNMENT);
966 KASSERT(DMA_BEGINALIGNMENT ==
967 DMA_ENDALIGNMENT);
968 esc->sc_main_size += slop_end_size;
969 slop_end_size = 0;
970 if (!esc->sc_datain) {
971 esc->sc_main_size =
972 DMA_ENDALIGN(uint8_t *,
973 esc->sc_main +
974 esc->sc_main_size) -
975 esc->sc_main;
976 }
977 }
978
979 error = bus_dmamap_load(esc->sc_dma->sc_dmat,
980 esc->sc_main_dmamap,
981 esc->sc_main, esc->sc_main_size,
982 NULL, BUS_DMA_NOWAIT);
983 if (error != 0) {
984 #ifdef ESP_DEBUG
985 printf("%s: esc->sc_main_dmamap->"
986 "_dm_size = %ld\n",
987 device_xname(sc->sc_dev),
988 esc->sc_main_dmamap->_dm_size);
989 printf("%s: esc->sc_main_dmamap->"
990 "_dm_segcnt = %d\n",
991 device_xname(sc->sc_dev),
992 esc->sc_main_dmamap->_dm_segcnt);
993 #ifdef notdef
994 printf("%s: esc->sc_main_dmamap->"
995 "_dm_maxsegsz = %ld\n",
996 device_xname(sc->sc_dev),
997 esc->sc_main_dmamap->_dm_maxsegsz);
998 #endif
999 printf("%s: esc->sc_main_dmamap->"
1000 "_dm_boundary = %ld\n",
1001 device_xname(sc->sc_dev),
1002 esc->sc_main_dmamap->_dm_boundary);
1003 esp_dma_print(sc);
1004 #endif
1005 panic("%s: can't load main DMA map."
1006 " error = %d, addr=%p, size=0x%08x",
1007 device_xname(sc->sc_dev),
1008 error, esc->sc_main,
1009 esc->sc_main_size);
1010 }
1011 if (!esc->sc_datain) {
1012 /*
1013 * patch the DMA map for write overrun
1014 */
1015 esc->sc_main_dmamap->dm_mapsize +=
1016 ESP_DMA_OVERRUN;
1017 esc->sc_main_dmamap->dm_segs[
1018 esc->sc_main_dmamap->dm_nsegs -
1019 1].ds_len +=
1020 ESP_DMA_OVERRUN;
1021 }
1022 #if 0
1023 bus_dmamap_sync(esc->sc_dma->sc_dmat,
1024 esc->sc_main_dmamap,
1025 0, esc->sc_main_dmamap->dm_mapsize,
1026 (esc->sc_datain ? BUS_DMASYNC_PREREAD :
1027 BUS_DMASYNC_PREWRITE));
1028 esc->sc_main_dmamap->dm_xfer_len = 0;
1029 #endif
1030 } else {
1031 esc->sc_main = 0;
1032 }
1033 }
1034
1035 /* Load the tail DMA map */
1036 if (slop_end_size != 0) {
1037 esc->sc_tail = DMA_ENDALIGN(uint8_t *,
1038 esc->sc_tailbuf + slop_end_size) - slop_end_size;
1039 /*
1040 * If the beginning of the tail is not correctly
1041 * aligned, we have no choice but to align the start,
1042 * which might then unalign the end.
1043 */
1044 esc->sc_tail = DMA_SCSI_ALIGN(uint8_t *, esc->sc_tail);
1045 /*
1046 * So therefore, we change the tail size to be
1047 * end aligned again.
1048 */
1049 esc->sc_tail_size = DMA_ENDALIGN(uint8_t *,
1050 esc->sc_tail + slop_end_size) - esc->sc_tail;
1051
1052 /* @@@ next DMA overrun lossage */
1053 if (!esc->sc_datain) {
1054 esc->sc_tail_size += ESP_DMA_OVERRUN;
1055 }
1056
1057 {
1058 int error;
1059 error = bus_dmamap_load(esc->sc_dma->sc_dmat,
1060 esc->sc_tail_dmamap,
1061 esc->sc_tail, esc->sc_tail_size,
1062 NULL, BUS_DMA_NOWAIT);
1063 if (error) {
1064 panic("%s: can't load tail DMA map."
1065 " error = %d, addr=%p, size=0x%08x",
1066 device_xname(sc->sc_dev), error,
1067 esc->sc_tail,esc->sc_tail_size);
1068 }
1069 #if 0
1070 bus_dmamap_sync(esc->sc_dma->sc_dmat,
1071 esc->sc_tail_dmamap, 0,
1072 esc->sc_tail_dmamap->dm_mapsize,
1073 (esc->sc_datain ? BUS_DMASYNC_PREREAD :
1074 BUS_DMASYNC_PREWRITE));
1075 esc->sc_tail_dmamap->dm_xfer_len = 0;
1076 #endif
1077 }
1078 }
1079 #else
1080
1081 esc->sc_begin = *esc->sc_dmaaddr;
1082 slop_bgn_size = DMA_SCSI_ALIGNMENT -
1083 ((u_long)esc->sc_begin % DMA_SCSI_ALIGNMENT);
1084 if (slop_bgn_size == DMA_SCSI_ALIGNMENT)
1085 slop_bgn_size = 0;
1086 slop_end_size = esc->sc_dmasize - slop_bgn_size;
1087
1088 if (slop_bgn_size < esc->sc_dmasize) {
1089 int error;
1090
1091 esc->sc_tail = 0;
1092 esc->sc_tail_size = 0;
1093
1094 esc->sc_begin_size = slop_bgn_size;
1095 esc->sc_main = *esc->sc_dmaaddr;
1096 esc->sc_main += slop_bgn_size;
1097 esc->sc_main_size = DMA_ENDALIGN(uint8_t *,
1098 esc->sc_main + esc->sc_dmasize - slop_bgn_size) -
1099 esc->sc_main;
1100
1101 if (!esc->sc_datain) {
1102 esc->sc_main_size += ESP_DMA_OVERRUN;
1103 }
1104 error = bus_dmamap_load(esc->sc_dma->sc_dmat,
1105 esc->sc_main_dmamap,
1106 esc->sc_main, esc->sc_main_size,
1107 NULL, BUS_DMA_NOWAIT);
1108 if (error) {
1109 panic("%s: can't load main DMA map."
1110 " error = %d, addr=%p, size=0x%08x",
1111 device_xname(sc->sc_dev), error,
1112 esc->sc_main,esc->sc_main_size);
1113 }
1114 } else {
1115 esc->sc_begin = 0;
1116 esc->sc_begin_size = 0;
1117 esc->sc_main = 0;
1118 esc->sc_main_size = 0;
1119
1120 #if 0
1121 esc->sc_tail = DMA_ENDALIGN(uint8_t *,
1122 esc->sc_tailbuf + slop_bgn_size) - slop_bgn_size;
1123 /*
1124 * If the beginning of the tail is not correctly
1125 * aligned, we have no choice but to align the start,
1126 * which might then unalign the end.
1127 */
1128 #endif
1129 esc->sc_tail = DMA_SCSI_ALIGN(void *, esc->sc_tailbuf);
1130 /*
1131 * So therefore, we change the tail size to be
1132 * end aligned again.
1133 */
1134 esc->sc_tail_size = DMA_ENDALIGN(uint8_t *,
1135 esc->sc_tail + esc->sc_dmasize) - esc->sc_tail;
1136
1137 /* @@@ next DMA overrun lossage */
1138 if (!esc->sc_datain) {
1139 esc->sc_tail_size += ESP_DMA_OVERRUN;
1140 }
1141
1142 {
1143 int error;
1144 error = bus_dmamap_load(esc->sc_dma->sc_dmat,
1145 esc->sc_tail_dmamap,
1146 esc->sc_tail, esc->sc_tail_size,
1147 NULL, BUS_DMA_NOWAIT);
1148 if (error != 0) {
1149 panic("%s: can't load tail DMA map."
1150 " error = %d, addr=%p, size=0x%08x",
1151 device_xname(sc->sc_dev), error,
1152 esc->sc_tail, esc->sc_tail_size);
1153 }
1154 }
1155 }
1156 #endif
1157
1158 DPRINTF(("%s: setup: %8p %d %8p %d %8p %d %8p %d\n",
1159 device_xname(sc->sc_dev),
1160 *esc->sc_dmaaddr, esc->sc_dmasize,
1161 esc->sc_begin, esc->sc_begin_size,
1162 esc->sc_main, esc->sc_main_size,
1163 esc->sc_tail, esc->sc_tail_size));
1164 }
1165
1166 return 0;
1167 }
1168
1169 #ifdef ESP_DEBUG
1170 /* For debugging */
1171 void
esp_dma_store(struct ncr53c9x_softc * sc)1172 esp_dma_store(struct ncr53c9x_softc *sc)
1173 {
1174 struct esp_softc *esc = (struct esp_softc *)sc;
1175 char *p = esp_dma_dump;
1176 size_t l = 0;
1177 size_t len = sizeof(esp_dma_dump);
1178
1179 l += snprintf(p + l, len - l, "%s: sc_datain=%d\n",
1180 device_xname(sc->sc_dev), esc->sc_datain);
1181 if (l > len)
1182 return;
1183 l += snprintf(p + l, len - l, "%s: sc_loaded=0x%08x\n",
1184 device_xname(sc->sc_dev), esc->sc_loaded);
1185 if (l > len)
1186 return;
1187
1188 if (esc->sc_dmaaddr != 0) {
1189 l += snprintf(p + l, len - l, "%s: sc_dmaaddr=%p\n",
1190 device_xname(sc->sc_dev), *esc->sc_dmaaddr);
1191 } else {
1192 l += snprintf(p + l, len - l, "%s: sc_dmaaddr=NULL\n",
1193 device_xname(sc->sc_dev));
1194 }
1195 if (l > len)
1196 return;
1197 if (esc->sc_dmalen) {
1198 l += snprintf(p + l, len - l, "%s: sc_dmalen=0x%08x\n",
1199 device_xname(sc->sc_dev), *esc->sc_dmalen);
1200 } else {
1201 l += snprintf(p + l, len - l, "%s: sc_dmalen=NULL\n",
1202 device_xname(sc->sc_dev));
1203 }
1204 if (l > len)
1205 return;
1206 l += snprintf(p + l, len - l, "%s: sc_dmasize=0x%08x\n",
1207 device_xname(sc->sc_dev), esc->sc_dmasize);
1208 if (l > len)
1209 return;
1210
1211 l += snprintf(p + l, len - l,
1212 "%s: sc_begin = %p, sc_begin_size = 0x%08x\n",
1213 device_xname(sc->sc_dev), esc->sc_begin, esc->sc_begin_size);
1214 if (l > len)
1215 return;
1216 l += snprintf(p + l, len - l,
1217 "%s: sc_main = %p, sc_main_size = 0x%08x\n",
1218 device_xname(sc->sc_dev), esc->sc_main, esc->sc_main_size);
1219 if (l > len)
1220 return;
1221 #if 0
1222 if (esc->sc_main)
1223 #endif
1224 {
1225 int i;
1226 bus_dmamap_t map = esc->sc_main_dmamap;
1227 l += snprintf(p + l, len - l, "%s: sc_main_dmamap."
1228 " mapsize = 0x%08lx, nsegs = %d\n",
1229 device_xname(sc->sc_dev), map->dm_mapsize, map->dm_nsegs);
1230 if (l > len)
1231 return;
1232 for(i = 0; i < map->dm_nsegs; i++) {
1233 l += snprintf(p + l, len - l, "%s:"
1234 " map->dm_segs[%d].ds_addr = 0x%08lx,"
1235 " len = 0x%08lx\n",
1236 device_xname(sc->sc_dev),
1237 i, map->dm_segs[i].ds_addr,
1238 map->dm_segs[i].ds_len);
1239 if (l > len)
1240 return;
1241 }
1242 }
1243 l += snprintf(p + l, len - l,
1244 "%s: sc_tail = %p, sc_tail_size = 0x%08x\n",
1245 device_xname(sc->sc_dev), esc->sc_tail, esc->sc_tail_size);
1246 if (l > len)
1247 return;
1248 #if 0
1249 if (esc->sc_tail)
1250 #endif
1251 {
1252 int i;
1253 bus_dmamap_t map = esc->sc_tail_dmamap;
1254 l += snprintf(p + l, len - l, "%s: sc_tail_dmamap."
1255 " mapsize = 0x%08lx, nsegs = %d\n",
1256 device_xname(sc->sc_dev), map->dm_mapsize, map->dm_nsegs);
1257 if (l > len)
1258 return;
1259 for (i = 0; i < map->dm_nsegs; i++) {
1260 l += snprintf(p + l, len - l, "%s:"
1261 " map->dm_segs[%d].ds_addr = 0x%08lx,"
1262 " len = 0x%08lx\n",
1263 device_xname(sc->sc_dev),
1264 i, map->dm_segs[i].ds_addr,
1265 map->dm_segs[i].ds_len);
1266 if (l > len)
1267 return;
1268 }
1269 }
1270 }
1271
1272 void
esp_dma_print(struct ncr53c9x_softc * sc)1273 esp_dma_print(struct ncr53c9x_softc *sc)
1274 {
1275
1276 esp_dma_store(sc);
1277 printf("%s", esp_dma_dump);
1278 }
1279 #endif
1280
1281 static void
esp_dma_go(struct ncr53c9x_softc * sc)1282 esp_dma_go(struct ncr53c9x_softc *sc)
1283 {
1284 struct esp_softc *esc = (struct esp_softc *)sc;
1285 struct nextdma_softc *nsc = esc->sc_dma;
1286 struct nextdma_status *stat = &nsc->sc_stat;
1287 #if 0
1288 int s = spldma();
1289 #endif
1290
1291 #ifdef ESP_DEBUG
1292 if (!ndtrace_empty()) {
1293 if (esptraceshow) {
1294 printf("esp ndtrace: %s\n", ndtrace_get());
1295 esptraceshow = 0;
1296 } else {
1297 DPRINTF(("X"));
1298 }
1299 ndtrace_reset();
1300 }
1301 #endif
1302
1303 DPRINTF(("%s: esp_dma_go(datain = %d)\n",
1304 device_xname(sc->sc_dev), esc->sc_datain));
1305
1306 #ifdef ESP_DEBUG
1307 if (esp_debug)
1308 esp_dma_print(sc);
1309 else
1310 esp_dma_store(sc);
1311 #endif
1312
1313 #ifdef ESP_DEBUG
1314 {
1315 int n = NCR_READ_REG(sc, NCR_FFLAG);
1316 DPRINTF(("%s: fifo size = %d, seq = 0x%x\n",
1317 device_xname(sc->sc_dev),
1318 n & NCRFIFO_FF, (n & NCRFIFO_SS) >> 5));
1319 }
1320 #endif
1321
1322 /* zero length DMA transfers are boring */
1323 if (esc->sc_dmasize == 0) {
1324 #if 0
1325 splx(s);
1326 #endif
1327 return;
1328 }
1329
1330 #if defined(DIAGNOSTIC)
1331 if ((esc->sc_begin_size == 0) &&
1332 (esc->sc_main_dmamap->dm_mapsize == 0) &&
1333 (esc->sc_tail_dmamap->dm_mapsize == 0)) {
1334 #ifdef ESP_DEBUG
1335 esp_dma_print(sc);
1336 #endif
1337 panic("%s: No DMA requested!", device_xname(sc->sc_dev));
1338 }
1339 #endif
1340
1341 /* Stuff the fifo with the begin buffer */
1342 if (esc->sc_datain) {
1343 int i;
1344 DPRINTF(("%s: FIFO read of %d bytes:",
1345 device_xname(sc->sc_dev), esc->sc_begin_size));
1346 for (i = 0; i < esc->sc_begin_size; i++) {
1347 esc->sc_begin[i] = NCR_READ_REG(sc, NCR_FIFO);
1348 DPRINTF((" %02x", esc->sc_begin[i] & 0xff));
1349 }
1350 DPRINTF(("\n"));
1351 } else {
1352 int i;
1353 DPRINTF(("%s: FIFO write of %d bytes:",
1354 device_xname(sc->sc_dev), esc->sc_begin_size));
1355 for (i = 0; i < esc->sc_begin_size; i++) {
1356 NCR_WRITE_REG(sc, NCR_FIFO, esc->sc_begin[i]);
1357 DPRINTF((" %02x",esc->sc_begin[i] & 0xff));
1358 }
1359 DPRINTF(("\n"));
1360 }
1361
1362 if (esc->sc_main_dmamap->dm_mapsize != 0) {
1363 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_main_dmamap,
1364 0, esc->sc_main_dmamap->dm_mapsize,
1365 (esc->sc_datain ?
1366 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
1367 esc->sc_main_dmamap->dm_xfer_len = 0;
1368 }
1369
1370 if (esc->sc_tail_dmamap->dm_mapsize != 0) {
1371 /* if we are a DMA write cycle, copy the end slop */
1372 if (!esc->sc_datain) {
1373 memcpy(esc->sc_tail, *esc->sc_dmaaddr +
1374 esc->sc_begin_size+esc->sc_main_size,
1375 esc->sc_dmasize -
1376 (esc->sc_begin_size + esc->sc_main_size));
1377 }
1378 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap,
1379 0, esc->sc_tail_dmamap->dm_mapsize,
1380 (esc->sc_datain ?
1381 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
1382 esc->sc_tail_dmamap->dm_xfer_len = 0;
1383 }
1384
1385 stat->nd_exception = 0;
1386 nextdma_start(nsc, (esc->sc_datain ? DMACSR_SETREAD : DMACSR_SETWRITE));
1387
1388 if (esc->sc_datain) {
1389 NCR_WRITE_REG(sc, ESP_DCTL,
1390 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD |
1391 ESPDCTL_DMARD);
1392 } else {
1393 NCR_WRITE_REG(sc, ESP_DCTL,
1394 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD);
1395 }
1396 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
1397
1398 NDTRACEIF(
1399 if (esc->sc_begin_size != 0) {
1400 ndtrace_addc('1');
1401 ndtrace_addc('A' + esc->sc_begin_size);
1402 }
1403 );
1404 NDTRACEIF(
1405 if (esc->sc_main_size != 0) {
1406 ndtrace_addc('2');
1407 ndtrace_addc('0' + esc->sc_main_dmamap->dm_nsegs);
1408 }
1409 );
1410 NDTRACEIF(
1411 if (esc->sc_tail_size != 0) {
1412 ndtrace_addc('3');
1413 ndtrace_addc('A' + esc->sc_tail_size);
1414 }
1415 );
1416
1417 #if 0
1418 splx(s);
1419 #endif
1420 }
1421
1422 static void
esp_dma_stop(struct ncr53c9x_softc * sc)1423 esp_dma_stop(struct ncr53c9x_softc *sc)
1424 {
1425 struct esp_softc *esc = (struct esp_softc *)sc;
1426
1427 nextdma_print(esc->sc_dma);
1428 #ifdef ESP_DEBUG
1429 esp_dma_print(sc);
1430 #endif
1431 #if 1
1432 panic("%s: stop not yet implemented", device_xname(sc->sc_dev));
1433 #endif
1434 }
1435
1436 static int
esp_dma_isactive(struct ncr53c9x_softc * sc)1437 esp_dma_isactive(struct ncr53c9x_softc *sc)
1438 {
1439 struct esp_softc *esc = (struct esp_softc *)sc;
1440 int r;
1441
1442 #if 0
1443 r = !nextdma_finished(esc->sc_dma);
1444 #else
1445 r = (esc->sc_dmaaddr != NULL);
1446 #endif
1447 DPRINTF(("esp_dma_isactive = %d\n",r));
1448 return r;
1449 }
1450
1451 /****************************************************************/
1452
1453 int esp_dma_int(void *); /* XXX: called from nextdma.c */
esp_dma_int(void * arg)1454 int esp_dma_int(void *arg)
1455 {
1456 void nextdma_rotate(struct nextdma_softc *); /* XXX */
1457 void nextdma_setup_curr_regs(struct nextdma_softc *); /* XXX */
1458 void nextdma_setup_cont_regs(struct nextdma_softc *); /* XXX */
1459
1460 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
1461 struct esp_softc *esc = (struct esp_softc *)sc;
1462 struct nextdma_softc *nsc = esc->sc_dma;
1463 struct nextdma_status *stat = &nsc->sc_stat;
1464 unsigned int state;
1465
1466 NDTRACEIF(ndtrace_addc('E'));
1467
1468 state = nd_bsr4(DD_CSR);
1469
1470 #if 1
1471 NDTRACEIF(
1472 if (state & DMACSR_COMPLETE)
1473 ndtrace_addc('c');
1474 if (state & DMACSR_ENABLE)
1475 ndtrace_addc('e');
1476 if (state & DMACSR_BUSEXC)
1477 ndtrace_addc('b');
1478 if (state & DMACSR_READ)
1479 ndtrace_addc('r');
1480 if (state & DMACSR_SUPDATE)
1481 ndtrace_addc('s');
1482 );
1483
1484 NDTRACEIF(ndtrace_addc('E'));
1485
1486 #ifdef ESP_DEBUG
1487 if (0)
1488 if ((state & DMACSR_BUSEXC) && (state & DMACSR_ENABLE))
1489 esptraceshow++;
1490 if (0)
1491 if ((state & DMACSR_SUPDATE))
1492 esptraceshow++;
1493 #endif
1494 #endif
1495
1496 if ((stat->nd_exception == 0) &&
1497 ((state & DMACSR_COMPLETE) != 0) &&
1498 ((state & DMACSR_ENABLE) != 0)) {
1499 stat->nd_map->dm_xfer_len +=
1500 stat->nd_map->dm_segs[stat->nd_idx].ds_len;
1501 }
1502
1503 if ((stat->nd_idx + 1) == stat->nd_map->dm_nsegs) {
1504 if (nsc->sc_conf.nd_completed_cb)
1505 (*nsc->sc_conf.nd_completed_cb)(stat->nd_map,
1506 nsc->sc_conf.nd_cb_arg);
1507 }
1508 nextdma_rotate(nsc);
1509
1510 if ((state & DMACSR_COMPLETE) != 0 &&
1511 (state & DMACSR_ENABLE) != 0) {
1512 #if 0
1513 int l = nd_bsr4(DD_LIMIT) & 0x7FFFFFFF;
1514 int s = nd_bsr4(DD_STOP);
1515 #endif
1516 #if 0
1517 nextdma_setup_cont_regs(nsc);
1518 #endif
1519 if (stat->nd_map_cont != NULL) {
1520 nd_bsw4(DD_START, stat->nd_map_cont->dm_segs[
1521 stat->nd_idx_cont].ds_addr);
1522 nd_bsw4(DD_STOP, (stat->nd_map_cont->dm_segs[
1523 stat->nd_idx_cont].ds_addr +
1524 stat->nd_map_cont->dm_segs[
1525 stat->nd_idx_cont].ds_len));
1526 }
1527
1528 nd_bsw4(DD_CSR, DMACSR_CLRCOMPLETE |
1529 (state & DMACSR_READ ? DMACSR_SETREAD : DMACSR_SETWRITE) |
1530 (stat->nd_map_cont ? DMACSR_SETSUPDATE : 0));
1531
1532 #if 0
1533 #ifdef ESP_DEBUG
1534 if ((state & DMACSR_BUSEXC) != 0) {
1535 ndtrace_printf("CE/BUSEXC: %08lX %08X %08X\n",
1536 (stat->nd_map->dm_segs[stat->nd_idx].ds_addr +
1537 stat->nd_map->dm_segs[stat->nd_idx].ds_len),
1538 l, s);
1539 }
1540 #endif
1541 #endif
1542 } else {
1543 #if 0
1544 if ((state & DMACSR_BUSEXC) != 0) {
1545 while (nd_bsr4(DD_NEXT) !=
1546 (nd_bsr4(DD_LIMIT) & 0x7FFFFFFF))
1547 printf("Y"); /* DELAY(50); */
1548 state = nd_bsr4(DD_CSR);
1549 }
1550 #endif
1551
1552 if ((state & DMACSR_SUPDATE) == 0) {
1553 nextdma_rotate(nsc);
1554 } else {
1555 nd_bsw4(DD_CSR, DMACSR_CLRCOMPLETE |
1556 DMACSR_INITBUF | DMACSR_RESET |
1557 (state & DMACSR_READ ?
1558 DMACSR_SETREAD : DMACSR_SETWRITE));
1559
1560 nd_bsw4(DD_NEXT,
1561 stat->nd_map->dm_segs[stat->nd_idx].ds_addr);
1562 nd_bsw4(DD_LIMIT,
1563 (stat->nd_map->dm_segs[stat->nd_idx].ds_addr +
1564 stat->nd_map->dm_segs[stat->nd_idx].ds_len) |
1565 0/* x80000000 */);
1566 if (stat->nd_map_cont) {
1567 nd_bsw4(DD_START,
1568 stat->nd_map_cont->dm_segs[
1569 stat->nd_idx_cont].ds_addr);
1570 nd_bsw4(DD_STOP,
1571 (stat->nd_map_cont->dm_segs[
1572 stat->nd_idx_cont].ds_addr +
1573 stat->nd_map_cont->dm_segs[
1574 stat->nd_idx_cont].ds_len) |
1575 0/* x80000000 */);
1576 }
1577 nd_bsw4(DD_CSR, DMACSR_SETENABLE | DMACSR_CLRCOMPLETE |
1578 (state & DMACSR_READ ?
1579 DMACSR_SETREAD : DMACSR_SETWRITE) |
1580 (stat->nd_map_cont ? DMACSR_SETSUPDATE : 0));
1581 #if 1
1582 #ifdef ESP_DEBUG
1583 ndtrace_printf("supdate ");
1584 ndtrace_printf("%08X %08X %08X %08X ",
1585 nd_bsr4(DD_NEXT),
1586 nd_bsr4(DD_LIMIT) & 0x7FFFFFFF,
1587 nd_bsr4(DD_START),
1588 nd_bsr4(DD_STOP) & 0x7FFFFFFF);
1589 #endif
1590 #endif
1591 stat->nd_exception++;
1592 return 1;
1593 /* NCR_WRITE_REG(sc, ESP_DCTL, ctl); */
1594 goto restart;
1595 }
1596
1597 if (stat->nd_map != NULL) {
1598 #if 1
1599 #ifdef ESP_DEBUG
1600 ndtrace_printf("%08X %08X %08X %08X ",
1601 nd_bsr4(DD_NEXT),
1602 nd_bsr4(DD_LIMIT) & 0x7FFFFFFF,
1603 nd_bsr4(DD_START),
1604 nd_bsr4(DD_STOP) & 0x7FFFFFFF);
1605 #endif
1606 #endif
1607
1608 #if 0
1609 nd_bsw4(DD_CSR, DMACSR_CLRCOMPLETE | DMACSR_RESET);
1610
1611 nd_bsw4(DD_CSR, 0);
1612 #endif
1613 #if 1
1614 /* 6/2 */
1615 nd_bsw4(DD_CSR, DMACSR_CLRCOMPLETE |
1616 DMACSR_INITBUF | DMACSR_RESET |
1617 (state & DMACSR_READ ?
1618 DMACSR_SETREAD : DMACSR_SETWRITE));
1619
1620 /* nextdma_setup_curr_regs(nsc); */
1621 nd_bsw4(DD_NEXT,
1622 stat->nd_map->dm_segs[stat->nd_idx].ds_addr);
1623 nd_bsw4(DD_LIMIT,
1624 (stat->nd_map->dm_segs[stat->nd_idx].ds_addr +
1625 stat->nd_map->dm_segs[stat->nd_idx].ds_len) |
1626 0/* x80000000 */);
1627 /* nextdma_setup_cont_regs(nsc); */
1628 if (stat->nd_map_cont != NULL) {
1629 nd_bsw4(DD_START,
1630 stat->nd_map_cont->dm_segs[
1631 stat->nd_idx_cont].ds_addr);
1632 nd_bsw4(DD_STOP,
1633 (stat->nd_map_cont->dm_segs[
1634 stat->nd_idx_cont].ds_addr +
1635 stat->nd_map_cont->dm_segs[
1636 stat->nd_idx_cont].ds_len) |
1637 0/* x80000000 */);
1638 }
1639
1640 nd_bsw4(DD_CSR, DMACSR_SETENABLE |
1641 (stat->nd_map_cont ? DMACSR_SETSUPDATE : 0) |
1642 (state & DMACSR_READ ?
1643 DMACSR_SETREAD : DMACSR_SETWRITE));
1644 #ifdef ESP_DEBUG
1645 #if 0
1646 esptraceshow++;
1647 #endif
1648 #endif
1649 stat->nd_exception++;
1650 return 1;
1651 #endif
1652 #if 0
1653 NCR_WRITE_REG(sc, ESP_DCTL, ctl);
1654 #endif
1655 goto restart;
1656 restart:
1657 #if 1
1658 #ifdef ESP_DEBUG
1659 ndtrace_printf("restart %08lX %08lX\n",
1660 stat->nd_map->dm_segs[stat->nd_idx].ds_addr,
1661 stat->nd_map->dm_segs[stat->nd_idx].ds_addr +
1662 stat->nd_map->dm_segs[stat->nd_idx].ds_len);
1663 if (stat->nd_map_cont != NULL) {
1664 ndtrace_printf(" %08lX %08lX\n",
1665 stat->nd_map_cont->dm_segs[
1666 stat->nd_idx_cont].ds_addr,
1667 stat->nd_map_cont->dm_segs[
1668 stat->nd_idx_cont].ds_addr +
1669 stat->nd_map_cont->dm_segs[
1670 stat->nd_idx_cont].ds_len);
1671 }
1672 #endif
1673 #endif
1674 nextdma_print(nsc);
1675 NCR_WRITE_REG(sc, ESP_DCTL,
1676 ESPDCTL_16MHZ | ESPDCTL_INTENB);
1677 printf("ff:%02x tcm:%d tcl:%d esp_dstat:%02x"
1678 " state:%02x step: %02x intr:%02x state:%08X\n",
1679 NCR_READ_REG(sc, NCR_FFLAG),
1680 NCR_READ_REG((sc), NCR_TCM),
1681 NCR_READ_REG((sc), NCR_TCL),
1682 NCR_READ_REG(sc, ESP_DSTAT),
1683 NCR_READ_REG(sc, NCR_STAT),
1684 NCR_READ_REG(sc, NCR_STEP),
1685 NCR_READ_REG(sc, NCR_INTR), state);
1686 #ifdef ESP_DEBUG
1687 printf("ndtrace: %s\n", ndtrace_get());
1688 #endif
1689 panic("%s: busexc/supdate occurred."
1690 " Please email this output to chris@pin.lu.",
1691 device_xname(sc->sc_dev));
1692 #ifdef ESP_DEBUG
1693 esptraceshow++;
1694 #endif
1695 } else {
1696 nd_bsw4(DD_CSR, DMACSR_CLRCOMPLETE | DMACSR_RESET);
1697 if (nsc->sc_conf.nd_shutdown_cb)
1698 (*nsc->sc_conf.nd_shutdown_cb)(
1699 nsc->sc_conf.nd_cb_arg);
1700 }
1701 }
1702 return 1;
1703 }
1704
1705 /* Internal DMA callback routines */
1706 static bus_dmamap_t
esp_dmacb_continue(void * arg)1707 esp_dmacb_continue(void *arg)
1708 {
1709 struct ncr53c9x_softc *sc = arg;
1710 struct esp_softc *esc = (struct esp_softc *)sc;
1711
1712 NDTRACEIF(ndtrace_addc('x'));
1713 DPRINTF(("%s: DMA continue\n", device_xname(sc->sc_dev)));
1714
1715 #ifdef DIAGNOSTIC
1716 if (esc->sc_datain < 0 || esc->sc_datain > 1) {
1717 panic("%s: map not loaded in DMA continue callback,"
1718 " datain = %d",
1719 device_xname(sc->sc_dev), esc->sc_datain);
1720 }
1721 #endif
1722
1723 if ((esc->sc_loaded & ESP_LOADED_MAIN) == 0 &&
1724 esc->sc_main_dmamap->dm_mapsize != 0) {
1725 DPRINTF(("%s: Loading main map\n", device_xname(sc->sc_dev)));
1726 #if 0
1727 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_main_dmamap,
1728 0, esc->sc_main_dmamap->dm_mapsize,
1729 (esc->sc_datain ?
1730 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
1731 esc->sc_main_dmamap->dm_xfer_len = 0;
1732 #endif
1733 esc->sc_loaded |= ESP_LOADED_MAIN;
1734 return esc->sc_main_dmamap;
1735 }
1736
1737 if ((esc->sc_loaded & ESP_LOADED_TAIL) == 0 &&
1738 esc->sc_tail_dmamap->dm_mapsize != 0) {
1739 DPRINTF(("%s: Loading tail map\n", device_xname(sc->sc_dev)));
1740 #if 0
1741 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap,
1742 0, esc->sc_tail_dmamap->dm_mapsize,
1743 (esc->sc_datain ?
1744 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
1745 esc->sc_tail_dmamap->dm_xfer_len = 0;
1746 #endif
1747 esc->sc_loaded |= ESP_LOADED_TAIL;
1748 return esc->sc_tail_dmamap;
1749 }
1750
1751 DPRINTF(("%s: not loading map\n", device_xname(sc->sc_dev)));
1752 return 0;
1753 }
1754
1755
1756 static void
esp_dmacb_completed(bus_dmamap_t map,void * arg)1757 esp_dmacb_completed(bus_dmamap_t map, void *arg)
1758 {
1759 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
1760 struct esp_softc *esc = (struct esp_softc *)sc;
1761
1762 NDTRACEIF(ndtrace_addc('X'));
1763 DPRINTF(("%s: DMA completed\n", device_xname(sc->sc_dev)));
1764
1765 #ifdef DIAGNOSTIC
1766 if (esc->sc_datain < 0 || esc->sc_datain > 1) {
1767 panic("%s: invalid DMA direction in completed callback,"
1768 " datain = %d",
1769 device_xname(sc->sc_dev), esc->sc_datain);
1770 }
1771 #endif
1772
1773 #if defined(DIAGNOSTIC) && 0
1774 {
1775 int i;
1776 for(i = 0; i < map->dm_nsegs; i++) {
1777 if (map->dm_xfer_len != map->dm_mapsize) {
1778 printf("%s: map->dm_mapsize = %d\n",
1779 device_xname(sc->sc_dev), map->dm_mapsize);
1780 printf("%s: map->dm_nsegs = %d\n",
1781 device_xname(sc->sc_dev), map->dm_nsegs);
1782 printf("%s: map->dm_xfer_len = %d\n",
1783 device_xname(sc->sc_dev), map->dm_xfer_len);
1784 for(i = 0; i < map->dm_nsegs; i++) {
1785 printf("%s: map->dm_segs[%d].ds_addr ="
1786 " 0x%08lx\n",
1787 device_xname(sc->sc_dev), i,
1788 map->dm_segs[i].ds_addr);
1789 printf("%s: map->dm_segs[%d].ds_len ="
1790 " %d\n",
1791 device_xname(sc->sc_dev), i,
1792 map->dm_segs[i].ds_len);
1793 }
1794 panic("%s: incomplete DMA transfer",
1795 device_xname(sc->sc_dev));
1796 }
1797 }
1798 }
1799 #endif
1800
1801 if (map == esc->sc_main_dmamap) {
1802 #ifdef DIAGNOSTIC
1803 if ((esc->sc_loaded & ESP_UNLOADED_MAIN) ||
1804 (esc->sc_loaded & ESP_LOADED_MAIN) == 0) {
1805 panic("%s: unexpected completed call for main map",
1806 device_xname(sc->sc_dev));
1807 }
1808 #endif
1809 esc->sc_loaded |= ESP_UNLOADED_MAIN;
1810 } else if (map == esc->sc_tail_dmamap) {
1811 #ifdef DIAGNOSTIC
1812 if ((esc->sc_loaded & ESP_UNLOADED_TAIL) ||
1813 (esc->sc_loaded & ESP_LOADED_TAIL) == 0) {
1814 panic("%s: unexpected completed call for tail map",
1815 device_xname(sc->sc_dev));
1816 }
1817 #endif
1818 esc->sc_loaded |= ESP_UNLOADED_TAIL;
1819 }
1820 #ifdef DIAGNOSTIC
1821 else {
1822 panic("%s: unexpected completed map", device_xname(sc->sc_dev));
1823 }
1824 #endif
1825
1826 #ifdef ESP_DEBUG
1827 if (esp_debug) {
1828 if (map == esc->sc_main_dmamap) {
1829 printf("%s: completed main map\n",
1830 device_xname(sc->sc_dev));
1831 } else if (map == esc->sc_tail_dmamap) {
1832 printf("%s: completed tail map\n",
1833 device_xname(sc->sc_dev));
1834 }
1835 }
1836 #endif
1837
1838 #if 0
1839 if ((map == esc->sc_tail_dmamap) ||
1840 ((esc->sc_tail_size == 0) && (map == esc->sc_main_dmamap))) {
1841
1842 /*
1843 * Clear the DMAMOD bit in the DCTL register to give control
1844 * back to the scsi chip.
1845 */
1846 if (esc->sc_datain) {
1847 NCR_WRITE_REG(sc, ESP_DCTL,
1848 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
1849 } else {
1850 NCR_WRITE_REG(sc, ESP_DCTL,
1851 ESPDCTL_16MHZ | ESPDCTL_INTENB);
1852 }
1853 DPRINTF(("esp dctl is 0x%02x\n", NCR_READ_REG(sc, ESP_DCTL)));
1854 }
1855 #endif
1856
1857
1858 #if 0
1859 bus_dmamap_sync(esc->sc_dma->sc_dmat, map,
1860 0, map->dm_mapsize,
1861 (esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
1862 #endif
1863
1864 }
1865
1866 static void
esp_dmacb_shutdown(void * arg)1867 esp_dmacb_shutdown(void *arg)
1868 {
1869 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
1870 struct esp_softc *esc = (struct esp_softc *)sc;
1871
1872 NDTRACEIF (ndtrace_addc('S'));
1873 DPRINTF(("%s: DMA shutdown\n", device_xname(sc->sc_dev)));
1874
1875 if (esc->sc_loaded == 0)
1876 return;
1877
1878 #if 0
1879 {
1880 /* Clear the DMAMOD bit in the DCTL register to give control
1881 * back to the scsi chip.
1882 */
1883 if (esc->sc_datain) {
1884 NCR_WRITE_REG(sc, ESP_DCTL,
1885 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
1886 } else {
1887 NCR_WRITE_REG(sc, ESP_DCTL,
1888 ESPDCTL_16MHZ | ESPDCTL_INTENB);
1889 }
1890 DPRINTF(("esp dctl is 0x%02x\n", NCR_READ_REG(sc, ESP_DCTL)));
1891 }
1892 #endif
1893
1894 DPRINTF(("%s: esp_dma_nest == %d\n",
1895 device_xname(sc->sc_dev), esp_dma_nest));
1896
1897 /* Stuff the end slop into fifo */
1898
1899 #ifdef ESP_DEBUG
1900 if (esp_debug) {
1901 int n = NCR_READ_REG(sc, NCR_FFLAG);
1902
1903 DPRINTF(("%s: fifo size = %d, seq = 0x%x\n",
1904 device_xname(sc->sc_dev), n & NCRFIFO_FF,
1905 (n & NCRFIFO_SS) >> 5));
1906 }
1907 #endif
1908
1909 if (esc->sc_main_dmamap->dm_mapsize != 0) {
1910 if (!esc->sc_datain) {
1911 /* unpatch the DMA map for write overrun */
1912 esc->sc_main_dmamap->dm_mapsize -= ESP_DMA_OVERRUN;
1913 esc->sc_main_dmamap->dm_segs[
1914 esc->sc_main_dmamap->dm_nsegs - 1].ds_len -=
1915 ESP_DMA_OVERRUN;
1916 }
1917 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_main_dmamap,
1918 0, esc->sc_main_dmamap->dm_mapsize,
1919 (esc->sc_datain ?
1920 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
1921 bus_dmamap_unload(esc->sc_dma->sc_dmat, esc->sc_main_dmamap);
1922 NDTRACEIF(
1923 ndtrace_printf("m%ld",
1924 esc->sc_main_dmamap->dm_xfer_len);
1925 );
1926 }
1927
1928 if (esc->sc_tail_dmamap->dm_mapsize != 0) {
1929 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap,
1930 0, esc->sc_tail_dmamap->dm_mapsize,
1931 (esc->sc_datain ?
1932 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
1933 bus_dmamap_unload(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap);
1934 /* copy the tail DMA buffer data for read transfers */
1935 if (esc->sc_datain) {
1936 memcpy(*esc->sc_dmaaddr + esc->sc_begin_size +
1937 esc->sc_main_size, esc->sc_tail,
1938 esc->sc_dmasize -
1939 (esc->sc_begin_size + esc->sc_main_size));
1940 }
1941 NDTRACEIF(
1942 ndtrace_printf("t%ld",
1943 esc->sc_tail_dmamap->dm_xfer_len);
1944 );
1945 }
1946
1947 #ifdef ESP_DEBUG
1948 if (esp_debug) {
1949 printf("%s: dma_shutdown: addr=%p,len=0x%08x,size=0x%08x\n",
1950 device_xname(sc->sc_dev),
1951 *esc->sc_dmaaddr, *esc->sc_dmalen, esc->sc_dmasize);
1952 if (esp_debug > 10) {
1953 esp_hex_dump(*(esc->sc_dmaaddr), esc->sc_dmasize);
1954 printf("%s: tail=%p,tailbuf=%p,tail_size=0x%08x\n",
1955 device_xname(sc->sc_dev),
1956 esc->sc_tail, &(esc->sc_tailbuf[0]),
1957 esc->sc_tail_size);
1958 esp_hex_dump(&(esc->sc_tailbuf[0]),
1959 sizeof(esc->sc_tailbuf));
1960 }
1961 }
1962 #endif
1963
1964 esc->sc_main = 0;
1965 esc->sc_main_size = 0;
1966 esc->sc_tail = 0;
1967 esc->sc_tail_size = 0;
1968
1969 esc->sc_datain = -1;
1970 #if 0
1971 esc->sc_dmaaddr = 0;
1972 esc->sc_dmalen = 0;
1973 esc->sc_dmasize = 0;
1974 #endif
1975
1976 esc->sc_loaded = 0;
1977
1978 esc->sc_begin = 0;
1979 esc->sc_begin_size = 0;
1980
1981 #ifdef ESP_DEBUG
1982 if (esp_debug) {
1983 char sbuf[256];
1984
1985 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS,
1986 (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)));
1987 printf(" *intrstat = %s\n", sbuf);
1988
1989 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS,
1990 (*(volatile u_long *)IIOV(NEXT_P_INTRMASK)));
1991 printf(" *intrmask = %s\n", sbuf);
1992 }
1993 #endif
1994 }
1995