1*40f7eaafSjdolecek /* $NetBSD: bzivsc.c,v 1.33 2019/01/08 19:41:09 jdolecek Exp $ */
206ff9502Smhitch
306ff9502Smhitch /*
406ff9502Smhitch * Copyright (c) 1997 Michael L. Hitch
506ff9502Smhitch * Copyright (c) 1982, 1990 The Regents of the University of California.
606ff9502Smhitch * All rights reserved.
706ff9502Smhitch *
806ff9502Smhitch * Redistribution and use in source and binary forms, with or without
906ff9502Smhitch * modification, are permitted provided that the following conditions
1006ff9502Smhitch * are met:
1106ff9502Smhitch * 1. Redistributions of source code must retain the above copyright
1206ff9502Smhitch * notice, this list of conditions and the following disclaimer.
1306ff9502Smhitch * 2. Redistributions in binary form must reproduce the above copyright
1406ff9502Smhitch * notice, this list of conditions and the following disclaimer in the
1506ff9502Smhitch * documentation and/or other materials provided with the distribution.
1678f74058Ssnj * 3. Neither the name of the University nor the names of its contributors
1706ff9502Smhitch * may be used to endorse or promote products derived from this software
1806ff9502Smhitch * without specific prior written permission.
1906ff9502Smhitch *
2006ff9502Smhitch * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2106ff9502Smhitch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2206ff9502Smhitch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2306ff9502Smhitch * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2406ff9502Smhitch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2506ff9502Smhitch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2606ff9502Smhitch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2706ff9502Smhitch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2806ff9502Smhitch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2906ff9502Smhitch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3006ff9502Smhitch * SUCH DAMAGE.
3106ff9502Smhitch *
3206ff9502Smhitch */
3306ff9502Smhitch
3423b820a8Sphx #ifdef __m68k__
35bd01b4a3Smrg #include "opt_m68k_arch.h"
3623b820a8Sphx #endif
37bd01b4a3Smrg
381ea4df81Saymeric #include <sys/cdefs.h>
39*40f7eaafSjdolecek __KERNEL_RCSID(0, "$NetBSD: bzivsc.c,v 1.33 2019/01/08 19:41:09 jdolecek Exp $");
401ea4df81Saymeric
4106ff9502Smhitch #include <sys/types.h>
4206ff9502Smhitch #include <sys/param.h>
4306ff9502Smhitch #include <sys/systm.h>
4406ff9502Smhitch #include <sys/kernel.h>
4506ff9502Smhitch #include <sys/errno.h>
4606ff9502Smhitch #include <sys/ioctl.h>
4706ff9502Smhitch #include <sys/device.h>
4806ff9502Smhitch #include <sys/buf.h>
4906ff9502Smhitch #include <sys/proc.h>
5006ff9502Smhitch #include <sys/queue.h>
5106ff9502Smhitch
5206ff9502Smhitch #include <dev/scsipi/scsi_all.h>
5306ff9502Smhitch #include <dev/scsipi/scsipi_all.h>
5406ff9502Smhitch #include <dev/scsipi/scsiconf.h>
5506ff9502Smhitch #include <dev/scsipi/scsi_message.h>
5606ff9502Smhitch
5706ff9502Smhitch #include <machine/cpu.h>
5806ff9502Smhitch
5906ff9502Smhitch #include <dev/ic/ncr53c9xreg.h>
6006ff9502Smhitch #include <dev/ic/ncr53c9xvar.h>
6106ff9502Smhitch
6206ff9502Smhitch #include <amiga/amiga/isr.h>
6306ff9502Smhitch #include <amiga/dev/bzivscvar.h>
6406ff9502Smhitch #include <amiga/dev/zbusvar.h>
6506ff9502Smhitch
661ee8b50fSis #ifdef __powerpc__
671ee8b50fSis #define badaddr(a) badaddr_read(a, 2, NULL)
681ee8b50fSis #endif
691ee8b50fSis
7078a1d236Stsutsui int bzivscmatch(device_t, cfdata_t, void *);
7178a1d236Stsutsui void bzivscattach(device_t, device_t, void *);
7206ff9502Smhitch
7306ff9502Smhitch /* Linkup to the rest of the kernel */
7478a1d236Stsutsui CFATTACH_DECL_NEW(bzivsc, sizeof(struct bzivsc_softc),
75c5e91d44Sthorpej bzivscmatch, bzivscattach, NULL, NULL);
7606ff9502Smhitch
7706ff9502Smhitch /*
7806ff9502Smhitch * Functions and the switch for the MI code.
7906ff9502Smhitch */
8078a1d236Stsutsui uint8_t bzivsc_read_reg(struct ncr53c9x_softc *, int);
8178a1d236Stsutsui void bzivsc_write_reg(struct ncr53c9x_softc *, int, uint8_t);
829382c873Saymeric int bzivsc_dma_isintr(struct ncr53c9x_softc *);
839382c873Saymeric void bzivsc_dma_reset(struct ncr53c9x_softc *);
849382c873Saymeric int bzivsc_dma_intr(struct ncr53c9x_softc *);
8578a1d236Stsutsui int bzivsc_dma_setup(struct ncr53c9x_softc *, uint8_t **,
869382c873Saymeric size_t *, int, size_t *);
879382c873Saymeric void bzivsc_dma_go(struct ncr53c9x_softc *);
889382c873Saymeric void bzivsc_dma_stop(struct ncr53c9x_softc *);
899382c873Saymeric int bzivsc_dma_isactive(struct ncr53c9x_softc *);
9006ff9502Smhitch
9106ff9502Smhitch struct ncr53c9x_glue bzivsc_glue = {
9206ff9502Smhitch bzivsc_read_reg,
9306ff9502Smhitch bzivsc_write_reg,
9406ff9502Smhitch bzivsc_dma_isintr,
9506ff9502Smhitch bzivsc_dma_reset,
9606ff9502Smhitch bzivsc_dma_intr,
9706ff9502Smhitch bzivsc_dma_setup,
9806ff9502Smhitch bzivsc_dma_go,
9906ff9502Smhitch bzivsc_dma_stop,
10006ff9502Smhitch bzivsc_dma_isactive,
10178a1d236Stsutsui NULL,
10206ff9502Smhitch };
10306ff9502Smhitch
10406ff9502Smhitch /* Maximum DMA transfer length to reduce impact on high-speed serial input */
10506ff9502Smhitch u_long bzivsc_max_dma = 1024;
10606ff9502Smhitch extern int ser_open_speed;
10706ff9502Smhitch
10806ff9502Smhitch u_long bzivsc_cnt_pio = 0; /* number of PIO transfers */
10906ff9502Smhitch u_long bzivsc_cnt_dma = 0; /* number of DMA transfers */
11006ff9502Smhitch u_long bzivsc_cnt_dma2 = 0; /* number of DMA transfers broken up */
11106ff9502Smhitch u_long bzivsc_cnt_dma3 = 0; /* number of pages combined */
11206ff9502Smhitch
11306ff9502Smhitch #ifdef DEBUG
11406ff9502Smhitch struct {
11578a1d236Stsutsui uint8_t hardbits;
11678a1d236Stsutsui uint8_t status;
11778a1d236Stsutsui uint8_t xx;
11878a1d236Stsutsui uint8_t yy;
11906ff9502Smhitch } bzivsc_trace[128];
12006ff9502Smhitch int bzivsc_trace_ptr = 0;
12106ff9502Smhitch int bzivsc_trace_enable = 1;
1229382c873Saymeric void bzivsc_dump(void);
12306ff9502Smhitch #endif
12406ff9502Smhitch
12506ff9502Smhitch /*
12606ff9502Smhitch * if we are a Phase5 Blizzard 12x0-IV
12706ff9502Smhitch */
12806ff9502Smhitch int
bzivscmatch(device_t parent,cfdata_t cf,void * aux)12978a1d236Stsutsui bzivscmatch(device_t parent, cfdata_t cf, void *aux)
13006ff9502Smhitch {
13106ff9502Smhitch struct zbus_args *zap;
13278a1d236Stsutsui volatile uint8_t *regs;
13306ff9502Smhitch
13406ff9502Smhitch zap = aux;
13506ff9502Smhitch if (zap->manid != 0x2140)
13678a1d236Stsutsui return 0; /* It's not Phase 5 */
13706ff9502Smhitch if (zap->prodid != 11 && zap->prodid != 17)
13878a1d236Stsutsui return 0; /* Not Blizzard 12x0 */
13906ff9502Smhitch if (!is_a1200())
14078a1d236Stsutsui return 0; /* And not A1200 */
14106ff9502Smhitch regs = &((volatile u_char *)zap->va)[0x8000];
14253524e44Schristos if (badaddr((void *)__UNVOLATILE(regs)))
14378a1d236Stsutsui return 0;
14406ff9502Smhitch regs[NCR_CFG1 * 4] = 0;
14506ff9502Smhitch regs[NCR_CFG1 * 4] = NCRCFG1_PARENB | 7;
14606ff9502Smhitch delay(5);
14706ff9502Smhitch if (regs[NCR_CFG1 * 4] != (NCRCFG1_PARENB | 7))
14878a1d236Stsutsui return 0;
14978a1d236Stsutsui return 1;
15006ff9502Smhitch }
15106ff9502Smhitch
15206ff9502Smhitch /*
15306ff9502Smhitch * Attach this instance, and then all the sub-devices
15406ff9502Smhitch */
15506ff9502Smhitch void
bzivscattach(device_t parent,device_t self,void * aux)15678a1d236Stsutsui bzivscattach(device_t parent, device_t self, void *aux)
15706ff9502Smhitch {
15878a1d236Stsutsui struct bzivsc_softc *bsc = device_private(self);
15906ff9502Smhitch struct ncr53c9x_softc *sc = &bsc->sc_ncr53c9x;
16006ff9502Smhitch struct zbus_args *zap;
16106ff9502Smhitch extern u_long scsi_nosync;
16206ff9502Smhitch extern int shift_nosync;
16306ff9502Smhitch extern int ncr53c9x_debug;
16406ff9502Smhitch
16506ff9502Smhitch /*
16606ff9502Smhitch * Set up the glue for MI code early; we use some of it here.
16706ff9502Smhitch */
16878a1d236Stsutsui sc->sc_dev = self;
16906ff9502Smhitch sc->sc_glue = &bzivsc_glue;
17006ff9502Smhitch
17106ff9502Smhitch /*
17206ff9502Smhitch * Save the regs
17306ff9502Smhitch */
17406ff9502Smhitch zap = aux;
17578a1d236Stsutsui bsc->sc_reg = &((volatile uint8_t *)zap->va)[0x8000];
17606ff9502Smhitch bsc->sc_dmabase = &bsc->sc_reg[0x8000];
17706ff9502Smhitch
178a1f606d3Slukem sc->sc_freq = 40; /* Clocked at 40 MHz */
17906ff9502Smhitch
18078a1d236Stsutsui aprint_normal(": address %p", bsc->sc_reg);
18106ff9502Smhitch
18206ff9502Smhitch sc->sc_id = 7;
18306ff9502Smhitch
18406ff9502Smhitch /*
18506ff9502Smhitch * It is necessary to try to load the 2nd config register here,
18606ff9502Smhitch * to find out what rev the FAS chip is, else the ncr53c9x_reset
18706ff9502Smhitch * will not set up the defaults correctly.
18806ff9502Smhitch */
18906ff9502Smhitch sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
19006ff9502Smhitch sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_FE;
19106ff9502Smhitch sc->sc_cfg3 = 0x08 /*FCLK*/ | NCRESPCFG3_FSCSI | NCRESPCFG3_CDB;
19206ff9502Smhitch sc->sc_rev = NCR_VARIANT_FAS216;
19306ff9502Smhitch
19406ff9502Smhitch /*
19506ff9502Smhitch * This is the value used to start sync negotiations
19606ff9502Smhitch * Note that the NCR register "SYNCTP" is programmed
19706ff9502Smhitch * in "clocks per byte", and has a minimum value of 4.
19806ff9502Smhitch * The SCSI period used in negotiation is one-fourth
19906ff9502Smhitch * of the time (in nanoseconds) needed to transfer one byte.
20006ff9502Smhitch * Since the chip's clock is given in MHz, we have the following
20106ff9502Smhitch * formula: 4 * period = (1000 / freq) * 4
20206ff9502Smhitch */
20306ff9502Smhitch sc->sc_minsync = 1000 / sc->sc_freq;
20406ff9502Smhitch
20506ff9502Smhitch /*
20606ff9502Smhitch * get flags from -I argument and set cf_flags.
20706ff9502Smhitch * NOTE: low 8 bits are to disable disconnect, and the next
20806ff9502Smhitch * 8 bits are to disable sync.
20906ff9502Smhitch */
21078a1d236Stsutsui device_cfdata(self)->cf_flags |= (scsi_nosync >> shift_nosync)
21106ff9502Smhitch & 0xffff;
21206ff9502Smhitch shift_nosync += 16;
21306ff9502Smhitch
21406ff9502Smhitch /* Use next 16 bits of -I argument to set ncr53c9x_debug flags */
21506ff9502Smhitch ncr53c9x_debug |= (scsi_nosync >> shift_nosync) & 0xffff;
21606ff9502Smhitch shift_nosync += 16;
21706ff9502Smhitch
21806ff9502Smhitch #if 1
21906ff9502Smhitch if (((scsi_nosync >> shift_nosync) & 0xff00) == 0xff00)
22006ff9502Smhitch sc->sc_minsync = 0;
22106ff9502Smhitch #endif
22206ff9502Smhitch
22306ff9502Smhitch /* Really no limit, but since we want to fit into the TCR... */
22406ff9502Smhitch sc->sc_maxxfer = 64 * 1024;
22506ff9502Smhitch
22606ff9502Smhitch /*
22706ff9502Smhitch * Configure interrupts.
22806ff9502Smhitch */
2298c4d1bf1Stsutsui bsc->sc_isr.isr_intr = ncr53c9x_intr;
23006ff9502Smhitch bsc->sc_isr.isr_arg = sc;
23106ff9502Smhitch bsc->sc_isr.isr_ipl = 2;
23206ff9502Smhitch add_isr(&bsc->sc_isr);
23306ff9502Smhitch
23406ff9502Smhitch /*
23506ff9502Smhitch * Now try to attach all the sub-devices
23606ff9502Smhitch */
237937a7a3eSbouyer sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request;
238937a7a3eSbouyer sc->sc_adapter.adapt_minphys = minphys;
239937a7a3eSbouyer ncr53c9x_attach(sc);
24006ff9502Smhitch }
24106ff9502Smhitch
24206ff9502Smhitch /*
24306ff9502Smhitch * Glue functions.
24406ff9502Smhitch */
24506ff9502Smhitch
24678a1d236Stsutsui uint8_t
bzivsc_read_reg(struct ncr53c9x_softc * sc,int reg)2479382c873Saymeric bzivsc_read_reg(struct ncr53c9x_softc *sc, int reg)
24806ff9502Smhitch {
24906ff9502Smhitch struct bzivsc_softc *bsc = (struct bzivsc_softc *)sc;
25006ff9502Smhitch
25106ff9502Smhitch return bsc->sc_reg[reg * 4];
25206ff9502Smhitch }
25306ff9502Smhitch
25406ff9502Smhitch void
bzivsc_write_reg(struct ncr53c9x_softc * sc,int reg,uint8_t val)25578a1d236Stsutsui bzivsc_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t val)
25606ff9502Smhitch {
25706ff9502Smhitch struct bzivsc_softc *bsc = (struct bzivsc_softc *)sc;
25878a1d236Stsutsui uint8_t v = val;
25906ff9502Smhitch
26006ff9502Smhitch bsc->sc_reg[reg * 4] = v;
26106ff9502Smhitch #ifdef DEBUG
262e6c88a76Sthorpej if (bzivsc_trace_enable/* && sc->sc_nexus && sc->sc_nexus->xs->xs_control & XS_CTL_POLL */ &&
26306ff9502Smhitch reg == NCR_CMD/* && bsc->sc_active*/) {
26406ff9502Smhitch bzivsc_trace[(bzivsc_trace_ptr - 1) & 127].yy = v;
26506ff9502Smhitch /* printf(" cmd %x", v);*/
26606ff9502Smhitch }
26706ff9502Smhitch #endif
26806ff9502Smhitch }
26906ff9502Smhitch
27006ff9502Smhitch int
bzivsc_dma_isintr(struct ncr53c9x_softc * sc)2719382c873Saymeric bzivsc_dma_isintr(struct ncr53c9x_softc *sc)
27206ff9502Smhitch {
27306ff9502Smhitch struct bzivsc_softc *bsc = (struct bzivsc_softc *)sc;
27406ff9502Smhitch
27506ff9502Smhitch if ((bsc->sc_reg[NCR_STAT * 4] & NCRSTAT_INT) == 0)
27606ff9502Smhitch return 0;
27706ff9502Smhitch
27806ff9502Smhitch #ifdef DEBUG
279e6c88a76Sthorpej if (/*sc->sc_nexus && sc->sc_nexus->xs->xs_control & XS_CTL_POLL &&*/ bzivsc_trace_enable) {
28006ff9502Smhitch bzivsc_trace[bzivsc_trace_ptr].status = bsc->sc_reg[NCR_STAT * 4];
28106ff9502Smhitch bzivsc_trace[bzivsc_trace_ptr].xx = bsc->sc_reg[NCR_CMD * 4];
28206ff9502Smhitch bzivsc_trace[bzivsc_trace_ptr].yy = bsc->sc_active;
28306ff9502Smhitch bzivsc_trace_ptr = (bzivsc_trace_ptr + 1) & 127;
28406ff9502Smhitch }
28506ff9502Smhitch #endif
28606ff9502Smhitch return 1;
28706ff9502Smhitch }
28806ff9502Smhitch
28906ff9502Smhitch void
bzivsc_dma_reset(struct ncr53c9x_softc * sc)2909382c873Saymeric bzivsc_dma_reset(struct ncr53c9x_softc *sc)
29106ff9502Smhitch {
29206ff9502Smhitch struct bzivsc_softc *bsc = (struct bzivsc_softc *)sc;
29306ff9502Smhitch
29406ff9502Smhitch bsc->sc_active = 0;
29506ff9502Smhitch }
29606ff9502Smhitch
29706ff9502Smhitch int
bzivsc_dma_intr(struct ncr53c9x_softc * sc)2989382c873Saymeric bzivsc_dma_intr(struct ncr53c9x_softc *sc)
29906ff9502Smhitch {
30006ff9502Smhitch register struct bzivsc_softc *bsc = (struct bzivsc_softc *)sc;
30106ff9502Smhitch register int cnt;
30206ff9502Smhitch
30306ff9502Smhitch NCR_DMA(("bzivsc_dma_intr: cnt %d int %x stat %x fifo %d ",
30406ff9502Smhitch bsc->sc_dmasize, sc->sc_espintr, sc->sc_espstat,
30506ff9502Smhitch bsc->sc_reg[NCR_FFLAG * 4] & NCRFIFO_FF));
30606ff9502Smhitch if (bsc->sc_active == 0) {
30706ff9502Smhitch printf("bzivsc_intr--inactive DMA\n");
30806ff9502Smhitch return -1;
30906ff9502Smhitch }
31006ff9502Smhitch
31106ff9502Smhitch /* update sc_dmaaddr and sc_pdmalen */
31206ff9502Smhitch cnt = bsc->sc_reg[NCR_TCL * 4];
31306ff9502Smhitch cnt += bsc->sc_reg[NCR_TCM * 4] << 8;
31406ff9502Smhitch cnt += bsc->sc_reg[NCR_TCH * 4] << 16;
31506ff9502Smhitch if (!bsc->sc_datain) {
31606ff9502Smhitch cnt += bsc->sc_reg[NCR_FFLAG * 4] & NCRFIFO_FF;
31706ff9502Smhitch bsc->sc_reg[NCR_CMD * 4] = NCRCMD_FLUSH;
31806ff9502Smhitch }
31906ff9502Smhitch cnt = bsc->sc_dmasize - cnt; /* number of bytes transferred */
32006ff9502Smhitch NCR_DMA(("DMA xferred %d\n", cnt));
32106ff9502Smhitch if (bsc->sc_xfr_align) {
32278a1d236Stsutsui memcpy(*bsc->sc_dmaaddr, bsc->sc_alignbuf, cnt);
32306ff9502Smhitch bsc->sc_xfr_align = 0;
32406ff9502Smhitch }
32506ff9502Smhitch *bsc->sc_dmaaddr += cnt;
32606ff9502Smhitch *bsc->sc_pdmalen -= cnt;
32706ff9502Smhitch bsc->sc_active = 0;
32806ff9502Smhitch return 0;
32906ff9502Smhitch }
33006ff9502Smhitch
33106ff9502Smhitch int
bzivsc_dma_setup(struct ncr53c9x_softc * sc,uint8_t ** addr,size_t * len,int datain,size_t * dmasize)33278a1d236Stsutsui bzivsc_dma_setup(struct ncr53c9x_softc *sc, uint8_t **addr, size_t *len,
3339382c873Saymeric int datain, size_t *dmasize)
33406ff9502Smhitch {
33506ff9502Smhitch struct bzivsc_softc *bsc = (struct bzivsc_softc *)sc;
336744246faSis paddr_t pa;
33778a1d236Stsutsui uint8_t *ptr;
33806ff9502Smhitch size_t xfer;
33906ff9502Smhitch
34078a1d236Stsutsui bsc->sc_dmaaddr = addr;
34106ff9502Smhitch bsc->sc_pdmalen = len;
34206ff9502Smhitch bsc->sc_datain = datain;
34306ff9502Smhitch bsc->sc_dmasize = *dmasize;
34406ff9502Smhitch /*
34506ff9502Smhitch * DMA can be nasty for high-speed serial input, so limit the
34606ff9502Smhitch * size of this DMA operation if the serial port is running at
34706ff9502Smhitch * a high speed (higher than 19200 for now - should be adjusted
348d20841bbSwiz * based on CPU type and speed?).
34906ff9502Smhitch * XXX - add serial speed check XXX
35006ff9502Smhitch */
35106ff9502Smhitch if (ser_open_speed > 19200 && bzivsc_max_dma != 0 &&
35206ff9502Smhitch bsc->sc_dmasize > bzivsc_max_dma)
35306ff9502Smhitch bsc->sc_dmasize = bzivsc_max_dma;
35406ff9502Smhitch ptr = *addr; /* Kernel virtual address */
35506ff9502Smhitch pa = kvtop(ptr); /* Physical address of DMA */
356d1579b2dSriastradh xfer = uimin(bsc->sc_dmasize, PAGE_SIZE - (pa & (PAGE_SIZE - 1)));
35706ff9502Smhitch bsc->sc_xfr_align = 0;
35806ff9502Smhitch /*
35906ff9502Smhitch * If output and unaligned, stuff odd byte into FIFO
36006ff9502Smhitch */
36106ff9502Smhitch if (datain == 0 && (int)ptr & 1) {
36206ff9502Smhitch NCR_DMA(("bzivsc_dma_setup: align byte written to fifo\n"));
36306ff9502Smhitch pa++;
36406ff9502Smhitch xfer--; /* XXXX CHECK THIS !!!! XXXX */
36506ff9502Smhitch bsc->sc_reg[NCR_FIFO * 4] = *ptr++;
36606ff9502Smhitch }
36706ff9502Smhitch /*
36806ff9502Smhitch * If unaligned address, read unaligned bytes into alignment buffer
36906ff9502Smhitch */
37006ff9502Smhitch else if ((int)ptr & 1) {
37153524e44Schristos pa = kvtop((void *)&bsc->sc_alignbuf);
372d1579b2dSriastradh xfer = bsc->sc_dmasize = uimin(xfer, sizeof(bsc->sc_alignbuf));
37306ff9502Smhitch NCR_DMA(("bzivsc_dma_setup: align read by %d bytes\n", xfer));
37406ff9502Smhitch bsc->sc_xfr_align = 1;
37506ff9502Smhitch }
37606ff9502Smhitch ++bzivsc_cnt_dma; /* number of DMA operations */
37706ff9502Smhitch
37806ff9502Smhitch while (xfer < bsc->sc_dmasize) {
37978a1d236Stsutsui if ((pa + xfer) != kvtop(*addr + xfer))
38006ff9502Smhitch break;
3818818afa4Sthorpej if ((bsc->sc_dmasize - xfer) < PAGE_SIZE)
38206ff9502Smhitch xfer = bsc->sc_dmasize;
38306ff9502Smhitch else
3848818afa4Sthorpej xfer += PAGE_SIZE;
38506ff9502Smhitch ++bzivsc_cnt_dma3;
38606ff9502Smhitch }
38706ff9502Smhitch if (xfer != *len)
38806ff9502Smhitch ++bzivsc_cnt_dma2;
38906ff9502Smhitch
39006ff9502Smhitch bsc->sc_dmasize = xfer;
39106ff9502Smhitch *dmasize = bsc->sc_dmasize;
39206ff9502Smhitch bsc->sc_pa = pa;
39306ff9502Smhitch #if defined(M68040) || defined(M68060)
39406ff9502Smhitch if (mmutype == MMU_68040) {
39506ff9502Smhitch if (bsc->sc_xfr_align) {
39606ff9502Smhitch dma_cachectl(bsc->sc_alignbuf,
39706ff9502Smhitch sizeof(bsc->sc_alignbuf));
39806ff9502Smhitch }
39906ff9502Smhitch else
40006ff9502Smhitch dma_cachectl(*bsc->sc_dmaaddr, bsc->sc_dmasize);
40106ff9502Smhitch }
40206ff9502Smhitch #endif
40306ff9502Smhitch
40406ff9502Smhitch pa >>= 1;
40506ff9502Smhitch if (!bsc->sc_datain)
40606ff9502Smhitch pa |= 0x80000000;
40778a1d236Stsutsui bsc->sc_dmabase[0x8000] = (uint8_t)(pa >> 24);
40878a1d236Stsutsui bsc->sc_dmabase[0] = (uint8_t)(pa >> 24);
40978a1d236Stsutsui bsc->sc_dmabase[0] = (uint8_t)(pa >> 16);
41078a1d236Stsutsui bsc->sc_dmabase[0] = (uint8_t)(pa >> 8);
41178a1d236Stsutsui bsc->sc_dmabase[0] = (uint8_t)(pa);
41206ff9502Smhitch bsc->sc_active = 1;
41306ff9502Smhitch return 0;
41406ff9502Smhitch }
41506ff9502Smhitch
41606ff9502Smhitch void
bzivsc_dma_go(struct ncr53c9x_softc * sc)4179382c873Saymeric bzivsc_dma_go(struct ncr53c9x_softc *sc)
41806ff9502Smhitch {
41906ff9502Smhitch }
42006ff9502Smhitch
42106ff9502Smhitch void
bzivsc_dma_stop(struct ncr53c9x_softc * sc)4229382c873Saymeric bzivsc_dma_stop(struct ncr53c9x_softc *sc)
42306ff9502Smhitch {
42406ff9502Smhitch }
42506ff9502Smhitch
42606ff9502Smhitch int
bzivsc_dma_isactive(struct ncr53c9x_softc * sc)4279382c873Saymeric bzivsc_dma_isactive(struct ncr53c9x_softc *sc)
42806ff9502Smhitch {
42906ff9502Smhitch struct bzivsc_softc *bsc = (struct bzivsc_softc *)sc;
43006ff9502Smhitch
43106ff9502Smhitch return bsc->sc_active;
43206ff9502Smhitch }
43306ff9502Smhitch
43406ff9502Smhitch #ifdef DEBUG
43506ff9502Smhitch void
bzivsc_dump(void)4369382c873Saymeric bzivsc_dump(void)
43706ff9502Smhitch {
43806ff9502Smhitch int i;
43906ff9502Smhitch
44006ff9502Smhitch i = bzivsc_trace_ptr;
44106ff9502Smhitch printf("bzivsc_trace dump: ptr %x\n", bzivsc_trace_ptr);
44206ff9502Smhitch do {
44306ff9502Smhitch if (bzivsc_trace[i].hardbits == 0) {
44406ff9502Smhitch i = (i + 1) & 127;
44506ff9502Smhitch continue;
44606ff9502Smhitch }
44706ff9502Smhitch printf("%02x%02x%02x%02x(", bzivsc_trace[i].hardbits,
44806ff9502Smhitch bzivsc_trace[i].status, bzivsc_trace[i].xx, bzivsc_trace[i].yy);
44906ff9502Smhitch if (bzivsc_trace[i].status & NCRSTAT_INT)
45006ff9502Smhitch printf("NCRINT/");
45106ff9502Smhitch if (bzivsc_trace[i].status & NCRSTAT_TC)
45206ff9502Smhitch printf("NCRTC/");
45306ff9502Smhitch switch(bzivsc_trace[i].status & NCRSTAT_PHASE) {
45406ff9502Smhitch case 0:
45506ff9502Smhitch printf("dataout"); break;
45606ff9502Smhitch case 1:
45706ff9502Smhitch printf("datain"); break;
45806ff9502Smhitch case 2:
45906ff9502Smhitch printf("cmdout"); break;
46006ff9502Smhitch case 3:
46106ff9502Smhitch printf("status"); break;
46206ff9502Smhitch case 6:
46306ff9502Smhitch printf("msgout"); break;
46406ff9502Smhitch case 7:
46506ff9502Smhitch printf("msgin"); break;
46606ff9502Smhitch default:
46706ff9502Smhitch printf("phase%d?", bzivsc_trace[i].status & NCRSTAT_PHASE);
46806ff9502Smhitch }
46906ff9502Smhitch printf(") ");
47006ff9502Smhitch i = (i + 1) & 127;
47106ff9502Smhitch } while (i != bzivsc_trace_ptr);
47206ff9502Smhitch printf("\n");
47306ff9502Smhitch }
47406ff9502Smhitch #endif
475