Home | History | Annotate | Line # | Download | only in dev
si.c revision 1.18
      1 /*	$NetBSD: si.c,v 1.18 1995/07/24 07:39:44 cgd 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 u_int		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 u_int
    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 	return (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 	if (--arb_retries <= 0) {
    541 #ifdef	DEBUG
    542 		if (si_debug) {
    543 			printf("si_select: arb_retries expended; resetting...\n");
    544 		}
    545 #endif
    546 		ret = SCSI_RET_NEED_RESET;
    547 		goto nosel;
    548 	}
    549 
    550 	icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
    551 
    552 	if ((regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) &&
    553 	    (regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) &&
    554 	    (regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)))
    555 	{
    556 		/* Something is sitting on the SCSI bus... */
    557 #ifdef	DEBUG
    558 		if (si_debug) {
    559 			printf("si_select_target: still BSY+SEL; resetting...\n");
    560 		}
    561 #endif
    562 		/* Send bus device reset. */
    563 		ret = SCSI_RET_NEED_RESET;
    564 		goto nosel;
    565 	}
    566 
    567 	regs->sci_odata = myid;
    568 	regs->sci_mode = SCI_MODE_ARB;
    569 /*	regs->sci_mode |= SCI_MODE_ARB;	XXX? */
    570 
    571 	/* AIP might not set if BSY went true after we checked */
    572 	/* Wait up to about 100 usec. for it to appear. */
    573 	arb_wait = 50;	/* X2 */
    574 	do {
    575 		if (regs->sci_icmd & SCI_ICMD_AIP)
    576 			goto got_aip;
    577 		delay2us();
    578 	} while (--arb_wait > 0);
    579 	/* XXX - Could have missed it? */
    580 #ifdef	DEBUG
    581 	if (si_debug)
    582 		printf("si_select_target: API did not appear\n");
    583 #endif
    584 	goto retry_arbitration;
    585 
    586 	got_aip:
    587 #ifdef	DEBUG
    588 	if (si_debug & 4) {
    589 		printf("si_select_target: API after %d tries (last wait %d)\n",
    590 			   ARBITRATION_RETRIES - arb_retries,
    591 			   (50 - arb_wait));
    592 	}
    593 #endif
    594 
    595 	delay(3);	/* 2.2 uSec. arbitration delay */
    596 
    597 	if (regs->sci_icmd & SCI_ICMD_LST) {
    598 #ifdef	DEBUG
    599 		if (si_debug)
    600 			printf ("lost 1\n");
    601 #endif
    602 		goto retry_arbitration;	/* XXX */
    603 	}
    604 
    605 	regs->sci_mode &= ~SCI_MODE_PAR_CHK;
    606 	bid = regs->sci_data;
    607 
    608 	if ((bid & ~myid) > myid) {
    609 #ifdef	DEBUG
    610 		if (si_debug)
    611 			printf ("lost 2\n");
    612 #endif
    613 		/* Trying again will not help. */
    614 		goto lost;
    615 	}
    616 	if (regs->sci_icmd & SCI_ICMD_LST) {
    617 #ifdef	DEBUG
    618 		if (si_debug)
    619 			printf ("lost 3\n");
    620 #endif
    621 		goto lost;
    622 	}
    623 
    624 	/* Won arbitration, enter selection phase now */
    625 	icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
    626 	icmd |= (with_atn ? (SCI_ICMD_SEL|SCI_ICMD_ATN) : SCI_ICMD_SEL);
    627 	regs->sci_icmd = icmd;
    628 
    629 	if (regs->sci_icmd & SCI_ICMD_LST) {
    630 #ifdef	DEBUG
    631 		if (si_debug)
    632 			printf ("nosel\n");
    633 #endif
    634 		goto nosel;
    635 	}
    636 
    637 	/* XXX a target that violates specs might still drive the bus XXX */
    638 	/* XXX should put our id out, and after the delay check nothi XXX */
    639 	/* XXX ng else is out there.				      XXX */
    640 
    641 	delay2us();
    642 
    643 	regs->sci_sel_enb = 0;
    644 
    645 	regs->sci_odata = myid | tid;
    646 
    647 	icmd |= SCI_ICMD_BSY|SCI_ICMD_DATA;
    648 	regs->sci_icmd = icmd;
    649 
    650 /*	regs->sci_mode &= ~SCI_MODE_ARB;	 2 deskew delays, too */
    651 	regs->sci_mode = 0;			/* 2 deskew delays, too */
    652 
    653 	icmd &= ~SCI_ICMD_BSY;
    654 	regs->sci_icmd = icmd;
    655 
    656 	/* bus settle delay, 400ns */
    657 	delay2us(); /* too much (was 2) ? */
    658 
    659 	regs->sci_mode |= SCI_MODE_PAR_CHK;
    660 
    661 	{
    662 		register int timeo  = 2500;/* 250 msecs in 100 usecs chunks */
    663 		while ((regs->sci_bus_csr & SCI_BUS_BSY) == 0) {
    664 			if (--timeo > 0) {
    665 				delay(100);
    666 			} else {
    667 				/* This is the "normal" no-such-device select error. */
    668 #ifdef	DEBUG
    669 				if (si_debug)
    670 					printf("si_select: not BSY (nothing there)\n");
    671 #endif
    672 				goto nodev;
    673 			}
    674 		}
    675 	}
    676 
    677 	icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_SEL);
    678 	regs->sci_icmd = icmd;
    679 /*	regs->sci_sel_enb = myid;*/	/* looks like we should NOT have it */
    680 	/* XXX - SCI_MODE_PAR_CHK ? */
    681 	return SCSI_RET_SUCCESS;
    682 
    683 nodev:
    684 	ret = SCSI_RET_DEVICE_DOWN;
    685 	regs->sci_sel_enb = myid;
    686 nosel:
    687 	regs->sci_icmd = 0;
    688 	regs->sci_mode = 0;
    689 	return ret;
    690 
    691 lost:
    692 	regs->sci_icmd = 0;
    693 	regs->sci_mode = 0;
    694 #ifdef	DEBUG
    695 	if (si_debug) {
    696 		printf("si_select: lost arbitration\n");
    697 	}
    698 #endif
    699 	return ret;
    700 }
    701 
    702 sci_data_out(regs, phase, count, data)
    703 	register volatile sci_regmap_t	*regs;
    704 	unsigned char		*data;
    705 {
    706 	register unsigned char	icmd;
    707 	register int		cnt=0;
    708 
    709 	/* ..checks.. */
    710 
    711 	icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
    712 loop:
    713 	if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase)
    714 		return cnt;
    715 
    716 	WAIT_FOR_REQ(regs);
    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 	if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase)
    746 		return cnt;
    747 
    748 	WAIT_FOR_REQ(regs);
    749 	*data++ = regs->sci_data;
    750 	icmd |= SCI_ICMD_ACK;
    751 	regs->sci_icmd = icmd;
    752 
    753 	icmd &= ~SCI_ICMD_ACK;
    754 	WAIT_FOR_NOT_REQ(regs);
    755 	regs->sci_icmd = icmd;
    756 	++cnt;
    757 	if (--count > 0)
    758 		goto loop;
    759 
    760 scsi_timeout_error:
    761 	return cnt;
    762 }
    763 
    764 /* Return -1 (error) or number of bytes sent (>=0). */
    765 static int
    766 si_command_transfer(register volatile sci_regmap_t *regs,
    767 		 int maxlen, u_char *data, u_char *status, u_char *msg)
    768 {
    769 	int	xfer, phase;
    770 
    771 	xfer = 0;
    772 	regs->sci_icmd = 0;
    773 
    774 	while (1) {
    775 
    776 		WAIT_FOR_REQ(regs);
    777 
    778 		phase = SCI_CUR_PHASE(regs->sci_bus_csr);
    779 
    780 		switch (phase) {
    781 			case SCSI_PHASE_CMD:
    782 				SCI_ACK(regs,SCSI_PHASE_CMD);
    783 				xfer += sci_data_out(regs, SCSI_PHASE_CMD,
    784 						   	maxlen, data);
    785 				goto out;
    786 
    787 			case SCSI_PHASE_DATA_IN:
    788 				printf("command_transfer: Data in phase?\n");
    789 				goto err;
    790 
    791 			case SCSI_PHASE_DATA_OUT:
    792 				printf("command_transfer: Data out phase?\n");
    793 				goto err;
    794 
    795 			case SCSI_PHASE_STATUS:
    796 				SCI_ACK(regs,SCSI_PHASE_STATUS);
    797 				printf("command_transfer: status in...\n");
    798 				sci_data_in(regs, SCSI_PHASE_STATUS,
    799 					  	1, status);
    800 				printf("command_transfer: status=0x%x\n", *status);
    801 				goto err;
    802 
    803 			case SCSI_PHASE_MESSAGE_IN:
    804 				SCI_ACK(regs,SCSI_PHASE_MESSAGE_IN);
    805 				printf("command_transfer: msg in?\n");
    806 				sci_data_in(regs, SCSI_PHASE_MESSAGE_IN,
    807 					  	1, msg);
    808 				break;
    809 
    810 			case SCSI_PHASE_MESSAGE_OUT:
    811 				SCI_ACK(regs,SCSI_PHASE_MESSAGE_OUT);
    812 				sci_data_out(regs, SCSI_PHASE_MESSAGE_OUT,
    813 					  	1, msg);
    814 				break;
    815 
    816 			default:
    817 				printf("command_transfer: Unexpected phase 0x%x\n", phase);
    818 				goto err;
    819 		}
    820 	}
    821 scsi_timeout_error:
    822  err:
    823 	xfer = -1;
    824  out:
    825 	return xfer;
    826 }
    827 
    828 static int
    829 si_data_transfer(register volatile sci_regmap_t *regs,
    830 	      int maxlen, u_char *data, u_char *status, u_char *msg)
    831 {
    832 	int	retlen = 0, xfer, phase;
    833 
    834 	regs->sci_icmd = 0;
    835 
    836 	*status = 0;
    837 
    838 	while (1) {
    839 
    840 		WAIT_FOR_REQ(regs);
    841 
    842 		phase = SCI_CUR_PHASE(regs->sci_bus_csr);
    843 
    844 		switch (phase) {
    845 			case SCSI_PHASE_CMD:
    846 				printf("Command phase in data_transfer().\n");
    847 				return retlen;
    848 			case SCSI_PHASE_DATA_IN:
    849 				SCI_ACK(regs,SCSI_PHASE_DATA_IN);
    850 #if PSEUDO_DMA
    851 				xfer = sci_pdma_in(regs, SCSI_PHASE_DATA_IN,
    852 						  	maxlen, data);
    853 #else
    854 				xfer = sci_data_in(regs, SCSI_PHASE_DATA_IN,
    855 						  	maxlen, data);
    856 #endif
    857 				retlen += xfer;
    858 				maxlen -= xfer;
    859 				break;
    860 			case SCSI_PHASE_DATA_OUT:
    861 				SCI_ACK(regs,SCSI_PHASE_DATA_OUT);
    862 #if PSEUDO_DMA
    863 				xfer = sci_pdma_out(regs, SCSI_PHASE_DATA_OUT,
    864 						   	maxlen, data);
    865 #else
    866 				xfer = sci_data_out(regs, SCSI_PHASE_DATA_OUT,
    867 						   	maxlen, data);
    868 #endif
    869 				retlen += xfer;
    870 				maxlen -= xfer;
    871 				break;
    872 			case SCSI_PHASE_STATUS:
    873 				SCI_ACK(regs,SCSI_PHASE_STATUS);
    874 				sci_data_in(regs, SCSI_PHASE_STATUS,
    875 					  	1, status);
    876 				break;
    877 			case SCSI_PHASE_MESSAGE_IN:
    878 				SCI_ACK(regs,SCSI_PHASE_MESSAGE_IN);
    879 				sci_data_in(regs, SCSI_PHASE_MESSAGE_IN,
    880 					  	1, msg);
    881 				if (*msg == 0) {
    882 					return retlen;
    883 				} else {
    884 					printf( "message 0x%x in "
    885 						"data_transfer.\n", *msg);
    886 				}
    887 				break;
    888 			case SCSI_PHASE_MESSAGE_OUT:
    889 				SCI_ACK(regs,SCSI_PHASE_MESSAGE_OUT);
    890 				sci_data_out(regs, SCSI_PHASE_MESSAGE_OUT,
    891 					  	1, msg);
    892 				break;
    893 			default:
    894 				printf( "Unexpected phase 0x%x in "
    895 					"data_transfer().\n", phase);
    896 scsi_timeout_error:
    897 				return retlen;
    898 				break;
    899 		}
    900 	}
    901 }
    902 
    903 static int
    904 si_dorequest(struct ncr5380_softc *sc,
    905 	int target, int lun, u_char *cmd, int cmdlen,
    906 	char *databuf, int datalen, int *sent)
    907 	/* Returns 0 on success, -1 on internal error, or the status byte */
    908 {
    909 	register volatile sci_regmap_t *regs = sc->sc_regs;
    910 	int	cmd_bytes_sent, r;
    911 	u_char	stat, msg, c;
    912 
    913 #ifdef	DEBUG
    914 	if (si_debug) {
    915 		printf("si_dorequest: target=%d, lun=%d\n", target, lun);
    916 	}
    917 #endif
    918 
    919 	*sent = 0;
    920 
    921 	if ( ( r = si_select_target(regs, 7, target, 1) ) != SCSI_RET_SUCCESS) {
    922 #ifdef	DEBUG
    923 		if (si_debug) {
    924 			printf("si_dorequest: select returned %d\n", r);
    925 		}
    926 #endif
    927 
    928 		SCI_CLR_INTR(regs);
    929 		switch (r) {
    930 
    931 		case SCSI_RET_NEED_RESET:
    932 			printf("si_dorequest: target=%d, lun=%d, resetting...\n",
    933 				   target, lun, r);
    934 			ncr5380_reset_adapter(sc);
    935 			ncr5380_reset_scsibus(sc);
    936 			/* fall through */
    937 		case SCSI_RET_RETRY:
    938 			return 0x08;	/* Busy - tell common code to retry. */
    939 
    940 		default:
    941 			printf("si_dorequest: target=%d, lun=%d, error=%d.\n",
    942 				target, lun, r);
    943 			/* fall through */
    944 		case SCSI_RET_DEVICE_DOWN:
    945 			return -1;	/* Dead - tell common code to give up. */
    946 		}
    947 	}
    948 
    949 	c = 0x80 | lun;
    950 
    951 	if ((cmd_bytes_sent = si_command_transfer(regs, cmdlen,
    952 				(u_char *) cmd, &stat, &c)) != cmdlen)
    953 	{
    954 		SCI_CLR_INTR(regs);
    955 		if (cmd_bytes_sent >= 0) {
    956 			printf("Data underrun sending CCB (%d bytes of %d, sent).\n",
    957 				   cmd_bytes_sent, cmdlen);
    958 		}
    959 		return -1;
    960 	}
    961 
    962 	*sent = si_data_transfer(regs, datalen, (u_char *)databuf,
    963 				  &stat, &msg);
    964 #ifdef	DEBUG
    965 	if (si_debug) {
    966 		printf("si_dorequest: data transfered = %d\n", *sent);
    967 	}
    968 #endif
    969 
    970 	return stat;
    971 }
    972 
    973 static int
    974 si_generic(int adapter, int id, int lun, struct scsi_generic *cmd,
    975   	 int cmdlen, void *databuf, int datalen)
    976 {
    977 	register struct ncr5380_softc *sc = sicd.cd_devs[adapter];
    978 	int i, j, sent;
    979 
    980 	if (cmd->opcode == TEST_UNIT_READY)	/* XXX */
    981 		cmd->bytes[0] = ((u_char) lun << 5);
    982 
    983 	i = si_dorequest(sc, id, lun, (u_char *) cmd, cmdlen,
    984 					 databuf, datalen, &sent);
    985 
    986 	return i;
    987 }
    988 
    989 static int
    990 si_group0(int adapter, int id, int lun, int opcode, int addr, int len,
    991 		int flags, caddr_t databuf, int datalen)
    992 {
    993 	register struct ncr5380_softc *sc = sicd.cd_devs[adapter];
    994 	unsigned char cmd[6];
    995 	int i, j, sent;
    996 
    997 	cmd[0] = opcode;		/* Operation code           		*/
    998 	cmd[1] = (lun << 5) | ((addr >> 16) & 0x1F);	/* Lun & MSB of addr	*/
    999 	cmd[2] = (addr >> 8) & 0xFF;	/* addr					*/
   1000 	cmd[3] = addr & 0xFF;		/* LSB of addr				*/
   1001 	cmd[4] = len;			/* Allocation length			*/
   1002 	cmd[5] = flags;		/* Link/Flag				*/
   1003 
   1004 	i = si_dorequest(sc, id, lun, cmd, 6, databuf, datalen, &sent);
   1005 
   1006 	return i;
   1007 }
   1008