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