1 /* $NetBSD: si.c,v 1.22 2008/12/16 22:35:36 christos Exp $ */
4 * Copyright (c) 1996,2000 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Glass, David Jones, Gordon W. Ross, Jason R. Thorpe and
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 * This file contains VME bus-dependent of the `si' SCSI adapter.
35 * This hardware is frequently found on Sun 3 and Sun 4 machines.
37 * The SCSI machinery on this adapter is implemented by an NCR5380,
38 * which is taken care of by the chipset driver in /sys/dev/ic/ncr5380sbc.c
40 * The logic has a bit to enable or disable the DMA engine,
41 * but that bit also gates the interrupt line from the NCR5380!
42 * Therefore, in order to get any interrupt from the 5380, (i.e.
43 * for reselect) one must clear the DMA engine transfer count and
44 * then enable DMA. This has the further complication that you
45 * CAN NOT touch the NCR5380 while the DMA enable bit is set, so
46 * we have to turn DMA back off before we even look at the 5380.
48 * What wonderfully whacky hardware this is!
53 * This driver originated as an MD implementation for the sun3 and sun4
54 * ports. The notes pertaining to that history are included below.
56 * David Jones wrote the initial version of this module for NetBSD/sun3,
57 * which included support for the VME adapter only. (no reselection).
59 * Gordon Ross added support for the Sun 3 OBIO adapter, and re-worked
60 * both the VME and OBIO code to support disconnect/reselect.
61 * (Required figuring out the hardware "features" noted above.)
63 * The autoconfiguration boilerplate came from Adam Glass.
65 * Jason R. Thorpe ported the autoconfiguration and VME portions to
66 * NetBSD/sparc, and added initial support for the 4/100 "SCSI Weird",
67 * a wacky OBIO variant of the VME SCSI-3. Many thanks to Chuck Cranor
68 * for lots of helpful tips and suggestions. Thanks also to Paul Kranenburg
69 * and Chris Torek for bits of insight needed along the way. Thanks to
70 * David Gilbert and Andrew Gillham who risked filesystem life-and-limb
71 * for the sake of testing. Andrew Gillham helped work out the bugs
75 #include <sys/cdefs.h>
76 __KERNEL_RCSID(0, "$NetBSD: si.c,v 1.22 2008/12/16 22:35:36 christos Exp $");
80 #include <sys/param.h>
81 #include <sys/systm.h>
82 #include <sys/kernel.h>
83 #include <sys/malloc.h>
84 #include <sys/errno.h>
85 #include <sys/device.h>
91 #include <dev/vme/vmereg.h>
92 #include <dev/vme/vmevar.h>
94 #include <dev/scsipi/scsi_all.h>
95 #include <dev/scsipi/scsipi_all.h>
96 #include <dev/scsipi/scsipi_debug.h>
97 #include <dev/scsipi/scsiconf.h>
107 #include <dev/ic/ncr5380reg.h>
108 #include <dev/ic/ncr5380var.h>
110 #include <dev/vme/sireg.h>
113 * Transfers smaller than this are done using PIO
114 * (on assumption they're not worth DMA overhead)
116 #define MIN_DMA_LEN 128
123 * This structure is used to keep track of mapped DMA requests.
125 struct si_dma_handle
{
127 #define SIDH_BUSY 0x01 /* This DH is in use */
128 #define SIDH_OUT 0x02 /* DMA does data out (write) */
129 int dh_maplen
; /* Original data length */
130 bus_dmamap_t dh_dmamap
;
131 #define dh_dvma dh_dmamap->dm_segs[0].ds_addr /* VA of buffer in DVMA space */
135 * The first structure member has to be the ncr5380_softc
136 * so we can just cast to go back and fourth between them.
139 struct ncr5380_softc ncr_sc
;
140 bus_space_tag_t sc_bustag
; /* bus tags */
141 bus_dma_tag_t sc_dmatag
;
142 vme_chipset_tag_t sc_vctag
;
144 int sc_adapter_iv_am
; /* int. vec + address modifier */
145 struct si_dma_handle
*sc_dma
;
146 int sc_xlen
; /* length of current DMA segment. */
147 int sc_options
; /* options for this instance. */
151 * Options. By default, DMA is enabled and DMA completion interrupts
152 * and reselect are disabled. You may enable additional features
153 * the `flags' directive in your kernel's configuration file.
155 * Alternatively, you can patch your kernel with DDB or some other
156 * mechanism. The sc_options member of the softc is OR'd with
157 * the value in si_options.
159 * Note, there's a separate sw_options to make life easier.
161 #define SI_ENABLE_DMA 0x01 /* Use DMA (maybe polled) */
162 #define SI_DMA_INTR 0x02 /* DMA completion interrupts */
163 #define SI_DO_RESELECT 0x04 /* Allow disconnect/reselect */
164 #define SI_OPTIONS_MASK (SI_ENABLE_DMA|SI_DMA_INTR|SI_DO_RESELECT)
165 #define SI_OPTIONS_BITS "\10\3RESELECT\2DMA_INTR\1DMA"
166 int si_options
= SI_ENABLE_DMA
|SI_DMA_INTR
|SI_DO_RESELECT
;
168 static int si_match(device_t
, cfdata_t
, void *);
169 static void si_attach(device_t
, device_t
, void *);
170 static int si_intr(void *);
171 static void si_reset_adapter(struct ncr5380_softc
*);
173 void si_dma_alloc(struct ncr5380_softc
*);
174 void si_dma_free(struct ncr5380_softc
*);
175 void si_dma_poll(struct ncr5380_softc
*);
177 void si_dma_setup(struct ncr5380_softc
*);
178 void si_dma_start(struct ncr5380_softc
*);
179 void si_dma_eop(struct ncr5380_softc
*);
180 void si_dma_stop(struct ncr5380_softc
*);
182 void si_intr_on (struct ncr5380_softc
*);
183 void si_intr_off(struct ncr5380_softc
*);
186 * Shorthand bus space access
187 * XXX - must look into endian issues here.
189 #define SIREG_READ(sc, index) \
190 bus_space_read_2((sc)->sc_regt, (sc)->sc_regh, index)
191 #define SIREG_WRITE(sc, index, v) \
192 bus_space_write_2((sc)->sc_regt, (sc)->sc_regh, index, v)
195 /* Auto-configuration glue. */
196 CFATTACH_DECL_NEW(si
, sizeof(struct si_softc
),
197 si_match
, si_attach
, NULL
, NULL
);
200 si_match(device_t parent
, cfdata_t cf
, void *aux
)
202 struct vme_attach_args
*va
= aux
;
203 vme_chipset_tag_t ct
= va
->va_vct
;
207 /* Make sure there is something there... */
208 mod
= VME_AM_A24
| VME_AM_MBO
| VME_AM_SUPER
| VME_AM_DATA
;
209 vme_addr
= va
->r
[0].offset
;
211 if (vme_probe(ct
, vme_addr
, 1, mod
, VME_D8
, NULL
, 0) != 0)
215 * If this is a VME SCSI board, we have to determine whether
216 * it is an "sc" (Sun2) or "si" (Sun3) SCSI board. This can
217 * be determined using the fact that the "sc" board occupies
218 * 4K bytes in VME space but the "si" board occupies 2K bytes.
220 return vme_probe(ct
, vme_addr
+ 0x801, 1, mod
, VME_D8
, NULL
, 0) != 0;
224 si_attach(device_t parent
, device_t self
, void *aux
)
226 struct si_softc
*sc
= device_private(self
);
227 struct ncr5380_softc
*ncr_sc
= &sc
->ncr_sc
;
228 struct vme_attach_args
*va
= aux
;
229 vme_chipset_tag_t ct
= va
->va_vct
;
231 bus_space_handle_t bh
;
233 vme_intr_handle_t ih
;
238 ncr_sc
->sc_dev
= self
;
239 sc
->sc_dmatag
= va
->va_bdt
;
242 mod
= VME_AM_A24
| VME_AM_MBO
| VME_AM_SUPER
| VME_AM_DATA
;
244 if (vme_space_map(ct
, va
->r
[0].offset
, SIREG_BANK_SZ
,
245 mod
, VME_D8
, 0, &bt
, &bh
, &resc
) != 0)
246 panic("%s: vme_space_map", device_xname(self
));
248 ncr_sc
->sc_regt
= bt
;
249 ncr_sc
->sc_regh
= bh
;
251 sc
->sc_options
= si_options
;
253 ncr_sc
->sc_dma_setup
= si_dma_setup
;
254 ncr_sc
->sc_dma_start
= si_dma_start
;
255 ncr_sc
->sc_dma_eop
= si_dma_stop
;
256 ncr_sc
->sc_dma_stop
= si_dma_stop
;
258 vme_intr_map(ct
, va
->ilevel
, va
->ivector
, &ih
);
259 vme_intr_establish(ct
, ih
, IPL_BIO
, si_intr
, sc
);
263 sc
->sc_adapter_iv_am
= (mod
<< 8) | (va
->ivector
& 0xFF);
266 * Pull in the options flags. Allow the user to completely
267 * override the default values.
269 if ((device_cfdata(self
)->cf_flags
& SI_OPTIONS_MASK
) != 0)
271 device_cfdata(self
)->cf_flags
& SI_OPTIONS_MASK
;
274 * Initialize fields used by the MI code
277 /* NCR5380 register bank offsets */
287 ncr_sc
->sc_rev
= NCR_VARIANT_NCR5380
;
290 * MD function pointers used by the MI code.
292 ncr_sc
->sc_pio_out
= ncr5380_pio_out
;
293 ncr_sc
->sc_pio_in
= ncr5380_pio_in
;
294 ncr_sc
->sc_dma_alloc
= si_dma_alloc
;
295 ncr_sc
->sc_dma_free
= si_dma_free
;
296 ncr_sc
->sc_dma_poll
= si_dma_poll
;
298 ncr_sc
->sc_flags
= 0;
299 if ((sc
->sc_options
& SI_DO_RESELECT
) == 0)
300 ncr_sc
->sc_no_disconnect
= 0xFF;
301 if ((sc
->sc_options
& SI_DMA_INTR
) == 0)
302 ncr_sc
->sc_flags
|= NCR5380_FORCE_POLLING
;
303 ncr_sc
->sc_min_dma_len
= MIN_DMA_LEN
;
306 * Allocate DMA handles.
308 i
= SCI_OPENINGS
* sizeof(struct si_dma_handle
);
309 sc
->sc_dma
= malloc(i
, M_DEVBUF
, M_NOWAIT
);
310 if (sc
->sc_dma
== NULL
)
311 panic("si: DMA handle malloc failed");
313 for (i
= 0; i
< SCI_OPENINGS
; i
++) {
314 sc
->sc_dma
[i
].dh_flags
= 0;
316 /* Allocate a DMA handle */
317 if (vme_dmamap_create(
318 sc
->sc_vctag
, /* VME chip tag */
320 VME_AM_A24
, /* address modifier */
321 VME_D16
, /* data size */
324 MAXPHYS
, /* maxsegsz */
327 &sc
->sc_dma
[i
].dh_dmamap
) != 0) {
329 aprint_error_dev(self
, "DMA buffer map create error\n");
334 if (sc
->sc_options
) {
335 snprintb(bits
, sizeof(bits
), SI_OPTIONS_BITS
, sc
->sc_options
);
336 aprint_normal_dev(self
, "options=%s\n", bits
);
339 ncr_sc
->sc_channel
.chan_id
= 7;
340 ncr_sc
->sc_adapter
.adapt_minphys
= minphys
;
343 * Initialize si board itself.
345 si_reset_adapter(ncr_sc
);
346 ncr5380_attach(ncr_sc
);
348 if (sc
->sc_options
& SI_DO_RESELECT
) {
350 * Need to enable interrupts (and DMA!)
351 * on this H/W for reselect to work.
353 ncr_sc
->sc_intr_on
= si_intr_on
;
354 ncr_sc
->sc_intr_off
= si_intr_off
;
358 #define CSR_WANT (SI_CSR_SBC_IP | SI_CSR_DMA_IP | \
359 SI_CSR_DMA_CONFLICT | SI_CSR_DMA_BUS_ERR )
364 struct si_softc
*sc
= arg
;
365 struct ncr5380_softc
*ncr_sc
= &sc
->ncr_sc
;
366 int dma_error
, claimed
;
372 /* SBC interrupt? DMA interrupt? */
373 csr
= SIREG_READ(ncr_sc
, SIREG_CSR
);
375 NCR_TRACE("si_intr: csr=0x%x\n", csr
);
377 if (csr
& SI_CSR_DMA_CONFLICT
) {
378 dma_error
|= SI_CSR_DMA_CONFLICT
;
379 printf("%s: DMA conflict\n", __func__
);
381 if (csr
& SI_CSR_DMA_BUS_ERR
) {
382 dma_error
|= SI_CSR_DMA_BUS_ERR
;
383 printf("%s: DMA bus error\n", __func__
);
386 if (sc
->ncr_sc
.sc_state
& NCR_DOINGDMA
)
387 sc
->ncr_sc
.sc_state
|= NCR_ABORTING
;
388 /* Make sure we will call the main isr. */
389 csr
|= SI_CSR_DMA_IP
;
392 if (csr
& (SI_CSR_SBC_IP
| SI_CSR_DMA_IP
)) {
393 claimed
= ncr5380_intr(&sc
->ncr_sc
);
396 printf("%s: spurious from SBC\n", __func__
);
398 Debugger(); /* XXX */
409 si_reset_adapter(struct ncr5380_softc
*ncr_sc
)
411 struct si_softc
*sc
= (struct si_softc
*)ncr_sc
;
415 printf("%s\n", __func__
);
420 * The SCSI3 controller has an 8K FIFO to buffer data between the
421 * 5380 and the DMA. Make sure it starts out empty.
423 * The reset bits in the CSR are active low.
425 SIREG_WRITE(ncr_sc
, SIREG_CSR
, 0);
427 SIREG_WRITE(ncr_sc
, SIREG_CSR
,
428 SI_CSR_FIFO_RES
| SI_CSR_SCSI_RES
| SI_CSR_INTR_EN
);
431 SIREG_WRITE(ncr_sc
, SIREG_FIFO_CNT
, 0);
432 SIREG_WRITE(ncr_sc
, SIREG_DMA_ADDRH
, 0);
433 SIREG_WRITE(ncr_sc
, SIREG_DMA_ADDRL
, 0);
434 SIREG_WRITE(ncr_sc
, SIREG_DMA_CNTH
, 0);
435 SIREG_WRITE(ncr_sc
, SIREG_DMA_CNTL
, 0);
436 SIREG_WRITE(ncr_sc
, SIREG_IV_AM
, sc
->sc_adapter_iv_am
);
437 SIREG_WRITE(ncr_sc
, SIREG_FIFO_CNTH
, 0);
439 SCI_CLR_INTR(ncr_sc
);
442 /*****************************************************************
443 * Common functions for DMA
444 ****************************************************************/
447 * Allocate a DMA handle and put it in sc->sc_dma. Prepare
451 si_dma_alloc(struct ncr5380_softc
*ncr_sc
)
453 struct si_softc
*sc
= (struct si_softc
*)ncr_sc
;
454 struct sci_req
*sr
= ncr_sc
->sc_current
;
455 struct scsipi_xfer
*xs
= sr
->sr_xs
;
456 struct si_dma_handle
*dh
;
461 if (sr
->sr_dma_hand
!= NULL
)
462 panic("%s: already have DMA handle", __func__
);
465 #if 1 /* XXX - Temporary */
466 /* XXX - In case we think DMA is completely broken... */
467 if ((sc
->sc_options
& SI_ENABLE_DMA
) == 0)
471 addr
= (u_long
)ncr_sc
->sc_dataptr
;
472 xlen
= ncr_sc
->sc_datalen
;
474 /* If the DMA start addr is misaligned then do PIO */
475 if ((addr
& 1) || (xlen
& 1)) {
476 printf("%s: misaligned.\n", __func__
);
480 /* Make sure our caller checked sc_min_dma_len. */
481 if (xlen
< MIN_DMA_LEN
)
482 panic("%s: xlen=0x%x", __func__
, xlen
);
484 /* Find free DMA handle. Guaranteed to find one since we have
485 as many DMA handles as the driver has processes. */
486 for (i
= 0; i
< SCI_OPENINGS
; i
++) {
487 if ((sc
->sc_dma
[i
].dh_flags
& SIDH_BUSY
) == 0)
490 panic("si: no free DMA handles.");
494 dh
->dh_flags
= SIDH_BUSY
;
495 dh
->dh_maplen
= xlen
;
497 /* Copy the "write" flag for convenience. */
498 if ((xs
->xs_control
& XS_CTL_DATA_OUT
) != 0)
499 dh
->dh_flags
|= SIDH_OUT
;
502 * Double-map the buffer into DVMA space. If we can't re-map
503 * the buffer, we print a warning and fall back to PIO mode.
505 * NOTE: it is not safe to sleep here!
507 if (bus_dmamap_load(sc
->sc_dmatag
, dh
->dh_dmamap
,
508 (void *)addr
, xlen
, NULL
, BUS_DMA_NOWAIT
) != 0) {
509 /* Can't remap segment */
510 printf("%s: can't remap 0x%lx/0x%x, doing PIO\n",
511 __func__
, addr
, dh
->dh_maplen
);
515 bus_dmamap_sync(sc
->sc_dmatag
, dh
->dh_dmamap
, addr
, xlen
,
516 (dh
->dh_flags
& SIDH_OUT
)
517 ? BUS_DMASYNC_PREWRITE
518 : BUS_DMASYNC_PREREAD
);
521 sr
->sr_dma_hand
= dh
;
526 si_dma_free(struct ncr5380_softc
*ncr_sc
)
528 struct si_softc
*sc
= (struct si_softc
*)ncr_sc
;
529 struct sci_req
*sr
= ncr_sc
->sc_current
;
530 struct si_dma_handle
*dh
= sr
->sr_dma_hand
;
534 panic("%s: no DMA handle", __func__
);
537 if (ncr_sc
->sc_state
& NCR_DOINGDMA
)
538 panic("%s: free while in progress", __func__
);
540 if (dh
->dh_flags
& SIDH_BUSY
) {
541 /* Give back the DVMA space. */
542 bus_dmamap_sync(sc
->sc_dmatag
, dh
->dh_dmamap
,
543 dh
->dh_dvma
, dh
->dh_maplen
,
544 (dh
->dh_flags
& SIDH_OUT
)
545 ? BUS_DMASYNC_POSTWRITE
546 : BUS_DMASYNC_POSTREAD
);
547 bus_dmamap_unload(sc
->sc_dmatag
, dh
->dh_dmamap
);
550 sr
->sr_dma_hand
= NULL
;
555 * Poll (spin-wait) for DMA completion.
556 * Called right after xx_dma_start(), and
557 * xx_dma_stop() will be called next.
558 * Same for either VME or OBIO.
561 si_dma_poll(struct ncr5380_softc
*ncr_sc
)
563 struct sci_req
*sr
= ncr_sc
->sc_current
;
564 int tmo
, csr_mask
, csr
;
566 /* Make sure DMA started successfully. */
567 if (ncr_sc
->sc_state
& NCR_ABORTING
)
570 csr_mask
= SI_CSR_SBC_IP
| SI_CSR_DMA_IP
|
571 SI_CSR_DMA_CONFLICT
| SI_CSR_DMA_BUS_ERR
;
573 tmo
= 50000; /* X100 = 5 sec. */
575 csr
= SIREG_READ(ncr_sc
, SIREG_CSR
);
579 printf("%s: DMA timeout (while polling)\n",
580 device_xname(ncr_sc
->sc_dev
));
581 /* Indicate timeout as MI code would. */
582 sr
->sr_flags
|= SR_OVERDUE
;
590 printf("%s: done, csr=0x%x\n", __func__
, csr
);
596 /*****************************************************************
597 * VME functions for DMA
598 ****************************************************************/
602 * This is called when the bus is going idle,
603 * so we want to enable the SBC interrupts.
604 * That is controlled by the DMA enable!
605 * Who would have guessed!
606 * What a NASTY trick!
609 si_intr_on(struct ncr5380_softc
*ncr_sc
)
613 /* Clear DMA start address and counters */
614 SIREG_WRITE(ncr_sc
, SIREG_DMA_ADDRH
, 0);
615 SIREG_WRITE(ncr_sc
, SIREG_DMA_ADDRL
, 0);
616 SIREG_WRITE(ncr_sc
, SIREG_DMA_CNTH
, 0);
617 SIREG_WRITE(ncr_sc
, SIREG_DMA_CNTL
, 0);
619 /* Enter receive mode (for safety) and enable DMA engine */
620 csr
= SIREG_READ(ncr_sc
, SIREG_CSR
);
622 csr
|= SI_CSR_DMA_EN
;
623 SIREG_WRITE(ncr_sc
, SIREG_CSR
, csr
);
627 * This is called when the bus is idle and we are
628 * about to start playing with the SBC chip.
631 si_intr_off(struct ncr5380_softc
*ncr_sc
)
635 csr
= SIREG_READ(ncr_sc
, SIREG_CSR
);
636 csr
&= ~SI_CSR_DMA_EN
;
637 SIREG_WRITE(ncr_sc
, SIREG_CSR
, csr
);
641 * This function is called during the COMMAND or MSG_IN phase
642 * that precedes a DATA_IN or DATA_OUT phase, in case we need
643 * to setup the DMA engine before the bus enters a DATA phase.
645 * XXX: The VME adapter appears to suppress SBC interrupts
646 * when the FIFO is not empty or the FIFO count is non-zero!
648 * On the VME version we just clear the DMA count and address
649 * here (to make sure it stays idle) and do the real setup
650 * later, in dma_start.
653 si_dma_setup(struct ncr5380_softc
*ncr_sc
)
655 struct si_softc
*sc
= (struct si_softc
*)ncr_sc
;
656 struct sci_req
*sr
= ncr_sc
->sc_current
;
657 struct si_dma_handle
*dh
= sr
->sr_dma_hand
;
663 * Set up the DMA controller.
664 * Note that (dh->dh_len < sc_datalen)
667 csr
= SIREG_READ(ncr_sc
, SIREG_CSR
);
669 /* Disable DMA while we're setting up the transfer */
670 csr
&= ~SI_CSR_DMA_EN
;
673 csr
&= ~SI_CSR_FIFO_RES
; /* active low */
674 SIREG_WRITE(ncr_sc
, SIREG_CSR
, csr
);
675 csr
|= SI_CSR_FIFO_RES
;
676 SIREG_WRITE(ncr_sc
, SIREG_CSR
, csr
);
679 * Get the DVMA mapping for this segment.
681 dva
= (u_long
)(dh
->dh_dvma
);
683 panic("%s: bad dmaaddr=0x%lx", __func__
, dva
);
684 xlen
= ncr_sc
->sc_datalen
;
686 sc
->sc_xlen
= xlen
; /* XXX: or less... */
690 printf("%s: dh=%p, dmaaddr=0x%lx, xlen=%d\n",
691 __func__
, dh
, dva
, xlen
);
694 /* Set direction (send/recv) */
695 if (dh
->dh_flags
& SIDH_OUT
) {
701 /* Set byte-packing control */
705 csr
&= ~SI_CSR_BPCON
;
708 SIREG_WRITE(ncr_sc
, SIREG_CSR
, csr
);
710 /* Load start address */
711 SIREG_WRITE(ncr_sc
, SIREG_DMA_ADDRH
, (uint16_t)(dva
>> 16));
712 SIREG_WRITE(ncr_sc
, SIREG_DMA_ADDRL
, (uint16_t)(dva
& 0xFFFF));
714 /* Clear DMA counters; these will be set in si_dma_start() */
715 SIREG_WRITE(ncr_sc
, SIREG_DMA_CNTH
, 0);
716 SIREG_WRITE(ncr_sc
, SIREG_DMA_CNTL
, 0);
718 /* Clear FIFO counter. (also hits dma_count) */
719 SIREG_WRITE(ncr_sc
, SIREG_FIFO_CNTH
, 0);
720 SIREG_WRITE(ncr_sc
, SIREG_FIFO_CNT
, 0);
725 si_dma_start(struct ncr5380_softc
*ncr_sc
)
727 struct si_softc
*sc
= (struct si_softc
*)ncr_sc
;
728 struct sci_req
*sr
= ncr_sc
->sc_current
;
729 struct si_dma_handle
*dh
= sr
->sr_dma_hand
;
736 /* Load transfer length */
737 SIREG_WRITE(ncr_sc
, SIREG_DMA_CNTH
, (uint16_t)(xlen
>> 16));
738 SIREG_WRITE(ncr_sc
, SIREG_DMA_CNTL
, (uint16_t)(xlen
& 0xFFFF));
739 SIREG_WRITE(ncr_sc
, SIREG_FIFO_CNTH
, (uint16_t)(xlen
>> 16));
740 SIREG_WRITE(ncr_sc
, SIREG_FIFO_CNT
, (uint16_t)(xlen
& 0xFFFF));
743 * Acknowledge the phase change. (After DMA setup!)
744 * Put the SBIC into DMA mode, and start the transfer.
746 if (dh
->dh_flags
& SIDH_OUT
) {
747 NCR5380_WRITE(ncr_sc
, sci_tcmd
, PHASE_DATA_OUT
);
748 SCI_CLR_INTR(ncr_sc
);
749 NCR5380_WRITE(ncr_sc
, sci_icmd
, SCI_ICMD_DATA
);
751 mode
= NCR5380_READ(ncr_sc
, sci_mode
);
752 mode
|= (SCI_MODE_DMA
| SCI_MODE_DMA_IE
);
753 NCR5380_WRITE(ncr_sc
, sci_mode
, mode
);
755 NCR5380_WRITE(ncr_sc
, sci_dma_send
, 0); /* start it */
757 NCR5380_WRITE(ncr_sc
, sci_tcmd
, PHASE_DATA_IN
);
758 SCI_CLR_INTR(ncr_sc
);
759 NCR5380_WRITE(ncr_sc
, sci_icmd
, 0);
761 mode
= NCR5380_READ(ncr_sc
, sci_mode
);
762 mode
|= (SCI_MODE_DMA
| SCI_MODE_DMA_IE
);
763 NCR5380_WRITE(ncr_sc
, sci_mode
, mode
);
765 NCR5380_WRITE(ncr_sc
, sci_irecv
, 0); /* start it */
768 ncr_sc
->sc_state
|= NCR_DOINGDMA
;
770 /* Enable DMA engine */
771 csr
= SIREG_READ(ncr_sc
, SIREG_CSR
);
772 csr
|= SI_CSR_DMA_EN
;
773 SIREG_WRITE(ncr_sc
, SIREG_CSR
, csr
);
777 printf("%s: started, flags=0x%x\n",
778 __func__
, ncr_sc
->sc_state
);
785 si_dma_eop(struct ncr5380_softc
*ncr_sc
)
788 /* Not needed - DMA was stopped prior to examining sci_csr */
793 si_dma_stop(struct ncr5380_softc
*ncr_sc
)
795 struct si_softc
*sc
= (struct si_softc
*)ncr_sc
;
796 struct sci_req
*sr
= ncr_sc
->sc_current
;
797 struct si_dma_handle
*dh
= sr
->sr_dma_hand
;
802 if ((ncr_sc
->sc_state
& NCR_DOINGDMA
) == 0) {
804 printf("%s: DMA not running\n", __func__
);
809 ncr_sc
->sc_state
&= ~NCR_DOINGDMA
;
811 csr
= SIREG_READ(ncr_sc
, SIREG_CSR
);
813 /* First, halt the DMA engine. */
814 csr
&= ~SI_CSR_DMA_EN
;
815 SIREG_WRITE(ncr_sc
, SIREG_CSR
, csr
);
817 if (csr
& (SI_CSR_DMA_CONFLICT
| SI_CSR_DMA_BUS_ERR
)) {
818 printf("si: DMA error, csr=0x%x, reset\n", csr
);
819 sr
->sr_xs
->error
= XS_DRIVER_STUFFUP
;
820 ncr_sc
->sc_state
|= NCR_ABORTING
;
821 si_reset_adapter(ncr_sc
);
824 /* Note that timeout may have set the error flag. */
825 if (ncr_sc
->sc_state
& NCR_ABORTING
)
829 * Now try to figure out how much actually transferred
831 * The fifo_count does not reflect how many bytes were
832 * actually transferred for VME.
834 * SCSI-3 VME interface is a little funny on writes:
835 * if we have a disconnect, the DMA has overshot by
836 * one byte and the resid needs to be incremented.
837 * Only happens for partial transfers.
838 * (Thanks to Matt Jacob)
841 resid
= SIREG_READ(ncr_sc
, SIREG_FIFO_CNTH
) << 16;
842 resid
|= SIREG_READ(ncr_sc
, SIREG_FIFO_CNT
) & 0xFFFF;
843 if (dh
->dh_flags
& SIDH_OUT
)
844 if ((resid
> 0) && (resid
< sc
->sc_xlen
))
846 ntrans
= sc
->sc_xlen
- resid
;
850 printf("%s: resid=0x%x ntrans=0x%x\n",
851 __func__
, resid
, ntrans
);
855 if (ntrans
> ncr_sc
->sc_datalen
)
856 panic("%s: excess transfer", __func__
);
858 /* Adjust data pointer */
859 ncr_sc
->sc_dataptr
+= ntrans
;
860 ncr_sc
->sc_datalen
-= ntrans
;
864 printf("%s: ntrans=0x%x\n", __func__
, ntrans
);
869 * After a read, we may need to clean-up
870 * "Left-over bytes" (yuck!)
872 if (((dh
->dh_flags
& SIDH_OUT
) == 0) &&
873 ((csr
& SI_CSR_LOB
) != 0)) {
874 uint8_t *cp
= ncr_sc
->sc_dataptr
;
877 bprh
= SIREG_READ(ncr_sc
, SIREG_BPRH
);
878 bprl
= SIREG_READ(ncr_sc
, SIREG_BPRL
);
881 printf("si: got left-over bytes: bprh=%x, bprl=%x, csr=%x\n",
885 if (csr
& SI_CSR_BPCON
) {
886 /* have SI_CSR_BPCON */
887 cp
[-1] = (bprl
& 0xff00) >> 8;
889 switch (csr
& SI_CSR_LOB
) {
890 case SI_CSR_LOB_THREE
:
891 cp
[-3] = (bprh
& 0xff00) >> 8;
892 cp
[-2] = (bprh
& 0x00ff);
893 cp
[-1] = (bprl
& 0xff00) >> 8;
896 cp
[-2] = (bprh
& 0xff00) >> 8;
897 cp
[-1] = (bprh
& 0x00ff);
900 cp
[-1] = (bprh
& 0xff00) >> 8;
907 SIREG_WRITE(ncr_sc
, SIREG_DMA_ADDRH
, 0);
908 SIREG_WRITE(ncr_sc
, SIREG_DMA_ADDRL
, 0);
910 SIREG_WRITE(ncr_sc
, SIREG_DMA_CNTH
, 0);
911 SIREG_WRITE(ncr_sc
, SIREG_DMA_CNTL
, 0);
913 SIREG_WRITE(ncr_sc
, SIREG_FIFO_CNTH
, 0);
914 SIREG_WRITE(ncr_sc
, SIREG_FIFO_CNT
, 0);
916 mode
= NCR5380_READ(ncr_sc
, sci_mode
);
917 /* Put SBIC back in PIO mode. */
918 mode
&= ~(SCI_MODE_DMA
| SCI_MODE_DMA_IE
);
919 NCR5380_WRITE(ncr_sc
, sci_mode
, mode
);
920 NCR5380_WRITE(ncr_sc
, sci_icmd
, 0);