Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / next68k / dev / esp.c
blob2216ce86fe4acbd712c9f744cbc4b4120c198955
1 /* $NetBSD: esp.c,v 1.58 2009/09/02 10:34:05 tsutsui Exp $ */
3 /*-
4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
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.
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.
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.
34 * Copyright (c) 1994 Peter Galbavy
35 * All rights reserved.
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.
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.
65 * Based on aic6360 by Jarle Greipsland
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!
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
77 #include <sys/cdefs.h>
78 __KERNEL_RCSID(0, "$NetBSD: esp.c,v 1.58 2009/09/02 10:34:05 tsutsui Exp $");
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>
91 #include <uvm/uvm_extern.h>
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>
98 #include <machine/bus.h>
99 #include <machine/autoconf.h>
100 #include <machine/cpu.h>
102 #include <dev/ic/ncr53c9xreg.h>
103 #include <dev/ic/ncr53c9xvar.h>
105 #include <next68k/next68k/isr.h>
107 #include <next68k/dev/intiovar.h>
108 #include <next68k/dev/nextdmareg.h>
109 #include <next68k/dev/nextdmavar.h>
111 #include <next68k/dev/espreg.h>
112 #include <next68k/dev/espvar.h>
114 #ifdef DEBUG
115 #undef ESP_DEBUG
116 #endif
118 #ifdef ESP_DEBUG
119 int esp_debug = 0;
120 #define DPRINTF(x) if (esp_debug) printf x;
121 extern char *ndtracep;
122 extern char ndtrace[];
123 extern int ndtraceshow;
124 #define NDTRACEIF(x) if (10 && ndtracep < (ndtrace + 8192)) do {x;} while (0)
125 #else
126 #define DPRINTF(x)
127 #define NDTRACEIF(x)
128 #endif
129 #define PRINTF(x) printf x;
132 int espmatch_intio(device_t, cfdata_t, void *);
133 void espattach_intio(device_t, device_t, void *);
135 /* DMA callbacks */
136 bus_dmamap_t esp_dmacb_continue(void *);
137 void esp_dmacb_completed(bus_dmamap_t, void *);
138 void esp_dmacb_shutdown(void *);
140 static void findchannel_defer(struct device *);
142 #ifdef ESP_DEBUG
143 char esp_dma_dump[5*1024] = "";
144 struct ncr53c9x_softc *esp_debug_sc = 0;
145 void esp_dma_store(struct ncr53c9x_softc *);
146 void esp_dma_print(struct ncr53c9x_softc *);
147 int esp_dma_nest = 0;
148 #endif
151 /* Linkup to the rest of the kernel */
152 CFATTACH_DECL_NEW(esp, sizeof(struct esp_softc),
153 espmatch_intio, espattach_intio, NULL, NULL);
155 static int attached = 0;
158 * Functions and the switch for the MI code.
160 uint8_t esp_read_reg(struct ncr53c9x_softc *, int);
161 void esp_write_reg(struct ncr53c9x_softc *, int, uint8_t);
162 int esp_dma_isintr(struct ncr53c9x_softc *);
163 void esp_dma_reset(struct ncr53c9x_softc *);
164 int esp_dma_intr(struct ncr53c9x_softc *);
165 int esp_dma_setup(struct ncr53c9x_softc *, uint8_t **, size_t *, int,
166 size_t *);
167 void esp_dma_go(struct ncr53c9x_softc *);
168 void esp_dma_stop(struct ncr53c9x_softc *);
169 int esp_dma_isactive(struct ncr53c9x_softc *);
171 struct ncr53c9x_glue esp_glue = {
172 esp_read_reg,
173 esp_write_reg,
174 esp_dma_isintr,
175 esp_dma_reset,
176 esp_dma_intr,
177 esp_dma_setup,
178 esp_dma_go,
179 esp_dma_stop,
180 esp_dma_isactive,
181 NULL, /* gl_clear_latched_intr */
184 #ifdef ESP_DEBUG
185 #define XCHR(x) hexdigits[(x) & 0xf]
186 static void
187 esp_hex_dump(unsigned char *pkt, size_t len)
189 size_t i, j;
191 printf("00000000 ");
192 for(i = 0; i < len; i++) {
193 printf("%c%c ", XCHR(pkt[i]>>4), XCHR(pkt[i]));
194 if ((i + 1) % 16 == 8) {
195 printf(" ");
197 if ((i + 1) % 16 == 0) {
198 printf(" %c", '|');
199 for(j = 0; j < 16; j++) {
200 printf("%c", pkt[i-15+j]>=32 && pkt[i-15+j]<127?pkt[i-15+j]:'.');
202 printf("%c\n%c%c%c%c%c%c%c%c ", '|',
203 XCHR((i+1)>>28),XCHR((i+1)>>24),XCHR((i+1)>>20),XCHR((i+1)>>16),
204 XCHR((i+1)>>12), XCHR((i+1)>>8), XCHR((i+1)>>4), XCHR(i+1));
207 printf("\n");
209 #endif
212 espmatch_intio(device_t parent, cfdata_t cf, void *aux)
214 struct intio_attach_args *ia = aux;
216 if (attached)
217 return 0;
219 ia->ia_addr = (void *)NEXT_P_SCSI;
221 return 1;
224 static void
225 findchannel_defer(struct device *self)
227 struct esp_softc *esc = device_private(self);
228 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
229 int error;
231 if (!esc->sc_dma) {
232 aprint_normal("%s", device_xname(sc->sc_dev));
233 esc->sc_dma = nextdma_findchannel("scsi");
234 if (!esc->sc_dma)
235 panic("%s: can't find DMA channel",
236 device_xname(sc->sc_dev));
239 nextdma_setconf(esc->sc_dma, shutdown_cb, &esp_dmacb_shutdown);
240 nextdma_setconf(esc->sc_dma, continue_cb, &esp_dmacb_continue);
241 nextdma_setconf(esc->sc_dma, completed_cb, &esp_dmacb_completed);
242 nextdma_setconf(esc->sc_dma, cb_arg, sc);
244 error = bus_dmamap_create(esc->sc_dma->sc_dmat,
245 sc->sc_maxxfer,
246 sc->sc_maxxfer / PAGE_SIZE + 1,
247 sc->sc_maxxfer,
248 0, BUS_DMA_ALLOCNOW, &esc->sc_main_dmamap);
249 if (error) {
250 panic("%s: can't create main i/o DMA map, error = %d",
251 device_xname(sc->sc_dev), error);
254 error = bus_dmamap_create(esc->sc_dma->sc_dmat,
255 ESP_DMA_TAILBUFSIZE, 1, ESP_DMA_TAILBUFSIZE,
256 0, BUS_DMA_ALLOCNOW, &esc->sc_tail_dmamap);
257 if (error) {
258 panic("%s: can't create tail i/o DMA map, error = %d",
259 device_xname(sc->sc_dev), error);
262 #if 0
263 /* Turn on target selection using the `DMA' method */
264 sc->sc_features |= NCR_F_DMASELECT;
265 #endif
267 /* Do the common parts of attachment. */
268 sc->sc_adapter.adapt_minphys = minphys;
269 sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request;
270 ncr53c9x_attach(sc);
272 /* Establish interrupt channel */
273 isrlink_autovec(ncr53c9x_intr, sc, NEXT_I_IPL(NEXT_I_SCSI), 0, NULL);
274 INTR_ENABLE(NEXT_I_SCSI);
276 /* register interrupt stats */
277 evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
278 device_xname(sc->sc_dev), "intr");
280 aprint_normal_dev(sc->sc_dev, "using DMA channel %s\n",
281 device_xname(&esc->sc_dma->sc_dev));
284 void
285 espattach_intio(device_t parent, device_t self, void *aux)
287 struct esp_softc *esc = device_private(self);
288 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
289 struct intio_attach_args *ia = aux;
291 sc->sc_dev = self;
293 #ifdef ESP_DEBUG
294 esp_debug_sc = sc;
295 #endif
297 esc->sc_bst = ia->ia_bst;
298 if (bus_space_map(esc->sc_bst, NEXT_P_SCSI,
299 ESP_DEVICE_SIZE, 0, &esc->sc_bsh)) {
300 aprint_normal("\n");
301 panic("%s: can't map ncr53c90 registers",
302 device_xname(self));
305 sc->sc_id = 7;
306 sc->sc_freq = 20; /* MHz */
309 * Set up glue for MI code early; we use some of it here.
311 sc->sc_glue = &esp_glue;
314 * XXX More of this should be in ncr53c9x_attach(), but
315 * XXX should we really poke around the chip that much in
316 * XXX the MI code? Think about this more...
320 * It is necessary to try to load the 2nd config register here,
321 * to find out what rev the esp chip is, else the ncr53c9x_reset
322 * will not set up the defaults correctly.
324 sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
325 sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE;
326 sc->sc_cfg3 = NCRCFG3_CDB;
327 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
329 if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
330 (NCRCFG2_SCSI2 | NCRCFG2_RPE)) {
331 sc->sc_rev = NCR_VARIANT_ESP100;
332 } else {
333 sc->sc_cfg2 = NCRCFG2_SCSI2;
334 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
335 sc->sc_cfg3 = 0;
336 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
337 sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK);
338 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
339 if (NCR_READ_REG(sc, NCR_CFG3) !=
340 (NCRCFG3_CDB | NCRCFG3_FCLK)) {
341 sc->sc_rev = NCR_VARIANT_ESP100A;
342 } else {
343 /* NCRCFG2_FE enables > 64K transfers */
344 sc->sc_cfg2 |= NCRCFG2_FE;
345 sc->sc_cfg3 = 0;
346 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
347 sc->sc_rev = NCR_VARIANT_ESP200;
352 * XXX minsync and maxxfer _should_ be set up in MI code,
353 * XXX but it appears to have some dependency on what sort
354 * XXX of DMA we're hooked up to, etc.
358 * This is the value used to start sync negotiations
359 * Note that the NCR register "SYNCTP" is programmed
360 * in "clocks per byte", and has a minimum value of 4.
361 * The SCSI period used in negotiation is one-fourth
362 * of the time (in nanoseconds) needed to transfer one byte.
363 * Since the chip's clock is given in MHz, we have the following
364 * formula: 4 * period = (1000 / freq) * 4
366 sc->sc_minsync = /* 1000 / sc->sc_freq */ 0;
369 * Alas, we must now modify the value a bit, because it's
370 * only valid when can switch on FASTCLK and FASTSCSI bits
371 * in config register 3...
373 switch (sc->sc_rev) {
374 case NCR_VARIANT_ESP100:
375 sc->sc_maxxfer = 64 * 1024;
376 sc->sc_minsync = 0; /* No synch on old chip? */
377 break;
379 case NCR_VARIANT_ESP100A:
380 sc->sc_maxxfer = 64 * 1024;
381 /* Min clocks/byte is 5 */
382 sc->sc_minsync = /* ncr53c9x_cpb2stp(sc, 5) */ 0;
383 break;
385 case NCR_VARIANT_ESP200:
386 sc->sc_maxxfer = 16 * 1024 * 1024;
387 /* XXX - do actually set FAST* bits */
388 break;
391 /* @@@ Some ESP_DCTL bits probably need setting */
392 NCR_WRITE_REG(sc, ESP_DCTL,
393 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_RESET);
394 DELAY(10);
395 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
396 NCR_WRITE_REG(sc, ESP_DCTL, ESPDCTL_16MHZ | ESPDCTL_INTENB);
397 DELAY(10);
398 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
400 esc->sc_dma = nextdma_findchannel ("scsi");
401 if (esc->sc_dma) {
402 findchannel_defer(self);
403 } else {
404 aprint_normal("\n");
405 config_defer(self, findchannel_defer);
408 attached = 1;
412 * Glue functions.
415 uint8_t
416 esp_read_reg(struct ncr53c9x_softc *sc, int reg)
418 struct esp_softc *esc = (struct esp_softc *)sc;
420 return bus_space_read_1(esc->sc_bst, esc->sc_bsh, reg);
423 void
424 esp_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t val)
426 struct esp_softc *esc = (struct esp_softc *)sc;
428 bus_space_write_1(esc->sc_bst, esc->sc_bsh, reg, val);
431 volatile uint32_t save1;
433 #define xADDR 0x0211a000
434 int doze(volatile int);
436 doze(volatile int c)
438 /* static int tmp1; */
439 uint32_t tmp1;
440 volatile uint8_t tmp2;
441 volatile uint8_t *reg = (volatile uint8_t *)IIOV(xADDR);
443 if (c > 244)
444 return 0;
445 if (c == 0)
446 return 0;
447 /* ((*(volatile u_long *)IIOV(NEXT_P_INTRMASK))&=(~NEXT_I_BIT(x))) */
448 (*reg) = 0;
449 (*reg) = 0;
450 do {
451 save1 = (*reg);
452 tmp2 = *(reg + 3);
453 tmp1 = tmp2;
454 } while (tmp1 <= c);
455 return 0;
459 esp_dma_isintr(struct ncr53c9x_softc *sc)
461 struct esp_softc *esc = (struct esp_softc *)sc;
463 if (INTR_OCCURRED(NEXT_I_SCSI)) {
464 NDTRACEIF (*ndtracep++ = 'i');
465 NCR_WRITE_REG(sc, ESP_DCTL,
466 ESPDCTL_16MHZ | ESPDCTL_INTENB |
467 (esc->sc_datain ? ESPDCTL_DMARD : 0));
468 return 1;
469 } else {
470 return 0;
474 #define nd_bsr4(reg) \
475 bus_space_read_4(nsc->sc_bst, nsc->sc_bsh, (reg))
476 #define nd_bsw4(reg,val) \
477 bus_space_write_4(nsc->sc_bst, nsc->sc_bsh, (reg), (val))
480 esp_dma_intr(struct ncr53c9x_softc *sc)
482 struct esp_softc *esc = (struct esp_softc *)sc;
483 struct nextdma_softc *nsc = esc->sc_dma;
484 struct nextdma_status *stat = &nsc->sc_stat;
485 int r = (INTR_OCCURRED(NEXT_I_SCSI));
486 int flushcount;
488 r = 1;
490 NDTRACEIF (*ndtracep++ = 'I');
491 if (r) {
492 /* printf ("esp_dma_isintr start\n"); */
494 int s = spldma();
495 void *ndmap = stat->nd_map;
496 int ndidx = stat->nd_idx;
497 splx(s);
499 flushcount = 0;
501 #ifdef ESP_DEBUG
502 /* esp_dma_nest++; */
504 if (esp_debug) {
505 char sbuf[256];
507 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS,
508 (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)));
510 printf("esp_dma_isintr = 0x%s\n", sbuf);
512 #endif
514 while (!nextdma_finished(nsc)) {
515 /* esp_dma_isactive(sc)) { */
516 NDTRACEIF (*ndtracep++ = 'w');
517 NDTRACEIF (
518 sprintf(ndtracep, "f%dm%dl%dw",
519 NCR_READ_REG(sc, NCR_FFLAG) &
520 NCRFIFO_FF,
521 NCR_READ_REG((sc), NCR_TCM),
522 NCR_READ_REG((sc), NCR_TCL));
523 ndtracep += strlen(ndtracep);
525 if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF)
526 flushcount = 5;
527 NCR_WRITE_REG(sc, ESP_DCTL,
528 ESPDCTL_16MHZ | ESPDCTL_INTENB |
529 ESPDCTL_DMAMOD |
530 (esc->sc_datain ? ESPDCTL_DMARD : 0));
532 s = spldma();
533 while (ndmap == stat->nd_map &&
534 ndidx == stat->nd_idx &&
535 (nd_bsr4 (DD_CSR) & 0x08000000) == 0&&
536 ++flushcount < 5) {
537 splx(s);
538 NDTRACEIF (*ndtracep++ = 'F');
539 NCR_WRITE_REG(sc, ESP_DCTL,
540 ESPDCTL_FLUSH | ESPDCTL_16MHZ |
541 ESPDCTL_INTENB | ESPDCTL_DMAMOD |
542 (esc->sc_datain ?
543 ESPDCTL_DMARD : 0));
544 doze(0x32);
545 NCR_WRITE_REG(sc, ESP_DCTL,
546 ESPDCTL_16MHZ | ESPDCTL_INTENB |
547 ESPDCTL_DMAMOD |
548 (esc->sc_datain ?
549 ESPDCTL_DMARD : 0));
550 doze(0x32);
551 s = spldma();
553 NDTRACEIF (*ndtracep++ = '0' + flushcount);
554 if (flushcount > 4) {
555 int next;
556 int onext = 0;
558 splx(s);
559 DPRINTF(("DMA reset\n"));
560 while (((next = nd_bsr4 (DD_NEXT)) !=
561 (nd_bsr4(DD_LIMIT) & 0x7FFFFFFF)) &&
562 onext != next) {
563 onext = next;
564 DELAY(50);
566 NDTRACEIF (*ndtracep++ = 'R');
567 NCR_WRITE_REG(sc, ESP_DCTL,
568 ESPDCTL_16MHZ | ESPDCTL_INTENB);
569 NDTRACEIF (
570 sprintf(ndtracep,
571 "ff:%d tcm:%d tcl:%d ",
572 NCR_READ_REG(sc, NCR_FFLAG)
573 & NCRFIFO_FF,
574 NCR_READ_REG((sc), NCR_TCM),
575 NCR_READ_REG((sc),
576 NCR_TCL));
577 ndtracep += strlen (ndtracep);
579 s = spldma();
580 nextdma_reset (nsc);
581 splx(s);
582 goto out;
584 splx(s);
586 #ifdef DIAGNOSTIC
587 if (flushcount > 4) {
588 NDTRACEIF (*ndtracep++ = '+');
589 printf("%s: unexpected flushcount"
590 " %d on %s\n",
591 device_xname(sc->sc_dev),
592 flushcount,
593 esc->sc_datain ? "read" : "write");
595 #endif
597 if (!nextdma_finished(nsc)) {
598 /* esp_dma_isactive(sc)) { */
599 NDTRACEIF (*ndtracep++ = '1');
601 flushcount = 0;
602 s = spldma();
603 ndmap = stat->nd_map;
604 ndidx = stat->nd_idx;
605 splx(s);
608 out:
611 #ifdef ESP_DEBUG
612 /* esp_dma_nest--; */
613 #endif
617 doze(0x32);
618 NCR_WRITE_REG(sc, ESP_DCTL,
619 ESPDCTL_16MHZ | ESPDCTL_INTENB |
620 (esc->sc_datain ? ESPDCTL_DMARD : 0));
621 NDTRACEIF (*ndtracep++ = 'b');
623 while (esc->sc_datain != -1)
624 DELAY(50);
626 if (esc->sc_dmaaddr) {
627 bus_size_t xfer_len = 0;
628 int resid;
630 NCR_WRITE_REG(sc, ESP_DCTL,
631 ESPDCTL_16MHZ | ESPDCTL_INTENB);
632 if (stat->nd_exception == 0) {
633 resid = NCR_READ_REG((sc), NCR_TCL) +
634 (NCR_READ_REG((sc), NCR_TCM) << 8);
635 if (resid) {
636 resid += (NCR_READ_REG(sc, NCR_FFLAG) &
637 NCRFIFO_FF);
638 #ifdef ESP_DEBUG
639 if (NCR_READ_REG(sc, NCR_FFLAG) &
640 NCRFIFO_FF)
641 if ((NCR_READ_REG(sc,
642 NCR_FFLAG) & NCRFIFO_FF) !=
643 16 ||
644 NCR_READ_REG((sc),
645 NCR_TCL) != 240)
646 ndtraceshow++;
647 #endif
649 xfer_len = esc->sc_dmasize - resid;
650 } else {
651 #define ncr53c9x_sched_msgout(m) \
652 do { \
653 NCR_MISC(("ncr53c9x_sched_msgout %x %d", m, __LINE__)); \
654 NCRCMD(sc, NCRCMD_SETATN); \
655 sc->sc_flags |= NCR_ATN; \
656 sc->sc_msgpriq |= (m); \
657 } while (0)
658 int i;
660 xfer_len = 0;
661 if (esc->sc_begin)
662 xfer_len += esc->sc_begin_size;
663 if (esc->sc_main_dmamap)
664 xfer_len +=
665 esc->sc_main_dmamap->dm_xfer_len;
666 if (esc->sc_tail_dmamap)
667 xfer_len +=
668 esc->sc_tail_dmamap->dm_xfer_len;
669 resid = 0;
670 printf ("X\n");
671 for (i = 0; i < 16; i++) {
672 NCR_WRITE_REG(sc, ESP_DCTL,
673 ESPDCTL_FLUSH | ESPDCTL_16MHZ |
674 ESPDCTL_INTENB |
675 (esc->sc_datain ?
676 ESPDCTL_DMARD : 0));
677 NCR_WRITE_REG(sc, ESP_DCTL,
678 ESPDCTL_16MHZ | ESPDCTL_INTENB |
679 (esc->sc_datain ?
680 ESPDCTL_DMARD : 0));
682 #if 0
683 printf ("ff:%02x tcm:%d tcl:%d esp_dstat:%02x"
684 " stat:%02x step: %02x intr:%02x"
685 " new stat:%02X\n",
686 NCR_READ_REG(sc, NCR_FFLAG),
687 NCR_READ_REG((sc), NCR_TCM),
688 NCR_READ_REG((sc), NCR_TCL),
689 NCR_READ_REG(sc, ESP_DSTAT),
690 sc->sc_espstat, sc->sc_espstep,
691 sc->sc_espintr,
692 NCR_READ_REG(sc, NCR_STAT));
693 printf("sc->sc_state: %x sc->sc_phase: %x"
694 " sc->sc_espstep:%x sc->sc_prevphase:%x"
695 " sc->sc_flags:%x\n",
696 sc->sc_state, sc->sc_phase, sc->sc_espstep,
697 sc->sc_prevphase, sc->sc_flags);
698 #endif
699 /* sc->sc_flags &= ~NCR_ICCS; */
700 sc->sc_nexus->flags |= ECB_ABORT;
701 if (sc->sc_phase == MESSAGE_IN_PHASE) {
702 /* ncr53c9x_sched_msgout(SEND_ABORT); */
703 ncr53c9x_abort(sc, sc->sc_nexus);
704 } else if (sc->sc_phase != STATUS_PHASE) {
705 printf("ATTENTION!!! "
706 "not message/status phase: %d\n",
707 sc->sc_phase);
711 NDTRACEIF(
712 sprintf(ndtracep, "f%dm%dl%ds%dx%dr%dS",
713 NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF,
714 NCR_READ_REG((sc), NCR_TCM),
715 NCR_READ_REG((sc), NCR_TCL),
716 esc->sc_dmasize, (int)xfer_len, resid);
717 ndtracep += strlen(ndtracep);
720 *esc->sc_dmaaddr += xfer_len;
721 *esc->sc_dmalen -= xfer_len;
722 esc->sc_dmaaddr = 0;
723 esc->sc_dmalen = 0;
724 esc->sc_dmasize = 0;
727 NDTRACEIF (*ndtracep++ = 'B');
728 sc->sc_espstat = NCR_READ_REG(sc, NCR_STAT) |
729 (sc->sc_espstat & NCRSTAT_INT);
731 DPRINTF(("esp dctl is 0x%02x\n", NCR_READ_REG(sc, ESP_DCTL)));
732 /* printf ("esp_dma_isintr DONE\n"); */
736 return r;
739 void
740 esp_dma_reset(struct ncr53c9x_softc *sc)
742 struct esp_softc *esc = (struct esp_softc *)sc;
744 DPRINTF(("esp DMA reset\n"));
746 #ifdef ESP_DEBUG
747 if (esp_debug) {
748 char sbuf[256];
750 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS,
751 (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)));
752 printf(" *intrstat = 0x%s\n", sbuf);
754 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS,
755 (*(volatile u_long *)IIOV(NEXT_P_INTRMASK)));
756 printf(" *intrmask = 0x%s\n", sbuf);
758 #endif
760 #if 0
761 /* Clear the DMAMOD bit in the DCTL register: */
762 NCR_WRITE_REG(sc, ESP_DCTL, ESPDCTL_16MHZ | ESPDCTL_INTENB);
763 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
764 #endif
766 nextdma_reset(esc->sc_dma);
767 nextdma_init(esc->sc_dma);
769 esc->sc_datain = -1;
770 esc->sc_dmaaddr = 0;
771 esc->sc_dmalen = 0;
772 esc->sc_dmasize = 0;
774 esc->sc_loaded = 0;
776 esc->sc_begin = 0;
777 esc->sc_begin_size = 0;
779 if (esc->sc_main_dmamap->dm_mapsize) {
780 bus_dmamap_unload(esc->sc_dma->sc_dmat, esc->sc_main_dmamap);
782 esc->sc_main = 0;
783 esc->sc_main_size = 0;
785 if (esc->sc_tail_dmamap->dm_mapsize) {
786 bus_dmamap_unload(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap);
788 esc->sc_tail = 0;
789 esc->sc_tail_size = 0;
792 /* it appears that:
793 * addr and len arguments to this need to be kept up to date
794 * with the status of the transfter.
795 * the dmasize of this is the actual length of the transfer
796 * request, which is guaranteed to be less than maxxfer.
797 * (len may be > maxxfer)
801 esp_dma_setup(struct ncr53c9x_softc *sc, uint8_t **addr, size_t *len,
802 int datain, size_t *dmasize)
804 struct esp_softc *esc = (struct esp_softc *)sc;
806 NDTRACEIF (*ndtracep++ = 'h');
807 #ifdef DIAGNOSTIC
808 #ifdef ESP_DEBUG
809 /* if this is a read DMA, pre-fill the buffer with 0xdeadbeef
810 * to identify bogus reads
812 if (datain) {
813 int *v = (int *)(*addr);
814 int i;
815 for (i = 0; i < ((*len) / 4); i++)
816 v[i] = 0xdeadbeef;
817 v = (int *)(&(esc->sc_tailbuf[0]));
818 for (i = 0; i < ((sizeof(esc->sc_tailbuf) / 4)); i++)
819 v[i] = 0xdeafbeef;
820 } else {
821 int *v;
822 int i;
823 v = (int *)(&(esc->sc_tailbuf[0]));
824 for (i = 0; i < ((sizeof(esc->sc_tailbuf) / 4)); i++)
825 v[i] = 0xfeeb1eed;
827 #endif
828 #endif
830 DPRINTF(("esp_dma_setup(%p,0x%08x,0x%08x)\n", *addr, *len, *dmasize));
832 #if 0
833 #ifdef DIAGNOSTIC /* @@@ this is ok sometimes. verify that we handle it ok
834 * and then remove this check
836 if (*len != *dmasize) {
837 panic("esp dmalen 0x%lx != size 0x%lx", *len, *dmasize);
839 #endif
840 #endif
842 #ifdef DIAGNOSTIC
843 if ((esc->sc_datain != -1) ||
844 (esc->sc_main_dmamap->dm_mapsize != 0) ||
845 (esc->sc_tail_dmamap->dm_mapsize != 0) ||
846 (esc->sc_dmasize != 0)) {
847 panic("%s: map already loaded in esp_dma_setup"
848 "\tdatain = %d\n\tmain_mapsize=%ld\n"
849 "\tail_mapsize=%ld\n\tdmasize = %d",
850 device_xname(sc->sc_dev), esc->sc_datain,
851 esc->sc_main_dmamap->dm_mapsize,
852 esc->sc_tail_dmamap->dm_mapsize,
853 esc->sc_dmasize);
855 #endif
857 /* we are sometimes asked to DMA zero bytes, that's easy */
858 if (*dmasize <= 0) {
859 return 0;
862 if (*dmasize > ESP_MAX_DMASIZE)
863 *dmasize = ESP_MAX_DMASIZE;
865 /* Save these in case we have to abort DMA */
866 esc->sc_datain = datain;
867 esc->sc_dmaaddr = addr;
868 esc->sc_dmalen = len;
869 esc->sc_dmasize = *dmasize;
871 esc->sc_loaded = 0;
873 #define DMA_SCSI_ALIGNMENT 16
874 #define DMA_SCSI_ALIGN(type, addr) \
875 ((type)(((unsigned int)(addr) + DMA_SCSI_ALIGNMENT - 1) \
876 &~(DMA_SCSI_ALIGNMENT-1)))
877 #define DMA_SCSI_ALIGNED(addr) \
878 (((unsigned int)(addr) & (DMA_SCSI_ALIGNMENT - 1))==0)
881 size_t slop_bgn_size; /* # bytes to be fifo'd at beginning */
882 size_t slop_end_size; /* # bytes to be transferred in tail buffer */
885 u_long bgn = (u_long)(*esc->sc_dmaaddr);
886 u_long end = bgn + esc->sc_dmasize;
888 slop_bgn_size =
889 DMA_SCSI_ALIGNMENT - (bgn % DMA_SCSI_ALIGNMENT);
890 if (slop_bgn_size == DMA_SCSI_ALIGNMENT)
891 slop_bgn_size = 0;
892 slop_end_size = end % DMA_ENDALIGNMENT;
895 /* Force a minimum slop end size. This ensures that write
896 * requests will overrun, as required to get completion
897 * interrupts.
898 * In addition, since the tail buffer is guaranteed to be mapped
899 * in a single DMA segment, the overrun won't accidentally
900 * end up in its own segment.
902 if (!esc->sc_datain) {
903 #if 0
904 slop_end_size += ESP_DMA_MAXTAIL;
905 #else
906 slop_end_size += 0x10;
907 #endif
910 /* Check to make sure we haven't counted extra slop
911 * as would happen for a very short DMA buffer, also
912 * for short buffers, just stuff the entire thing in the tail
914 if ((slop_bgn_size+slop_end_size >= esc->sc_dmasize)
915 #if 0
916 || (esc->sc_dmasize <= ESP_DMA_MAXTAIL)
917 #endif
919 slop_bgn_size = 0;
920 slop_end_size = esc->sc_dmasize;
923 /* initialize the fifo buffer */
924 if (slop_bgn_size) {
925 esc->sc_begin = *esc->sc_dmaaddr;
926 esc->sc_begin_size = slop_bgn_size;
927 } else {
928 esc->sc_begin = 0;
929 esc->sc_begin_size = 0;
932 #if 01
933 /* Load the normal DMA map */
935 esc->sc_main = *esc->sc_dmaaddr;
936 esc->sc_main += slop_bgn_size;
937 esc->sc_main_size =
938 (esc->sc_dmasize) - (slop_end_size+slop_bgn_size);
940 if (esc->sc_main_size) {
941 int error;
943 if (!esc->sc_datain ||
944 DMA_ENDALIGNED(esc->sc_main_size +
945 slop_end_size)) {
946 KASSERT(DMA_SCSI_ALIGNMENT ==
947 DMA_ENDALIGNMENT);
948 KASSERT(DMA_BEGINALIGNMENT ==
949 DMA_ENDALIGNMENT);
950 esc->sc_main_size += slop_end_size;
951 slop_end_size = 0;
952 if (!esc->sc_datain) {
953 esc->sc_main_size =
954 DMA_ENDALIGN(uint8_t *,
955 esc->sc_main +
956 esc->sc_main_size) -
957 esc->sc_main;
961 error = bus_dmamap_load(esc->sc_dma->sc_dmat,
962 esc->sc_main_dmamap,
963 esc->sc_main, esc->sc_main_size,
964 NULL, BUS_DMA_NOWAIT);
965 if (error) {
966 #ifdef ESP_DEBUG
967 printf("%s: esc->sc_main_dmamap->"
968 "_dm_size = %ld\n",
969 device_xname(sc->sc_dev),
970 esc->sc_main_dmamap->_dm_size);
971 printf("%s: esc->sc_main_dmamap->"
972 "_dm_segcnt = %d\n",
973 device_xname(sc->sc_dev),
974 esc->sc_main_dmamap->_dm_segcnt);
975 printf("%s: esc->sc_main_dmamap->"
976 "_dm_maxsegsz = %ld\n",
977 device_xname(sc->sc_dev),
978 esc->sc_main_dmamap->_dm_maxsegsz);
979 printf("%s: esc->sc_main_dmamap->"
980 "_dm_boundary = %ld\n",
981 device_xname(sc->sc_dev),
982 esc->sc_main_dmamap->_dm_boundary);
983 esp_dma_print(sc);
984 #endif
985 panic("%s: can't load main DMA map."
986 " error = %d, addr=%p, size=0x%08x",
987 device_xname(sc->sc_dev),
988 error, esc->sc_main,
989 esc->sc_main_size);
991 if (!esc->sc_datain) {
993 * patch the DMA map for write overrun
995 esc->sc_main_dmamap->dm_mapsize +=
996 ESP_DMA_OVERRUN;
997 esc->sc_main_dmamap->dm_segs[
998 esc->sc_main_dmamap->dm_nsegs -
999 1].ds_len +=
1000 ESP_DMA_OVERRUN;
1002 #if 0
1003 bus_dmamap_sync(esc->sc_dma->sc_dmat,
1004 esc->sc_main_dmamap,
1005 0, esc->sc_main_dmamap->dm_mapsize,
1006 (esc->sc_datain ? BUS_DMASYNC_PREREAD :
1007 BUS_DMASYNC_PREWRITE));
1008 esc->sc_main_dmamap->dm_xfer_len = 0;
1009 #endif
1010 } else {
1011 esc->sc_main = 0;
1015 /* Load the tail DMA map */
1016 if (slop_end_size) {
1017 esc->sc_tail = DMA_ENDALIGN(uint8_t *,
1018 esc->sc_tailbuf + slop_end_size) - slop_end_size;
1020 * If the beginning of the tail is not correctly
1021 * aligned, we have no choice but to align the start,
1022 * which might then unalign the end.
1024 esc->sc_tail = DMA_SCSI_ALIGN(uint8_t *, esc->sc_tail);
1026 * So therefore, we change the tail size to be
1027 * end aligned again.
1029 esc->sc_tail_size = DMA_ENDALIGN(uint8_t *,
1030 esc->sc_tail + slop_end_size) - esc->sc_tail;
1032 /* @@@ next DMA overrun lossage */
1033 if (!esc->sc_datain) {
1034 esc->sc_tail_size += ESP_DMA_OVERRUN;
1038 int error;
1039 error = bus_dmamap_load(esc->sc_dma->sc_dmat,
1040 esc->sc_tail_dmamap,
1041 esc->sc_tail, esc->sc_tail_size,
1042 NULL, BUS_DMA_NOWAIT);
1043 if (error) {
1044 panic("%s: can't load tail DMA map."
1045 " error = %d, addr=%p, size=0x%08x",
1046 device_xname(sc->sc_dev), error,
1047 esc->sc_tail,esc->sc_tail_size);
1049 #if 0
1050 bus_dmamap_sync(esc->sc_dma->sc_dmat,
1051 esc->sc_tail_dmamap, 0,
1052 esc->sc_tail_dmamap->dm_mapsize,
1053 (esc->sc_datain ? BUS_DMASYNC_PREREAD :
1054 BUS_DMASYNC_PREWRITE));
1055 esc->sc_tail_dmamap->dm_xfer_len = 0;
1056 #endif
1059 #else
1061 esc->sc_begin = *esc->sc_dmaaddr;
1062 slop_bgn_size = DMA_SCSI_ALIGNMENT -
1063 ((u_long)esc->sc_begin % DMA_SCSI_ALIGNMENT);
1064 if (slop_bgn_size == DMA_SCSI_ALIGNMENT)
1065 slop_bgn_size = 0;
1066 slop_end_size = esc->sc_dmasize - slop_bgn_size;
1068 if (slop_bgn_size < esc->sc_dmasize) {
1069 int error;
1071 esc->sc_tail = 0;
1072 esc->sc_tail_size = 0;
1074 esc->sc_begin_size = slop_bgn_size;
1075 esc->sc_main = *esc->sc_dmaaddr;
1076 esc->sc_main += slop_bgn_size;
1077 esc->sc_main_size = DMA_ENDALIGN(uint8_t *,
1078 esc->sc_main + esc->sc_dmasize - slop_bgn_size) -
1079 esc->sc_main;
1081 if (!esc->sc_datain) {
1082 esc->sc_main_size += ESP_DMA_OVERRUN;
1084 error = bus_dmamap_load(esc->sc_dma->sc_dmat,
1085 esc->sc_main_dmamap,
1086 esc->sc_main, esc->sc_main_size,
1087 NULL, BUS_DMA_NOWAIT);
1088 if (error) {
1089 panic("%s: can't load main DMA map."
1090 " error = %d, addr=%p, size=0x%08x",
1091 device_xname(sc->sc_dev), error,
1092 esc->sc_main,esc->sc_main_size);
1094 } else {
1095 esc->sc_begin = 0;
1096 esc->sc_begin_size = 0;
1097 esc->sc_main = 0;
1098 esc->sc_main_size = 0;
1100 #if 0
1101 esc->sc_tail = DMA_ENDALIGN(uint8_t *,
1102 esc->sc_tailbuf + slop_bgn_size) - slop_bgn_size;
1104 * If the beginning of the tail is not correctly
1105 * aligned, we have no choice but to align the start,
1106 * which might then unalign the end.
1108 #endif
1109 esc->sc_tail = DMA_SCSI_ALIGN(void *, esc->sc_tailbuf);
1111 * So therefore, we change the tail size to be
1112 * end aligned again.
1114 esc->sc_tail_size = DMA_ENDALIGN(uint8_t *,
1115 esc->sc_tail + esc->sc_dmasize) - esc->sc_tail;
1117 /* @@@ next DMA overrun lossage */
1118 if (!esc->sc_datain) {
1119 esc->sc_tail_size += ESP_DMA_OVERRUN;
1123 int error;
1124 error = bus_dmamap_load(esc->sc_dma->sc_dmat,
1125 esc->sc_tail_dmamap,
1126 esc->sc_tail, esc->sc_tail_size,
1127 NULL, BUS_DMA_NOWAIT);
1128 if (error) {
1129 panic("%s: can't load tail DMA map."
1130 " error = %d, addr=%p, size=0x%08x",
1131 device_xname(sc->sc_dev), error,
1132 esc->sc_tail, esc->sc_tail_size);
1136 #endif
1138 DPRINTF(("%s: setup: %8p %d %8p %d %8p %d %8p %d\n",
1139 device_xname(sc->sc_dev),
1140 *esc->sc_dmaaddr, esc->sc_dmasize,
1141 esc->sc_begin, esc->sc_begin_size,
1142 esc->sc_main, esc->sc_main_size,
1143 esc->sc_tail, esc->sc_tail_size));
1146 return 0;
1149 #ifdef ESP_DEBUG
1150 /* For debugging */
1151 void
1152 esp_dma_store(struct ncr53c9x_softc *sc)
1154 struct esp_softc *esc = (struct esp_softc *)sc;
1155 char *p = &esp_dma_dump[0];
1157 p += sprintf(p, "%s: sc_datain=%d\n",
1158 device_xname(sc->sc_dev), esc->sc_datain);
1159 p += sprintf(p, "%s: sc_loaded=0x%08x\n",
1160 device_xname(sc->sc_dev), esc->sc_loaded);
1162 if (esc->sc_dmaaddr) {
1163 p += sprintf(p, "%s: sc_dmaaddr=%p\n",
1164 device_xname(sc->sc_dev), *esc->sc_dmaaddr);
1165 } else {
1166 p += sprintf(p, "%s: sc_dmaaddr=NULL\n",
1167 device_xname(sc->sc_dev));
1169 if (esc->sc_dmalen) {
1170 p += sprintf(p, "%s: sc_dmalen=0x%08x\n",
1171 device_xname(sc->sc_dev), *esc->sc_dmalen);
1172 } else {
1173 p += sprintf(p, "%s: sc_dmalen=NULL\n",
1174 device_xname(sc->sc_dev));
1176 p += sprintf(p, "%s: sc_dmasize=0x%08x\n",
1177 device_xname(sc->sc_dev), esc->sc_dmasize);
1179 p += sprintf(p, "%s: sc_begin = %p, sc_begin_size = 0x%08x\n",
1180 device_xname(sc->sc_dev), esc->sc_begin, esc->sc_begin_size);
1181 p += sprintf(p, "%s: sc_main = %p, sc_main_size = 0x%08x\n",
1182 device_xname(sc->sc_dev), esc->sc_main, esc->sc_main_size);
1183 /* if (esc->sc_main) */ {
1184 int i;
1185 bus_dmamap_t map = esc->sc_main_dmamap;
1186 p += sprintf(p, "%s: sc_main_dmamap."
1187 " mapsize = 0x%08lx, nsegs = %d\n",
1188 device_xname(sc->sc_dev), map->dm_mapsize, map->dm_nsegs);
1189 for(i = 0; i < map->dm_nsegs; i++) {
1190 p += sprintf(p, "%s:"
1191 " map->dm_segs[%d].ds_addr = 0x%08lx,"
1192 " len = 0x%08lx\n",
1193 device_xname(sc->sc_dev),
1194 i, map->dm_segs[i].ds_addr,
1195 map->dm_segs[i].ds_len);
1198 p += sprintf(p, "%s: sc_tail = %p, sc_tail_size = 0x%08x\n",
1199 device_xname(sc->sc_dev), esc->sc_tail, esc->sc_tail_size);
1200 /* if (esc->sc_tail) */ {
1201 int i;
1202 bus_dmamap_t map = esc->sc_tail_dmamap;
1203 p += sprintf(p, "%s: sc_tail_dmamap."
1204 " mapsize = 0x%08lx, nsegs = %d\n",
1205 device_xname(sc->sc_dev), map->dm_mapsize, map->dm_nsegs);
1206 for (i = 0; i < map->dm_nsegs; i++) {
1207 p += sprintf(p, "%s:"
1208 " map->dm_segs[%d].ds_addr = 0x%08lx,"
1209 " len = 0x%08lx\n",
1210 device_xname(sc->sc_dev),
1211 i, map->dm_segs[i].ds_addr,
1212 map->dm_segs[i].ds_len);
1217 void
1218 esp_dma_print(struct ncr53c9x_softc *sc)
1221 esp_dma_store(sc);
1222 printf("%s", esp_dma_dump);
1224 #endif
1226 void
1227 esp_dma_go(struct ncr53c9x_softc *sc)
1229 struct esp_softc *esc = (struct esp_softc *)sc;
1230 struct nextdma_softc *nsc = esc->sc_dma;
1231 struct nextdma_status *stat = &nsc->sc_stat;
1232 /* int s = spldma(); */
1234 #ifdef ESP_DEBUG
1235 if (ndtracep != ndtrace) {
1236 if (ndtraceshow) {
1237 *ndtracep = '\0';
1238 printf("esp ndtrace: %s\n", ndtrace);
1239 ndtraceshow = 0;
1240 } else {
1241 DPRINTF(("X"));
1243 ndtracep = ndtrace;
1245 #endif
1247 DPRINTF(("%s: esp_dma_go(datain = %d)\n",
1248 device_xname(sc->sc_dev), esc->sc_datain));
1250 #ifdef ESP_DEBUG
1251 if (esp_debug)
1252 esp_dma_print(sc);
1253 else
1254 esp_dma_store(sc);
1255 #endif
1257 #ifdef ESP_DEBUG
1259 int n = NCR_READ_REG(sc, NCR_FFLAG);
1260 DPRINTF(("%s: fifo size = %d, seq = 0x%x\n",
1261 device_xname(sc->sc_dev),
1262 n & NCRFIFO_FF, (n & NCRFIFO_SS) >> 5));
1264 #endif
1266 /* zero length DMA transfers are boring */
1267 if (esc->sc_dmasize == 0) {
1268 /* splx(s); */
1269 return;
1272 #if defined(DIAGNOSTIC)
1273 if ((esc->sc_begin_size == 0) &&
1274 (esc->sc_main_dmamap->dm_mapsize == 0) &&
1275 (esc->sc_tail_dmamap->dm_mapsize == 0)) {
1276 #ifdef ESP_DEBUG
1277 esp_dma_print(sc);
1278 #endif
1279 panic("%s: No DMA requested!", device_xname(sc->sc_dev));
1281 #endif
1283 /* Stuff the fifo with the begin buffer */
1284 if (esc->sc_datain) {
1285 int i;
1286 DPRINTF(("%s: FIFO read of %d bytes:",
1287 device_xname(sc->sc_dev), esc->sc_begin_size));
1288 for (i = 0; i < esc->sc_begin_size; i++) {
1289 esc->sc_begin[i] = NCR_READ_REG(sc, NCR_FIFO);
1290 DPRINTF((" %02x", esc->sc_begin[i] & 0xff));
1292 DPRINTF(("\n"));
1293 } else {
1294 int i;
1295 DPRINTF(("%s: FIFO write of %d bytes:",
1296 device_xname(sc->sc_dev), esc->sc_begin_size));
1297 for (i = 0; i < esc->sc_begin_size; i++) {
1298 NCR_WRITE_REG(sc, NCR_FIFO, esc->sc_begin[i]);
1299 DPRINTF((" %02x",esc->sc_begin[i] & 0xff));
1301 DPRINTF(("\n"));
1304 if (esc->sc_main_dmamap->dm_mapsize) {
1305 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_main_dmamap,
1306 0, esc->sc_main_dmamap->dm_mapsize,
1307 (esc->sc_datain ?
1308 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
1309 esc->sc_main_dmamap->dm_xfer_len = 0;
1312 if (esc->sc_tail_dmamap->dm_mapsize) {
1313 /* if we are a DMA write cycle, copy the end slop */
1314 if (!esc->sc_datain) {
1315 memcpy(esc->sc_tail, *esc->sc_dmaaddr +
1316 esc->sc_begin_size+esc->sc_main_size,
1317 esc->sc_dmasize -
1318 (esc->sc_begin_size + esc->sc_main_size));
1320 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap,
1321 0, esc->sc_tail_dmamap->dm_mapsize,
1322 (esc->sc_datain ?
1323 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
1324 esc->sc_tail_dmamap->dm_xfer_len = 0;
1327 stat->nd_exception = 0;
1328 nextdma_start(nsc, (esc->sc_datain ? DMACSR_SETREAD : DMACSR_SETWRITE));
1330 if (esc->sc_datain) {
1331 NCR_WRITE_REG(sc, ESP_DCTL,
1332 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD |
1333 ESPDCTL_DMARD);
1334 } else {
1335 NCR_WRITE_REG(sc, ESP_DCTL,
1336 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD);
1338 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
1340 NDTRACEIF(
1341 if (esc->sc_begin_size) {
1342 *ndtracep++ = '1';
1343 *ndtracep++ = 'A' + esc->sc_begin_size;
1346 NDTRACEIF(
1347 if (esc->sc_main_size) {
1348 *ndtracep++ = '2';
1349 *ndtracep++ = '0' + esc->sc_main_dmamap->dm_nsegs;
1352 NDTRACEIF(
1353 if (esc->sc_tail_size) {
1354 *ndtracep++ = '3';
1355 *ndtracep++ = 'A' + esc->sc_tail_size;
1359 /* splx(s); */
1362 void
1363 esp_dma_stop(struct ncr53c9x_softc *sc)
1365 struct esp_softc *esc = (struct esp_softc *)sc;
1367 nextdma_print(esc->sc_dma);
1368 #ifdef ESP_DEBUG
1369 esp_dma_print(sc);
1370 #endif
1371 #if 1
1372 panic("%s: stop not yet implemented", device_xname(sc->sc_dev));
1373 #endif
1377 esp_dma_isactive(struct ncr53c9x_softc *sc)
1379 struct esp_softc *esc = (struct esp_softc *)sc;
1380 int r;
1382 r = (esc->sc_dmaaddr != NULL); /* !nextdma_finished(esc->sc_dma); */
1383 DPRINTF(("esp_dma_isactive = %d\n",r));
1384 return r;
1387 /****************************************************************/
1389 int esp_dma_int(void *);
1390 int esp_dma_int(void *arg)
1392 void nextdma_rotate(struct nextdma_softc *);
1393 void nextdma_setup_curr_regs(struct nextdma_softc *);
1394 void nextdma_setup_cont_regs(struct nextdma_softc *);
1396 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
1397 struct esp_softc *esc = (struct esp_softc *)sc;
1398 struct nextdma_softc *nsc = esc->sc_dma;
1399 struct nextdma_status *stat = &nsc->sc_stat;
1400 unsigned int state;
1402 NDTRACEIF (*ndtracep++ = 'E');
1404 state = nd_bsr4 (DD_CSR);
1406 #if 1
1407 NDTRACEIF (
1408 if (state & DMACSR_COMPLETE)
1409 *ndtracep++ = 'c';
1410 if (state & DMACSR_ENABLE)
1411 *ndtracep++ = 'e';
1412 if (state & DMACSR_BUSEXC)
1413 *ndtracep++ = 'b';
1414 if (state & DMACSR_READ)
1415 *ndtracep++ = 'r';
1416 if (state & DMACSR_SUPDATE)
1417 *ndtracep++ = 's';
1420 NDTRACEIF (*ndtracep++ = 'E');
1422 #ifdef ESP_DEBUG
1423 if (0)
1424 if ((state & DMACSR_BUSEXC) && (state & DMACSR_ENABLE))
1425 ndtraceshow++;
1426 if (0)
1427 if ((state & DMACSR_SUPDATE))
1428 ndtraceshow++;
1429 #endif
1430 #endif
1432 if ((stat->nd_exception == 0) &&
1433 (state & DMACSR_COMPLETE) &&
1434 (state & DMACSR_ENABLE)) {
1435 stat->nd_map->dm_xfer_len +=
1436 stat->nd_map->dm_segs[stat->nd_idx].ds_len;
1439 if ((stat->nd_idx + 1) == stat->nd_map->dm_nsegs) {
1440 if (nsc->sc_conf.nd_completed_cb)
1441 (*nsc->sc_conf.nd_completed_cb)(stat->nd_map,
1442 nsc->sc_conf.nd_cb_arg);
1444 nextdma_rotate(nsc);
1446 if ((state & DMACSR_COMPLETE) && (state & DMACSR_ENABLE)) {
1447 #if 0
1448 int l = nd_bsr4 (DD_LIMIT) & 0x7FFFFFFF;
1449 int s = nd_bsr4 (DD_STOP);
1450 #endif
1451 /* nextdma_setup_cont_regs(nsc); */
1452 if (stat->nd_map_cont) {
1453 nd_bsw4(DD_START, stat->nd_map_cont->dm_segs[
1454 stat->nd_idx_cont].ds_addr);
1455 nd_bsw4(DD_STOP, (stat->nd_map_cont->dm_segs[
1456 stat->nd_idx_cont].ds_addr +
1457 stat->nd_map_cont->dm_segs[
1458 stat->nd_idx_cont].ds_len));
1461 nd_bsw4 (DD_CSR, DMACSR_CLRCOMPLETE |
1462 (state & DMACSR_READ ? DMACSR_SETREAD : DMACSR_SETWRITE) |
1463 (stat->nd_map_cont ? DMACSR_SETSUPDATE : 0));
1465 #if 0
1466 #ifdef ESP_DEBUG
1467 if (state & DMACSR_BUSEXC) {
1468 sprintf(ndtracep, "CE/BUSEXC: %08lX %08X %08X\n",
1469 (stat->nd_map->dm_segs[stat->nd_idx].ds_addr +
1470 stat->nd_map->dm_segs[stat->nd_idx].ds_len),
1471 l, s);
1472 ndtracep += strlen(ndtracep);
1474 #endif
1475 #endif
1476 } else {
1477 #if 0
1478 if (state & DMACSR_BUSEXC) {
1479 while (nd_bsr4(DD_NEXT) !=
1480 (nd_bsr4(DD_LIMIT) & 0x7FFFFFFF))
1481 printf("Y"); /* DELAY(50); */
1482 state = nd_bsr4(DD_CSR);
1484 #endif
1486 if (!(state & DMACSR_SUPDATE)) {
1487 nextdma_rotate(nsc);
1488 } else {
1489 nd_bsw4(DD_CSR, DMACSR_CLRCOMPLETE |
1490 DMACSR_INITBUF | DMACSR_RESET |
1491 (state & DMACSR_READ ?
1492 DMACSR_SETREAD : DMACSR_SETWRITE));
1494 nd_bsw4(DD_NEXT,
1495 stat->nd_map->dm_segs[stat->nd_idx].ds_addr);
1496 nd_bsw4(DD_LIMIT,
1497 (stat->nd_map->dm_segs[stat->nd_idx].ds_addr +
1498 stat->nd_map->dm_segs[stat->nd_idx].ds_len) |
1499 0/* x80000000 */);
1500 if (stat->nd_map_cont) {
1501 nd_bsw4(DD_START,
1502 stat->nd_map_cont->dm_segs[
1503 stat->nd_idx_cont].ds_addr);
1504 nd_bsw4(DD_STOP,
1505 (stat->nd_map_cont->dm_segs[
1506 stat->nd_idx_cont].ds_addr +
1507 stat->nd_map_cont->dm_segs[
1508 stat->nd_idx_cont].ds_len) |
1509 0/* x80000000 */);
1511 nd_bsw4(DD_CSR, DMACSR_SETENABLE | DMACSR_CLRCOMPLETE |
1512 (state & DMACSR_READ ?
1513 DMACSR_SETREAD : DMACSR_SETWRITE) |
1514 (stat->nd_map_cont ? DMACSR_SETSUPDATE : 0));
1515 #if 1
1516 #ifdef ESP_DEBUG
1517 sprintf(ndtracep, "supdate ");
1518 ndtracep += strlen(ndtracep);
1519 sprintf(ndtracep, "%08X %08X %08X %08X ",
1520 nd_bsr4(DD_NEXT),
1521 nd_bsr4(DD_LIMIT) & 0x7FFFFFFF,
1522 nd_bsr4 (DD_START),
1523 nd_bsr4 (DD_STOP) & 0x7FFFFFFF);
1524 ndtracep += strlen(ndtracep);
1525 #endif
1526 #endif
1527 stat->nd_exception++;
1528 return 1;
1529 /* NCR_WRITE_REG(sc, ESP_DCTL, ctl); */
1530 goto restart;
1533 if (stat->nd_map) {
1534 #if 1
1535 #ifdef ESP_DEBUG
1536 sprintf(ndtracep, "%08X %08X %08X %08X ",
1537 nd_bsr4 (DD_NEXT),
1538 nd_bsr4 (DD_LIMIT) & 0x7FFFFFFF,
1539 nd_bsr4 (DD_START),
1540 nd_bsr4 (DD_STOP) & 0x7FFFFFFF);
1541 ndtracep += strlen(ndtracep);
1542 #endif
1543 #endif
1545 #if 0
1546 nd_bsw4(DD_CSR, DMACSR_CLRCOMPLETE | DMACSR_RESET);
1548 nd_bsw4(DD_CSR, 0);
1549 #endif
1550 #if 1
1551 /* 6/2 */
1552 nd_bsw4(DD_CSR, DMACSR_CLRCOMPLETE |
1553 DMACSR_INITBUF | DMACSR_RESET |
1554 (state & DMACSR_READ ?
1555 DMACSR_SETREAD : DMACSR_SETWRITE));
1557 /* nextdma_setup_curr_regs(nsc); */
1558 nd_bsw4(DD_NEXT,
1559 stat->nd_map->dm_segs[stat->nd_idx].ds_addr);
1560 nd_bsw4(DD_LIMIT,
1561 (stat->nd_map->dm_segs[stat->nd_idx].ds_addr +
1562 stat->nd_map->dm_segs[stat->nd_idx].ds_len) |
1563 0/* x80000000 */);
1564 /* nextdma_setup_cont_regs(nsc); */
1565 if (stat->nd_map_cont) {
1566 nd_bsw4(DD_START,
1567 stat->nd_map_cont->dm_segs[
1568 stat->nd_idx_cont].ds_addr);
1569 nd_bsw4(DD_STOP,
1570 (stat->nd_map_cont->dm_segs[
1571 stat->nd_idx_cont].ds_addr +
1572 stat->nd_map_cont->dm_segs[
1573 stat->nd_idx_cont].ds_len) |
1574 0/* x80000000 */);
1577 nd_bsw4(DD_CSR, DMACSR_SETENABLE |
1578 (stat->nd_map_cont ? DMACSR_SETSUPDATE : 0) |
1579 (state & DMACSR_READ ?
1580 DMACSR_SETREAD : DMACSR_SETWRITE));
1581 #ifdef ESP_DEBUG
1582 /* ndtraceshow++; */
1583 #endif
1584 stat->nd_exception++;
1585 return 1;
1586 #endif
1587 /* NCR_WRITE_REG(sc, ESP_DCTL, ctl); */
1588 goto restart;
1589 restart:
1590 #if 1
1591 #ifdef ESP_DEBUG
1592 sprintf(ndtracep, "restart %08lX %08lX\n",
1593 stat->nd_map->dm_segs[stat->nd_idx].ds_addr,
1594 stat->nd_map->dm_segs[stat->nd_idx].ds_addr +
1595 stat->nd_map->dm_segs[stat->nd_idx].ds_len);
1596 if (stat->nd_map_cont) {
1597 sprintf(ndtracep + strlen(ndtracep) - 1,
1598 " %08lX %08lX\n",
1599 stat->nd_map_cont->dm_segs[
1600 stat->nd_idx_cont].ds_addr,
1601 stat->nd_map_cont->dm_segs[
1602 stat->nd_idx_cont].ds_addr +
1603 stat->nd_map_cont->dm_segs[
1604 stat->nd_idx_cont].ds_len);
1606 ndtracep += strlen(ndtracep);
1607 #endif
1608 #endif
1609 nextdma_print(nsc);
1610 NCR_WRITE_REG(sc, ESP_DCTL,
1611 ESPDCTL_16MHZ | ESPDCTL_INTENB);
1612 printf("ff:%02x tcm:%d tcl:%d esp_dstat:%02x"
1613 " state:%02x step: %02x intr:%02x state:%08X\n",
1614 NCR_READ_REG(sc, NCR_FFLAG),
1615 NCR_READ_REG((sc), NCR_TCM),
1616 NCR_READ_REG((sc), NCR_TCL),
1617 NCR_READ_REG(sc, ESP_DSTAT),
1618 NCR_READ_REG(sc, NCR_STAT),
1619 NCR_READ_REG(sc, NCR_STEP),
1620 NCR_READ_REG(sc, NCR_INTR), state);
1621 #ifdef ESP_DEBUG
1622 *ndtracep = '\0';
1623 printf("ndtrace: %s\n", ndtrace);
1624 #endif
1625 panic("%s: busexc/supdate occurred."
1626 " Please email this output to chris@pin.lu.",
1627 device_xname(sc->sc_dev));
1628 #ifdef ESP_DEBUG
1629 ndtraceshow++;
1630 #endif
1631 } else {
1632 nd_bsw4(DD_CSR, DMACSR_CLRCOMPLETE | DMACSR_RESET);
1633 if (nsc->sc_conf.nd_shutdown_cb)
1634 (*nsc->sc_conf.nd_shutdown_cb)(nsc->sc_conf.nd_cb_arg);
1637 return 1;
1640 /* Internal DMA callback routines */
1641 bus_dmamap_t
1642 esp_dmacb_continue(void *arg)
1644 struct ncr53c9x_softc *sc = arg;
1645 struct esp_softc *esc = (struct esp_softc *)sc;
1647 NDTRACEIF (*ndtracep++ = 'x');
1648 DPRINTF(("%s: DMA continue\n",sc->sc_dev.dv_xname));
1650 #ifdef DIAGNOSTIC
1651 if ((esc->sc_datain < 0) || (esc->sc_datain > 1)) {
1652 panic("%s: map not loaded in DMA continue callback,"
1653 " datain = %d",
1654 device_xname(sc->sc_dev), esc->sc_datain);
1656 #endif
1658 if (((esc->sc_loaded & ESP_LOADED_MAIN) == 0) &&
1659 (esc->sc_main_dmamap->dm_mapsize)) {
1660 DPRINTF(("%s: Loading main map\n", device_xname(sc->sc_dev)));
1661 #if 0
1662 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_main_dmamap,
1663 0, esc->sc_main_dmamap->dm_mapsize,
1664 (esc->sc_datain ?
1665 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
1666 esc->sc_main_dmamap->dm_xfer_len = 0;
1667 #endif
1668 esc->sc_loaded |= ESP_LOADED_MAIN;
1669 return esc->sc_main_dmamap;
1672 if (((esc->sc_loaded & ESP_LOADED_TAIL) == 0) &&
1673 (esc->sc_tail_dmamap->dm_mapsize)) {
1674 DPRINTF(("%s: Loading tail map\n", device_xname(sc->sc_dev)));
1675 #if 0
1676 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap,
1677 0, esc->sc_tail_dmamap->dm_mapsize,
1678 (esc->sc_datain ?
1679 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
1680 esc->sc_tail_dmamap->dm_xfer_len = 0;
1681 #endif
1682 esc->sc_loaded |= ESP_LOADED_TAIL;
1683 return esc->sc_tail_dmamap;
1686 DPRINTF(("%s: not loading map\n", device_xname(sc->sc_dev)));
1687 return 0;
1691 void
1692 esp_dmacb_completed(bus_dmamap_t map, void *arg)
1694 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
1695 struct esp_softc *esc = (struct esp_softc *)sc;
1697 NDTRACEIF (*ndtracep++ = 'X');
1698 DPRINTF(("%s: DMA completed\n", device_xname(sc->sc_dev)));
1700 #ifdef DIAGNOSTIC
1701 if ((esc->sc_datain < 0) || (esc->sc_datain > 1)) {
1702 panic("%s: invalid DMA direction in completed callback,"
1703 " datain = %d",
1704 device_xname(sc->sc_dev), esc->sc_datain);
1706 #endif
1708 #if defined(DIAGNOSTIC) && 0
1710 int i;
1711 for(i = 0; i < map->dm_nsegs; i++) {
1712 if (map->dm_xfer_len != map->dm_mapsize) {
1713 printf("%s: map->dm_mapsize = %d\n",
1714 device_xname(sc->sc_dev), map->dm_mapsize);
1715 printf("%s: map->dm_nsegs = %d\n",
1716 device_xname(sc->sc_dev), map->dm_nsegs);
1717 printf("%s: map->dm_xfer_len = %d\n",
1718 device_xname(sc->sc_dev), map->dm_xfer_len);
1719 for(i = 0; i < map->dm_nsegs; i++) {
1720 printf("%s: map->dm_segs[%d].ds_addr ="
1721 " 0x%08lx\n",
1722 device_xname(sc->sc_dev), i,
1723 map->dm_segs[i].ds_addr);
1724 printf("%s: map->dm_segs[%d].ds_len ="
1725 " %d\n",
1726 device_xname(sc->sc_dev), i,
1727 map->dm_segs[i].ds_len);
1729 panic("%s: incomplete DMA transfer",
1730 device_xname(sc->sc_dev));
1734 #endif
1736 if (map == esc->sc_main_dmamap) {
1737 #ifdef DIAGNOSTIC
1738 if ((esc->sc_loaded & ESP_UNLOADED_MAIN) ||
1739 (esc->sc_loaded & ESP_LOADED_MAIN) == 0) {
1740 panic("%s: unexpected completed call for main map",
1741 device_xname(sc->sc_dev));
1743 #endif
1744 esc->sc_loaded |= ESP_UNLOADED_MAIN;
1745 } else if (map == esc->sc_tail_dmamap) {
1746 #ifdef DIAGNOSTIC
1747 if ((esc->sc_loaded & ESP_UNLOADED_TAIL) ||
1748 (esc->sc_loaded & ESP_LOADED_TAIL) == 0) {
1749 panic("%s: unexpected completed call for tail map",
1750 device_xname(sc->sc_dev));
1752 #endif
1753 esc->sc_loaded |= ESP_UNLOADED_TAIL;
1755 #ifdef DIAGNOSTIC
1756 else {
1757 panic("%s: unexpected completed map", device_xname(sc->sc_dev));
1759 #endif
1761 #ifdef ESP_DEBUG
1762 if (esp_debug) {
1763 if (map == esc->sc_main_dmamap) {
1764 printf("%s: completed main map\n",
1765 device_xname(sc->sc_dev));
1766 } else if (map == esc->sc_tail_dmamap) {
1767 printf("%s: completed tail map\n",
1768 device_xname(sc->sc_dev));
1771 #endif
1773 #if 0
1774 if ((map == esc->sc_tail_dmamap) ||
1775 ((esc->sc_tail_size == 0) && (map == esc->sc_main_dmamap))) {
1778 * Clear the DMAMOD bit in the DCTL register to give control
1779 * back to the scsi chip.
1781 if (esc->sc_datain) {
1782 NCR_WRITE_REG(sc, ESP_DCTL,
1783 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
1784 } else {
1785 NCR_WRITE_REG(sc, ESP_DCTL,
1786 ESPDCTL_16MHZ | ESPDCTL_INTENB);
1788 DPRINTF(("esp dctl is 0x%02x\n", NCR_READ_REG(sc, ESP_DCTL)));
1790 #endif
1793 #if 0
1794 bus_dmamap_sync(esc->sc_dma->sc_dmat, map,
1795 0, map->dm_mapsize,
1796 (esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
1797 #endif
1801 void
1802 esp_dmacb_shutdown(void *arg)
1804 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
1805 struct esp_softc *esc = (struct esp_softc *)sc;
1807 NDTRACEIF (*ndtracep++ = 'S');
1808 DPRINTF(("%s: DMA shutdown\n", device_xname(sc->sc_dev)));
1810 if (esc->sc_loaded == 0)
1811 return;
1813 #if 0
1815 /* Clear the DMAMOD bit in the DCTL register to give control
1816 * back to the scsi chip.
1818 if (esc->sc_datain) {
1819 NCR_WRITE_REG(sc, ESP_DCTL,
1820 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
1821 } else {
1822 NCR_WRITE_REG(sc, ESP_DCTL,
1823 ESPDCTL_16MHZ | ESPDCTL_INTENB);
1825 DPRINTF(("esp dctl is 0x%02x\n", NCR_READ_REG(sc, ESP_DCTL)));
1827 #endif
1829 DPRINTF(("%s: esp_dma_nest == %d\n",
1830 device_xname(sc->sc_dev), esp_dma_nest));
1832 /* Stuff the end slop into fifo */
1834 #ifdef ESP_DEBUG
1835 if (esp_debug) {
1836 int n = NCR_READ_REG(sc, NCR_FFLAG);
1838 DPRINTF(("%s: fifo size = %d, seq = 0x%x\n",
1839 device_xname(sc->sc_dev), n & NCRFIFO_FF,
1840 (n & NCRFIFO_SS) >> 5));
1842 #endif
1844 if (esc->sc_main_dmamap->dm_mapsize) {
1845 if (!esc->sc_datain) {
1846 /* unpatch the DMA map for write overrun */
1847 esc->sc_main_dmamap->dm_mapsize -= ESP_DMA_OVERRUN;
1848 esc->sc_main_dmamap->dm_segs[
1849 esc->sc_main_dmamap->dm_nsegs - 1].ds_len -=
1850 ESP_DMA_OVERRUN;
1852 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_main_dmamap,
1853 0, esc->sc_main_dmamap->dm_mapsize,
1854 (esc->sc_datain ?
1855 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
1856 bus_dmamap_unload(esc->sc_dma->sc_dmat, esc->sc_main_dmamap);
1857 NDTRACEIF (
1858 sprintf(ndtracep, "m%ld",
1859 esc->sc_main_dmamap->dm_xfer_len);
1860 ndtracep += strlen(ndtracep);
1864 if (esc->sc_tail_dmamap->dm_mapsize) {
1865 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap,
1866 0, esc->sc_tail_dmamap->dm_mapsize,
1867 (esc->sc_datain ?
1868 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
1869 bus_dmamap_unload(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap);
1870 /* copy the tail DMA buffer data for read transfers */
1871 if (esc->sc_datain) {
1872 memcpy(*esc->sc_dmaaddr + esc->sc_begin_size +
1873 esc->sc_main_size, esc->sc_tail,
1874 esc->sc_dmasize -
1875 (esc->sc_begin_size + esc->sc_main_size));
1877 NDTRACEIF (
1878 sprintf(ndtracep, "t%ld",
1879 esc->sc_tail_dmamap->dm_xfer_len);
1880 ndtracep += strlen(ndtracep);
1884 #ifdef ESP_DEBUG
1885 if (esp_debug) {
1886 printf("%s: dma_shutdown: addr=%p,len=0x%08x,size=0x%08x\n",
1887 device_xname(sc->sc_dev),
1888 *esc->sc_dmaaddr, *esc->sc_dmalen, esc->sc_dmasize);
1889 if (esp_debug > 10) {
1890 esp_hex_dump(*(esc->sc_dmaaddr), esc->sc_dmasize);
1891 printf("%s: tail=%p,tailbuf=%p,tail_size=0x%08x\n",
1892 device_xname(sc->sc_dev),
1893 esc->sc_tail, &(esc->sc_tailbuf[0]),
1894 esc->sc_tail_size);
1895 esp_hex_dump(&(esc->sc_tailbuf[0]),
1896 sizeof(esc->sc_tailbuf));
1899 #endif
1901 esc->sc_main = 0;
1902 esc->sc_main_size = 0;
1903 esc->sc_tail = 0;
1904 esc->sc_tail_size = 0;
1906 esc->sc_datain = -1;
1907 /* esc->sc_dmaaddr = 0; */
1908 /* esc->sc_dmalen = 0; */
1909 /* esc->sc_dmasize = 0; */
1911 esc->sc_loaded = 0;
1913 esc->sc_begin = 0;
1914 esc->sc_begin_size = 0;
1916 #ifdef ESP_DEBUG
1917 if (esp_debug) {
1918 char sbuf[256];
1920 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS,
1921 (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)));
1922 printf(" *intrstat = 0x%s\n", sbuf);
1924 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS,
1925 (*(volatile u_long *)IIOV(NEXT_P_INTRMASK)));
1926 printf(" *intrmask = 0x%s\n", sbuf);
1928 #endif