xref: /netbsd-src/sys/arch/amiga/dev/bzsc.c (revision 40f7eaaf2596ce16adf343e6680d62b6ed6f12dd)
1*40f7eaafSjdolecek /*	$NetBSD: bzsc.c,v 1.50 2019/01/08 19:41:09 jdolecek Exp $ */
2974e9f6eSveego 
321d667c8Schopps /*
431508593Smhitch  * Copyright (c) 1997 Michael L. Hitch
521d667c8Schopps  * Copyright (c) 1995 Daniel Widenfalk
621d667c8Schopps  * Copyright (c) 1994 Christian E. Hopps
721d667c8Schopps  * Copyright (c) 1982, 1990 The Regents of the University of California.
821d667c8Schopps  * All rights reserved.
921d667c8Schopps  *
1021d667c8Schopps  * Redistribution and use in source and binary forms, with or without
1121d667c8Schopps  * modification, are permitted provided that the following conditions
1221d667c8Schopps  * are met:
1321d667c8Schopps  * 1. Redistributions of source code must retain the above copyright
1421d667c8Schopps  *    notice, this list of conditions and the following disclaimer.
1521d667c8Schopps  * 2. Redistributions in binary form must reproduce the above copyright
1621d667c8Schopps  *    notice, this list of conditions and the following disclaimer in the
1721d667c8Schopps  *    documentation and/or other materials provided with the distribution.
1821d667c8Schopps  * 3. All advertising materials mentioning features or use of this software
1921d667c8Schopps  *    must display the following acknowledgement:
2031508593Smhitch  *	This product includes software developed by Daniel Widenfalk
2131508593Smhitch  *	and Michael L. Hitch.
2221d667c8Schopps  * 4. Neither the name of the University nor the names of its contributors
2321d667c8Schopps  *    may be used to endorse or promote products derived from this software
2421d667c8Schopps  *    without specific prior written permission.
2521d667c8Schopps  *
2621d667c8Schopps  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2721d667c8Schopps  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2821d667c8Schopps  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2921d667c8Schopps  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3021d667c8Schopps  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3121d667c8Schopps  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3221d667c8Schopps  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3321d667c8Schopps  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3421d667c8Schopps  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3521d667c8Schopps  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3621d667c8Schopps  * SUCH DAMAGE.
3721d667c8Schopps  */
3821d667c8Schopps 
3923b820a8Sphx #ifdef __m68k__
40bd01b4a3Smrg #include "opt_m68k_arch.h"
4123b820a8Sphx #endif
42bd01b4a3Smrg 
431ea4df81Saymeric #include <sys/cdefs.h>
44*40f7eaafSjdolecek __KERNEL_RCSID(0, "$NetBSD: bzsc.c,v 1.50 2019/01/08 19:41:09 jdolecek Exp $");
451ea4df81Saymeric 
4631508593Smhitch /*
4731508593Smhitch  * Initial amiga Blizzard 1230-II driver by Daniel Widenfalk.  Conversion to
4831508593Smhitch  * 53c9x MI driver by Michael L. Hitch (mhitch@montana.edu).
4931508593Smhitch  */
5031508593Smhitch 
5131508593Smhitch #include <sys/types.h>
5221d667c8Schopps #include <sys/param.h>
5321d667c8Schopps #include <sys/systm.h>
5421d667c8Schopps #include <sys/kernel.h>
5531508593Smhitch #include <sys/errno.h>
5631508593Smhitch #include <sys/ioctl.h>
5721d667c8Schopps #include <sys/device.h>
5831508593Smhitch #include <sys/buf.h>
5931508593Smhitch #include <sys/proc.h>
6031508593Smhitch #include <sys/queue.h>
6131508593Smhitch 
6231508593Smhitch #include <dev/scsipi/scsi_all.h>
6331508593Smhitch #include <dev/scsipi/scsipi_all.h>
6431508593Smhitch #include <dev/scsipi/scsiconf.h>
6531508593Smhitch #include <dev/scsipi/scsi_message.h>
6631508593Smhitch 
6731508593Smhitch #include <machine/cpu.h>
6831508593Smhitch 
6931508593Smhitch #include <dev/ic/ncr53c9xreg.h>
7031508593Smhitch #include <dev/ic/ncr53c9xvar.h>
7131508593Smhitch 
7221d667c8Schopps #include <amiga/amiga/isr.h>
7306ff9502Smhitch #include <amiga/dev/bzscvar.h>
7431508593Smhitch #include <amiga/dev/zbusvar.h>
7521d667c8Schopps 
761ee8b50fSis #ifdef __powerpc__
771ee8b50fSis #define badaddr(a)      badaddr_read(a, 2, NULL)
781ee8b50fSis #endif
791ee8b50fSis 
8078a1d236Stsutsui int	bzscmatch(device_t, cfdata_t, void *);
8178a1d236Stsutsui void	bzscattach(device_t, device_t, void *);
8221d667c8Schopps 
8331508593Smhitch /* Linkup to the rest of the kernel */
8478a1d236Stsutsui CFATTACH_DECL_NEW(bzsc, sizeof(struct bzsc_softc),
85c5e91d44Sthorpej     bzscmatch, bzscattach, NULL, NULL);
8621d667c8Schopps 
8721d667c8Schopps /*
8831508593Smhitch  * Functions and the switch for the MI code.
8931508593Smhitch  */
9078a1d236Stsutsui uint8_t	bzsc_read_reg(struct ncr53c9x_softc *, int);
9178a1d236Stsutsui void	bzsc_write_reg(struct ncr53c9x_softc *, int, uint8_t);
929382c873Saymeric int	bzsc_dma_isintr(struct ncr53c9x_softc *);
939382c873Saymeric void	bzsc_dma_reset(struct ncr53c9x_softc *);
949382c873Saymeric int	bzsc_dma_intr(struct ncr53c9x_softc *);
9578a1d236Stsutsui int	bzsc_dma_setup(struct ncr53c9x_softc *, uint8_t **,
969382c873Saymeric 	    size_t *, int, size_t *);
979382c873Saymeric void	bzsc_dma_go(struct ncr53c9x_softc *);
989382c873Saymeric void	bzsc_dma_stop(struct ncr53c9x_softc *);
999382c873Saymeric int	bzsc_dma_isactive(struct ncr53c9x_softc *);
10031508593Smhitch 
10131508593Smhitch struct ncr53c9x_glue bzsc_glue = {
10231508593Smhitch 	bzsc_read_reg,
10331508593Smhitch 	bzsc_write_reg,
10431508593Smhitch 	bzsc_dma_isintr,
10531508593Smhitch 	bzsc_dma_reset,
10631508593Smhitch 	bzsc_dma_intr,
10731508593Smhitch 	bzsc_dma_setup,
10831508593Smhitch 	bzsc_dma_go,
10931508593Smhitch 	bzsc_dma_stop,
11031508593Smhitch 	bzsc_dma_isactive,
11178a1d236Stsutsui 	NULL,
11231508593Smhitch };
11331508593Smhitch 
11431508593Smhitch /* Maximum DMA transfer length to reduce impact on high-speed serial input */
11531508593Smhitch u_long bzsc_max_dma = 1024;
11631508593Smhitch extern int ser_open_speed;
11731508593Smhitch 
11831508593Smhitch u_long bzsc_cnt_pio = 0;	/* number of PIO transfers */
11931508593Smhitch u_long bzsc_cnt_dma = 0;	/* number of DMA transfers */
12031508593Smhitch u_long bzsc_cnt_dma2 = 0;	/* number of DMA transfers broken up */
12131508593Smhitch u_long bzsc_cnt_dma3 = 0;	/* number of pages combined */
12231508593Smhitch 
12331508593Smhitch #ifdef DEBUG
12431508593Smhitch struct {
12578a1d236Stsutsui 	uint8_t hardbits;
12678a1d236Stsutsui 	uint8_t status;
12778a1d236Stsutsui 	uint8_t xx;
12878a1d236Stsutsui 	uint8_t yy;
12931508593Smhitch } bzsc_trace[128];
13031508593Smhitch int bzsc_trace_ptr = 0;
13131508593Smhitch int bzsc_trace_enable = 1;
1329382c873Saymeric void bzsc_dump(void);
13331508593Smhitch #endif
13431508593Smhitch 
13531508593Smhitch /*
13631508593Smhitch  * if we are a Phase5 Blizzard 1230 II
13721d667c8Schopps  */
138974e9f6eSveego int
bzscmatch(device_t parent,cfdata_t cf,void * aux)13978a1d236Stsutsui bzscmatch(device_t parent, cfdata_t cf, void *aux)
14021d667c8Schopps {
14121d667c8Schopps 	struct zbus_args *zap;
14278a1d236Stsutsui 	volatile uint8_t *regs;
14321d667c8Schopps 
14431508593Smhitch 	zap = aux;
14506ff9502Smhitch 	if (zap->manid != 0x2140 || zap->prodid != 11)
14678a1d236Stsutsui 		return 0;			/* It's not Blizzard 1230 */
14731508593Smhitch 	if (!is_a1200())
14878a1d236Stsutsui 		return 0;			/* And not A1200 */
14978a1d236Stsutsui 	regs = &((volatile uint8_t *)zap->va)[0x10000];
15053524e44Schristos 	if (badaddr((void *)__UNVOLATILE(regs)))
15178a1d236Stsutsui 		return 0;
15231508593Smhitch 	regs[NCR_CFG1 * 2] = 0;
15331508593Smhitch 	regs[NCR_CFG1 * 2] = NCRCFG1_PARENB | 7;
15431508593Smhitch 	delay(5);
15531508593Smhitch 	if (regs[NCR_CFG1 * 2] != (NCRCFG1_PARENB | 7))
15678a1d236Stsutsui 		return 0;
15778a1d236Stsutsui 	return 1;
15821d667c8Schopps }
15921d667c8Schopps 
16031508593Smhitch /*
16131508593Smhitch  * Attach this instance, and then all the sub-devices
16231508593Smhitch  */
163974e9f6eSveego void
bzscattach(device_t parent,device_t self,void * aux)16478a1d236Stsutsui bzscattach(device_t parent, device_t self, void *aux)
16521d667c8Schopps {
16678a1d236Stsutsui 	struct bzsc_softc *bsc = device_private(self);
16731508593Smhitch 	struct ncr53c9x_softc *sc = &bsc->sc_ncr53c9x;
16821d667c8Schopps 	struct zbus_args  *zap;
16931508593Smhitch 	extern u_long scsi_nosync;
17031508593Smhitch 	extern int shift_nosync;
17131508593Smhitch 	extern int ncr53c9x_debug;
17221d667c8Schopps 
17331508593Smhitch 	/*
17431508593Smhitch 	 * Set up the glue for MI code early; we use some of it here.
17531508593Smhitch 	 */
17678a1d236Stsutsui 	sc->sc_dev = self;
17731508593Smhitch 	sc->sc_glue = &bzsc_glue;
17821d667c8Schopps 
17931508593Smhitch 	/*
18031508593Smhitch 	 * Save the regs
18131508593Smhitch 	 */
18231508593Smhitch 	zap = aux;
18378a1d236Stsutsui 	bsc->sc_reg = &((volatile uint8_t *)zap->va)[0x10000];
18431508593Smhitch 	bsc->sc_dmabase = &bsc->sc_reg[0x21];
18506ff9502Smhitch 
186a1f606d3Slukem 	sc->sc_freq = 40;		/* Clocked at 40 MHz */
18706ff9502Smhitch 
18878a1d236Stsutsui 	aprint_normal(": address %p", bsc->sc_reg);
18906ff9502Smhitch 
19031508593Smhitch 	sc->sc_id = 7;
19106ff9502Smhitch 
19231508593Smhitch 	/*
19331508593Smhitch 	 * It is necessary to try to load the 2nd config register here,
19431508593Smhitch 	 * to find out what rev the FAS chip is, else the ncr53c9x_reset
19531508593Smhitch 	 * will not set up the defaults correctly.
19631508593Smhitch 	 */
19731508593Smhitch 	sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
19831508593Smhitch 	sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_FE;
19931508593Smhitch 	sc->sc_cfg3 = 0x08 /*FCLK*/ | NCRESPCFG3_FSCSI | NCRESPCFG3_CDB;
20031508593Smhitch 	sc->sc_rev = NCR_VARIANT_FAS216;
20106ff9502Smhitch 
20231508593Smhitch 	/*
20331508593Smhitch 	 * This is the value used to start sync negotiations
20431508593Smhitch 	 * Note that the NCR register "SYNCTP" is programmed
20531508593Smhitch 	 * in "clocks per byte", and has a minimum value of 4.
20631508593Smhitch 	 * The SCSI period used in negotiation is one-fourth
20731508593Smhitch 	 * of the time (in nanoseconds) needed to transfer one byte.
20831508593Smhitch 	 * Since the chip's clock is given in MHz, we have the following
20931508593Smhitch 	 * formula: 4 * period = (1000 / freq) * 4
21031508593Smhitch 	 */
21131508593Smhitch 	sc->sc_minsync = 1000 / sc->sc_freq;
21206ff9502Smhitch 
21331508593Smhitch 	/*
21431508593Smhitch 	 * get flags from -I argument and set cf_flags.
21531508593Smhitch 	 * NOTE: low 8 bits are to disable disconnect, and the next
21631508593Smhitch 	 *       8 bits are to disable sync.
21731508593Smhitch 	 */
21878a1d236Stsutsui 	device_cfdata(self)->cf_flags |= (scsi_nosync >> shift_nosync)
21931508593Smhitch 	    & 0xffff;
22031508593Smhitch 	shift_nosync += 16;
22106ff9502Smhitch 
22231508593Smhitch 	/* Use next 16 bits of -I argument to set ncr53c9x_debug flags */
22331508593Smhitch 	ncr53c9x_debug |= (scsi_nosync >> shift_nosync) & 0xffff;
22431508593Smhitch 	shift_nosync += 16;
22506ff9502Smhitch 
22631508593Smhitch #if 1
22731508593Smhitch 	if (((scsi_nosync >> shift_nosync) & 0xff00) == 0xff00)
22831508593Smhitch 		sc->sc_minsync = 0;
22906ff9502Smhitch #endif
23006ff9502Smhitch 
23131508593Smhitch 	/* Really no limit, but since we want to fit into the TCR... */
23231508593Smhitch 	sc->sc_maxxfer = 64 * 1024;
23306ff9502Smhitch 
23431508593Smhitch 	/*
23531508593Smhitch 	 * Configure interrupts.
23631508593Smhitch 	 */
2378c4d1bf1Stsutsui 	bsc->sc_isr.isr_intr = ncr53c9x_intr;
23831508593Smhitch 	bsc->sc_isr.isr_arg  = sc;
23931508593Smhitch 	bsc->sc_isr.isr_ipl  = 2;
24031508593Smhitch 	add_isr(&bsc->sc_isr);
24106ff9502Smhitch 
24231508593Smhitch 	/*
24331508593Smhitch 	 * Now try to attach all the sub-devices
24431508593Smhitch 	 */
245937a7a3eSbouyer 	sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request;
246937a7a3eSbouyer 	sc->sc_adapter.adapt_minphys = minphys;
247937a7a3eSbouyer 	ncr53c9x_attach(sc);
24821d667c8Schopps }
24921d667c8Schopps 
25031508593Smhitch /*
25131508593Smhitch  * Glue functions.
25231508593Smhitch  */
25321d667c8Schopps 
25478a1d236Stsutsui uint8_t
bzsc_read_reg(struct ncr53c9x_softc * sc,int reg)2559382c873Saymeric bzsc_read_reg(struct ncr53c9x_softc *sc, int reg)
25631508593Smhitch {
25731508593Smhitch 	struct bzsc_softc *bsc = (struct bzsc_softc *)sc;
25821d667c8Schopps 
25931508593Smhitch 	return bsc->sc_reg[reg * 2];
26031508593Smhitch }
26131508593Smhitch 
26231508593Smhitch void
bzsc_write_reg(struct ncr53c9x_softc * sc,int reg,uint8_t val)26378a1d236Stsutsui bzsc_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t val)
26431508593Smhitch {
26531508593Smhitch 	struct bzsc_softc *bsc = (struct bzsc_softc *)sc;
26678a1d236Stsutsui 	uint8_t v = val;
26731508593Smhitch 
26831508593Smhitch 	bsc->sc_reg[reg * 2] = v;
26931508593Smhitch #ifdef DEBUG
270e6c88a76Sthorpej if (bzsc_trace_enable/* && sc->sc_nexus && sc->sc_nexus->xs->xs_control & XS_CTL_POLL*/ &&
27131508593Smhitch   reg == NCR_CMD/* && bsc->sc_active*/) {
27231508593Smhitch   bzsc_trace[(bzsc_trace_ptr - 1) & 127].yy = v;
27331508593Smhitch /*  printf(" cmd %x", v);*/
27431508593Smhitch }
27531508593Smhitch #endif
27631508593Smhitch }
27731508593Smhitch 
27831508593Smhitch int
bzsc_dma_isintr(struct ncr53c9x_softc * sc)2799382c873Saymeric bzsc_dma_isintr(struct ncr53c9x_softc *sc)
28031508593Smhitch {
28131508593Smhitch 	struct bzsc_softc *bsc = (struct bzsc_softc *)sc;
28231508593Smhitch 
28331508593Smhitch 	if ((bsc->sc_reg[NCR_STAT * 2] & NCRSTAT_INT) == 0)
28431508593Smhitch 		return 0;
28531508593Smhitch 
28631508593Smhitch #ifdef DEBUG
287e6c88a76Sthorpej if (/*sc->sc_nexus && sc->sc_nexus->xs->xs_control & XS_CTL_POLL &&*/ bzsc_trace_enable) {
28831508593Smhitch   bzsc_trace[bzsc_trace_ptr].status = bsc->sc_reg[NCR_STAT * 2];
28931508593Smhitch   bzsc_trace[bzsc_trace_ptr].xx = bsc->sc_reg[NCR_CMD * 2];
29031508593Smhitch   bzsc_trace[bzsc_trace_ptr].yy = bsc->sc_active;
29131508593Smhitch   bzsc_trace_ptr = (bzsc_trace_ptr + 1) & 127;
29231508593Smhitch }
29331508593Smhitch #endif
29431508593Smhitch 	return 1;
29531508593Smhitch }
29631508593Smhitch 
29731508593Smhitch void
bzsc_dma_reset(struct ncr53c9x_softc * sc)2989382c873Saymeric bzsc_dma_reset(struct ncr53c9x_softc *sc)
29931508593Smhitch {
30031508593Smhitch 	struct bzsc_softc *bsc = (struct bzsc_softc *)sc;
30131508593Smhitch 
30231508593Smhitch 	bsc->sc_active = 0;
30331508593Smhitch }
30431508593Smhitch 
30531508593Smhitch int
bzsc_dma_intr(struct ncr53c9x_softc * sc)3069382c873Saymeric bzsc_dma_intr(struct ncr53c9x_softc *sc)
30731508593Smhitch {
30878a1d236Stsutsui 	struct bzsc_softc *bsc = (struct bzsc_softc *)sc;
30978a1d236Stsutsui 	int	cnt;
31031508593Smhitch 
31131508593Smhitch 	NCR_DMA(("bzsc_dma_intr: cnt %d int %x stat %x fifo %d ",
31231508593Smhitch 	    bsc->sc_dmasize, sc->sc_espintr, sc->sc_espstat,
31331508593Smhitch 	    bsc->sc_reg[NCR_FFLAG * 2] & NCRFIFO_FF));
31431508593Smhitch 	if (bsc->sc_active == 0) {
31531508593Smhitch 		printf("bzsc_intr--inactive DMA\n");
31631508593Smhitch 		return -1;
31731508593Smhitch 	}
31831508593Smhitch 
31931508593Smhitch 	/* update sc_dmaaddr and sc_pdmalen */
32031508593Smhitch 	cnt = bsc->sc_reg[NCR_TCL * 2];
32131508593Smhitch 	cnt += bsc->sc_reg[NCR_TCM * 2] << 8;
32231508593Smhitch 	cnt += bsc->sc_reg[NCR_TCH * 2] << 16;
32331508593Smhitch 	if (!bsc->sc_datain) {
32431508593Smhitch 		cnt += bsc->sc_reg[NCR_FFLAG * 2] & NCRFIFO_FF;
32531508593Smhitch 		bsc->sc_reg[NCR_CMD * 2] = NCRCMD_FLUSH;
32631508593Smhitch 	}
32731508593Smhitch 	cnt = bsc->sc_dmasize - cnt;	/* number of bytes transferred */
32831508593Smhitch 	NCR_DMA(("DMA xferred %d\n", cnt));
32931508593Smhitch 	if (bsc->sc_xfr_align) {
33078a1d236Stsutsui 		memcpy(*bsc->sc_dmaaddr, bsc->sc_alignbuf, cnt);
33131508593Smhitch 		bsc->sc_xfr_align = 0;
33231508593Smhitch 	}
33331508593Smhitch 	*bsc->sc_dmaaddr += cnt;
33431508593Smhitch 	*bsc->sc_pdmalen -= cnt;
33531508593Smhitch 	bsc->sc_active = 0;
33631508593Smhitch 	return 0;
33731508593Smhitch }
33831508593Smhitch 
33931508593Smhitch int
bzsc_dma_setup(struct ncr53c9x_softc * sc,uint8_t ** addr,size_t * len,int datain,size_t * dmasize)34078a1d236Stsutsui bzsc_dma_setup(struct ncr53c9x_softc *sc, uint8_t **addr, size_t *len,
3419382c873Saymeric                int datain, size_t *dmasize)
34231508593Smhitch {
34331508593Smhitch 	struct bzsc_softc *bsc = (struct bzsc_softc *)sc;
344744246faSis 	paddr_t pa;
34578a1d236Stsutsui 	uint8_t *ptr;
34631508593Smhitch 	size_t xfer;
34731508593Smhitch 
34878a1d236Stsutsui 	bsc->sc_dmaaddr = addr;
34931508593Smhitch 	bsc->sc_pdmalen = len;
35031508593Smhitch 	bsc->sc_datain = datain;
35131508593Smhitch 	bsc->sc_dmasize = *dmasize;
35231508593Smhitch 	/*
35331508593Smhitch 	 * DMA can be nasty for high-speed serial input, so limit the
35431508593Smhitch 	 * size of this DMA operation if the serial port is running at
35531508593Smhitch 	 * a high speed (higher than 19200 for now - should be adjusted
356d20841bbSwiz 	 * based on CPU type and speed?).
35731508593Smhitch 	 * XXX - add serial speed check XXX
35831508593Smhitch 	 */
35931508593Smhitch 	if (ser_open_speed > 19200 && bzsc_max_dma != 0 &&
36031508593Smhitch 	    bsc->sc_dmasize > bzsc_max_dma)
36131508593Smhitch 		bsc->sc_dmasize = bzsc_max_dma;
36231508593Smhitch 	ptr = *addr;			/* Kernel virtual address */
36331508593Smhitch 	pa = kvtop(ptr);		/* Physical address of DMA */
364d1579b2dSriastradh 	xfer = uimin(bsc->sc_dmasize, PAGE_SIZE - (pa & (PAGE_SIZE - 1)));
36531508593Smhitch 	bsc->sc_xfr_align = 0;
36631508593Smhitch 	/*
36731508593Smhitch 	 * If output and unaligned, stuff odd byte into FIFO
36831508593Smhitch 	 */
36931508593Smhitch 	if (datain == 0 && (int)ptr & 1) {
37031508593Smhitch 		NCR_DMA(("bzsc_dma_setup: align byte written to fifo\n"));
37131508593Smhitch 		pa++;
37231508593Smhitch 		xfer--;			/* XXXX CHECK THIS !!!! XXXX */
37331508593Smhitch 		bsc->sc_reg[NCR_FIFO * 2] = *ptr++;
37431508593Smhitch 	}
37531508593Smhitch 	/*
37631508593Smhitch 	 * If unaligned address, read unaligned bytes into alignment buffer
37731508593Smhitch 	 */
37831508593Smhitch 	else if ((int)ptr & 1) {
37953524e44Schristos 		pa = kvtop((void *)&bsc->sc_alignbuf);
380d1579b2dSriastradh 		xfer = bsc->sc_dmasize = uimin(xfer, sizeof(bsc->sc_alignbuf));
38131508593Smhitch 		NCR_DMA(("bzsc_dma_setup: align read by %d bytes\n", xfer));
38231508593Smhitch 		bsc->sc_xfr_align = 1;
38331508593Smhitch 	}
38431508593Smhitch ++bzsc_cnt_dma;		/* number of DMA operations */
38531508593Smhitch 
38631508593Smhitch 	while (xfer < bsc->sc_dmasize) {
38778a1d236Stsutsui 		if ((pa + xfer) != kvtop(*addr + xfer))
38831508593Smhitch 			break;
3898818afa4Sthorpej 		if ((bsc->sc_dmasize - xfer) < PAGE_SIZE)
39031508593Smhitch 			xfer = bsc->sc_dmasize;
39121d667c8Schopps 		else
3928818afa4Sthorpej 			xfer += PAGE_SIZE;
39331508593Smhitch ++bzsc_cnt_dma3;
39431508593Smhitch 	}
39531508593Smhitch if (xfer != *len)
39631508593Smhitch   ++bzsc_cnt_dma2;
39721d667c8Schopps 
39831508593Smhitch 	bsc->sc_dmasize = xfer;
39931508593Smhitch 	*dmasize = bsc->sc_dmasize;
40031508593Smhitch 	bsc->sc_pa = pa;
40131508593Smhitch #if defined(M68040) || defined(M68060)
40231508593Smhitch 	if (mmutype == MMU_68040) {
40331508593Smhitch 		if (bsc->sc_xfr_align) {
40431508593Smhitch 			dma_cachectl(bsc->sc_alignbuf,
40531508593Smhitch 			    sizeof(bsc->sc_alignbuf));
40631508593Smhitch 		}
40731508593Smhitch 		else
40831508593Smhitch 			dma_cachectl(*bsc->sc_dmaaddr, bsc->sc_dmasize);
40931508593Smhitch 	}
41031508593Smhitch #endif
41121d667c8Schopps 
41231508593Smhitch 	pa >>= 1;
41331508593Smhitch 	if (!bsc->sc_datain)
41431508593Smhitch 		pa |= 0x80000000;
41578a1d236Stsutsui 	bsc->sc_dmabase[0x10] = (uint8_t)(pa >> 24);
41678a1d236Stsutsui 	bsc->sc_dmabase[0] = (uint8_t)(pa >> 16);
41778a1d236Stsutsui 	bsc->sc_dmabase[0] = (uint8_t)(pa >> 8);
41878a1d236Stsutsui 	bsc->sc_dmabase[0] = (uint8_t)(pa);
41931508593Smhitch 	bsc->sc_active = 1;
42031508593Smhitch 	return 0;
42121d667c8Schopps }
42221d667c8Schopps 
42331508593Smhitch void
bzsc_dma_go(struct ncr53c9x_softc * sc)4249382c873Saymeric bzsc_dma_go(struct ncr53c9x_softc *sc)
42521d667c8Schopps {
42621d667c8Schopps }
42731508593Smhitch 
42831508593Smhitch void
bzsc_dma_stop(struct ncr53c9x_softc * sc)4299382c873Saymeric bzsc_dma_stop(struct ncr53c9x_softc *sc)
43031508593Smhitch {
43131508593Smhitch }
43231508593Smhitch 
43331508593Smhitch int
bzsc_dma_isactive(struct ncr53c9x_softc * sc)4349382c873Saymeric bzsc_dma_isactive(struct ncr53c9x_softc *sc)
43531508593Smhitch {
43631508593Smhitch 	struct bzsc_softc *bsc = (struct bzsc_softc *)sc;
43731508593Smhitch 
43831508593Smhitch 	return bsc->sc_active;
43931508593Smhitch }
44031508593Smhitch 
44131508593Smhitch #ifdef DEBUG
44231508593Smhitch void
bzsc_dump(void)4439382c873Saymeric bzsc_dump(void)
44431508593Smhitch {
44531508593Smhitch 	int i;
44631508593Smhitch 
44731508593Smhitch 	i = bzsc_trace_ptr;
44831508593Smhitch 	printf("bzsc_trace dump: ptr %x\n", bzsc_trace_ptr);
44931508593Smhitch 	do {
45031508593Smhitch 		if (bzsc_trace[i].hardbits == 0) {
45131508593Smhitch 			i = (i + 1) & 127;
45231508593Smhitch 			continue;
45331508593Smhitch 		}
45431508593Smhitch 		printf("%02x%02x%02x%02x(", bzsc_trace[i].hardbits,
45531508593Smhitch 		    bzsc_trace[i].status, bzsc_trace[i].xx, bzsc_trace[i].yy);
45631508593Smhitch 		if (bzsc_trace[i].status & NCRSTAT_INT)
45731508593Smhitch 			printf("NCRINT/");
45831508593Smhitch 		if (bzsc_trace[i].status & NCRSTAT_TC)
45931508593Smhitch 			printf("NCRTC/");
46031508593Smhitch 		switch(bzsc_trace[i].status & NCRSTAT_PHASE) {
46131508593Smhitch 		case 0:
46231508593Smhitch 			printf("dataout"); break;
46331508593Smhitch 		case 1:
46431508593Smhitch 			printf("datain"); break;
46531508593Smhitch 		case 2:
46631508593Smhitch 			printf("cmdout"); break;
46731508593Smhitch 		case 3:
46831508593Smhitch 			printf("status"); break;
46931508593Smhitch 		case 6:
47031508593Smhitch 			printf("msgout"); break;
47131508593Smhitch 		case 7:
47231508593Smhitch 			printf("msgin"); break;
47331508593Smhitch 		default:
47431508593Smhitch 			printf("phase%d?", bzsc_trace[i].status & NCRSTAT_PHASE);
47531508593Smhitch 		}
47631508593Smhitch 		printf(") ");
47731508593Smhitch 		i = (i + 1) & 127;
47831508593Smhitch 	} while (i != bzsc_trace_ptr);
47931508593Smhitch 	printf("\n");
48031508593Smhitch }
48131508593Smhitch #endif
482