Home | History | Annotate | Line # | Download | only in dev
si.c revision 1.21
      1 /*	$NetBSD: si.c,v 1.21 1995/08/14 20:00:00 gwr Exp $	*/
      2 
      3 /*
      4  * Copyright (C) 1994 Adam Glass, Gordon W. Ross
      5  * Copyright (C) 1993	Allen K. Briggs, Chris P. Caputo,
      6  *			Michael L. Finch, Bradley A. Grantham, and
      7  *			Lawrence A. Kesteloot
      8  * All rights reserved.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *	This product includes software developed by the Alice Group.
     21  * 4. The names of the Alice Group or any of its members may not be used
     22  *    to endorse or promote products derived from this software without
     23  *    specific prior written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
     26  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     27  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     28  * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
     29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     30  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     34  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     35  */
     36 
     37 #define DEBUG 1
     38 
     39 /* XXX - Need to add support for real DMA. -gwr */
     40 /* #define PSEUDO_DMA 1 (broken) */
     41 
     42 #include <sys/types.h>
     43 #include <sys/malloc.h>
     44 #include <sys/param.h>
     45 #include <sys/systm.h>
     46 #include <sys/errno.h>
     47 #include <sys/buf.h>
     48 #include <sys/proc.h>
     49 #include <sys/user.h>
     50 #include <sys/device.h>
     51 
     52 #include <machine/autoconf.h>
     53 #include <machine/isr.h>
     54 #include <machine/obio.h>
     55 
     56 #include <scsi/scsi_all.h>
     57 #include <scsi/scsi_debug.h>
     58 #include <scsi/scsiconf.h>
     59 
     60 #include "scsi_defs.h"
     61 #include "scsi_5380.h"
     62 #include "scsi_sunsi.h"
     63 
     64 #ifdef	DEBUG
     65 static int si_debug = 0;
     66 static int si_flags = 0 /* | SDEV_DB2 */ ;
     67 #endif
     68 
     69 #define SCI_PHASE_DISC		0	/* sort of ... */
     70 #define SCI_CLR_INTR(regs)	((volatile)(regs->sci_iack))
     71 #define SCI_ACK(ptr,phase)	(ptr)->sci_tcmd = (phase)
     72 #define SCSI_TIMEOUT_VAL	1000000
     73 #define WAIT_FOR_NOT_REQ(ptr) {	\
     74 	int scsi_timeout = SCSI_TIMEOUT_VAL; \
     75 	while ( ((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
     76 		 ((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
     77 		 ((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
     78 		 (--scsi_timeout) ); \
     79 	if (!scsi_timeout) { \
     80 		printf("scsi timeout--WAIT_FOR_NOT_REQ---%s, line %d.\n", \
     81 			__FILE__, __LINE__); \
     82 		goto scsi_timeout_error; \
     83 	} \
     84 	}
     85 #define WAIT_FOR_REQ(ptr) {	\
     86 	int scsi_timeout = SCSI_TIMEOUT_VAL; \
     87 	while ( (((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
     88 		(((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
     89 		(((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
     90 		 (--scsi_timeout) ); \
     91 	if (!scsi_timeout) { \
     92 		printf("scsi timeout--WAIT_FOR_REQ---%s, line %d.\n", \
     93 			__FILE__, __LINE__); \
     94 		goto scsi_timeout_error; \
     95 	} \
     96 	}
     97 #define WAIT_FOR_BSY(ptr) {	\
     98 	int scsi_timeout = SCSI_TIMEOUT_VAL; \
     99 	while ( (((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
    100 		(((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
    101 		(((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
    102 		 (--scsi_timeout) ); \
    103 	if (!scsi_timeout) { \
    104 		printf("scsi timeout--WAIT_FOR_BSY---%s, line %d.\n", \
    105 			__FILE__, __LINE__); \
    106 		goto scsi_timeout_error; \
    107 	} \
    108 	}
    109 
    110 #define ARBITRATION_RETRIES 1000
    111 
    112 #ifdef DDB
    113 int Debugger();
    114 #else
    115 #define Debugger() panic("Should call Debugger here %s:%d", \
    116 			 __FILE__, __LINE__)
    117 #endif
    118 
    119 struct ncr5380_softc {
    120     struct device sc_dev;
    121     volatile void *sc_regs;
    122     int sc_adapter_type;
    123     int sc_adapter_iv_am;	/* int. vec + address modifier */
    124     struct scsi_link sc_link;
    125 };
    126 
    127 static void		ncr5380_minphys(struct buf *bp);
    128 static int		ncr5380_scsi_cmd(struct scsi_xfer *xs);
    129 static int		ncr5380_reset_adapter(struct ncr5380_softc *);
    130 static int		ncr5380_reset_scsibus(struct ncr5380_softc *);
    131 static int		ncr5380_poll(int adapter, int timeout);
    132 static int		ncr5380_send_cmd(struct scsi_xfer *xs);
    133 
    134 static int		ncr_intr(void *);
    135 
    136 static int	si_generic(int adapter, int id, int lun,
    137 			 struct scsi_generic *cmd, int cmdlen,
    138 			 void *databuf, int datalen);
    139 static int	si_group0(int adapter, int id, int lun,
    140 			    int opcode, int addr, int len,
    141 			    int flags, caddr_t databuf, int datalen);
    142 
    143 static char scsi_name[] = "si";
    144 
    145 struct scsi_adapter	ncr5380_switch = {
    146 	ncr5380_scsi_cmd,		/* scsi_cmd()		*/
    147 	ncr5380_minphys,		/* scsi_minphys()	*/
    148 	NULL,				/* open_target_lu()	*/
    149 	NULL,				/* close_target_lu()	*/
    150 };
    151 
    152 /* This is copied from julian's bt driver */
    153 /* "so we have a default dev struct for our link struct." */
    154 struct scsi_device ncr_dev = {
    155 	NULL,		/* Use default error handler.	    */
    156 	NULL,		/* Use default start handler.		*/
    157 	NULL,		/* Use default async handler.	    */
    158 	NULL,		/* Use default "done" routine.	    */
    159 };
    160 
    161 static int	si_match();
    162 static void	si_attach();
    163 
    164 struct cfdriver sicd = {
    165 	NULL, "si", si_match, si_attach, DV_DULL,
    166 	sizeof(struct ncr5380_softc), NULL, 0,
    167 };
    168 
    169 static int
    170 si_print(aux, name)
    171 	void *aux;
    172 	char *name;
    173 {
    174 }
    175 
    176 static int
    177 si_match(parent, vcf, args)
    178 	struct device	*parent;
    179 	void		*vcf, *args;
    180 {
    181 	struct cfdata	*cf = vcf;
    182 	struct confargs *ca = args;
    183 	int x, probe_addr;
    184 
    185 	/* Default interrupt priority always splbio==2 */
    186 	if (ca->ca_intpri == -1)
    187 		ca->ca_intpri = 2;
    188 
    189 	if ((cpu_machine_id == SUN3_MACH_50) ||
    190 	    (cpu_machine_id == SUN3_MACH_60) )
    191 	{
    192 		/* Sun3/50 or Sun3/60 have only OBIO "si" */
    193 		if (ca->ca_bustype != BUS_OBIO)
    194 			return(0);
    195 		if (ca->ca_paddr == -1)
    196 			ca->ca_paddr = OBIO_NCR_SCSI;
    197 		/* OK... */
    198 	} else {
    199 		/* Other Sun3 models may have VME "si" or "sc" */
    200 		if (ca->ca_bustype != BUS_VME16)
    201 			return (0);
    202 		if (ca->ca_paddr == -1)
    203 			return (0);
    204 		/* OK... */
    205 	}
    206 
    207 	/* Make sure there is something there... */
    208 	x = bus_peek(ca->ca_bustype, ca->ca_paddr + 1, 1);
    209 	if (x == -1)
    210 		return (0);
    211 
    212 	/*
    213 	 * If this is a VME SCSI board, we have to determine whether
    214 	 * it is an "sc" (Sun2) or "si" (Sun3) SCSI board.  This can
    215 	 * be determined using the fact that the "sc" board occupies
    216 	 * 4K bytes in VME space but the "si" board occupies 2K bytes.
    217 	 */
    218 	if (ca->ca_bustype == BUS_VME16) {
    219 		/* Note, the "si" board should NOT respond here. */
    220 		x = bus_peek(ca->ca_bustype, ca->ca_paddr + 0x801, 1);
    221 		if (x != -1)
    222 			return(0);
    223 	}
    224 
    225     return (1);
    226 }
    227 
    228 static void
    229 si_attach(parent, self, args)
    230 	struct device	*parent, *self;
    231 	void		*args;
    232 {
    233 	struct ncr5380_softc *ncr5380 = (struct ncr5380_softc *) self;
    234 	volatile sci_regmap_t *regs;
    235 	struct confargs *ca = args;
    236 
    237 	switch (ca->ca_bustype) {
    238 
    239 	case BUS_OBIO:
    240 		regs = (sci_regmap_t *)
    241 			obio_alloc(ca->ca_paddr, sizeof(*regs));
    242 		isr_add_autovect(ncr_intr, (void *)ncr5380,
    243 						 ca->ca_intpri);
    244 		break;
    245 
    246 	case BUS_VME16:
    247 		regs = (sci_regmap_t *)
    248 			bus_mapin(ca->ca_bustype, ca->ca_paddr, sizeof(*regs));
    249 		isr_add_vectored(ncr_intr, (void *)ncr5380,
    250 						 ca->ca_intpri, ca->ca_intvec);
    251 		break;
    252 
    253 	default:
    254 		printf("unknown\n");
    255 		return;
    256 	}
    257 
    258 	ncr5380->sc_adapter_type = ca->ca_bustype;
    259 	ncr5380->sc_adapter_iv_am =
    260 		VME_SUPV_DATA_24 | (ca->ca_intvec & 0xFF);
    261 	ncr5380->sc_regs = regs;
    262 
    263 	/*
    264 	 * fill in the prototype scsi_link.
    265 	 */
    266     ncr5380->sc_link.adapter_softc = ncr5380;
    267     ncr5380->sc_link.adapter_target = 7;
    268     ncr5380->sc_link.adapter = &ncr5380_switch;
    269     ncr5380->sc_link.device = &ncr_dev;
    270     ncr5380->sc_link.openings = 2;
    271 #ifdef	DEBUG
    272     ncr5380->sc_link.flags |= si_flags;
    273 #endif
    274 
    275     printf("\n");
    276 	ncr5380_reset_adapter(ncr5380);
    277 	ncr5380_reset_scsibus(ncr5380);
    278 	config_found(self, &(ncr5380->sc_link), si_print);
    279 }
    280 
    281 #define MIN_PHYS	65536	/*BARF!!!!*/
    282 static void
    283 ncr5380_minphys(struct buf *bp)
    284 {
    285 	if (bp->b_bcount > MIN_PHYS) {
    286 		printf("Uh-oh...  ncr5380_minphys setting bp->b_bcount = %x.\n", MIN_PHYS);
    287 		bp->b_bcount = MIN_PHYS;
    288 	}
    289 	minphys(bp);
    290 }
    291 #undef MIN_PHYS
    292 
    293 static int
    294 ncr5380_scsi_cmd(struct scsi_xfer *xs)
    295 {
    296 	int flags, s, r;
    297 
    298 	flags = xs->flags;
    299 	if (xs->bp) flags |= (SCSI_NOSLEEP);
    300 	if ( flags & ITSDONE ) {
    301 		printf("Already done?");
    302 		xs->flags &= ~ITSDONE;
    303 	}
    304 	if ( ! ( flags & INUSE ) ) {
    305 		printf("Not in use?");
    306 		xs->flags |= INUSE;
    307 	}
    308 
    309 	s = splbio();
    310 
    311 	if ( flags & SCSI_RESET ) {
    312 		printf("flags & SCSIRESET.\n");
    313 		ncr5380_reset_scsibus(xs->sc_link->adapter_softc);
    314 		r = COMPLETE;
    315 	} else {
    316 		r = ncr5380_send_cmd(xs);
    317 		xs->flags |= ITSDONE;
    318 		scsi_done(xs);
    319 	}
    320 
    321 	splx(s);
    322 
    323 	switch(r) {
    324 	case COMPLETE:
    325 	case SUCCESSFULLY_QUEUED:
    326 		r = SUCCESSFULLY_QUEUED;
    327 		if (xs->flags & SCSI_POLL)
    328 			r = COMPLETE;
    329 		break;
    330 	default:
    331 		break;
    332 	}
    333 	return r;
    334 }
    335 
    336 #ifdef	DEBUG
    337 static int
    338 ncr5380_show_scsi_cmd(struct scsi_xfer *xs)
    339 {
    340 	u_char	*b = (u_char *) xs->cmd;
    341 	int	i  = 0;
    342 
    343 	if ( ! ( xs->flags & SCSI_RESET ) ) {
    344 		printf("si(%d:%d:%d)-",
    345 			   xs->sc_link->scsibus,
    346 			   xs->sc_link->target,
    347 			   xs->sc_link->lun);
    348 		while (i < xs->cmdlen) {
    349 			if (i) printf(",");
    350 			printf("%x",b[i++]);
    351 		}
    352 		printf("-\n");
    353 	} else {
    354 		printf("si(%d:%d:%d)-RESET-\n",
    355 			   xs->sc_link->scsibus,
    356 			   xs->sc_link->target,
    357 			   xs->sc_link->lun);
    358 	}
    359 }
    360 #endif
    361 
    362 /*
    363  * Actual chip control.
    364  */
    365 
    366 static void
    367 ncr_sbc_intr(struct ncr5380_softc *ncr5380)
    368 {
    369 	volatile sci_regmap_t *regs = ncr5380->sc_regs;
    370 
    371 	if ((regs->sci_csr & SCI_CSR_INT) == 0) {
    372 #ifdef	DEBUG
    373 		printf (" ncr_sbc_intr: spurrious\n");
    374 #endif
    375 		return;
    376 	}
    377 
    378 	SCI_CLR_INTR(regs);
    379 #ifdef	DEBUG
    380 	printf (" ncr_sbc_intr\n");
    381 #endif
    382 }
    383 
    384 static void
    385 ncr_dma_intr(struct ncr5380_softc *ncr5380)
    386 {
    387 	volatile struct si_regs *regs = ncr5380->sc_regs;
    388 
    389 #ifdef	DEBUG
    390 	printf (" ncr_dma_intr\n");
    391 #endif
    392 }
    393 
    394 static int
    395 ncr_intr(void *arg)
    396 {
    397 	struct ncr5380_softc *ncr5380 = arg;
    398 	volatile struct si_regs *si = ncr5380->sc_regs;
    399 	int rv = 0;
    400 
    401 	/* Interrupts not enabled?  Can not be for us. */
    402 	if ((si->si_csr & SI_CSR_INTR_EN) == 0)
    403 		return rv;
    404 
    405 	if (si->si_csr & SI_CSR_DMA_IP) {
    406 		ncr_dma_intr(ncr5380);
    407 		rv++;
    408 	}
    409 	if (si->si_csr & SI_CSR_SBC_IP) {
    410 		ncr_sbc_intr(ncr5380);
    411 		rv++;
    412 	}
    413 	return rv;
    414 }
    415 
    416 static int
    417 ncr5380_reset_adapter(struct ncr5380_softc *sc)
    418 {
    419 	volatile struct si_regs *si = sc->sc_regs;
    420 
    421 #ifdef	DEBUG
    422 	if (si_debug) {
    423 		printf("si_reset_adapter\n");
    424 	}
    425 #endif
    426 
    427 	/* The reset bits in the CSR are active low. */
    428 	si->si_csr = 0;
    429 	delay(20);
    430 	si->si_csr = SI_CSR_FIFO_RES | SI_CSR_SCSI_RES;
    431 	si->fifo_count = 0;
    432 	if (sc->sc_adapter_type == BUS_VME16) {
    433 		si->dma_addrh = 0;
    434 		si->dma_addrl = 0;
    435 		si->dma_counth = 0;
    436 		si->dma_countl = 0;
    437 		si->iv_am = sc->sc_adapter_iv_am;
    438 	}
    439 }
    440 
    441 static int
    442 ncr5380_reset_scsibus(struct ncr5380_softc *ncr5380)
    443 {
    444 	volatile sci_regmap_t *regs = ncr5380->sc_regs;
    445 
    446 #ifdef	DEBUG
    447 	if (si_debug) {
    448 		printf("si_reset_scsibus\n");
    449 	}
    450 #endif
    451 
    452 	regs->sci_icmd = SCI_ICMD_RST;
    453 	delay(100);
    454 	regs->sci_icmd = 0;
    455 
    456 	regs->sci_mode = 0;
    457 	regs->sci_tcmd = SCI_PHASE_DISC;
    458 	regs->sci_sel_enb = 0;
    459 
    460 	SCI_CLR_INTR(regs);
    461 	/* XXX - Need long delay here! */
    462 }
    463 
    464 static int
    465 ncr5380_poll(int adapter, int timeout)
    466 {
    467 }
    468 
    469 static int
    470 ncr5380_send_cmd(struct scsi_xfer *xs)
    471 {
    472 	int	sense;
    473 
    474 #ifdef	DIAGNOSTIC
    475 	if ((getsr() & PSL_IPL) < PSL_IPL2)
    476 		panic("ncr_send_cmd: bad spl");
    477 #endif
    478 
    479 #ifdef	DEBUG
    480 	if (si_debug & 2)
    481 		ncr5380_show_scsi_cmd(xs);
    482 #endif
    483 
    484 	sense = si_generic( xs->sc_link->scsibus, xs->sc_link->target,
    485 			  xs->sc_link->lun, xs->cmd, xs->cmdlen,
    486 			  xs->data, xs->datalen );
    487 
    488 	switch (sense) {
    489 	case 0:	/* success */
    490 		xs->resid = 0;
    491 		xs->error = XS_NOERROR;
    492 		break;
    493 
    494 	case 0x02:	/* Check condition */
    495 #ifdef	DEBUG
    496 		if (si_debug)
    497 			printf("check cond. target %d.\n",
    498 				   xs->sc_link->target);
    499 #endif
    500 		delay(10);	/* Phil's fix for slow devices. */
    501 		si_group0(xs->sc_link->scsibus,
    502 				  xs->sc_link->target,
    503 				  xs->sc_link->lun,
    504 				  0x3, 0x0,
    505 				  sizeof(struct scsi_sense_data),
    506 				  0, (caddr_t) &(xs->sense),
    507 				  sizeof(struct scsi_sense_data));
    508 		xs->error = XS_SENSE;
    509 		break;
    510 	case 0x08:	/* Busy - common code will delay, retry. */
    511 		xs->error = XS_BUSY;
    512 		break;
    513 	default:	/* Dead - tell common code to give up. */
    514 		xs->error = XS_DRIVER_STUFFUP;
    515 		break;
    516 
    517 	}
    518 	return (COMPLETE);
    519 }
    520 
    521 static int
    522 si_select_target(register volatile sci_regmap_t *regs,
    523 	      u_char myid, u_char tid, int with_atn)
    524 {
    525 	register u_char	bid, icmd;
    526 	int		ret = SCSI_RET_RETRY;
    527 	int 	arb_retries, arb_wait;
    528 
    529 	/* for our purposes.. */
    530 	myid = 1 << myid;
    531 	tid = 1 << tid;
    532 
    533 	regs->sci_sel_enb = 0; /* we don't want any interrupts. */
    534 	regs->sci_tcmd = 0;	/* get into a harmless state */
    535 
    536 	arb_retries = ARBITRATION_RETRIES;
    537 
    538 retry_arbitration:
    539 	regs->sci_mode = 0;	/* get into a harmless state */
    540 wait_for_bus_free:
    541 	if (--arb_retries <= 0) {
    542 #ifdef	DEBUG
    543 		if (si_debug) {
    544 			printf("si_select: arb_retries expended; resetting...\n");
    545 		}
    546 #endif
    547 		ret = SCSI_RET_NEED_RESET;
    548 		goto nosel;
    549 	}
    550 
    551 	icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
    552 
    553 	if (regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) {
    554 		/* Something is sitting on the SCSI bus... */
    555 #ifdef	DEBUG
    556 		/* Only complain once (the last time through). */
    557 		if (si_debug && (arb_retries <= 1)) {
    558 			printf("si_select_target: still BSY+SEL\n");
    559 		}
    560 #endif
    561 		/* Give it a little time, then try again. */
    562 		delay(10);
    563 		goto wait_for_bus_free;
    564 	}
    565 
    566 	regs->sci_odata = myid;
    567 	regs->sci_mode = SCI_MODE_ARB;
    568 /*	regs->sci_mode |= SCI_MODE_ARB;	XXX? */
    569 
    570 	/* AIP might not set if BSY went true after we checked */
    571 	/* Wait up to about 100 usec. for it to appear. */
    572 	arb_wait = 50;	/* X2 */
    573 	do {
    574 		if (regs->sci_icmd & SCI_ICMD_AIP)
    575 			goto got_aip;
    576 		delay2us();
    577 	} while (--arb_wait > 0);
    578 	/* XXX - Could have missed it? */
    579 #ifdef	DEBUG
    580 	if (si_debug)
    581 		printf("si_select_target: API did not appear\n");
    582 #endif
    583 	goto retry_arbitration;
    584 
    585 	got_aip:
    586 #ifdef	DEBUG
    587 	if (si_debug & 4) {
    588 		printf("si_select_target: API after %d tries (last wait %d)\n",
    589 			   ARBITRATION_RETRIES - arb_retries,
    590 			   (50 - arb_wait));
    591 	}
    592 #endif
    593 
    594 	delay(3);	/* 2.2 uSec. arbitration delay */
    595 
    596 	if (regs->sci_icmd & SCI_ICMD_LST) {
    597 #ifdef	DEBUG
    598 		if (si_debug)
    599 			printf ("lost 1\n");
    600 #endif
    601 		goto retry_arbitration;	/* XXX */
    602 	}
    603 
    604 	regs->sci_mode &= ~SCI_MODE_PAR_CHK;
    605 	bid = regs->sci_data;
    606 
    607 	if ((bid & ~myid) > myid) {
    608 #ifdef	DEBUG
    609 		if (si_debug)
    610 			printf ("lost 2\n");
    611 #endif
    612 		/* Trying again will not help. */
    613 		goto lost;
    614 	}
    615 	if (regs->sci_icmd & SCI_ICMD_LST) {
    616 #ifdef	DEBUG
    617 		if (si_debug)
    618 			printf ("lost 3\n");
    619 #endif
    620 		goto lost;
    621 	}
    622 
    623 	/* Won arbitration, enter selection phase now */
    624 	icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
    625 	icmd |= (with_atn ? (SCI_ICMD_SEL|SCI_ICMD_ATN) : SCI_ICMD_SEL);
    626 	regs->sci_icmd = icmd;
    627 
    628 	if (regs->sci_icmd & SCI_ICMD_LST) {
    629 #ifdef	DEBUG
    630 		if (si_debug)
    631 			printf ("nosel\n");
    632 #endif
    633 		goto nosel;
    634 	}
    635 
    636 	/* XXX a target that violates specs might still drive the bus XXX */
    637 	/* XXX should put our id out, and after the delay check nothi XXX */
    638 	/* XXX ng else is out there.				      XXX */
    639 
    640 	delay2us();
    641 
    642 	regs->sci_sel_enb = 0;
    643 
    644 	regs->sci_odata = myid | tid;
    645 
    646 	icmd |= SCI_ICMD_BSY|SCI_ICMD_DATA;
    647 	regs->sci_icmd = icmd;
    648 
    649 /*	regs->sci_mode &= ~SCI_MODE_ARB;	 2 deskew delays, too */
    650 	regs->sci_mode = 0;			/* 2 deskew delays, too */
    651 
    652 	icmd &= ~SCI_ICMD_BSY;
    653 	regs->sci_icmd = icmd;
    654 
    655 	/* bus settle delay, 400ns */
    656 	delay2us(); /* too much (was 2) ? */
    657 
    658 	regs->sci_mode |= SCI_MODE_PAR_CHK;
    659 
    660 	{
    661 		register int timeo  = 2500;/* 250 msecs in 100 usecs chunks */
    662 		while ((regs->sci_bus_csr & SCI_BUS_BSY) == 0) {
    663 			if (--timeo > 0) {
    664 				delay(100);
    665 			} else {
    666 				/* This is the "normal" no-such-device select error. */
    667 #ifdef	DEBUG
    668 				if (si_debug)
    669 					printf("si_select: not BSY (nothing there)\n");
    670 #endif
    671 				goto nodev;
    672 			}
    673 		}
    674 	}
    675 
    676 	icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_SEL);
    677 	regs->sci_icmd = icmd;
    678 /*	regs->sci_sel_enb = myid;*/	/* looks like we should NOT have it */
    679 	/* XXX - SCI_MODE_PAR_CHK ? */
    680 	return SCSI_RET_SUCCESS;
    681 
    682 nodev:
    683 	ret = SCSI_RET_DEVICE_DOWN;
    684 	regs->sci_sel_enb = myid;
    685 nosel:
    686 	regs->sci_icmd = 0;
    687 	regs->sci_mode = 0;
    688 	return ret;
    689 
    690 lost:
    691 	regs->sci_icmd = 0;
    692 	regs->sci_mode = 0;
    693 #ifdef	DEBUG
    694 	if (si_debug) {
    695 		printf("si_select: lost arbitration\n");
    696 	}
    697 #endif
    698 	return ret;
    699 }
    700 
    701 sci_data_out(regs, phase, count, data)
    702 	register volatile sci_regmap_t	*regs;
    703 	unsigned char		*data;
    704 {
    705 	register unsigned char	icmd;
    706 	register int		cnt=0;
    707 
    708 	/* ..checks.. */
    709 
    710 	icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
    711 loop:
    712 	/* SCSI bus phase not valid until REQ is true. */
    713 	WAIT_FOR_REQ(regs);
    714 	if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase)
    715 		return cnt;
    716 
    717 	icmd |= SCI_ICMD_DATA;
    718 	regs->sci_icmd = icmd;
    719 	regs->sci_odata = *data++;
    720 	icmd |= SCI_ICMD_ACK;
    721 	regs->sci_icmd = icmd;
    722 
    723 	icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_ACK);
    724 	WAIT_FOR_NOT_REQ(regs);
    725 	regs->sci_icmd = icmd;
    726 	++cnt;
    727 	if (--count > 0)
    728 		goto loop;
    729 scsi_timeout_error:
    730 	return cnt;
    731 }
    732 
    733 sci_data_in(regs, phase, count, data)
    734 	register volatile sci_regmap_t	*regs;
    735 	unsigned char		*data;
    736 {
    737 	register unsigned char	icmd;
    738 	register int		cnt=0;
    739 
    740 	/* ..checks.. */
    741 
    742 	icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
    743 
    744 loop:
    745 	/* SCSI bus phase not valid until REQ is true. */
    746 	WAIT_FOR_REQ(regs);
    747 	if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase)
    748 		return cnt;
    749 
    750 	*data++ = regs->sci_data;
    751 	icmd |= SCI_ICMD_ACK;
    752 	regs->sci_icmd = icmd;
    753 
    754 	icmd &= ~SCI_ICMD_ACK;
    755 	WAIT_FOR_NOT_REQ(regs);
    756 	regs->sci_icmd = icmd;
    757 	++cnt;
    758 	if (--count > 0)
    759 		goto loop;
    760 
    761 scsi_timeout_error:
    762 	return cnt;
    763 }
    764 
    765 /* Return -1 (error) or number of bytes sent (>=0). */
    766 static int
    767 si_command_transfer(register volatile sci_regmap_t *regs,
    768 		 int maxlen, u_char *data, u_char *status, u_char *msg)
    769 {
    770 	int	xfer, phase;
    771 
    772 	xfer = 0;
    773 	regs->sci_icmd = 0;
    774 
    775 	while (1) {
    776 
    777 		WAIT_FOR_REQ(regs);
    778 
    779 		phase = SCI_CUR_PHASE(regs->sci_bus_csr);
    780 
    781 		switch (phase) {
    782 			case SCSI_PHASE_CMD:
    783 				SCI_ACK(regs,SCSI_PHASE_CMD);
    784 				xfer += sci_data_out(regs, SCSI_PHASE_CMD,
    785 						   	maxlen, data);
    786 				goto out;
    787 
    788 			case SCSI_PHASE_DATA_IN:
    789 				printf("command_transfer: Data in phase?\n");
    790 				goto err;
    791 
    792 			case SCSI_PHASE_DATA_OUT:
    793 				printf("command_transfer: Data out phase?\n");
    794 				goto err;
    795 
    796 			case SCSI_PHASE_STATUS:
    797 				SCI_ACK(regs,SCSI_PHASE_STATUS);
    798 				printf("command_transfer: status in...\n");
    799 				sci_data_in(regs, SCSI_PHASE_STATUS,
    800 					  	1, status);
    801 				printf("command_transfer: status=0x%x\n", *status);
    802 				goto err;
    803 
    804 			case SCSI_PHASE_MESSAGE_IN:
    805 				SCI_ACK(regs,SCSI_PHASE_MESSAGE_IN);
    806 				printf("command_transfer: msg in?\n");
    807 				sci_data_in(regs, SCSI_PHASE_MESSAGE_IN,
    808 					  	1, msg);
    809 				break;
    810 
    811 			case SCSI_PHASE_MESSAGE_OUT:
    812 				SCI_ACK(regs,SCSI_PHASE_MESSAGE_OUT);
    813 				sci_data_out(regs, SCSI_PHASE_MESSAGE_OUT,
    814 					  	1, msg);
    815 				break;
    816 
    817 			default:
    818 				printf("command_transfer: Unexpected phase 0x%x\n", phase);
    819 				goto err;
    820 		}
    821 	}
    822 scsi_timeout_error:
    823  err:
    824 	xfer = -1;
    825  out:
    826 	return xfer;
    827 }
    828 
    829 static int
    830 si_data_transfer(register volatile sci_regmap_t *regs,
    831 	      int maxlen, u_char *data, u_char *status, u_char *msg)
    832 {
    833 	int	retlen = 0, xfer, phase;
    834 
    835 	regs->sci_icmd = 0;
    836 
    837 	*status = 0;
    838 
    839 	while (1) {
    840 
    841 		WAIT_FOR_REQ(regs);
    842 
    843 		phase = SCI_CUR_PHASE(regs->sci_bus_csr);
    844 
    845 		switch (phase) {
    846 			case SCSI_PHASE_CMD:
    847 				printf("Command phase in data_transfer().\n");
    848 				return retlen;
    849 			case SCSI_PHASE_DATA_IN:
    850 				SCI_ACK(regs,SCSI_PHASE_DATA_IN);
    851 #if PSEUDO_DMA
    852 				xfer = sci_pdma_in(regs, SCSI_PHASE_DATA_IN,
    853 						  	maxlen, data);
    854 #else
    855 				xfer = sci_data_in(regs, SCSI_PHASE_DATA_IN,
    856 						  	maxlen, data);
    857 #endif
    858 				retlen += xfer;
    859 				maxlen -= xfer;
    860 				break;
    861 			case SCSI_PHASE_DATA_OUT:
    862 				SCI_ACK(regs,SCSI_PHASE_DATA_OUT);
    863 #if PSEUDO_DMA
    864 				xfer = sci_pdma_out(regs, SCSI_PHASE_DATA_OUT,
    865 						   	maxlen, data);
    866 #else
    867 				xfer = sci_data_out(regs, SCSI_PHASE_DATA_OUT,
    868 						   	maxlen, data);
    869 #endif
    870 				retlen += xfer;
    871 				maxlen -= xfer;
    872 				break;
    873 			case SCSI_PHASE_STATUS:
    874 				SCI_ACK(regs,SCSI_PHASE_STATUS);
    875 				sci_data_in(regs, SCSI_PHASE_STATUS,
    876 					  	1, status);
    877 				break;
    878 			case SCSI_PHASE_MESSAGE_IN:
    879 				SCI_ACK(regs,SCSI_PHASE_MESSAGE_IN);
    880 				sci_data_in(regs, SCSI_PHASE_MESSAGE_IN,
    881 					  	1, msg);
    882 				if (*msg == 0) {
    883 					return retlen;
    884 				} else {
    885 					printf( "message 0x%x in "
    886 						"data_transfer.\n", *msg);
    887 				}
    888 				break;
    889 			case SCSI_PHASE_MESSAGE_OUT:
    890 				SCI_ACK(regs,SCSI_PHASE_MESSAGE_OUT);
    891 				sci_data_out(regs, SCSI_PHASE_MESSAGE_OUT,
    892 					  	1, msg);
    893 				break;
    894 			default:
    895 				printf( "Unexpected phase 0x%x in "
    896 					"data_transfer().\n", phase);
    897 scsi_timeout_error:
    898 				return retlen;
    899 				break;
    900 		}
    901 	}
    902 }
    903 
    904 static int
    905 si_dorequest(struct ncr5380_softc *sc,
    906 	int target, int lun, u_char *cmd, int cmdlen,
    907 	char *databuf, int datalen, int *sent)
    908 	/* Returns 0 on success, -1 on internal error, or the status byte */
    909 {
    910 	register volatile sci_regmap_t *regs = sc->sc_regs;
    911 	int	cmd_bytes_sent, r;
    912 	u_char	stat, msg, c;
    913 
    914 #ifdef	DEBUG
    915 	if (si_debug) {
    916 		printf("si_dorequest: target=%d, lun=%d\n", target, lun);
    917 	}
    918 #endif
    919 
    920 	*sent = 0;
    921 
    922 	if ( ( r = si_select_target(regs, 7, target, 1) ) != SCSI_RET_SUCCESS) {
    923 #ifdef	DEBUG
    924 		if (si_debug) {
    925 			printf("si_dorequest: select returned %d\n", r);
    926 		}
    927 #endif
    928 
    929 		SCI_CLR_INTR(regs);
    930 		switch (r) {
    931 
    932 		case SCSI_RET_NEED_RESET:
    933 			printf("si_dorequest: target=%d, lun=%d, resetting...\n",
    934 				   target, lun, r);
    935 			ncr5380_reset_adapter(sc);
    936 			ncr5380_reset_scsibus(sc);
    937 			/* fall through */
    938 		case SCSI_RET_RETRY:
    939 			return 0x08;	/* Busy - tell common code to retry. */
    940 
    941 		default:
    942 			printf("si_dorequest: target=%d, lun=%d, error=%d.\n",
    943 				target, lun, r);
    944 			/* fall through */
    945 		case SCSI_RET_DEVICE_DOWN:
    946 			return -1;	/* Dead - tell common code to give up. */
    947 		}
    948 	}
    949 
    950 	c = 0x80 | lun;
    951 
    952 	if ((cmd_bytes_sent = si_command_transfer(regs, cmdlen,
    953 				(u_char *) cmd, &stat, &c)) != cmdlen)
    954 	{
    955 		SCI_CLR_INTR(regs);
    956 		if (cmd_bytes_sent >= 0) {
    957 			printf("Data underrun sending CCB (%d bytes of %d, sent).\n",
    958 				   cmd_bytes_sent, cmdlen);
    959 		}
    960 		return -1;
    961 	}
    962 
    963 	*sent = si_data_transfer(regs, datalen, (u_char *)databuf,
    964 				  &stat, &msg);
    965 #ifdef	DEBUG
    966 	if (si_debug) {
    967 		printf("si_dorequest: data transfered = %d\n", *sent);
    968 	}
    969 #endif
    970 
    971 	return stat;
    972 }
    973 
    974 static int
    975 si_generic(int adapter, int id, int lun, struct scsi_generic *cmd,
    976   	 int cmdlen, void *databuf, int datalen)
    977 {
    978 	register struct ncr5380_softc *sc = sicd.cd_devs[adapter];
    979 	int i, j, sent;
    980 
    981 	if (cmd->opcode == TEST_UNIT_READY)	/* XXX */
    982 		cmd->bytes[0] = ((u_char) lun << 5);
    983 
    984 	i = si_dorequest(sc, id, lun, (u_char *) cmd, cmdlen,
    985 					 databuf, datalen, &sent);
    986 
    987 	return i;
    988 }
    989 
    990 static int
    991 si_group0(int adapter, int id, int lun, int opcode, int addr, int len,
    992 		int flags, caddr_t databuf, int datalen)
    993 {
    994 	register struct ncr5380_softc *sc = sicd.cd_devs[adapter];
    995 	unsigned char cmd[6];
    996 	int i, j, sent;
    997 
    998 	cmd[0] = opcode;		/* Operation code           		*/
    999 	cmd[1] = (lun << 5) | ((addr >> 16) & 0x1F);	/* Lun & MSB of addr	*/
   1000 	cmd[2] = (addr >> 8) & 0xFF;	/* addr					*/
   1001 	cmd[3] = addr & 0xFF;		/* LSB of addr				*/
   1002 	cmd[4] = len;			/* Allocation length			*/
   1003 	cmd[5] = flags;		/* Link/Flag				*/
   1004 
   1005 	i = si_dorequest(sc, id, lun, cmd, 6, databuf, datalen, &sent);
   1006 
   1007 	return i;
   1008 }
   1009