1 /* $NetBSD: esp.c,v 1.58 2009/09/02 10:34:05 tsutsui Exp $ */
4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
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
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
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>
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>
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)
129 #define PRINTF(x) printf x;
132 int espmatch_intio(device_t
, cfdata_t
, void *);
133 void espattach_intio(device_t
, device_t
, void *);
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
*);
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;
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,
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
= {
181 NULL
, /* gl_clear_latched_intr */
185 #define XCHR(x) hexdigits[(x) & 0xf]
187 esp_hex_dump(unsigned char *pkt
, size_t len
)
192 for(i
= 0; i
< len
; i
++) {
193 printf("%c%c ", XCHR(pkt
[i
]>>4), XCHR(pkt
[i
]));
194 if ((i
+ 1) % 16 == 8) {
197 if ((i
+ 1) % 16 == 0) {
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));
212 espmatch_intio(device_t parent
, cfdata_t cf
, void *aux
)
214 struct intio_attach_args
*ia
= aux
;
219 ia
->ia_addr
= (void *)NEXT_P_SCSI
;
225 findchannel_defer(struct device
*self
)
227 struct esp_softc
*esc
= device_private(self
);
228 struct ncr53c9x_softc
*sc
= &esc
->sc_ncr53c9x
;
232 aprint_normal("%s", device_xname(sc
->sc_dev
));
233 esc
->sc_dma
= nextdma_findchannel("scsi");
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
,
246 sc
->sc_maxxfer
/ PAGE_SIZE
+ 1,
248 0, BUS_DMA_ALLOCNOW
, &esc
->sc_main_dmamap
);
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
);
258 panic("%s: can't create tail i/o DMA map, error = %d",
259 device_xname(sc
->sc_dev
), error
);
263 /* Turn on target selection using the `DMA' method */
264 sc
->sc_features
|= NCR_F_DMASELECT
;
267 /* Do the common parts of attachment. */
268 sc
->sc_adapter
.adapt_minphys
= minphys
;
269 sc
->sc_adapter
.adapt_request
= ncr53c9x_scsipi_request
;
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
));
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
;
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
)) {
301 panic("%s: can't map ncr53c90 registers",
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
;
333 sc
->sc_cfg2
= NCRCFG2_SCSI2
;
334 NCR_WRITE_REG(sc
, NCR_CFG2
, sc
->sc_cfg2
);
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
;
343 /* NCRCFG2_FE enables > 64K transfers */
344 sc
->sc_cfg2
|= NCRCFG2_FE
;
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? */
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;
385 case NCR_VARIANT_ESP200
:
386 sc
->sc_maxxfer
= 16 * 1024 * 1024;
387 /* XXX - do actually set FAST* bits */
391 /* @@@ Some ESP_DCTL bits probably need setting */
392 NCR_WRITE_REG(sc
, ESP_DCTL
,
393 ESPDCTL_16MHZ
| ESPDCTL_INTENB
| ESPDCTL_RESET
);
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
);
398 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc
,ESP_DCTL
)));
400 esc
->sc_dma
= nextdma_findchannel ("scsi");
402 findchannel_defer(self
);
405 config_defer(self
, findchannel_defer
);
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
);
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);
438 /* static int tmp1; */
440 volatile uint8_t tmp2
;
441 volatile uint8_t *reg
= (volatile uint8_t *)IIOV(xADDR
);
447 /* ((*(volatile u_long *)IIOV(NEXT_P_INTRMASK))&=(~NEXT_I_BIT(x))) */
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));
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
));
490 NDTRACEIF (*ndtracep
++ = 'I');
492 /* printf ("esp_dma_isintr start\n"); */
495 void *ndmap
= stat
->nd_map
;
496 int ndidx
= stat
->nd_idx
;
502 /* esp_dma_nest++; */
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
);
514 while (!nextdma_finished(nsc
)) {
515 /* esp_dma_isactive(sc)) { */
516 NDTRACEIF (*ndtracep
++ = 'w');
518 sprintf(ndtracep
, "f%dm%dl%dw",
519 NCR_READ_REG(sc
, NCR_FFLAG
) &
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
)
527 NCR_WRITE_REG(sc
, ESP_DCTL
,
528 ESPDCTL_16MHZ
| ESPDCTL_INTENB
|
530 (esc
->sc_datain
? ESPDCTL_DMARD
: 0));
533 while (ndmap
== stat
->nd_map
&&
534 ndidx
== stat
->nd_idx
&&
535 (nd_bsr4 (DD_CSR
) & 0x08000000) == 0&&
538 NDTRACEIF (*ndtracep
++ = 'F');
539 NCR_WRITE_REG(sc
, ESP_DCTL
,
540 ESPDCTL_FLUSH
| ESPDCTL_16MHZ
|
541 ESPDCTL_INTENB
| ESPDCTL_DMAMOD
|
545 NCR_WRITE_REG(sc
, ESP_DCTL
,
546 ESPDCTL_16MHZ
| ESPDCTL_INTENB
|
553 NDTRACEIF (*ndtracep
++ = '0' + flushcount
);
554 if (flushcount
> 4) {
559 DPRINTF(("DMA reset\n"));
560 while (((next
= nd_bsr4 (DD_NEXT
)) !=
561 (nd_bsr4(DD_LIMIT
) & 0x7FFFFFFF)) &&
566 NDTRACEIF (*ndtracep
++ = 'R');
567 NCR_WRITE_REG(sc
, ESP_DCTL
,
568 ESPDCTL_16MHZ
| ESPDCTL_INTENB
);
571 "ff:%d tcm:%d tcl:%d ",
572 NCR_READ_REG(sc
, NCR_FFLAG
)
574 NCR_READ_REG((sc
), NCR_TCM
),
577 ndtracep
+= strlen (ndtracep
);
587 if (flushcount
> 4) {
588 NDTRACEIF (*ndtracep
++ = '+');
589 printf("%s: unexpected flushcount"
591 device_xname(sc
->sc_dev
),
593 esc
->sc_datain
? "read" : "write");
597 if (!nextdma_finished(nsc
)) {
598 /* esp_dma_isactive(sc)) { */
599 NDTRACEIF (*ndtracep
++ = '1');
603 ndmap
= stat
->nd_map
;
604 ndidx
= stat
->nd_idx
;
612 /* esp_dma_nest--; */
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)
626 if (esc
->sc_dmaaddr
) {
627 bus_size_t xfer_len
= 0;
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);
636 resid
+= (NCR_READ_REG(sc
, NCR_FFLAG
) &
639 if (NCR_READ_REG(sc
, NCR_FFLAG
) &
641 if ((NCR_READ_REG(sc
,
642 NCR_FFLAG
) & NCRFIFO_FF
) !=
649 xfer_len
= esc
->sc_dmasize
- resid
;
651 #define ncr53c9x_sched_msgout(m) \
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); \
662 xfer_len
+= esc
->sc_begin_size
;
663 if (esc
->sc_main_dmamap
)
665 esc
->sc_main_dmamap
->dm_xfer_len
;
666 if (esc
->sc_tail_dmamap
)
668 esc
->sc_tail_dmamap
->dm_xfer_len
;
671 for (i
= 0; i
< 16; i
++) {
672 NCR_WRITE_REG(sc
, ESP_DCTL
,
673 ESPDCTL_FLUSH
| ESPDCTL_16MHZ
|
677 NCR_WRITE_REG(sc
, ESP_DCTL
,
678 ESPDCTL_16MHZ
| ESPDCTL_INTENB
|
683 printf ("ff:%02x tcm:%d tcl:%d esp_dstat:%02x"
684 " stat:%02x step: %02x intr:%02x"
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
,
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
);
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",
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
;
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"); */
740 esp_dma_reset(struct ncr53c9x_softc
*sc
)
742 struct esp_softc
*esc
= (struct esp_softc
*)sc
;
744 DPRINTF(("esp DMA reset\n"));
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
);
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
)));
766 nextdma_reset(esc
->sc_dma
);
767 nextdma_init(esc
->sc_dma
);
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
);
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
);
789 esc
->sc_tail_size
= 0;
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');
809 /* if this is a read DMA, pre-fill the buffer with 0xdeadbeef
810 * to identify bogus reads
813 int *v
= (int *)(*addr
);
815 for (i
= 0; i
< ((*len
) / 4); i
++)
817 v
= (int *)(&(esc
->sc_tailbuf
[0]));
818 for (i
= 0; i
< ((sizeof(esc
->sc_tailbuf
) / 4)); i
++)
823 v
= (int *)(&(esc
->sc_tailbuf
[0]));
824 for (i
= 0; i
< ((sizeof(esc
->sc_tailbuf
) / 4)); i
++)
830 DPRINTF(("esp_dma_setup(%p,0x%08x,0x%08x)\n", *addr
, *len
, *dmasize
));
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
);
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
,
857 /* we are sometimes asked to DMA zero bytes, that's easy */
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
;
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
;
889 DMA_SCSI_ALIGNMENT
- (bgn
% DMA_SCSI_ALIGNMENT
);
890 if (slop_bgn_size
== DMA_SCSI_ALIGNMENT
)
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
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
) {
904 slop_end_size
+= ESP_DMA_MAXTAIL
;
906 slop_end_size
+= 0x10;
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
)
916 || (esc
->sc_dmasize
<= ESP_DMA_MAXTAIL
)
920 slop_end_size
= esc
->sc_dmasize
;
923 /* initialize the fifo buffer */
925 esc
->sc_begin
= *esc
->sc_dmaaddr
;
926 esc
->sc_begin_size
= slop_bgn_size
;
929 esc
->sc_begin_size
= 0;
933 /* Load the normal DMA map */
935 esc
->sc_main
= *esc
->sc_dmaaddr
;
936 esc
->sc_main
+= slop_bgn_size
;
938 (esc
->sc_dmasize
) - (slop_end_size
+slop_bgn_size
);
940 if (esc
->sc_main_size
) {
943 if (!esc
->sc_datain
||
944 DMA_ENDALIGNED(esc
->sc_main_size
+
946 KASSERT(DMA_SCSI_ALIGNMENT
==
948 KASSERT(DMA_BEGINALIGNMENT
==
950 esc
->sc_main_size
+= slop_end_size
;
952 if (!esc
->sc_datain
) {
954 DMA_ENDALIGN(uint8_t *,
961 error
= bus_dmamap_load(esc
->sc_dma
->sc_dmat
,
963 esc
->sc_main
, esc
->sc_main_size
,
964 NULL
, BUS_DMA_NOWAIT
);
967 printf("%s: esc->sc_main_dmamap->"
969 device_xname(sc
->sc_dev
),
970 esc
->sc_main_dmamap
->_dm_size
);
971 printf("%s: esc->sc_main_dmamap->"
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
);
985 panic("%s: can't load main DMA map."
986 " error = %d, addr=%p, size=0x%08x",
987 device_xname(sc
->sc_dev
),
991 if (!esc
->sc_datain
) {
993 * patch the DMA map for write overrun
995 esc
->sc_main_dmamap
->dm_mapsize
+=
997 esc
->sc_main_dmamap
->dm_segs
[
998 esc
->sc_main_dmamap
->dm_nsegs
-
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;
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
;
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
);
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
);
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;
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
)
1066 slop_end_size
= esc
->sc_dmasize
- slop_bgn_size
;
1068 if (slop_bgn_size
< esc
->sc_dmasize
) {
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
) -
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
);
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
);
1096 esc
->sc_begin_size
= 0;
1098 esc
->sc_main_size
= 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.
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
;
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
);
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
);
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
));
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
);
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
);
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) */ {
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,"
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) */ {
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,"
1210 device_xname(sc
->sc_dev
),
1211 i
, map
->dm_segs
[i
].ds_addr
,
1212 map
->dm_segs
[i
].ds_len
);
1218 esp_dma_print(struct ncr53c9x_softc
*sc
)
1222 printf("%s", esp_dma_dump
);
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(); */
1235 if (ndtracep
!= ndtrace
) {
1238 printf("esp ndtrace: %s\n", ndtrace
);
1247 DPRINTF(("%s: esp_dma_go(datain = %d)\n",
1248 device_xname(sc
->sc_dev
), esc
->sc_datain
));
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));
1266 /* zero length DMA transfers are boring */
1267 if (esc
->sc_dmasize
== 0) {
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)) {
1279 panic("%s: No DMA requested!", device_xname(sc
->sc_dev
));
1283 /* Stuff the fifo with the begin buffer */
1284 if (esc
->sc_datain
) {
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));
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));
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
,
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
,
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
,
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
|
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
)));
1341 if (esc
->sc_begin_size
) {
1343 *ndtracep
++ = 'A' + esc
->sc_begin_size
;
1347 if (esc
->sc_main_size
) {
1349 *ndtracep
++ = '0' + esc
->sc_main_dmamap
->dm_nsegs
;
1353 if (esc
->sc_tail_size
) {
1355 *ndtracep
++ = 'A' + esc
->sc_tail_size
;
1363 esp_dma_stop(struct ncr53c9x_softc
*sc
)
1365 struct esp_softc
*esc
= (struct esp_softc
*)sc
;
1367 nextdma_print(esc
->sc_dma
);
1372 panic("%s: stop not yet implemented", device_xname(sc
->sc_dev
));
1377 esp_dma_isactive(struct ncr53c9x_softc
*sc
)
1379 struct esp_softc
*esc
= (struct esp_softc
*)sc
;
1382 r
= (esc
->sc_dmaaddr
!= NULL
); /* !nextdma_finished(esc->sc_dma); */
1383 DPRINTF(("esp_dma_isactive = %d\n",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
;
1402 NDTRACEIF (*ndtracep
++ = 'E');
1404 state
= nd_bsr4 (DD_CSR
);
1408 if (state
& DMACSR_COMPLETE
)
1410 if (state
& DMACSR_ENABLE
)
1412 if (state
& DMACSR_BUSEXC
)
1414 if (state
& DMACSR_READ
)
1416 if (state
& DMACSR_SUPDATE
)
1420 NDTRACEIF (*ndtracep
++ = 'E');
1424 if ((state
& DMACSR_BUSEXC
) && (state
& DMACSR_ENABLE
))
1427 if ((state
& DMACSR_SUPDATE
))
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
)) {
1448 int l
= nd_bsr4 (DD_LIMIT
) & 0x7FFFFFFF;
1449 int s
= nd_bsr4 (DD_STOP
);
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));
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
),
1472 ndtracep
+= strlen(ndtracep
);
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
);
1486 if (!(state
& DMACSR_SUPDATE
)) {
1487 nextdma_rotate(nsc
);
1489 nd_bsw4(DD_CSR
, DMACSR_CLRCOMPLETE
|
1490 DMACSR_INITBUF
| DMACSR_RESET
|
1491 (state
& DMACSR_READ
?
1492 DMACSR_SETREAD
: DMACSR_SETWRITE
));
1495 stat
->nd_map
->dm_segs
[stat
->nd_idx
].ds_addr
);
1497 (stat
->nd_map
->dm_segs
[stat
->nd_idx
].ds_addr
+
1498 stat
->nd_map
->dm_segs
[stat
->nd_idx
].ds_len
) |
1500 if (stat
->nd_map_cont
) {
1502 stat
->nd_map_cont
->dm_segs
[
1503 stat
->nd_idx_cont
].ds_addr
);
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
) |
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));
1517 sprintf(ndtracep
, "supdate ");
1518 ndtracep
+= strlen(ndtracep
);
1519 sprintf(ndtracep
, "%08X %08X %08X %08X ",
1521 nd_bsr4(DD_LIMIT
) & 0x7FFFFFFF,
1523 nd_bsr4 (DD_STOP
) & 0x7FFFFFFF);
1524 ndtracep
+= strlen(ndtracep
);
1527 stat
->nd_exception
++;
1529 /* NCR_WRITE_REG(sc, ESP_DCTL, ctl); */
1536 sprintf(ndtracep
, "%08X %08X %08X %08X ",
1538 nd_bsr4 (DD_LIMIT
) & 0x7FFFFFFF,
1540 nd_bsr4 (DD_STOP
) & 0x7FFFFFFF);
1541 ndtracep
+= strlen(ndtracep
);
1546 nd_bsw4(DD_CSR
, DMACSR_CLRCOMPLETE
| DMACSR_RESET
);
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); */
1559 stat
->nd_map
->dm_segs
[stat
->nd_idx
].ds_addr
);
1561 (stat
->nd_map
->dm_segs
[stat
->nd_idx
].ds_addr
+
1562 stat
->nd_map
->dm_segs
[stat
->nd_idx
].ds_len
) |
1564 /* nextdma_setup_cont_regs(nsc); */
1565 if (stat
->nd_map_cont
) {
1567 stat
->nd_map_cont
->dm_segs
[
1568 stat
->nd_idx_cont
].ds_addr
);
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
) |
1577 nd_bsw4(DD_CSR
, DMACSR_SETENABLE
|
1578 (stat
->nd_map_cont
? DMACSR_SETSUPDATE
: 0) |
1579 (state
& DMACSR_READ
?
1580 DMACSR_SETREAD
: DMACSR_SETWRITE
));
1582 /* ndtraceshow++; */
1584 stat
->nd_exception
++;
1587 /* NCR_WRITE_REG(sc, ESP_DCTL, ctl); */
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,
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
);
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
);
1623 printf("ndtrace: %s\n", ndtrace
);
1625 panic("%s: busexc/supdate occurred."
1626 " Please email this output to chris@pin.lu.",
1627 device_xname(sc
->sc_dev
));
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
);
1640 /* Internal DMA callback routines */
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
));
1651 if ((esc
->sc_datain
< 0) || (esc
->sc_datain
> 1)) {
1652 panic("%s: map not loaded in DMA continue callback,"
1654 device_xname(sc
->sc_dev
), esc
->sc_datain
);
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
)));
1662 bus_dmamap_sync(esc
->sc_dma
->sc_dmat
, esc
->sc_main_dmamap
,
1663 0, esc
->sc_main_dmamap
->dm_mapsize
,
1665 BUS_DMASYNC_PREREAD
: BUS_DMASYNC_PREWRITE
));
1666 esc
->sc_main_dmamap
->dm_xfer_len
= 0;
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
)));
1676 bus_dmamap_sync(esc
->sc_dma
->sc_dmat
, esc
->sc_tail_dmamap
,
1677 0, esc
->sc_tail_dmamap
->dm_mapsize
,
1679 BUS_DMASYNC_PREREAD
: BUS_DMASYNC_PREWRITE
));
1680 esc
->sc_tail_dmamap
->dm_xfer_len
= 0;
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
)));
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
)));
1701 if ((esc
->sc_datain
< 0) || (esc
->sc_datain
> 1)) {
1702 panic("%s: invalid DMA direction in completed callback,"
1704 device_xname(sc
->sc_dev
), esc
->sc_datain
);
1708 #if defined(DIAGNOSTIC) && 0
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 ="
1722 device_xname(sc
->sc_dev
), i
,
1723 map
->dm_segs
[i
].ds_addr
);
1724 printf("%s: map->dm_segs[%d].ds_len ="
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
));
1736 if (map
== esc
->sc_main_dmamap
) {
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
));
1744 esc
->sc_loaded
|= ESP_UNLOADED_MAIN
;
1745 } else if (map
== esc
->sc_tail_dmamap
) {
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
));
1753 esc
->sc_loaded
|= ESP_UNLOADED_TAIL
;
1757 panic("%s: unexpected completed map", device_xname(sc
->sc_dev
));
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
));
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
);
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
)));
1794 bus_dmamap_sync(esc
->sc_dma
->sc_dmat
, map
,
1796 (esc
->sc_datain
? BUS_DMASYNC_POSTREAD
: BUS_DMASYNC_POSTWRITE
));
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)
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
);
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
)));
1829 DPRINTF(("%s: esp_dma_nest == %d\n",
1830 device_xname(sc
->sc_dev
), esp_dma_nest
));
1832 /* Stuff the end slop into fifo */
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));
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
-=
1852 bus_dmamap_sync(esc
->sc_dma
->sc_dmat
, esc
->sc_main_dmamap
,
1853 0, esc
->sc_main_dmamap
->dm_mapsize
,
1855 BUS_DMASYNC_POSTREAD
: BUS_DMASYNC_POSTWRITE
));
1856 bus_dmamap_unload(esc
->sc_dma
->sc_dmat
, esc
->sc_main_dmamap
);
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
,
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
,
1875 (esc
->sc_begin_size
+ esc
->sc_main_size
));
1878 sprintf(ndtracep
, "t%ld",
1879 esc
->sc_tail_dmamap
->dm_xfer_len
);
1880 ndtracep
+= strlen(ndtracep
);
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]),
1895 esp_hex_dump(&(esc
->sc_tailbuf
[0]),
1896 sizeof(esc
->sc_tailbuf
));
1902 esc
->sc_main_size
= 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; */
1914 esc
->sc_begin_size
= 0;
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
);