1 /* $NetBSD: flsc.c,v 1.41 2008/04/13 04:55:52 tsutsui Exp $ */
4 * Copyright (c) 1997 Michael L. Hitch
5 * Copyright (c) 1995 Daniel Widenfalk
6 * Copyright (c) 1994 Christian E. Hopps
7 * Copyright (c) 1982, 1990 The Regents of the University of California.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by Daniel Widenfalk
21 * and Michael L. Hitch.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * Initial amiga Fastlane driver by Daniel Widenfalk. Conversion to
41 * 53c9x MI driver by Michael L. Hitch (mhitch@montana.edu).
46 #include <sys/cdefs.h>
47 __KERNEL_RCSID(0, "$NetBSD: flsc.c,v 1.41 2008/04/13 04:55:52 tsutsui Exp $");
49 #include <sys/types.h>
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/kernel.h>
53 #include <sys/errno.h>
54 #include <sys/ioctl.h>
55 #include <sys/device.h>
58 #include <sys/queue.h>
60 #include <uvm/uvm_extern.h>
62 #include <dev/scsipi/scsi_all.h>
63 #include <dev/scsipi/scsipi_all.h>
64 #include <dev/scsipi/scsiconf.h>
65 #include <dev/scsipi/scsi_message.h>
67 #include <machine/cpu.h>
68 #include <machine/param.h>
70 #include <dev/ic/ncr53c9xreg.h>
71 #include <dev/ic/ncr53c9xvar.h>
73 #include <amiga/amiga/isr.h>
74 #include <amiga/dev/flscvar.h>
75 #include <amiga/dev/zbusvar.h>
77 int flscmatch(device_t
, cfdata_t
, void *);
78 void flscattach(device_t
, device_t
, void *);
80 /* Linkup to the rest of the kernel */
81 CFATTACH_DECL_NEW(flsc
, sizeof(struct flsc_softc
),
82 flscmatch
, flscattach
, NULL
, NULL
);
85 * Functions and the switch for the MI code.
87 uint8_t flsc_read_reg(struct ncr53c9x_softc
*, int);
88 void flsc_write_reg(struct ncr53c9x_softc
*, int, uint8_t);
89 int flsc_dma_isintr(struct ncr53c9x_softc
*);
90 void flsc_dma_reset(struct ncr53c9x_softc
*);
91 int flsc_dma_intr(struct ncr53c9x_softc
*);
92 int flsc_dma_setup(struct ncr53c9x_softc
*, uint8_t **,
93 size_t *, int, size_t *);
94 void flsc_dma_go(struct ncr53c9x_softc
*);
95 void flsc_dma_stop(struct ncr53c9x_softc
*);
96 int flsc_dma_isactive(struct ncr53c9x_softc
*);
97 void flsc_clear_latched_intr(struct ncr53c9x_softc
*);
99 struct ncr53c9x_glue flsc_glue
= {
109 flsc_clear_latched_intr
,
112 /* Maximum DMA transfer length to reduce impact on high-speed serial input */
113 u_long flsc_max_dma
= 1024;
114 extern int ser_open_speed
;
116 extern int ncr53c9x_debug
;
117 extern u_long scsi_nosync
;
118 extern int shift_nosync
;
121 * if we are an Advanced Systems & Software FastlaneZ3
124 flscmatch(device_t parent
, cfdata_t cf
, void *aux
)
126 struct zbus_args
*zap
;
128 if (!is_a4000() && !is_a3000())
132 if (zap
->manid
== 0x2140 && zap
->prodid
== 11
133 && iszthreepa(zap
->pa
))
140 * Attach this instance, and then all the sub-devices
143 flscattach(device_t parent
, device_t self
, void *aux
)
145 struct flsc_softc
*fsc
= device_private(self
);
146 struct ncr53c9x_softc
*sc
= &fsc
->sc_ncr53c9x
;
147 struct zbus_args
*zap
;
150 * Set up the glue for MI code early; we use some of it here.
153 sc
->sc_glue
= &flsc_glue
;
159 fsc
->sc_dmabase
= (volatile uint8_t *)zap
->va
;
160 fsc
->sc_reg
= &((volatile uint8_t *)zap
->va
)[0x1000001];
162 sc
->sc_freq
= 40; /* Clocked at 40 MHz */
164 aprint_normal(": address %p", fsc
->sc_reg
);
169 * It is necessary to try to load the 2nd config register here,
170 * to find out what rev the flsc chip is, else the flsc_reset
171 * will not set up the defaults correctly.
173 sc
->sc_cfg1
= sc
->sc_id
| NCRCFG1_PARENB
;
174 sc
->sc_cfg2
= NCRCFG2_SCSI2
| NCRCFG2_FE
;
175 sc
->sc_cfg3
= 0x08 /*FCLK*/ | NCRESPCFG3_FSCSI
| NCRESPCFG3_CDB
;
176 sc
->sc_rev
= NCR_VARIANT_FAS216
;
179 * This is the value used to start sync negotiations
180 * Note that the NCR register "SYNCTP" is programmed
181 * in "clocks per byte", and has a minimum value of 4.
182 * The SCSI period used in negotiation is one-fourth
183 * of the time (in nanoseconds) needed to transfer one byte.
184 * Since the chip's clock is given in MHz, we have the following
185 * formula: 4 * period = (1000 / freq) * 4
187 sc
->sc_minsync
= 1000 / sc
->sc_freq
;
189 if (((scsi_nosync
>> shift_nosync
) & 0xff00) == 0xff00)
192 /* Really no limit, but since we want to fit into the TCR... */
193 sc
->sc_maxxfer
= 64 * 1024;
195 fsc
->sc_portbits
= 0xa0 | FLSC_PB_EDI
| FLSC_PB_ESI
;
196 fsc
->sc_hardbits
= fsc
->sc_reg
[0x40];
198 fsc
->sc_alignbuf
= (uint8_t *)((u_long
)fsc
->sc_unalignbuf
& -4);
200 device_cfdata(self
)->cf_flags
|=
201 (scsi_nosync
>> shift_nosync
) & 0xffff;
203 ncr53c9x_debug
|= (scsi_nosync
>> shift_nosync
) & 0xffff;
207 * Configure interrupts.
209 fsc
->sc_isr
.isr_intr
= ncr53c9x_intr
;
210 fsc
->sc_isr
.isr_arg
= sc
;
211 fsc
->sc_isr
.isr_ipl
= 2;
212 add_isr(&fsc
->sc_isr
);
214 fsc
->sc_reg
[0x40] = fsc
->sc_portbits
;
217 * Now try to attach all the sub-devices
219 sc
->sc_adapter
.adapt_request
= ncr53c9x_scsipi_request
;
220 sc
->sc_adapter
.adapt_minphys
= minphys
;
229 flsc_read_reg(struct ncr53c9x_softc
*sc
, int reg
)
231 struct flsc_softc
*fsc
= (struct flsc_softc
*)sc
;
233 return fsc
->sc_reg
[reg
* 4];
237 flsc_write_reg(struct ncr53c9x_softc
*sc
, int reg
, uint8_t val
)
239 struct flsc_softc
*fsc
= (struct flsc_softc
*)sc
;
240 struct ncr53c9x_tinfo
*ti
;
243 if (fsc
->sc_piomode
&& reg
== NCR_CMD
&&
244 v
== (NCRCMD_TRANS
| NCRCMD_DMA
)) {
248 * Can't do synchronous transfers in XS_CTL_POLL mode:
249 * If starting XS_CTL_POLL command, clear defer sync negotiation
250 * by clearing the T_NEGOTIATE flag. If starting XS_CTL_POLL and
251 * the device is currently running synchronous, force another
252 * T_NEGOTIATE with 0 offset.
254 if (reg
== NCR_SELID
) {
256 sc
->sc_nexus
->xs
->xs_periph
->periph_target
];
257 if (sc
->sc_nexus
->xs
->xs_control
& XS_CTL_POLL
) {
258 if (ti
->flags
& T_SYNCMODE
) {
259 ti
->flags
^= T_SYNCMODE
| T_NEGOTIATE
;
260 } else if (ti
->flags
& T_NEGOTIATE
) {
261 ti
->flags
^= T_NEGOTIATE
| T_SYNCHOFF
;
262 /* save T_NEGOTIATE in private flags? */
266 * If we haven't attempted sync negotiation yet,
269 if ((ti
->flags
& (T_SYNCMODE
| T_SYNCHOFF
)) ==
271 sc
->sc_minsync
!= 0) /* XXX */
272 ti
->flags
^= T_NEGOTIATE
| T_SYNCHOFF
;
275 if (reg
== NCR_CMD
&& v
== NCRCMD_SETATN
&&
276 sc
->sc_flags
& NCR_SYNCHNEGO
&&
277 sc
->sc_nexus
->xs
->xs_control
& XS_CTL_POLL
) {
279 sc
->sc_nexus
->xs
->xs_periph
->periph_target
];
282 fsc
->sc_reg
[reg
* 4] = v
;
286 flsc_dma_isintr(struct ncr53c9x_softc
*sc
)
288 struct flsc_softc
*fsc
= (struct flsc_softc
*)sc
;
289 unsigned int hardbits
;
291 hardbits
= fsc
->sc_reg
[0x40];
292 if ((hardbits
& FLSC_HB_IACT
) != 0)
293 return (fsc
->sc_csr
= 0);
295 if (sc
->sc_state
== NCR_CONNECTED
|| sc
->sc_state
== NCR_SELECTING
)
296 fsc
->sc_portbits
|= FLSC_PB_LED
;
298 fsc
->sc_portbits
&= ~FLSC_PB_LED
;
300 if ((hardbits
& FLSC_HB_CREQ
) != 0 && (hardbits
& FLSC_HB_MINT
) == 0 &&
301 (fsc
->sc_reg
[NCR_STAT
* 4] & NCRSTAT_INT
) != 0) {
304 /* Do I still need this? */
305 if (fsc
->sc_piomode
&& (fsc
->sc_reg
[NCR_STAT
* 4] & NCRSTAT_INT
) != 0 &&
306 (hardbits
& FLSC_HB_MINT
) == 0)
309 fsc
->sc_reg
[0x40] = fsc
->sc_portbits
& ~FLSC_PB_INT_BITS
;
310 fsc
->sc_reg
[0x40] = fsc
->sc_portbits
;
315 flsc_clear_latched_intr(struct ncr53c9x_softc
*sc
)
317 struct flsc_softc
*fsc
= (struct flsc_softc
*)sc
;
319 fsc
->sc_reg
[0x40] = fsc
->sc_portbits
& ~FLSC_PB_INT_BITS
;
320 fsc
->sc_reg
[0x40] = fsc
->sc_portbits
;
324 flsc_dma_reset(struct ncr53c9x_softc
*sc
)
326 struct flsc_softc
*fsc
= (struct flsc_softc
*)sc
;
327 struct ncr53c9x_tinfo
*ti
;
330 ti
= &sc
->sc_tinfo
[sc
->sc_nexus
->xs
->xs_periph
->periph_target
];
332 ti
= &sc
->sc_tinfo
[1]; /* XXX */
333 if (fsc
->sc_active
) {
334 printf("dmaaddr %p dmasize %d stat %x flags %x off %d ",
335 *fsc
->sc_dmaaddr
, fsc
->sc_dmasize
,
336 fsc
->sc_reg
[NCR_STAT
* 4], ti
->flags
, ti
->offset
);
337 printf("per %d ff %x intr %x\n",
338 ti
->period
, fsc
->sc_reg
[NCR_FFLAG
* 4],
339 fsc
->sc_reg
[NCR_INTR
* 4]);
344 fsc
->sc_portbits
&= ~FLSC_PB_DMA_BITS
;
345 fsc
->sc_reg
[0x40] = fsc
->sc_portbits
;
346 fsc
->sc_reg
[0x80] = 0;
347 *((volatile uint32_t *)fsc
->sc_dmabase
) = 0;
353 flsc_dma_intr(struct ncr53c9x_softc
*sc
)
355 register struct flsc_softc
*fsc
= (struct flsc_softc
*)sc
;
357 volatile uint8_t *cmdreg
, *intrreg
, *statreg
, *fiforeg
;
358 u_int flscphase
, flscstat
, flscintr
;
361 NCR_DMA(("flsc_dma_intr: pio %d cnt %d int %x stat %x fifo %d ",
362 fsc
->sc_piomode
, fsc
->sc_dmasize
, sc
->sc_espintr
, sc
->sc_espstat
,
363 fsc
->sc_reg
[NCR_FFLAG
* 4] & NCRFIFO_FF
));
364 if ((fsc
->sc_reg
[0x40] & FLSC_HB_CREQ
) == 0)
365 printf("flsc_dma_intr: csr %x stat %x intr %x\n", fsc
->sc_csr
,
366 sc
->sc_espstat
, sc
->sc_espintr
);
367 if (fsc
->sc_active
== 0) {
368 printf("flsc_intr--inactive DMA\n");
372 /* if DMA transfer, update sc_dmaaddr and sc_pdmalen, else PIO xfer */
373 if (fsc
->sc_piomode
== 0) {
374 fsc
->sc_portbits
&= ~FLSC_PB_DMA_BITS
;
375 fsc
->sc_reg
[0x40] = fsc
->sc_portbits
;
376 fsc
->sc_reg
[0x80] = 0;
377 *((volatile uint32_t *)fsc
->sc_dmabase
) = 0;
378 cnt
= fsc
->sc_reg
[NCR_TCL
* 4];
379 cnt
+= fsc
->sc_reg
[NCR_TCM
* 4] << 8;
380 cnt
+= fsc
->sc_reg
[NCR_TCH
* 4] << 16;
381 if (!fsc
->sc_datain
) {
382 cnt
+= fsc
->sc_reg
[NCR_FFLAG
* 4] & NCRFIFO_FF
;
383 fsc
->sc_reg
[NCR_CMD
* 4] = NCRCMD_FLUSH
;
385 cnt
= fsc
->sc_dmasize
- cnt
; /* number of bytes transferred */
386 NCR_DMA(("DMA xferred %d\n", cnt
));
387 if (fsc
->sc_xfr_align
) {
389 for (i
= 0; i
< cnt
; ++i
)
390 (*fsc
->sc_dmaaddr
)[i
] = fsc
->sc_alignbuf
[i
];
391 fsc
->sc_xfr_align
= 0;
393 *fsc
->sc_dmaaddr
+= cnt
;
394 *fsc
->sc_pdmalen
-= cnt
;
399 if ((sc
->sc_espintr
& NCRINTR_BS
) == 0) {
402 NCR_DMA(("no NCRINTR_BS\n"));
406 cnt
= fsc
->sc_dmasize
;
409 printf("data interrupt, but no count left.");
413 p
= *fsc
->sc_dmaaddr
;
414 flscphase
= sc
->sc_phase
;
415 flscstat
= (u_int
)sc
->sc_espstat
;
416 flscintr
= (u_int
)sc
->sc_espintr
;
417 cmdreg
= fsc
->sc_reg
+ NCR_CMD
* 4;
418 fiforeg
= fsc
->sc_reg
+ NCR_FIFO
* 4;
419 statreg
= fsc
->sc_reg
+ NCR_STAT
* 4;
420 intrreg
= fsc
->sc_reg
+ NCR_INTR
* 4;
421 NCR_DMA(("PIO %d datain %d phase %d stat %x intr %x\n",
422 cnt
, fsc
->sc_datain
, flscphase
, flscstat
, flscintr
));
424 if (fsc
->sc_datain
) {
427 if (flscphase
== DATA_IN_PHASE
) {
428 *cmdreg
= NCRCMD_TRANS
;
433 NCR_DMA(("flsc_dma_intr: PIO out- phase %d cnt %d active %d\n", flscphase
, cnt
,
435 if ( (flscphase
== DATA_OUT_PHASE
)
436 || (flscphase
== MESSAGE_OUT_PHASE
)) {
438 n
= 16 - (fsc
->sc_reg
[NCR_FFLAG
* 4] & NCRFIFO_FF
);
444 *cmdreg
= NCRCMD_TRANS
;
450 if (fsc
->sc_active
&& cnt
) {
451 while ((*statreg
& 0x80) == 0)
455 flscphase
= (flscintr
& NCRINTR_DIS
)
456 ? /* Disconnected */ BUSFREE_PHASE
457 : flscstat
& PHASE_MASK
;
459 } while (cnt
&& fsc
->sc_active
&& (flscintr
& NCRINTR_BS
) != 0);
461 if (fsc
->sc_dmasize
< 8 && cnt
)
462 printf("flsc_dma_intr: short transfer: dmasize %d cnt %d\n",
463 fsc
->sc_dmasize
, cnt
);
465 NCR_DMA(("flsc_dma_intr: PIO transfer [%d], %d->%d phase %d stat %x intr %x\n",
466 *fsc
->sc_pdmalen
, fsc
->sc_dmasize
, cnt
, flscphase
, flscstat
, flscintr
));
467 sc
->sc_phase
= flscphase
;
468 sc
->sc_espstat
= (uint8_t)flscstat
;
469 sc
->sc_espintr
= (uint8_t)flscintr
;
470 *fsc
->sc_dmaaddr
= p
;
471 *fsc
->sc_pdmalen
-= fsc
->sc_dmasize
- cnt
;
472 fsc
->sc_dmasize
= cnt
;
474 if (*fsc
->sc_pdmalen
== 0) {
475 sc
->sc_espstat
|= NCRSTAT_TC
;
482 flsc_dma_setup(struct ncr53c9x_softc
*sc
, uint8_t **addr
, size_t *len
,
483 int datain
, size_t *dmasize
)
485 struct flsc_softc
*fsc
= (struct flsc_softc
*)sc
;
490 fsc
->sc_dmaaddr
= addr
;
491 fsc
->sc_pdmalen
= len
;
492 fsc
->sc_datain
= datain
;
493 fsc
->sc_dmasize
= *dmasize
;
494 if (sc
->sc_nexus
->xs
->xs_control
& XS_CTL_POLL
) {
495 /* polling mode, use PIO */
496 *dmasize
= fsc
->sc_dmasize
;
497 NCR_DMA(("pfsc_dma_setup: PIO %p/%d [%d]\n", *addr
,
498 fsc
->sc_dmasize
, *len
));
506 fsc
->sc_reg
[NCR_FIFO
* 4] = **fsc
->sc_dmaaddr
;
507 (*fsc
->sc_pdmalen
)--;
508 (*fsc
->sc_dmaaddr
)++;
515 * DMA can be nasty for high-speed serial input, so limit the
516 * size of this DMA operation if the serial port is running at
517 * a high speed (higher than 19200 for now - should be adjusted
518 * based on CPU type and speed?).
519 * XXX - add serial speed check XXX
521 if (ser_open_speed
> 19200 && flsc_max_dma
!= 0 &&
522 fsc
->sc_dmasize
> flsc_max_dma
)
523 fsc
->sc_dmasize
= flsc_max_dma
;
524 ptr
= *addr
; /* Kernel virtual address */
525 pa
= kvtop(ptr
); /* Physical address of DMA */
526 xfer
= min(fsc
->sc_dmasize
, PAGE_SIZE
- (pa
& (PAGE_SIZE
- 1)));
527 fsc
->sc_xfr_align
= 0;
529 fsc
->sc_portbits
&= ~FLSC_PB_DMA_BITS
;
530 fsc
->sc_reg
[0x40] = fsc
->sc_portbits
;
531 fsc
->sc_reg
[0x80] = 0;
532 *((volatile uint32_t *)fsc
->sc_dmabase
) = 0;
535 * If output and length < 16, copy to fifo
537 if (datain
== 0 && fsc
->sc_dmasize
< 16) {
539 for (n
= 0; n
< fsc
->sc_dmasize
; ++n
)
540 fsc
->sc_reg
[NCR_FIFO
* 4] = *ptr
++;
541 NCR_DMA(("flsc_dma_setup: %d bytes written to fifo\n", n
));
544 *fsc
->sc_pdmalen
-= fsc
->sc_dmasize
;
545 *fsc
->sc_dmaaddr
+= fsc
->sc_dmasize
;
546 *dmasize
= fsc
->sc_dmasize
;
548 return 0; /* All done */
551 * If output and unaligned, copy unaligned data to fifo
553 else if (datain
== 0 && (int)ptr
& 3) {
554 int n
= 4 - ((int)ptr
& 3);
555 NCR_DMA(("flsc_dma_setup: align %d bytes written to fifo\n", n
));
559 fsc
->sc_reg
[NCR_FIFO
* 4] = *ptr
++;
562 * If unaligned address, read unaligned bytes into alignment buffer
564 else if ((int)ptr
& 3 || xfer
& 3) {
565 pa
= kvtop((void *)fsc
->sc_alignbuf
);
566 xfer
= fsc
->sc_dmasize
= min(xfer
, sizeof(fsc
->sc_unalignbuf
));
567 NCR_DMA(("flsc_dma_setup: align read by %d bytes\n", xfer
));
568 fsc
->sc_xfr_align
= 1;
571 * If length smaller than longword, read into alignment buffer
572 * XXX doesn't work for 1 or 2 bytes !!!!
574 else if (fsc
->sc_dmasize
< 4) {
575 NCR_DMA(("flsc_dma_setup: read remaining %d bytes\n",
577 pa
= kvtop((void *)fsc
->sc_alignbuf
);
578 fsc
->sc_xfr_align
= 1;
581 * Finally, limit transfer length to multiple of 4 bytes.
584 fsc
->sc_dmasize
&= -4;
588 while (xfer
< fsc
->sc_dmasize
) {
589 if ((pa
+ xfer
) != kvtop(*addr
+ xfer
))
591 if ((fsc
->sc_dmasize
- xfer
) < PAGE_SIZE
)
592 xfer
= fsc
->sc_dmasize
;
597 fsc
->sc_dmasize
= xfer
;
598 *dmasize
= fsc
->sc_dmasize
;
600 #if defined(M68040) || defined(M68060)
601 if (mmutype
== MMU_68040
) {
602 if (fsc
->sc_xfr_align
) {
604 for (n
= 0; n
< sizeof(fsc
->sc_unalignbuf
); ++n
)
605 fsc
->sc_alignbuf
[n
] = n
| 0x80;
606 dma_cachectl(fsc
->sc_alignbuf
,
607 sizeof(fsc
->sc_unalignbuf
));
610 dma_cachectl(*fsc
->sc_dmaaddr
, fsc
->sc_dmasize
);
613 fsc
->sc_reg
[0x80] = 0;
614 *((volatile uint32_t *)(fsc
->sc_dmabase
+ (pa
& 0x00fffffc))) = pa
;
615 fsc
->sc_portbits
&= ~FLSC_PB_DMA_BITS
;
616 fsc
->sc_portbits
|= FLSC_PB_ENABLE_DMA
|
617 (fsc
->sc_datain
? FLSC_PB_DMA_READ
: FLSC_PB_DMA_WRITE
);
618 fsc
->sc_reg
[0x40] = fsc
->sc_portbits
;
619 NCR_DMA(("flsc_dma_setup: DMA %p->%lx/%d [%d]\n",
620 ptr
, pa
, fsc
->sc_dmasize
, *len
));
626 flsc_dma_go(struct ncr53c9x_softc
*sc
)
628 struct flsc_softc
*fsc
= (struct flsc_softc
*)sc
;
630 NCR_DMA(("flsc_dma_go: datain %d size %d\n", fsc
->sc_datain
,
632 if (sc
->sc_nexus
->xs
->xs_control
& XS_CTL_POLL
) {
635 } else if (fsc
->sc_piomode
== 0) {
636 fsc
->sc_portbits
&= ~FLSC_PB_DMA_BITS
;
637 fsc
->sc_portbits
|= FLSC_PB_ENABLE_DMA
|
638 (fsc
->sc_datain
? FLSC_PB_DMA_READ
: FLSC_PB_DMA_WRITE
);
639 fsc
->sc_reg
[0x40] = fsc
->sc_portbits
;
644 flsc_dma_stop(struct ncr53c9x_softc
*sc
)
646 struct flsc_softc
*fsc
= (struct flsc_softc
*)sc
;
648 fsc
->sc_portbits
&= ~FLSC_PB_DMA_BITS
;
649 fsc
->sc_reg
[0x40] = fsc
->sc_portbits
;
651 fsc
->sc_reg
[0x80] = 0;
652 *((volatile uint32_t *)fsc
->sc_dmabase
) = 0;
657 flsc_dma_isactive(struct ncr53c9x_softc
*sc
)
659 struct flsc_softc
*fsc
= (struct flsc_softc
*)sc
;
661 return fsc
->sc_active
;