Home | History | Annotate | Line # | Download | only in dev
sbc.c revision 1.1
      1 /*	$NetBSD: sbc.c,v 1.1 1996/04/25 22:26:52 scottr Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1996 Scott Reynolds
      5  * Copyright (c) 1995 David Jones
      6  * Copyright (c) 1995 Allen Briggs
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. The name of the authors may not be used to endorse or promote products
     18  *    derived from this software without specific prior written permission.
     19  * 4. All advertising materials mentioning features or use of this software
     20  *    must display the following acknowledgement:
     21  *      This product includes software developed by David Jones, Allen
     22  *	Briggs and Scott Reynolds.
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
     25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     26  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     27  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     29  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     33  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     34  */
     35 
     36 /*
     37  * This file contains only the machine-dependent parts of the mac68k
     38  * NCR 5380 SCSI driver.  (Autoconfig stuff and PDMA functions.)
     39  * The machine-independent parts are in ncr5380sbc.c
     40  *
     41  * Supported hardware includes:
     42  * Macintosh II family 5380-based controller
     43  *
     44  * Credits, history:
     45  *
     46  * Scott Reynolds wrote this module, based on work by Allen Briggs
     47  * (mac68k), David Jones (sun3), and Leo Weppelman (atari).  Allen
     48  * supplied some crucial interpretation of the NetBSD 1.1 'ncrscsi'
     49  * driver.  Allen, Gordon W. Ross, and Jason Thorpe all helped to
     50  * refine this code, and were considerable sources of moral support.
     51  *
     52  * The sbc_options code is based on similar code in Jason's modified
     53  * NetBSD/sparc 'si' driver.
     54  */
     55 
     56 #include <sys/types.h>
     57 #include <sys/param.h>
     58 #include <sys/systm.h>
     59 #include <sys/kernel.h>
     60 #include <sys/errno.h>
     61 #include <sys/device.h>
     62 #include <sys/buf.h>
     63 #include <sys/proc.h>
     64 #include <sys/user.h>
     65 
     66 #include <scsi/scsi_all.h>
     67 #include <scsi/scsi_debug.h>
     68 #include <scsi/scsiconf.h>
     69 
     70 #include <dev/ic/ncr5380reg.h>
     71 #include <dev/ic/ncr5380var.h>
     72 
     73 #include <machine/viareg.h>
     74 
     75 #include "ncr_sbcreg.h"
     76 
     77 /*
     78  * Transfers smaller than this are done using PIO
     79  * (on assumption they're not worth PDMA overhead)
     80  */
     81 #define	MIN_DMA_LEN 128
     82 
     83 /*
     84  * Transfers larger than 8192 bytes need to be split up
     85  * due to the size of the PDMA space.
     86  */
     87 #define	MAX_DMA_LEN 0x2000
     88 
     89 /*
     90  * From Guide to the Macintosh Family Hardware, p. 137
     91  * These are offsets from SCSIBase (see pmap_bootstrap.c)
     92  */
     93 #define	SBC_REGISTER_OFFSET	0x10000
     94 #define	SBC_DMA_DRQ_OFFSET	0x06000
     95 #define	SBC_DMA_NODRQ_OFFSET	0x12000
     96 
     97 #ifdef	SBC_DEBUG
     98 #define	SBC_DB_INTR	0x01
     99 #define	SBC_DB_DMA	0x02
    100 #define	SBC_DB_BREAK	0x04
    101 
    102 int	sbc_debug = 0 /* SBC_DB_INTR | SBC_DB_DMA */;
    103 int	sbc_link_flags = 0 /* | SDEV_DB2 */;
    104 #endif
    105 
    106 /*
    107  * This structure is used to keep track of PDMA requests.
    108  */
    109 struct sbc_pdma_handle {
    110 	int	dh_flags;	/* flags */
    111 #define	SBC_DH_BUSY	0x01	/* This DH is in use */
    112 #define	SBC_DH_OUT	0x02	/* PDMA does data out (write) */
    113 #define	SBC_DH_XFER	0x04	/* PDMA transfer not completed */
    114 	u_char	*dh_addr;	/* data buffer */
    115 	int	dh_len;		/* length of data buffer */
    116 };
    117 
    118 /*
    119  * The first structure member has to be the ncr5380_softc
    120  * so we can just cast to go back and forth between them.
    121  */
    122 struct sbc_softc {
    123 	struct ncr5380_softc ncr_sc;
    124 	volatile struct sbc_regs *sc_regs;
    125 	volatile long	*sc_drq_addr;
    126 	volatile u_char	*sc_nodrq_addr;
    127 	volatile u_char	*sc_ienable;
    128 	volatile u_char	*sc_iflag;
    129 	int		sc_options;	/* options for this instance. */
    130 	struct sbc_pdma_handle sc_pdma[SCI_OPENINGS];
    131 };
    132 
    133 /*
    134  * Options.  By default, SCSI interrupts and reselect are disabled.
    135  * You may enable either of these features with the `flags' directive
    136  * in your kernel's configuration file.
    137  *
    138  * Alternatively, you can patch your kernel with DDB or some other
    139  * mechanism.  The sc_options member of the softc is OR'd with
    140  * the value in sbc_options.
    141  */
    142 #define	SBC_INTR	0x01	/* Allow SCSI IRQ/DRQ interrupts */
    143 #define	SBC_RESELECT	0x02	/* Allow disconnect/reselect */
    144 #define	SBC_OPTIONS_MASK	(SBC_INTR|SBC_RESELECT)
    145 #define	SBC_OPTIONS_BITS	"\10\2RESELECT\1INTR"
    146 int sbc_options = 0;
    147 
    148 static	int	sbc_match __P(());
    149 static	void	sbc_attach __P(());
    150 static	void	sbc_minphys __P((struct buf *bp));
    151 
    152 static	int	sbc_wait_busy __P((struct ncr5380_softc *));
    153 static	int	sbc_ready __P((struct ncr5380_softc *));
    154 static	int	sbc_wait_dreq __P((struct ncr5380_softc *));
    155 static	int	sbc_pdma_in __P((struct ncr5380_softc *, int, int, u_char *));
    156 static	int	sbc_pdma_out __P((struct ncr5380_softc *, int, int, u_char *));
    157 
    158 	void	sbc_intr_enable __P((struct ncr5380_softc *));
    159 	void	sbc_intr_disable __P((struct ncr5380_softc *));
    160 	void	sbc_irq_intr __P((void *));
    161 	void	sbc_drq_intr __P((void *));
    162 	void	sbc_dma_alloc __P((struct ncr5380_softc *));
    163 	void	sbc_dma_free __P((struct ncr5380_softc *));
    164 	void	sbc_dma_poll __P((struct ncr5380_softc *));
    165 	void	sbc_dma_setup __P((struct ncr5380_softc *));
    166 	void	sbc_dma_start __P((struct ncr5380_softc *));
    167 	void	sbc_dma_eop __P((struct ncr5380_softc *));
    168 	void	sbc_dma_stop __P((struct ncr5380_softc *));
    169 
    170 static struct scsi_adapter	sbc_ops = {
    171 	ncr5380_scsi_cmd,		/* scsi_cmd()		*/
    172 	sbc_minphys,			/* scsi_minphys()	*/
    173 	NULL,				/* open_target_lu()	*/
    174 	NULL,				/* close_target_lu()	*/
    175 };
    176 
    177 /* This is copied from julian's bt driver */
    178 /* "so we have a default dev struct for our link struct." */
    179 static struct scsi_device sbc_dev = {
    180 	NULL,		/* Use default error handler.	    */
    181 	NULL,		/* Use default start handler.		*/
    182 	NULL,		/* Use default async handler.	    */
    183 	NULL,		/* Use default "done" routine.	    */
    184 };
    185 
    186 struct cfattach sbc_ca = {
    187 	sizeof(struct sbc_softc), sbc_match, sbc_attach
    188 };
    189 
    190 struct cfdriver sbc_cd = {
    191 	NULL, "sbc", DV_DULL
    192 };
    193 
    194 
    195 static int
    196 sbc_print(aux, name)
    197 	void *aux;
    198 	char *name;
    199 {
    200 	if (name != NULL)
    201 		printf("%s: scsibus ", name);
    202 	return UNCONF;
    203 }
    204 
    205 static int
    206 sbc_match(parent, match, args)
    207 	struct device	*parent;
    208 	void		*match, *args;
    209 {
    210 	struct device   *self = match;	/* XXX mainbus is "indirect" */
    211 	struct confargs *ca = args;
    212 
    213 	if (matchbyname(parent, match, ca) == 0)
    214 		return 0;
    215 	if (!mac68k_machine.scsi80)
    216 		return 0;
    217 	if (self->dv_cfdata->cf_unit != 0)
    218 		return 0;
    219 	return 1;
    220 }
    221 
    222 static void
    223 sbc_attach(parent, self, args)
    224 	struct device	*parent, *self;
    225 	void		*args;
    226 {
    227 	static int probed = 0;
    228 	struct sbc_softc *sc = (struct sbc_softc *) self;
    229 	struct ncr5380_softc *ncr_sc = (struct ncr5380_softc *) sc;
    230 	struct confargs *ca = args;
    231 	extern vm_offset_t SCSIBase;
    232 	int i;
    233 
    234 	/* Pull in the options flags. */
    235 	sc->sc_options =
    236 	((ncr_sc->sc_dev.dv_cfdata->cf_flags | sbc_options) & SBC_OPTIONS_MASK);
    237 
    238 	/*
    239 	 * Set up base address of 5380
    240 	 */
    241 	sc->sc_regs = (struct sbc_regs *)(SCSIBase + SBC_REGISTER_OFFSET);
    242 
    243 	/*
    244 	 * Fill in the prototype scsi_link.
    245 	 */
    246 	ncr_sc->sc_link.adapter_softc = sc;
    247 	ncr_sc->sc_link.adapter_target = 7;
    248 	ncr_sc->sc_link.adapter = &sbc_ops;
    249 	ncr_sc->sc_link.device = &sbc_dev;
    250 
    251 	/*
    252 	 * Initialize fields used by the MI code
    253 	 */
    254 	ncr_sc->sci_r0 = &sc->sc_regs->sci_pr0.sci_reg;
    255 	ncr_sc->sci_r1 = &sc->sc_regs->sci_pr1.sci_reg;
    256 	ncr_sc->sci_r2 = &sc->sc_regs->sci_pr2.sci_reg;
    257 	ncr_sc->sci_r3 = &sc->sc_regs->sci_pr3.sci_reg;
    258 	ncr_sc->sci_r4 = &sc->sc_regs->sci_pr4.sci_reg;
    259 	ncr_sc->sci_r5 = &sc->sc_regs->sci_pr5.sci_reg;
    260 	ncr_sc->sci_r6 = &sc->sc_regs->sci_pr6.sci_reg;
    261 	ncr_sc->sci_r7 = &sc->sc_regs->sci_pr7.sci_reg;
    262 
    263 	/*
    264 	 * MD function pointers used by the MI code.
    265 	 */
    266 	ncr_sc->sc_pio_out   = sbc_pdma_out;
    267 	ncr_sc->sc_pio_in    = sbc_pdma_in;
    268 	ncr_sc->sc_dma_alloc = NULL;
    269 	ncr_sc->sc_dma_free  = NULL;
    270 	ncr_sc->sc_dma_poll  = NULL;
    271 	ncr_sc->sc_intr_on   = NULL;
    272 	ncr_sc->sc_intr_off  = NULL;
    273 	ncr_sc->sc_dma_setup = NULL;
    274 	ncr_sc->sc_dma_start = NULL;
    275 	ncr_sc->sc_dma_eop   = NULL;
    276 	ncr_sc->sc_dma_stop  = NULL;
    277 	ncr_sc->sc_flags = 0;
    278 	ncr_sc->sc_min_dma_len = MIN_DMA_LEN;
    279 
    280 	/*
    281 	 * MD function pointers used by the MI code.
    282 	 */
    283 	if ((sc->sc_options & SBC_INTR) == 0) {
    284 		ncr_sc->sc_flags |= NCR5380_FORCE_POLLING;
    285 	} else {
    286 		if (sc->sc_options & SBC_RESELECT)
    287 			ncr_sc->sc_flags |= NCR5380_PERMIT_RESELECT;
    288 		ncr_sc->sc_dma_alloc = sbc_dma_alloc;
    289 		ncr_sc->sc_dma_free  = sbc_dma_free;
    290 		ncr_sc->sc_dma_poll  = sbc_dma_poll;
    291 		ncr_sc->sc_dma_setup = sbc_dma_setup;
    292 		ncr_sc->sc_dma_start = sbc_dma_start;
    293 		ncr_sc->sc_dma_eop   = sbc_dma_eop;
    294 		ncr_sc->sc_dma_stop  = sbc_dma_stop;
    295 		mac68k_register_scsi_drq(sbc_drq_intr, ncr_sc);
    296 		mac68k_register_scsi_irq(sbc_irq_intr, ncr_sc);
    297 	}
    298 
    299 	/*
    300 	 * Initialize fields used only here in the MD code.
    301 	 */
    302 	sc->sc_drq_addr = (long *) (SCSIBase + SBC_DMA_DRQ_OFFSET);
    303 	sc->sc_nodrq_addr = (u_char *) (SCSIBase + SBC_DMA_NODRQ_OFFSET);
    304 	if (VIA2 == VIA2OFF) {
    305 		sc->sc_ienable = Via1Base + VIA2 * 0x2000 + vIER;
    306 		sc->sc_iflag   = Via1Base + VIA2 * 0x2000 + vIFR;
    307 	} else {
    308 		sc->sc_ienable = Via1Base + VIA2 * 0x2000 + rIER;
    309 		sc->sc_iflag   = Via1Base + VIA2 * 0x2000 + rIFR;
    310 	}
    311 
    312 	if (sc->sc_options)
    313 		printf(": options=%b", sc->sc_options, SBC_OPTIONS_BITS);
    314 	printf("\n");
    315 
    316 	/* Now enable SCSI interrupts through VIA2, if appropriate */
    317 	if (sc->sc_options & SBC_INTR)
    318 		sbc_intr_enable(ncr_sc);
    319 
    320 #ifdef	SBC_DEBUG
    321 	if (sbc_debug)
    322 		printf("%s: softc=%x regs=%x\n", ncr_sc->sc_dev.dv_xname,
    323 		    sc, sc->sc_regs);
    324 	ncr_sc->sc_link.flags |= sbc_link_flags;
    325 #endif
    326 
    327 	/*
    328 	 *  Initialize the SCSI controller itself.
    329 	 */
    330 	ncr5380_init(ncr_sc);
    331 	ncr5380_reset_scsibus(ncr_sc);
    332 	config_found(self, &(ncr_sc->sc_link), sbc_print);
    333 }
    334 
    335 
    336 static void
    337 sbc_minphys(struct buf *bp)
    338 {
    339 	if (bp->b_bcount > MAX_DMA_LEN)
    340 		bp->b_bcount = MAX_DMA_LEN;
    341 	return (minphys(bp));
    342 }
    343 
    344 
    345 /***
    346  * General support for Mac-specific SCSI logic.
    347  ***/
    348 
    349 /* These are used in the following inline functions. */
    350 int sbc_wait_busy_timo = 1000 * 5000;	/* X2 = 10 S. */
    351 int sbc_ready_timo = 1000 * 5000;	/* X2 = 10 S. */
    352 int sbc_wait_dreq_timo = 1000 * 5000;	/* X2 = 10 S. */
    353 
    354 /* Return zero on success. */
    355 static __inline__ int
    356 sbc_wait_busy(sc)
    357 	struct ncr5380_softc *sc;
    358 {
    359 	register int timo = sbc_wait_busy_timo;
    360 	for (;;) {
    361 		if (SCI_BUSY(sc)) {
    362 			timo = 0;	/* return 0 */
    363 			break;
    364 		}
    365 		if (--timo < 0)
    366 			break;	/* return -1 */
    367 		delay(2);
    368 	}
    369 	return (timo);
    370 }
    371 
    372 static __inline__ int
    373 sbc_ready(sc)
    374 	struct ncr5380_softc *sc;
    375 {
    376 	register int timo = sbc_ready_timo;
    377 
    378 	for (;;) {
    379 		if ((*sc->sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH))
    380 		    == (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
    381 			timo = 0;
    382 			break;
    383 		}
    384 		if (((*sc->sci_csr & SCI_CSR_PHASE_MATCH) == 0)
    385 		    || (SCI_BUSY(sc) == 0)) {
    386 			timo = -1;
    387 			break;
    388 		}
    389 		if (--timo < 0)
    390 			break;	/* return -1 */
    391 		delay(2);
    392 	}
    393 	return (timo);
    394 }
    395 
    396 static __inline__ int
    397 sbc_wait_dreq(sc)
    398 	struct ncr5380_softc *sc;
    399 {
    400 	register int timo = sbc_wait_dreq_timo;
    401 
    402 	for (;;) {
    403 		if ((*sc->sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH))
    404 		    == (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
    405 			timo = 0;
    406 			break;
    407 		}
    408 		if (--timo < 0)
    409 			break;	/* return -1 */
    410 		delay(2);
    411 	}
    412 	return (timo);
    413 }
    414 
    415 
    416 /***
    417  * Macintosh SCSI interrupt support routines.
    418  ***/
    419 
    420 void
    421 sbc_intr_enable(ncr_sc)
    422 	struct ncr5380_softc *ncr_sc;
    423 {
    424 	register struct sbc_softc *sc = (struct sbc_softc *) ncr_sc;
    425 	int s;
    426 
    427 	s = splhigh();
    428 	*sc->sc_iflag   = (V2IF_SCSIIRQ | V2IF_SCSIDRQ);
    429 	*sc->sc_ienable = 0x80 | (V2IF_SCSIIRQ | V2IF_SCSIDRQ);
    430 	splx(s);
    431 }
    432 
    433 void
    434 sbc_intr_disable(ncr_sc)
    435 	struct ncr5380_softc *ncr_sc;
    436 {
    437 	register struct sbc_softc *sc = (struct sbc_softc *) ncr_sc;
    438 	int s;
    439 
    440 	s = splhigh();
    441 	*sc->sc_ienable = (V2IF_SCSIIRQ | V2IF_SCSIDRQ);
    442 	splx(s);
    443 }
    444 
    445 void
    446 sbc_irq_intr(p)
    447 	void *p;
    448 {
    449 	register struct ncr5380_softc *ncr_sc = p;
    450 	register int claimed = 0;
    451 
    452 	/* How we ever arrive here without IRQ set is a mystery... */
    453 	if (*ncr_sc->sci_csr & SCI_CSR_INT) {
    454 		claimed = ncr5380_intr(ncr_sc);
    455 		if (!claimed) {
    456 			if (((*ncr_sc->sci_csr & ~SCI_CSR_PHASE_MATCH) == SCI_CSR_INT)
    457 			    && ((*ncr_sc->sci_bus_csr & ~SCI_BUS_RST) == 0)) {
    458 				SCI_CLR_INTR(ncr_sc);	/* RST interrupt */
    459 			}
    460 #ifdef SBC_DEBUG
    461 			else {
    462 				printf("%s: spurious intr\n",
    463 				    ncr_sc->sc_dev.dv_xname);
    464 # ifdef DDB
    465 				if (sbc_debug & SBC_DB_BREAK)
    466 					Debugger();
    467 # endif
    468 			}
    469 #endif
    470 		}
    471 	}
    472 }
    473 
    474 
    475 /***
    476  * The following code implements polled PDMA.
    477  ***/
    478 
    479 static	int
    480 sbc_pdma_out(ncr_sc, phase, count, data)
    481 	struct ncr5380_softc *ncr_sc;
    482 	int phase;
    483 	int count;
    484 	u_char *data;
    485 {
    486 	struct sbc_softc *sc = (struct sbc_softc *)ncr_sc;
    487 	register volatile long *long_data = sc->sc_drq_addr;
    488 	register volatile u_char *byte_data = sc->sc_nodrq_addr;
    489 	register int len = count;
    490 
    491 	if (count < ncr_sc->sc_min_dma_len)
    492 		return ncr5380_pio_out(ncr_sc, phase, count, data);
    493 
    494 	if (sbc_wait_busy(ncr_sc) == 0) {
    495 		*ncr_sc->sci_mode &= ~SCI_MODE_MONBSY;	/* XXX */
    496 		*ncr_sc->sci_mode |= SCI_MODE_DMA;
    497 		*ncr_sc->sci_icmd |= SCI_ICMD_DATA;
    498 		*ncr_sc->sci_dma_send = 0;
    499 
    500 #define W1	*byte_data = *data++
    501 #define W4	*long_data = *((long*)data)++
    502 		while (len >= 64) {
    503 			if (sbc_ready(ncr_sc))
    504 				goto timeout;
    505 			W1;
    506 			if (sbc_ready(ncr_sc))
    507 				goto timeout;
    508 			W1;
    509 			if (sbc_ready(ncr_sc))
    510 				goto timeout;
    511 			W1;
    512 			if (sbc_ready(ncr_sc))
    513 				goto timeout;
    514 			W1;
    515 			if (sbc_ready(ncr_sc))
    516 				goto timeout;
    517 			W4; W4; W4; W4;
    518 			W4; W4; W4; W4;
    519 			W4; W4; W4; W4;
    520 			W4; W4; W4;
    521 			len -= 64;
    522 		}
    523 		while (len) {
    524 			if (sbc_ready(ncr_sc))
    525 				goto timeout;
    526 			W1;
    527 			len--;
    528 		}
    529 #undef  W1
    530 #undef  W4
    531 		if (sbc_wait_dreq(ncr_sc))
    532 			printf("%s: timeout waiting for DREQ.\n",
    533 			    ncr_sc->sc_dev.dv_xname);
    534 
    535 		*byte_data = 0;
    536 
    537 		SCI_CLR_INTR(ncr_sc);
    538 		*ncr_sc->sci_mode &= ~SCI_MODE_DMA;
    539 		*ncr_sc->sci_icmd = 0;
    540 	}
    541 	return count - len;
    542 
    543 timeout:
    544 	printf("%s: pdma_out: timeout len=%d count=%d\n",
    545 	    ncr_sc->sc_dev.dv_xname, len, count);
    546 	if ((*ncr_sc->sci_csr & SCI_CSR_PHASE_MATCH) == 0) {
    547 		*ncr_sc->sci_icmd &= ~SCI_ICMD_DATA;
    548 		--len;
    549 	}
    550 
    551 	SCI_CLR_INTR(ncr_sc);
    552 	*ncr_sc->sci_mode &= ~SCI_MODE_DMA;
    553 	*ncr_sc->sci_icmd = 0;
    554 	return count - len;
    555 }
    556 
    557 static	int
    558 sbc_pdma_in(ncr_sc, phase, count, data)
    559 	struct ncr5380_softc *ncr_sc;
    560 	int phase;
    561 	int count;
    562 	u_char *data;
    563 {
    564 	struct sbc_softc *sc = (struct sbc_softc *)ncr_sc;
    565 	register volatile long *long_data = sc->sc_drq_addr;
    566 	register volatile u_char *byte_data = sc->sc_nodrq_addr;
    567 	register int len = count;
    568 
    569 	if (count < ncr_sc->sc_min_dma_len)
    570 		return ncr5380_pio_in(ncr_sc, phase, count, data);
    571 
    572 	if (sbc_wait_busy(ncr_sc) == 0) {
    573 		*ncr_sc->sci_mode &= ~SCI_MODE_MONBSY;	/* XXX */
    574 		*ncr_sc->sci_mode |= SCI_MODE_DMA;
    575 		*ncr_sc->sci_icmd |= SCI_ICMD_DATA;
    576 		*ncr_sc->sci_irecv = 0;
    577 
    578 #define R4	*((long *)data)++ = *long_data
    579 #define R1	*data++ = *byte_data
    580 		while (len >= 1024) {
    581 			if (sbc_ready(ncr_sc))
    582 				goto timeout;
    583 			R4; R4; R4; R4; R4; R4; R4; R4;
    584 			R4; R4; R4; R4; R4; R4; R4; R4;
    585 			R4; R4; R4; R4; R4; R4; R4; R4;
    586 			R4; R4; R4; R4; R4; R4; R4; R4;		/* 128 */
    587 			if (sbc_ready(ncr_sc))
    588 				goto timeout;
    589 			R4; R4; R4; R4; R4; R4; R4; R4;
    590 			R4; R4; R4; R4; R4; R4; R4; R4;
    591 			R4; R4; R4; R4; R4; R4; R4; R4;
    592 			R4; R4; R4; R4; R4; R4; R4; R4;		/* 256 */
    593 			if (sbc_ready(ncr_sc))
    594 				goto timeout;
    595 			R4; R4; R4; R4; R4; R4; R4; R4;
    596 			R4; R4; R4; R4; R4; R4; R4; R4;
    597 			R4; R4; R4; R4; R4; R4; R4; R4;
    598 			R4; R4; R4; R4; R4; R4; R4; R4;		/* 384 */
    599 			if (sbc_ready(ncr_sc))
    600 				goto timeout;
    601 			R4; R4; R4; R4; R4; R4; R4; R4;
    602 			R4; R4; R4; R4; R4; R4; R4; R4;
    603 			R4; R4; R4; R4; R4; R4; R4; R4;
    604 			R4; R4; R4; R4; R4; R4; R4; R4;		/* 512 */
    605 			if (sbc_ready(ncr_sc))
    606 				goto timeout;
    607 			R4; R4; R4; R4; R4; R4; R4; R4;
    608 			R4; R4; R4; R4; R4; R4; R4; R4;
    609 			R4; R4; R4; R4; R4; R4; R4; R4;
    610 			R4; R4; R4; R4; R4; R4; R4; R4;		/* 640 */
    611 			if (sbc_ready(ncr_sc))
    612 				goto timeout;
    613 			R4; R4; R4; R4; R4; R4; R4; R4;
    614 			R4; R4; R4; R4; R4; R4; R4; R4;
    615 			R4; R4; R4; R4; R4; R4; R4; R4;
    616 			R4; R4; R4; R4; R4; R4; R4; R4;		/* 768 */
    617 			if (sbc_ready(ncr_sc))
    618 				goto timeout;
    619 			R4; R4; R4; R4; R4; R4; R4; R4;
    620 			R4; R4; R4; R4; R4; R4; R4; R4;
    621 			R4; R4; R4; R4; R4; R4; R4; R4;
    622 			R4; R4; R4; R4; R4; R4; R4; R4;		/* 896 */
    623 			if (sbc_ready(ncr_sc))
    624 				goto timeout;
    625 			R4; R4; R4; R4; R4; R4; R4; R4;
    626 			R4; R4; R4; R4; R4; R4; R4; R4;
    627 			R4; R4; R4; R4; R4; R4; R4; R4;
    628 			R4; R4; R4; R4; R4; R4; R4; R4;		/* 1024 */
    629 			len -= 1024;
    630 		}
    631 		while (len >= 128) {
    632 			if (sbc_ready(ncr_sc))
    633 				goto timeout;
    634 			R4; R4; R4; R4; R4; R4; R4; R4;
    635 			R4; R4; R4; R4; R4; R4; R4; R4;
    636 			R4; R4; R4; R4; R4; R4; R4; R4;
    637 			R4; R4; R4; R4; R4; R4; R4; R4;		/* 128 */
    638 			len -= 128;
    639 		}
    640 		while (len) {
    641 			if (sbc_ready(ncr_sc))
    642 				goto timeout;
    643 			R1;
    644 			len--;
    645 		}
    646 #undef R4
    647 #undef R1
    648 		SCI_CLR_INTR(ncr_sc);
    649 		*ncr_sc->sci_mode &= ~SCI_MODE_DMA;
    650 		*ncr_sc->sci_icmd = 0;
    651 	}
    652 	return count - len;
    653 
    654 timeout:
    655 	printf("%s: pdma_in: timeout len=%d count=%d\n",
    656 	    ncr_sc->sc_dev.dv_xname, len, count);
    657 
    658 	SCI_CLR_INTR(ncr_sc);
    659 	*ncr_sc->sci_mode &= ~SCI_MODE_DMA;
    660 	*ncr_sc->sci_icmd = 0;
    661 	return count - len;
    662 }
    663 
    664 
    665 /***
    666  * The following code implements interrupt-driven PDMA.
    667  ***/
    668 
    669 /*
    670  * This is the meat of the PDMA transfer.
    671  * When we get here, we shove data as fast as the mac can take it.
    672  * We depend on several things:
    673  *   * All macs after the Mac Plus that have a 5380 chip should have a general
    674  *     logic IC that handshakes data for blind transfers.
    675  *   * If the SCSI controller finishes sending/receiving data before we do,
    676  *     the same general logic IC will generate a /BERR for us in short order.
    677  *   * The fault address for said /BERR minus the base address for the
    678  *     transfer will be the amount of data that was actually written.
    679  *
    680  * We use the nofault flag and the setjmp/longjmp in locore.s so we can
    681  * detect and handle the bus error for early termination of a command.
    682  * This is usually caused by a disconnecting target.
    683  */
    684 void
    685 sbc_drq_intr(p)
    686 	void *p;
    687 {
    688 	extern	int		*nofault, mac68k_buserr_addr;
    689 	register struct sbc_softc *sc = (struct sbc_softc *) p;
    690 	register struct ncr5380_softc *ncr_sc = (struct ncr5380_softc *) p;
    691 	register struct sci_req *sr = ncr_sc->sc_current;
    692 	register struct sbc_pdma_handle *dh = sr->sr_dma_hand;
    693 	label_t			faultbuf;
    694 	volatile u_int32_t	*long_drq;
    695 	u_int32_t		*long_data;
    696 	volatile u_int8_t	*drq;
    697 	u_int8_t		*data;
    698 	register int		count;
    699 	int			dcount, resid;
    700 
    701 	/*
    702 	 * If we're not ready to xfer data, or have no more, just return.
    703 	 */
    704 	if ((*ncr_sc->sci_csr & SCI_CSR_DREQ) == 0)
    705 		return;
    706 	if (dh->dh_len == 0) {
    707 		dh->dh_flags &= ~SBC_DH_XFER;
    708 		return;
    709 	}
    710 
    711 #ifdef SBC_DEBUG
    712 	if (sbc_debug & SBC_DB_INTR)
    713 		printf("%s: drq intr, dh_len=0x%x, dh_flags=0x%x\n",
    714 		    ncr_sc->sc_dev.dv_xname, dh->dh_len, dh->dh_flags);
    715 #endif
    716 
    717 	/*
    718 	 * Setup for a possible bus error caused by SCSI controller
    719 	 * switching out of DATA-IN/OUT before we're done with the
    720 	 * current transfer.
    721 	 */
    722 	nofault = (int *) &faultbuf;
    723 
    724 	if (setjmp((label_t *) nofault)) {
    725 		nofault = (int *) 0;
    726 		count = (  (u_long) mac68k_buserr_addr
    727 			 - (u_long) sc->sc_drq_addr);
    728 
    729 		if ((count < 0) || (count > dh->dh_len)) {
    730 			printf("%s: complete=0x%x (pending 0x%x)\n",
    731 			    ncr_sc->sc_dev.dv_xname, count, dh->dh_len);
    732 			panic("something is wrong");
    733 		}
    734 #ifdef SBC_DEBUG
    735 		if (sbc_debug & SBC_DB_INTR)
    736 			printf("%s: drq /berr, pending=0x%x, complete=0x%x\n",
    737 			   ncr_sc->sc_dev.dv_xname, dh->dh_len, count);
    738 #endif
    739 
    740 		dh->dh_addr += count;
    741 		dh->dh_len -= count;
    742 		if (dh->dh_len == 0)
    743 			dh->dh_flags &= ~SBC_DH_XFER;
    744 		mac68k_buserr_addr = 0;
    745 		return;
    746 	}
    747 
    748 	if (dh->dh_flags & SBC_DH_OUT) { /* Data Out */
    749 		/*
    750 		 * Get the source address aligned.
    751 		 */
    752 		resid = count = min(dh->dh_len,
    753 			4 - (((int) dh->dh_addr) & 0x3));
    754 		if (count && count < 4) {
    755 			data = (u_int8_t *) dh->dh_addr;
    756 			drq = (u_int8_t *) sc->sc_drq_addr;
    757 #define W1		*drq++ = *data++
    758 			while (count) {
    759 				W1; count--;
    760 			}
    761 #undef W1
    762 			dh->dh_addr += resid;
    763 			dh->dh_len -= resid;
    764 		}
    765 
    766 		/*
    767 		 * Get ready to start the transfer.
    768 		 */
    769 		while (dh->dh_len) {
    770 			dcount = count = min(dh->dh_len, MAX_DMA_LEN);
    771 			long_drq = (volatile u_int32_t *) sc->sc_drq_addr;
    772 			long_data = (u_int32_t *) dh->dh_addr;
    773 
    774 #define W4		*long_drq++ = *long_data++
    775 			while (count >= 64) {
    776 				W4; W4; W4; W4; W4; W4; W4; W4;
    777 				W4; W4; W4; W4; W4; W4; W4; W4; /*  64 */
    778 				count -= 64;
    779 			}
    780 			while (count >= 4) {
    781 				W4; count -= 4;
    782 			}
    783 #undef W4
    784 			data = (u_int8_t *) long_data;
    785 			drq = (u_int8_t *) long_drq;
    786 #define W1		*drq++ = *data++
    787 			while (count) {
    788 				W1; count--;
    789 			}
    790 #undef W1
    791 			dh->dh_len -= dcount;
    792 			dh->dh_addr += dcount;
    793 		}
    794 	} else {	/* Data In */
    795 		/*
    796 		 * Get the dest address aligned.
    797 		 */
    798 		resid = count = min(dh->dh_len,
    799 			4 - (((int) dh->dh_addr) & 0x3));
    800 		if (count && count < 4) {
    801 			data = (u_int8_t *) dh->dh_addr;
    802 			drq = (u_int8_t *) sc->sc_drq_addr;
    803 #define R1		*data++ = *drq++
    804 			while (count) {
    805 				R1; count--;
    806 			}
    807 #undef R1
    808 			dh->dh_addr += resid;
    809 			dh->dh_len -= resid;
    810 		}
    811 
    812 		/*
    813 		 * Get ready to start the transfer.
    814 		 */
    815 		while (dh->dh_len) {
    816 			dcount = count = min(dh->dh_len, MAX_DMA_LEN);
    817 			long_drq = (volatile u_int32_t *) sc->sc_drq_addr;
    818 			long_data = (u_int32_t *) dh->dh_addr;
    819 
    820 #define R4		*long_data++ = *long_drq++
    821 			while (count >= 512) {
    822 				if ((*ncr_sc->sci_csr & SCI_CSR_DREQ) == 0) {
    823 					nofault = (int *) 0;
    824 
    825 					dh->dh_addr += (dcount - count);
    826 					dh->dh_len -= (dcount - count);
    827 					if (dh->dh_len == 0)
    828 						dh->dh_flags &= ~SBC_DH_XFER;
    829 					return;
    830 				}
    831 				R4; R4; R4; R4; R4; R4; R4; R4;
    832 				R4; R4; R4; R4; R4; R4; R4; R4;	/* 64 */
    833 				R4; R4; R4; R4; R4; R4; R4; R4;
    834 				R4; R4; R4; R4; R4; R4; R4; R4;	/* 128 */
    835 				R4; R4; R4; R4; R4; R4; R4; R4;
    836 				R4; R4; R4; R4; R4; R4; R4; R4;
    837 				R4; R4; R4; R4; R4; R4; R4; R4;
    838 				R4; R4; R4; R4; R4; R4; R4; R4;	/* 256 */
    839 				R4; R4; R4; R4; R4; R4; R4; R4;
    840 				R4; R4; R4; R4; R4; R4; R4; R4;
    841 				R4; R4; R4; R4; R4; R4; R4; R4;
    842 				R4; R4; R4; R4; R4; R4; R4; R4;
    843 				R4; R4; R4; R4; R4; R4; R4; R4;
    844 				R4; R4; R4; R4; R4; R4; R4; R4;
    845 				R4; R4; R4; R4; R4; R4; R4; R4;
    846 				R4; R4; R4; R4; R4; R4; R4; R4;	/* 512 */
    847 				count -= 512;
    848 			}
    849 			while (count >= 4) {
    850 				R4; count -= 4;
    851 			}
    852 #undef R4
    853 			data = (u_int8_t *) long_data;
    854 			drq = (u_int8_t *) long_drq;
    855 #define R1		*data++ = *drq++
    856 			while (count) {
    857 				R1; count--;
    858 			}
    859 #undef R1
    860 			dh->dh_len -= dcount;
    861 			dh->dh_addr += dcount;
    862 		}
    863 	}
    864 
    865 	/*
    866 	 * OK.  No bus error occurred above.  Clear the nofault flag
    867 	 * so we no longer short-circuit bus errors.
    868 	 */
    869 	nofault = (int *) 0;
    870 
    871 	if (dh->dh_len == 0)
    872 		dh->dh_flags &= ~SBC_DH_XFER;
    873 }
    874 
    875 void
    876 sbc_dma_alloc(ncr_sc)
    877 	struct ncr5380_softc *ncr_sc;
    878 {
    879 	struct sbc_softc *sc = (struct sbc_softc *) ncr_sc;
    880 	struct sci_req *sr = ncr_sc->sc_current;
    881 	struct scsi_xfer *xs = sr->sr_xs;
    882 	struct sbc_pdma_handle *dh;
    883 	int		i, xlen;
    884 
    885 #ifdef	DIAGNOSTIC
    886 	if (sr->sr_dma_hand != NULL)
    887 		panic("sbc_dma_alloc: already have PDMA handle");
    888 #endif
    889 
    890 	/* Polled transfers shouldn't allocate a PDMA handle. */
    891 	if (sr->sr_flags & SR_IMMED)
    892 		return;
    893 
    894 	/* XXX - we don't trust PDMA writes yet! */
    895 	if (xs->flags & SCSI_DATA_OUT)
    896 		return;
    897 
    898 	xlen = ncr_sc->sc_datalen;
    899 
    900 	/* Make sure our caller checked sc_min_dma_len. */
    901 	if (xlen < MIN_DMA_LEN)
    902 		panic("sbc_dma_alloc: len=0x%x\n", xlen);
    903 
    904 	/*
    905 	 * Find free PDMA handle.  Guaranteed to find one since we
    906 	 * have as many PDMA handles as the driver has processes.
    907 	 * (instances?)
    908 	 */
    909 	 for (i = 0; i < SCI_OPENINGS; i++) {
    910 		if ((sc->sc_pdma[i].dh_flags & SBC_DH_BUSY) == 0)
    911 			goto found;
    912 	}
    913 	panic("sbc: no free PDMA handles");
    914 found:
    915 	dh = &sc->sc_pdma[i];
    916 	dh->dh_flags = SBC_DH_BUSY;
    917 	dh->dh_addr = ncr_sc->sc_dataptr;
    918 	dh->dh_len = xlen;
    919 
    920 	/* Copy the 'write' flag for convenience. */
    921 	if (xs->flags & SCSI_DATA_OUT)
    922 		dh->dh_flags |= SBC_DH_OUT;
    923 
    924 	sr->sr_dma_hand = dh;
    925 }
    926 
    927 void
    928 sbc_dma_free(ncr_sc)
    929 	struct ncr5380_softc *ncr_sc;
    930 {
    931 	struct sci_req *sr = ncr_sc->sc_current;
    932 	struct sbc_pdma_handle *dh = sr->sr_dma_hand;
    933 
    934 #ifdef	DIAGNOSTIC
    935 	if (sr->sr_dma_hand == NULL)
    936 		panic("sbc_dma_free: no DMA handle");
    937 #endif
    938 
    939 	if (ncr_sc->sc_state & NCR_DOINGDMA)
    940 		panic("sbc_dma_free: free while in progress");
    941 
    942 	if (dh->dh_flags & SBC_DH_BUSY) {
    943 		dh->dh_flags = 0;
    944 		dh->dh_addr = NULL;
    945 		dh->dh_len = 0;
    946 	}
    947 	sr->sr_dma_hand = NULL;
    948 }
    949 
    950 void
    951 sbc_dma_poll(ncr_sc)
    952 	struct ncr5380_softc *ncr_sc;
    953 {
    954 	struct sbc_softc *sc = (struct sbc_softc *) ncr_sc;
    955 	struct sci_req *sr = ncr_sc->sc_current;
    956 	struct sbc_pdma_handle *dh = sr->sr_dma_hand;
    957 	volatile struct sbc_regs *sbc = sc->sc_regs;
    958 	register int s;
    959 	register int timo;
    960 
    961 	timo = 50000;	/* X100 = 5 sec. */
    962 	for (;;) {
    963 		if ((dh->dh_flags & SBC_DH_XFER) == 0)
    964 			break;
    965 		if (--timo <= 0) {
    966 			printf("%s: PDMA didn't complete (while polling)\n",
    967 			    ncr_sc->sc_dev.dv_xname);
    968 			sr->sr_flags |= SR_OVERDUE;
    969 			break;
    970 		}
    971 		delay(100);
    972 	}
    973 
    974 #ifdef	SBC_DEBUG
    975 	if (sbc_debug & SBC_DB_DMA)
    976 		printf("%s: poll done, csr=0x%x, bus_csr=0x%x\n",
    977 		    ncr_sc->sc_dev.dv_xname, *ncr_sc->sci_csr,
    978 		    *ncr_sc->sci_bus_csr);
    979 #endif
    980 }
    981 
    982 void
    983 sbc_dma_setup(ncr_sc)
    984 	struct ncr5380_softc *ncr_sc;
    985 {
    986 	/* Not needed; we don't have real DMA */
    987 }
    988 
    989 void
    990 sbc_dma_start(ncr_sc)
    991 	struct ncr5380_softc *ncr_sc;
    992 {
    993 	struct sci_req *sr = ncr_sc->sc_current;
    994 	struct sbc_pdma_handle *dh = sr->sr_dma_hand;
    995 
    996 	/*
    997 	 * Match bus phase, set DMA mode, and assert data bus (for
    998 	 * writing only), then start the transfer.
    999 	 */
   1000 	if (dh->dh_flags & SBC_DH_OUT) {
   1001 		*ncr_sc->sci_tcmd = PHASE_DATA_OUT;
   1002 		SCI_CLR_INTR(ncr_sc);
   1003 		*ncr_sc->sci_mode |= SCI_MODE_DMA;
   1004 		*ncr_sc->sci_icmd = SCI_ICMD_DATA;
   1005 		*ncr_sc->sci_dma_send = 0;
   1006 	} else {
   1007 		*ncr_sc->sci_tcmd = PHASE_DATA_IN;
   1008 		SCI_CLR_INTR(ncr_sc);
   1009 		*ncr_sc->sci_mode |= SCI_MODE_DMA;
   1010 		*ncr_sc->sci_icmd = 0;
   1011 		*ncr_sc->sci_irecv = 0;
   1012 	}
   1013 
   1014 	/*
   1015 	 * Set the SBC_DH_XFER flag so that sbc_dma_poll() will wait
   1016 	 * even if the SCSI DRQ service routine hasn't been serviced yet.
   1017 	 */
   1018 	dh->dh_flags |= SBC_DH_XFER;
   1019 
   1020 	ncr_sc->sc_state |= NCR_DOINGDMA;
   1021 
   1022 #ifdef	SBC_DEBUG
   1023 	if (sbc_debug & SBC_DB_DMA)
   1024 		printf("%s: PDMA started, va=%p, len=0x%x\n",
   1025 		    ncr_sc->sc_dev.dv_xname, dh->dh_addr, dh->dh_len);
   1026 #endif
   1027 }
   1028 
   1029 void
   1030 sbc_dma_eop(ncr_sc)
   1031 	struct ncr5380_softc *ncr_sc;
   1032 {
   1033 	/* Not used; the EOP pin is wired high (GMFH, pp. 389-390) */
   1034 }
   1035 
   1036 void
   1037 sbc_dma_stop(ncr_sc)
   1038 	struct ncr5380_softc *ncr_sc;
   1039 {
   1040 	struct sbc_softc *sc = (struct sbc_softc *) ncr_sc;
   1041 	struct sci_req *sr = ncr_sc->sc_current;
   1042 	struct sbc_pdma_handle *dh = sr->sr_dma_hand;
   1043 	register int ntrans;
   1044 
   1045 	if ((ncr_sc->sc_state & NCR_DOINGDMA) == 0) {
   1046 #ifdef SBC_DEBUG
   1047 		if (sbc_debug & SBC_DB_DMA)
   1048 			printf("%s: dma_stop: DMA not running\n",
   1049 			    ncr_sc->sc_dev.dv_xname);
   1050 #endif
   1051 		return;
   1052 	}
   1053 	ncr_sc->sc_state &= ~NCR_DOINGDMA;
   1054 
   1055 	if (!(ncr_sc->sc_state & NCR_ABORTING)) {
   1056 		ntrans = ncr_sc->sc_datalen - dh->dh_len;
   1057 
   1058 #ifdef SBC_DEBUG
   1059 		if (sbc_debug & SBC_DB_DMA)
   1060 			printf("%s: dma_stop: ntrans=0x%x\n",
   1061 			    ncr_sc->sc_dev.dv_xname, ntrans);
   1062 #endif
   1063 
   1064 		if (ntrans > ncr_sc->sc_datalen)
   1065 			panic("sbc_dma_stop: excess transfer\n");
   1066 
   1067 		/* Adjust data pointer */
   1068 		ncr_sc->sc_dataptr += ntrans;
   1069 		ncr_sc->sc_datalen -= ntrans;
   1070 
   1071 		/* Clear any pending interrupts. */
   1072 		SCI_CLR_INTR(ncr_sc);
   1073 	}
   1074 
   1075 	/* Put SBIC back into PIO mode. */
   1076 	*ncr_sc->sci_mode &= ~SCI_MODE_DMA;
   1077 	*ncr_sc->sci_icmd = 0;
   1078 
   1079 #ifdef SBC_DEBUG
   1080 	if (sbc_debug & SBC_DB_DMA)
   1081 		printf("%s: exit dma_stop, csr=0x%x, bus_csr=0x%x\n",
   1082 		    ncr_sc->sc_dev.dv_xname, *ncr_sc->sci_csr,
   1083 		    *ncr_sc->sci_bus_csr);
   1084 #endif
   1085 }
   1086