Home | History | Annotate | Line # | Download | only in dev
sbc.c revision 1.31
      1 /*	$NetBSD: sbc.c,v 1.31 1997/09/06 07:53:14 scottr Exp $	*/
      2 
      3 /*
      4  * Copyright (C) 1996 Scott Reynolds.  All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. All advertising materials mentioning features or use of this software
     15  *    must display the following acknowledgement:
     16  *      This product includes software developed by Scott Reynolds for
     17  *      the NetBSD Project.
     18  * 4. The name of the author may not be used to endorse or promote products
     19  *    derived from this software without specific prior written permission
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 /*
     34  * This file contains only the machine-dependent parts of the mac68k
     35  * NCR 5380 SCSI driver.  (Autoconfig stuff and PDMA functions.)
     36  * The machine-independent parts are in ncr5380sbc.c
     37  *
     38  * Supported hardware includes:
     39  * Macintosh II family 5380-based controller
     40  *
     41  * Credits, history:
     42  *
     43  * Scott Reynolds wrote this module, based on work by Allen Briggs
     44  * (mac68k), Gordon W. Ross and David Jones (sun3), and Leo Weppelman
     45  * (atari).  Thanks to Allen for supplying crucial interpretation of the
     46  * NetBSD/mac68k 1.1 'ncrscsi' driver.  Also, Allen, Gordon, and Jason
     47  * Thorpe all helped to refine this code, and were considerable sources
     48  * of moral support.
     49  */
     50 
     51 #include <sys/types.h>
     52 #include <sys/param.h>
     53 #include <sys/systm.h>
     54 #include <sys/kernel.h>
     55 #include <sys/errno.h>
     56 #include <sys/device.h>
     57 #include <sys/buf.h>
     58 #include <sys/proc.h>
     59 #include <sys/user.h>
     60 
     61 #include <dev/scsipi/scsi_all.h>
     62 #include <dev/scsipi/scsipi_all.h>
     63 #include <dev/scsipi/scsipi_debug.h>
     64 #include <dev/scsipi/scsiconf.h>
     65 
     66 #include <dev/ic/ncr5380reg.h>
     67 #include <dev/ic/ncr5380var.h>
     68 
     69 #include <machine/cpu.h>
     70 #include <machine/viareg.h>
     71 
     72 #include <mac68k/dev/sbcreg.h>
     73 #include <mac68k/dev/sbcvar.h>
     74 
     75 int	sbc_debug = 0 /* | SBC_DB_INTR | SBC_DB_DMA */;
     76 int	sbc_link_flags = 0 /* | SDEV_DB2 */;
     77 int	sbc_options = 0 /* | SBC_PDMA */;
     78 
     79 static	void	sbc_minphys __P((struct buf *bp));
     80 
     81 struct scsipi_adapter	sbc_ops = {
     82 	ncr5380_scsi_cmd,		/* scsi_cmd()		*/
     83 	sbc_minphys,			/* scsi_minphys()	*/
     84 	NULL,				/* open_target_lu()	*/
     85 	NULL,				/* close_target_lu()	*/
     86 };
     87 
     88 /* This is copied from julian's bt driver */
     89 /* "so we have a default dev struct for our link struct." */
     90 struct scsipi_device sbc_dev = {
     91 	NULL,		/* Use default error handler.	    */
     92 	NULL,		/* Use default start handler.		*/
     93 	NULL,		/* Use default async handler.	    */
     94 	NULL,		/* Use default "done" routine.	    */
     95 };
     96 
     97 struct cfdriver sbc_cd = {
     98 	NULL, "sbc", DV_DULL
     99 };
    100 
    101 extern label_t	*nofault;
    102 extern caddr_t	m68k_fault_addr;
    103 
    104 static	int	sbc_wait_busy __P((struct ncr5380_softc *));
    105 static	int	sbc_ready __P((struct ncr5380_softc *));
    106 static	int	sbc_wait_dreq __P((struct ncr5380_softc *));
    107 
    108 static void
    109 sbc_minphys(struct buf *bp)
    110 {
    111 	if (bp->b_bcount > MAX_DMA_LEN)
    112 		bp->b_bcount = MAX_DMA_LEN;
    113 	return (minphys(bp));
    114 }
    115 
    116 
    117 /***
    118  * General support for Mac-specific SCSI logic.
    119  ***/
    120 
    121 /* These are used in the following inline functions. */
    122 int sbc_wait_busy_timo = 1000 * 5000;	/* X2 = 10 S. */
    123 int sbc_ready_timo = 1000 * 5000;	/* X2 = 10 S. */
    124 int sbc_wait_dreq_timo = 1000 * 5000;	/* X2 = 10 S. */
    125 
    126 /* Return zero on success. */
    127 static __inline__ int
    128 sbc_wait_busy(sc)
    129 	struct ncr5380_softc *sc;
    130 {
    131 	int timo = sbc_wait_busy_timo;
    132 	for (;;) {
    133 		if (SCI_BUSY(sc)) {
    134 			timo = 0;	/* return 0 */
    135 			break;
    136 		}
    137 		if (--timo < 0)
    138 			break;	/* return -1 */
    139 		delay(2);
    140 	}
    141 	return (timo);
    142 }
    143 
    144 static __inline__ int
    145 sbc_ready(sc)
    146 	struct ncr5380_softc *sc;
    147 {
    148 	int timo = sbc_ready_timo;
    149 
    150 	for (;;) {
    151 		if ((*sc->sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH))
    152 		    == (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
    153 			timo = 0;
    154 			break;
    155 		}
    156 		if (((*sc->sci_csr & SCI_CSR_PHASE_MATCH) == 0)
    157 		    || (SCI_BUSY(sc) == 0)) {
    158 			timo = -1;
    159 			break;
    160 		}
    161 		if (--timo < 0)
    162 			break;	/* return -1 */
    163 		delay(2);
    164 	}
    165 	return (timo);
    166 }
    167 
    168 static __inline__ int
    169 sbc_wait_dreq(sc)
    170 	struct ncr5380_softc *sc;
    171 {
    172 	int timo = sbc_wait_dreq_timo;
    173 
    174 	for (;;) {
    175 		if ((*sc->sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH))
    176 		    == (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
    177 			timo = 0;
    178 			break;
    179 		}
    180 		if (--timo < 0)
    181 			break;	/* return -1 */
    182 		delay(2);
    183 	}
    184 	return (timo);
    185 }
    186 
    187 void
    188 sbc_irq_intr(p)
    189 	void *p;
    190 {
    191 	struct ncr5380_softc *ncr_sc = p;
    192 	int claimed = 0;
    193 
    194 	/* How we ever arrive here without IRQ set is a mystery... */
    195 	if (*ncr_sc->sci_csr & SCI_CSR_INT) {
    196 #ifdef SBC_DEBUG
    197 		if (sbc_debug & SBC_DB_INTR)
    198 			decode_5380_intr(ncr_sc);
    199 #endif
    200 		claimed = ncr5380_intr(ncr_sc);
    201 		if (!claimed) {
    202 			if (((*ncr_sc->sci_csr & ~SCI_CSR_PHASE_MATCH) == SCI_CSR_INT)
    203 			    && ((*ncr_sc->sci_bus_csr & ~SCI_BUS_RST) == 0))
    204 				SCI_CLR_INTR(ncr_sc);	/* RST interrupt */
    205 #ifdef SBC_DEBUG
    206 			else {
    207 				printf("%s: spurious intr\n",
    208 				    ncr_sc->sc_dev.dv_xname);
    209 				SBC_BREAK;
    210 			}
    211 #endif
    212 		}
    213 	}
    214 }
    215 
    216 #ifdef SBC_DEBUG
    217 void
    218 decode_5380_intr(ncr_sc)
    219 	struct ncr5380_softc *ncr_sc;
    220 {
    221 	u_int8_t csr = *ncr_sc->sci_csr;
    222 	u_int8_t bus_csr = *ncr_sc->sci_bus_csr;
    223 
    224 	if (((csr & ~(SCI_CSR_PHASE_MATCH | SCI_CSR_ATN)) == SCI_CSR_INT) &&
    225 	    ((bus_csr & ~(SCI_BUS_MSG | SCI_BUS_CD | SCI_BUS_IO | SCI_BUS_DBP)) == SCI_BUS_SEL)) {
    226 		if (csr & SCI_BUS_IO)
    227 			printf("%s: reselect\n", ncr_sc->sc_dev.dv_xname);
    228 		else
    229 			printf("%s: select\n", ncr_sc->sc_dev.dv_xname);
    230 	} else if (((csr & ~SCI_CSR_ACK) == (SCI_CSR_DONE | SCI_CSR_INT)) &&
    231 	    ((bus_csr & (SCI_BUS_RST | SCI_BUS_BSY | SCI_BUS_SEL)) == SCI_BUS_BSY))
    232 		printf("%s: dma eop\n", ncr_sc->sc_dev.dv_xname);
    233 	else if (((csr & ~SCI_CSR_PHASE_MATCH) == SCI_CSR_INT) &&
    234 	    ((bus_csr & ~SCI_BUS_RST) == 0))
    235 		printf("%s: bus reset\n", ncr_sc->sc_dev.dv_xname);
    236 	else if (((csr & ~(SCI_CSR_DREQ | SCI_CSR_ATN | SCI_CSR_ACK)) == (SCI_CSR_PERR | SCI_CSR_INT | SCI_CSR_PHASE_MATCH)) &&
    237 	    ((bus_csr & (SCI_BUS_RST | SCI_BUS_BSY | SCI_BUS_SEL)) == SCI_BUS_BSY))
    238 		printf("%s: parity error\n", ncr_sc->sc_dev.dv_xname);
    239 	else if (((csr & ~SCI_CSR_ATN) == SCI_CSR_INT) &&
    240 	    ((bus_csr & (SCI_BUS_RST | SCI_BUS_BSY | SCI_BUS_REQ | SCI_BUS_SEL)) == (SCI_BUS_BSY | SCI_BUS_REQ)))
    241 		printf("%s: phase mismatch\n", ncr_sc->sc_dev.dv_xname);
    242 	else if (((csr & ~SCI_CSR_PHASE_MATCH) == (SCI_CSR_INT | SCI_CSR_DISC)) &&
    243 	    (bus_csr == 0))
    244 		printf("%s: disconnect\n", ncr_sc->sc_dev.dv_xname);
    245 	else
    246 		printf("%s: unknown intr: csr=%x, bus_csr=%x\n",
    247 		    ncr_sc->sc_dev.dv_xname, csr, bus_csr);
    248 }
    249 #endif
    250 
    251 
    252 /***
    253  * The following code implements polled PDMA.
    254  ***/
    255 
    256 int
    257 sbc_pdma_in(ncr_sc, phase, datalen, data)
    258 	struct ncr5380_softc *ncr_sc;
    259 	int phase;
    260 	int datalen;
    261 	u_char *data;
    262 {
    263 	struct sbc_softc *sc = (struct sbc_softc *)ncr_sc;
    264 	volatile u_int32_t *long_data = (u_int32_t *)sc->sc_drq_addr;
    265 	volatile u_int8_t *byte_data = (u_int8_t *)sc->sc_nodrq_addr;
    266 	int resid, s;
    267 
    268 	if (datalen < ncr_sc->sc_min_dma_len ||
    269 	    (sc->sc_options & SBC_PDMA) == 0)
    270 		return ncr5380_pio_in(ncr_sc, phase, datalen, data);
    271 
    272 	s = splbio();
    273 	if (sbc_wait_busy(ncr_sc)) {
    274 		splx(s);
    275 		return 0;
    276 	}
    277 
    278 	*ncr_sc->sci_mode |= SCI_MODE_DMA;
    279 	*ncr_sc->sci_irecv = 0;
    280 
    281 #define R4	*((u_int32_t *)data)++ = *long_data
    282 #define R1	*((u_int8_t *)data)++ = *byte_data
    283 	for (resid = datalen; resid >= 128; resid -= 128) {
    284 		if (sbc_ready(ncr_sc))
    285 			goto interrupt;
    286 		R4; R4; R4; R4; R4; R4; R4; R4;
    287 		R4; R4; R4; R4; R4; R4; R4; R4;
    288 		R4; R4; R4; R4; R4; R4; R4; R4;
    289 		R4; R4; R4; R4; R4; R4; R4; R4;		/* 128 */
    290 	}
    291 	while (resid) {
    292 		if (sbc_ready(ncr_sc))
    293 			goto interrupt;
    294 		R1;
    295 		resid--;
    296 	}
    297 #undef R4
    298 #undef R1
    299 
    300 interrupt:
    301 	SCI_CLR_INTR(ncr_sc);
    302 	*ncr_sc->sci_mode &= ~SCI_MODE_DMA;
    303 	*ncr_sc->sci_icmd = 0;
    304 	splx(s);
    305 	return (datalen - resid);
    306 }
    307 
    308 int
    309 sbc_pdma_out(ncr_sc, phase, datalen, data)
    310 	struct ncr5380_softc *ncr_sc;
    311 	int phase;
    312 	int datalen;
    313 	u_char *data;
    314 {
    315 	struct sbc_softc *sc = (struct sbc_softc *)ncr_sc;
    316 	volatile u_int32_t *long_data = (u_int32_t *)sc->sc_drq_addr;
    317 	volatile u_int8_t *byte_data = (u_int8_t *)sc->sc_nodrq_addr;
    318 	label_t faultbuf;
    319 	int resid, s;
    320 	u_int8_t icmd;
    321 
    322 #if 1
    323 	/* Work around lame gcc initialization bug */
    324 	(void)&data;
    325 #endif
    326 
    327 	if (datalen < ncr_sc->sc_min_dma_len ||
    328 	    (sc->sc_options & SBC_PDMA) == 0)
    329 		return ncr5380_pio_out(ncr_sc, phase, datalen, data);
    330 
    331 	s = splbio();
    332 	if (sbc_wait_busy(ncr_sc)) {
    333 		splx(s);
    334 		return 0;
    335 	}
    336 
    337 	icmd = *(ncr_sc->sci_icmd) & SCI_ICMD_RMASK;
    338 	*ncr_sc->sci_icmd = icmd | SCI_ICMD_DATA;
    339 	*ncr_sc->sci_mode |= SCI_MODE_DMA;
    340 	*ncr_sc->sci_dma_send = 0;
    341 
    342 	/*
    343 	 * Setup for a possible bus error caused by SCSI controller
    344 	 * switching out of DATA OUT before we're done with the
    345 	 * current transfer.  (See comment before sbc_drq_intr().)
    346 	 */
    347 	nofault = &faultbuf;
    348 
    349 	if (setjmp(nofault)) {
    350 		printf("buf = 0x%lx, fault = 0x%lx\n",
    351 		    (u_long)sc->sc_drq_addr, (u_long)m68k_fault_addr);
    352 		panic("Unexpected bus error in sbc_pdma_out()");
    353 	}
    354 
    355 #define W1	*byte_data = *((u_int8_t *)data)++
    356 #define W4	*long_data = *((u_int32_t *)data)++
    357 	for (resid = datalen; resid >= 64; resid -= 64) {
    358 		if (sbc_ready(ncr_sc))
    359 			goto interrupt;
    360 		W1;
    361 		if (sbc_ready(ncr_sc))
    362 			goto interrupt;
    363 		W1;
    364 		if (sbc_ready(ncr_sc))
    365 			goto interrupt;
    366 		W1;
    367 		if (sbc_ready(ncr_sc))
    368 			goto interrupt;
    369 		W1;
    370 		if (sbc_ready(ncr_sc))
    371 			goto interrupt;
    372 		W4; W4; W4; W4;
    373 		W4; W4; W4; W4;
    374 		W4; W4; W4; W4;
    375 		W4; W4; W4;
    376 	}
    377 	while (resid) {
    378 		if (sbc_ready(ncr_sc))
    379 			goto interrupt;
    380 		W1;
    381 		resid--;
    382 	}
    383 #undef  W1
    384 #undef  W4
    385 	if (sbc_wait_dreq(ncr_sc))
    386 		printf("%s: timeout waiting for DREQ.\n",
    387 		    ncr_sc->sc_dev.dv_xname);
    388 
    389 	*byte_data = 0;
    390 	goto done;
    391 
    392 interrupt:
    393 	if ((*ncr_sc->sci_csr & SCI_CSR_PHASE_MATCH) == 0) {
    394 		*ncr_sc->sci_icmd = icmd & ~SCI_ICMD_DATA;
    395 		--resid;
    396 	}
    397 
    398 done:
    399 	SCI_CLR_INTR(ncr_sc);
    400 	*ncr_sc->sci_mode &= ~SCI_MODE_DMA;
    401 	*ncr_sc->sci_icmd = icmd;
    402 	splx(s);
    403 	return (datalen - resid);
    404 }
    405 
    406 
    407 /***
    408  * The following code implements interrupt-driven PDMA.
    409  ***/
    410 
    411 /*
    412  * This is the meat of the PDMA transfer.
    413  * When we get here, we shove data as fast as the mac can take it.
    414  * We depend on several things:
    415  *   * All macs after the Mac Plus that have a 5380 chip should have a general
    416  *     logic IC that handshakes data for blind transfers.
    417  *   * If the SCSI controller finishes sending/receiving data before we do,
    418  *     the same general logic IC will generate a /BERR for us in short order.
    419  *   * The fault address for said /BERR minus the base address for the
    420  *     transfer will be the amount of data that was actually written.
    421  *
    422  * We use the nofault flag and the setjmp/longjmp in locore.s so we can
    423  * detect and handle the bus error for early termination of a command.
    424  * This is usually caused by a disconnecting target.
    425  */
    426 void
    427 sbc_drq_intr(p)
    428 	void *p;
    429 {
    430 	struct sbc_softc *sc = (struct sbc_softc *)p;
    431 	struct ncr5380_softc *ncr_sc = (struct ncr5380_softc *)p;
    432 	struct sci_req *sr = ncr_sc->sc_current;
    433 	struct sbc_pdma_handle *dh = sr->sr_dma_hand;
    434 	label_t faultbuf;
    435 	volatile u_int32_t *long_drq;
    436 	u_int32_t *long_data;
    437 	volatile u_int8_t *drq;
    438 	u_int8_t *data;
    439 	int count, dcount, resid;
    440 	u_int8_t tmp;
    441 
    442 	/* Work around lame gcc initialization bug */
    443 	(void)&drq;
    444 
    445 	/*
    446 	 * If we're not ready to xfer data, or have no more, just return.
    447 	 */
    448 	if ((*ncr_sc->sci_csr & SCI_CSR_DREQ) == 0 || dh->dh_len == 0)
    449 		return;
    450 
    451 #ifdef SBC_DEBUG
    452 	if (sbc_debug & SBC_DB_INTR)
    453 		printf("%s: drq intr, dh_len=0x%x, dh_flags=0x%x\n",
    454 		    ncr_sc->sc_dev.dv_xname, dh->dh_len, dh->dh_flags);
    455 #endif
    456 
    457 	/*
    458 	 * Setup for a possible bus error caused by SCSI controller
    459 	 * switching out of DATA-IN/OUT before we're done with the
    460 	 * current transfer.
    461 	 */
    462 	nofault = &faultbuf;
    463 
    464 	if (setjmp((label_t *)nofault)) {
    465 		nofault = (label_t *)0;
    466 		if ((dh->dh_flags & SBC_DH_DONE) == 0) {
    467 			count = ((  (u_long)m68k_fault_addr
    468 				  - (u_long)sc->sc_drq_addr));
    469 
    470 			if ((count < 0) || (count > dh->dh_len)) {
    471 				printf("%s: complete=0x%x (pending 0x%x)\n",
    472 				    ncr_sc->sc_dev.dv_xname, count, dh->dh_len);
    473 				panic("something is wrong");
    474 			}
    475 
    476 			dh->dh_addr += count;
    477 			dh->dh_len -= count;
    478 		} else
    479 			count = 0;
    480 
    481 #ifdef SBC_DEBUG
    482 		if (sbc_debug & SBC_DB_INTR)
    483 			printf("%s: drq /berr, complete=0x%x (pending 0x%x)\n",
    484 			   ncr_sc->sc_dev.dv_xname, count, dh->dh_len);
    485 #endif
    486 		m68k_fault_addr = 0;
    487 
    488 		return;
    489 	}
    490 
    491 	if (dh->dh_flags & SBC_DH_OUT) { /* Data Out */
    492 		dcount = 0;
    493 
    494 		/*
    495 		 * Get the source address aligned.
    496 		 */
    497 		resid =
    498 		    count = min(dh->dh_len, 4 - (((int)dh->dh_addr) & 0x3));
    499 		if (count && count < 4) {
    500 			drq = (volatile u_int8_t *)sc->sc_drq_addr;
    501 			data = (u_int8_t *)dh->dh_addr;
    502 
    503 #define W1		*drq++ = *data++
    504 			while (count) {
    505 				W1; count--;
    506 			}
    507 #undef W1
    508 			dh->dh_addr += resid;
    509 			dh->dh_len -= resid;
    510 		}
    511 
    512 		/*
    513 		 * Start the transfer.
    514 		 */
    515 		while (dh->dh_len) {
    516 			dcount = count = min(dh->dh_len, MAX_DMA_LEN);
    517 			long_drq = (volatile u_int32_t *)sc->sc_drq_addr;
    518 			long_data = (u_int32_t *)dh->dh_addr;
    519 
    520 #define W4		*long_drq++ = *long_data++
    521 			while (count >= 64) {
    522 				W4; W4; W4; W4; W4; W4; W4; W4;
    523 				W4; W4; W4; W4; W4; W4; W4; W4; /*  64 */
    524 				count -= 64;
    525 			}
    526 			while (count >= 4) {
    527 				W4; count -= 4;
    528 			}
    529 #undef W4
    530 			data = (u_int8_t *)long_data;
    531 			drq = (u_int8_t *)long_drq;
    532 
    533 #define W1		*drq++ = *data++
    534 			while (count) {
    535 				W1; count--;
    536 			}
    537 #undef W1
    538 			dh->dh_len -= dcount;
    539 			dh->dh_addr += dcount;
    540 		}
    541 		dh->dh_flags |= SBC_DH_DONE;
    542 
    543 		/*
    544 		 * XXX -- Read a byte from the SBC to trigger a /BERR.
    545 		 * This seems to be necessary for us to notice that
    546 		 * the target has disconnected.  Ick.  06 jun 1996 (sr)
    547 		 */
    548 		if (dcount >= MAX_DMA_LEN)
    549 			drq = (volatile u_int8_t *)sc->sc_drq_addr;
    550 		tmp = *drq;
    551 	} else {	/* Data In */
    552 		/*
    553 		 * Get the dest address aligned.
    554 		 */
    555 		resid =
    556 		    count = min(dh->dh_len, 4 - (((int)dh->dh_addr) & 0x3));
    557 		if (count && count < 4) {
    558 			data = (u_int8_t *)dh->dh_addr;
    559 			drq = (volatile u_int8_t *)sc->sc_drq_addr;
    560 
    561 #define R1		*data++ = *drq++
    562 			while (count) {
    563 				R1; count--;
    564 			}
    565 #undef R1
    566 			dh->dh_addr += resid;
    567 			dh->dh_len -= resid;
    568 		}
    569 
    570 		/*
    571 		 * Start the transfer.
    572 		 */
    573 		while (dh->dh_len) {
    574 			dcount = count = min(dh->dh_len, MAX_DMA_LEN);
    575 			long_data = (u_int32_t *)dh->dh_addr;
    576 			long_drq = (volatile u_int32_t *)sc->sc_drq_addr;
    577 
    578 #define R4		*long_data++ = *long_drq++
    579 			while (count >= 64) {
    580 				R4; R4; R4; R4; R4; R4; R4; R4;
    581 				R4; R4; R4; R4; R4; R4; R4; R4;	/* 64 */
    582 				count -= 64;
    583 			}
    584 			while (count >= 4) {
    585 				R4; count -= 4;
    586 			}
    587 #undef R4
    588 			data = (u_int8_t *)long_data;
    589 			drq = (volatile u_int8_t *)long_drq;
    590 
    591 #define R1		*data++ = *drq++
    592 			while (count) {
    593 				R1; count--;
    594 			}
    595 #undef R1
    596 			dh->dh_len -= dcount;
    597 			dh->dh_addr += dcount;
    598 		}
    599 		dh->dh_flags |= SBC_DH_DONE;
    600 	}
    601 
    602 	/*
    603 	 * OK.  No bus error occurred above.  Clear the nofault flag
    604 	 * so we no longer short-circuit bus errors.
    605 	 */
    606 	nofault = (label_t *)0;
    607 
    608 #ifdef SBC_DEBUG
    609 	if (sbc_debug & (SBC_DB_REG | SBC_DB_INTR))
    610 		printf("%s: drq intr complete: csr=0x%x, bus_csr=0x%x\n",
    611 		    ncr_sc->sc_dev.dv_xname, *ncr_sc->sci_csr,
    612 		    *ncr_sc->sci_bus_csr);
    613 #endif
    614 }
    615 
    616 void
    617 sbc_dma_alloc(ncr_sc)
    618 	struct ncr5380_softc *ncr_sc;
    619 {
    620 	struct sbc_softc *sc = (struct sbc_softc *)ncr_sc;
    621 	struct sci_req *sr = ncr_sc->sc_current;
    622 	struct scsipi_xfer *xs = sr->sr_xs;
    623 	struct sbc_pdma_handle *dh;
    624 	int		i, xlen;
    625 
    626 #ifdef DIAGNOSTIC
    627 	if (sr->sr_dma_hand != NULL)
    628 		panic("sbc_dma_alloc: already have PDMA handle");
    629 #endif
    630 
    631 	/* Polled transfers shouldn't allocate a PDMA handle. */
    632 	if (sr->sr_flags & SR_IMMED)
    633 		return;
    634 
    635 	xlen = ncr_sc->sc_datalen;
    636 
    637 	/* Make sure our caller checked sc_min_dma_len. */
    638 	if (xlen < MIN_DMA_LEN)
    639 		panic("sbc_dma_alloc: len=0x%x\n", xlen);
    640 
    641 	/*
    642 	 * Find free PDMA handle.  Guaranteed to find one since we
    643 	 * have as many PDMA handles as the driver has processes.
    644 	 * (instances?)
    645 	 */
    646 	 for (i = 0; i < SCI_OPENINGS; i++) {
    647 		if ((sc->sc_pdma[i].dh_flags & SBC_DH_BUSY) == 0)
    648 			goto found;
    649 	}
    650 	panic("sbc: no free PDMA handles");
    651 found:
    652 	dh = &sc->sc_pdma[i];
    653 	dh->dh_flags = SBC_DH_BUSY;
    654 	dh->dh_addr = ncr_sc->sc_dataptr;
    655 	dh->dh_len = xlen;
    656 
    657 	/* Copy the 'write' flag for convenience. */
    658 	if (xs->flags & SCSI_DATA_OUT)
    659 		dh->dh_flags |= SBC_DH_OUT;
    660 
    661 	sr->sr_dma_hand = dh;
    662 }
    663 
    664 void
    665 sbc_dma_free(ncr_sc)
    666 	struct ncr5380_softc *ncr_sc;
    667 {
    668 	struct sci_req *sr = ncr_sc->sc_current;
    669 	struct sbc_pdma_handle *dh = sr->sr_dma_hand;
    670 
    671 #ifdef DIAGNOSTIC
    672 	if (sr->sr_dma_hand == NULL)
    673 		panic("sbc_dma_free: no DMA handle");
    674 #endif
    675 
    676 	if (ncr_sc->sc_state & NCR_DOINGDMA)
    677 		panic("sbc_dma_free: free while in progress");
    678 
    679 	if (dh->dh_flags & SBC_DH_BUSY) {
    680 		dh->dh_flags = 0;
    681 		dh->dh_addr = NULL;
    682 		dh->dh_len = 0;
    683 	}
    684 	sr->sr_dma_hand = NULL;
    685 }
    686 
    687 void
    688 sbc_dma_poll(ncr_sc)
    689 	struct ncr5380_softc *ncr_sc;
    690 {
    691 	struct sci_req *sr = ncr_sc->sc_current;
    692 
    693 	/*
    694 	 * We shouldn't arrive here; if SR_IMMED is set, then
    695 	 * dma_alloc() should have refused to allocate a handle
    696 	 * for the transfer.  This forces the polled PDMA code
    697 	 * to handle the request...
    698 	 */
    699 #ifdef SBC_DEBUG
    700 	if (sbc_debug & SBC_DB_DMA)
    701 		printf("%s: lost DRQ interrupt?\n", ncr_sc->sc_dev.dv_xname);
    702 #endif
    703 	sr->sr_flags |= SR_OVERDUE;
    704 }
    705 
    706 void
    707 sbc_dma_setup(ncr_sc)
    708 	struct ncr5380_softc *ncr_sc;
    709 {
    710 	/* Not needed; we don't have real DMA */
    711 }
    712 
    713 void
    714 sbc_dma_start(ncr_sc)
    715 	struct ncr5380_softc *ncr_sc;
    716 {
    717 	struct sbc_softc *sc = (struct sbc_softc *)ncr_sc;
    718 	struct sci_req *sr = ncr_sc->sc_current;
    719 	struct sbc_pdma_handle *dh = sr->sr_dma_hand;
    720 
    721 	/*
    722 	 * Match bus phase, clear pending interrupts, set DMA mode, and
    723 	 * assert data bus (for writing only), then start the transfer.
    724 	 */
    725 	if (dh->dh_flags & SBC_DH_OUT) {
    726 		*ncr_sc->sci_tcmd = PHASE_DATA_OUT;
    727 		SCI_CLR_INTR(ncr_sc);
    728 		if (sc->sc_clrintr)
    729 			(*sc->sc_clrintr)(ncr_sc);
    730 		*ncr_sc->sci_mode |= SCI_MODE_DMA;
    731 		*ncr_sc->sci_icmd = SCI_ICMD_DATA;
    732 		*ncr_sc->sci_dma_send = 0;
    733 	} else {
    734 		*ncr_sc->sci_tcmd = PHASE_DATA_IN;
    735 		SCI_CLR_INTR(ncr_sc);
    736 		if (sc->sc_clrintr)
    737 			(*sc->sc_clrintr)(ncr_sc);
    738 		*ncr_sc->sci_mode |= SCI_MODE_DMA;
    739 		*ncr_sc->sci_icmd = 0;
    740 		*ncr_sc->sci_irecv = 0;
    741 	}
    742 	ncr_sc->sc_state |= NCR_DOINGDMA;
    743 
    744 #ifdef SBC_DEBUG
    745 	if (sbc_debug & SBC_DB_DMA)
    746 		printf("%s: PDMA started, va=%p, len=0x%x\n",
    747 		    ncr_sc->sc_dev.dv_xname, dh->dh_addr, dh->dh_len);
    748 #endif
    749 }
    750 
    751 void
    752 sbc_dma_eop(ncr_sc)
    753 	struct ncr5380_softc *ncr_sc;
    754 {
    755 	/* Not used; the EOP pin is wired high (GMFH, pp. 389-390) */
    756 }
    757 
    758 void
    759 sbc_dma_stop(ncr_sc)
    760 	struct ncr5380_softc *ncr_sc;
    761 {
    762 	struct sbc_softc *sc = (struct sbc_softc *)ncr_sc;
    763 	struct sci_req *sr = ncr_sc->sc_current;
    764 	struct sbc_pdma_handle *dh = sr->sr_dma_hand;
    765 	int ntrans;
    766 
    767 	if ((ncr_sc->sc_state & NCR_DOINGDMA) == 0) {
    768 #ifdef SBC_DEBUG
    769 		if (sbc_debug & SBC_DB_DMA)
    770 			printf("%s: dma_stop: DMA not running\n",
    771 			    ncr_sc->sc_dev.dv_xname);
    772 #endif
    773 		return;
    774 	}
    775 	ncr_sc->sc_state &= ~NCR_DOINGDMA;
    776 
    777 	if ((ncr_sc->sc_state & NCR_ABORTING) == 0) {
    778 		ntrans = ncr_sc->sc_datalen - dh->dh_len;
    779 
    780 #ifdef SBC_DEBUG
    781 		if (sbc_debug & SBC_DB_DMA)
    782 			printf("%s: dma_stop: ntrans=0x%x\n",
    783 			    ncr_sc->sc_dev.dv_xname, ntrans);
    784 #endif
    785 
    786 		if (ntrans > ncr_sc->sc_datalen)
    787 			panic("sbc_dma_stop: excess transfer\n");
    788 
    789 		/* Adjust data pointer */
    790 		ncr_sc->sc_dataptr += ntrans;
    791 		ncr_sc->sc_datalen -= ntrans;
    792 
    793 		/* Clear any pending interrupts. */
    794 		SCI_CLR_INTR(ncr_sc);
    795 		if (sc->sc_clrintr)
    796 			(*sc->sc_clrintr)(ncr_sc);
    797 	}
    798 
    799 	/* Put SBIC back into PIO mode. */
    800 	*ncr_sc->sci_mode &= ~SCI_MODE_DMA;
    801 	*ncr_sc->sci_icmd = 0;
    802 
    803 #ifdef SBC_DEBUG
    804 	if (sbc_debug & SBC_DB_REG)
    805 		printf("%s: dma_stop: csr=0x%x, bus_csr=0x%x\n",
    806 		    ncr_sc->sc_dev.dv_xname, *ncr_sc->sci_csr,
    807 		    *ncr_sc->sci_bus_csr);
    808 #endif
    809 }
    810