Home | History | Annotate | Line # | Download | only in common
iris_scsi.c revision 1.2
      1 /*	$NetBSD: iris_scsi.c,v 1.2 2024/02/09 22:08:33 andvar Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2018 Naruaki Etomi
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 /*
     29  * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
     30  * WD33C93 SCSI bus driver for standalone programs.
     31  */
     32 
     33 #include <sys/cdefs.h>
     34 #include <lib/libsa/stand.h>
     35 
     36 #ifndef	INDIGO_R3K_MODE
     37 #include <dev/arcbios/arcbios.h>
     38 #endif
     39 
     40 #include "iris_machdep.h"
     41 #include "iris_scsivar.h"
     42 #include "iris_scsireg.h"
     43 #include "iris_scsicmd.h"
     44 #include <dev/scsipi/scsi_message.h>
     45 
     46 #define SBIC_WAIT(regs, until, timeo) wd33c93_wait(regs, until, timeo)
     47 
     48 /*
     49  * Timeouts
     50  */
     51 int	wd33c93_cmd_wait	= SBIC_CMD_WAIT;
     52 int	wd33c93_data_wait	= SBIC_DATA_WAIT;
     53 int	wd33c93_init_wait	= SBIC_INIT_WAIT;
     54 
     55 #define STATUS_UNKNOWN	0xff
     56 
     57 void	wd33c93_reset(struct wd33c93_softc *);
     58 int	wd33c93_wait(struct wd33c93_softc *, uint8_t, int);
     59 uint8_t	wd33c93_selectbus(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
     60 	    size_t *);
     61 void	wd33c93_setsync(struct wd33c93_softc *);
     62 int	wd33c93_nextstate(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
     63 	    size_t *, uint8_t, uint8_t);
     64 size_t	wd33c93_xfout(struct wd33c93_softc *, void *, size_t *);
     65 int	wd33c93_intr(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
     66 	    size_t *);
     67 size_t	wd33c93_xfin(struct wd33c93_softc *, void *, size_t *);
     68 void	wd33c93_xferdone(struct wd33c93_softc *);
     69 int	wd33c93_abort(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
     70 	    size_t *);
     71 int	wd33c93_poll(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
     72 	    size_t *);
     73 void	wd33c93_timeout(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
     74 	    size_t *);
     75 int	wd33c93_msgin_phase(struct wd33c93_softc *);
     76 void	wd33c93_scsistart(struct wd33c93_softc *);
     77 void	wd33c93_scsidone(struct wd33c93_softc *);
     78 void	wd33c93_error(struct wd33c93_softc *);
     79 
     80 /*
     81  * Initialize SPC & Data Structure
     82  */
     83 void
     84 wd33c93_init(void *aaddr, void *daddr)
     85 {
     86 	struct wd33c93_softc *sc;
     87 
     88 	sc = &wd33c93_softc[scsi_ctlr];
     89 
     90 	sc->sc_asr_regh = aaddr;
     91 	sc->sc_data_regh = daddr;
     92 	sc->sc_target = scsi_id;
     93 
     94 	sc->sc_flags = 0;
     95 	sc->sc_state = SBIC_IDLE;
     96 
     97 	wd33c93_reset(sc);
     98 }
     99 
    100 void
    101 wd33c93_reset(struct wd33c93_softc *sc)
    102 {
    103 	u_int my_id;
    104 	uint8_t csr;
    105 
    106 	SET_SBIC_cmd(sc, SBIC_CMD_ABORT);
    107 	WAIT_CIP(sc);
    108 
    109 	my_id = sc->sc_target & SBIC_ID_MASK;
    110 
    111 	/* Set Clock == 20.0 MHz */
    112 	my_id |= SBIC_ID_FS_8_10;
    113 	sc->sc_syncperiods = 2 * 2 * 1250 / SCSI_CLKFREQ;
    114 
    115 	SET_SBIC_myid(sc, my_id);
    116 
    117 	/* Reset the chip */
    118 	SET_SBIC_cmd(sc, SBIC_CMD_RESET);
    119 	DELAY(25);
    120 	SBIC_WAIT(sc, SBIC_ASR_INT, 0);
    121 
    122 	/* PIO  mode */
    123 	SBIC_TC_PUT(sc, 0);
    124 	SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
    125 
    126 	/* clears interrupt also */
    127 	GET_SBIC_csr(sc, csr);
    128 	__USE(csr);
    129 
    130 	SET_SBIC_rselid(sc, SBIC_RID_ER);
    131 	SET_SBIC_syn(sc, 0);
    132 
    133 	sc->sc_flags = 0;
    134 	sc->sc_state = SBIC_IDLE;
    135 }
    136 
    137 int
    138 wd33c93_wait(struct wd33c93_softc *sc, uint8_t until, int timeo)
    139 {
    140 	uint8_t val;
    141 
    142 	if (timeo == 0)
    143 		/* some large value.. */
    144 		timeo = 1000000;
    145 
    146 	GET_SBIC_asr(sc, val);
    147 
    148 	while ((val & until) == 0) {
    149 		if (timeo-- == 0) {
    150 			return val;
    151 			break;
    152 		}
    153 		DELAY(1);
    154 		GET_SBIC_asr(sc, val);
    155 	}
    156 	return val;
    157 }
    158 
    159 /* SCSI command entry point */
    160 int
    161 wd33c93_go(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen, uint8_t *buf,
    162     size_t *lenp)
    163 {
    164 	int	i;
    165 	uint8_t	csr, asr;
    166 
    167 	wd33c93_scsistart(sc);
    168 
    169 	sc->sc_status = STATUS_UNKNOWN;
    170 	sc->sc_flags = 0;
    171 	/* select the SCSI bus (it's an error if bus isn't free) */
    172 	if ((csr = wd33c93_selectbus(sc, cbuf, clen, buf, lenp)) == 0)
    173 		/* Not done: needs to be rescheduled */
    174 		return 1;
    175 
    176 	/*
    177 	 * Lets cycle a while then let the interrupt handler take over.
    178 	 */
    179 	GET_SBIC_asr(sc, asr);
    180 	do {
    181 		/* Handle the new phase */
    182 		i = wd33c93_nextstate(sc, cbuf, clen, buf, lenp, csr, asr);
    183 		WAIT_CIP(sc);		/* XXX */
    184 		if (sc->sc_state == SBIC_CONNECTED) {
    185 			GET_SBIC_asr(sc, asr);
    186 
    187 			if ((asr & SBIC_ASR_LCI) != 0)
    188 				DELAY(5000);
    189 
    190 			if ((asr & SBIC_ASR_INT) != 0)
    191 				GET_SBIC_csr(sc, csr);
    192 		}
    193 
    194 	} while (sc->sc_state == SBIC_CONNECTED &&
    195 	    (asr & (SBIC_ASR_INT|SBIC_ASR_LCI)) != 0);
    196 
    197 	if (i == SBIC_STATE_DONE) {
    198 		if (sc->sc_status == STATUS_UNKNOWN) {
    199 			printf("wd33c93_go: stat == UNKNOWN\n");
    200 			return 1;
    201 		}
    202 	}
    203 
    204 	if (wd33c93_poll(sc, cbuf, clen, buf, lenp)) {
    205 		wd33c93_timeout(sc, cbuf, clen, buf, lenp);
    206 		if (wd33c93_poll(sc, cbuf, clen, buf, lenp)) {
    207 			wd33c93_timeout(sc, cbuf, clen, buf, lenp);
    208 		}
    209 	}
    210 	return 0;
    211 }
    212 
    213 /*
    214  * select the bus, return when selected or error.
    215  *
    216  * Returns the current CSR following selection and optionally MSG out phase.
    217  * i.e. the returned CSR *should* indicate CMD phase...
    218  * If the return value is 0, some error happened.
    219  */
    220 uint8_t
    221 wd33c93_selectbus(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
    222     uint8_t *buf, size_t *lenp)
    223 {
    224 	uint8_t asr, csr, id, lun, target;
    225 	static int i = 0;
    226 
    227 	sc->sc_state = SBIC_SELECTING;
    228 
    229 	target = sc->sc_target;
    230 	lun = SCSI_LUN;
    231 
    232 	/*
    233 	 * issue select
    234 	 */
    235 	SBIC_TC_PUT(sc, 0);
    236 	SET_SBIC_selid(sc, target);
    237 	SET_SBIC_timeo(sc, SBIC_TIMEOUT(250, SCSI_CLKFREQ));
    238 
    239 	GET_SBIC_asr(sc, asr);
    240 
    241 	if ((asr & (SBIC_ASR_INT|SBIC_ASR_BSY)) != 0) {
    242 		return 0;
    243 	}
    244 
    245 	SET_SBIC_cmd(sc, SBIC_CMD_SEL_ATN);
    246 	WAIT_CIP(sc);
    247 
    248 	/*
    249 	 * wait for select (merged from separate function may need
    250 	 * cleanup)
    251 	 */
    252 	do {
    253 		asr = SBIC_WAIT(sc, SBIC_ASR_INT | SBIC_ASR_LCI, 0);
    254 
    255 		if ((asr & SBIC_ASR_LCI) != 0) {
    256 			return 0;
    257 		}
    258 
    259 		/* Clear interrupt */
    260 		GET_SBIC_csr(sc, csr);
    261 
    262 		/* Reselected from under our feet? */
    263 		if (csr == SBIC_CSR_RSLT_NI || csr == SBIC_CSR_RSLT_IFY) {
    264 			/*
    265 			 * We need to handle this now so we don't lock up later
    266 			 */
    267 			wd33c93_nextstate(sc, cbuf, clen, buf, lenp, csr, asr);
    268 			return 0;
    269 		}
    270 		/* Whoops! */
    271 		if (csr == SBIC_CSR_SLT || csr == SBIC_CSR_SLT_ATN) {
    272 			return 0;
    273 		}
    274 	} while (csr != (SBIC_CSR_MIS_2 | MESG_OUT_PHASE) &&
    275 	    csr != (SBIC_CSR_MIS_2 | CMD_PHASE) &&
    276 	    csr != SBIC_CSR_SEL_TIMEO);
    277 
    278 	/* Anyone at home? */
    279 	if (csr == SBIC_CSR_SEL_TIMEO) {
    280 		return 0;
    281 	}
    282 
    283 	/* Assume we're now selected */
    284 	GET_SBIC_selid(sc, id);
    285 
    286 	if (id != target) {
    287 		/* Something went wrong - wrong target was select */
    288 		printf("wd33c93_selectbus: wrong target selected WANTED %d GOT %d \n",
    289 		    target, id);
    290 		printf("Boot failed!  Halting...\n");
    291 		reboot();
    292 	}
    293 
    294 	sc->sc_flags |= SBICF_SELECTED;
    295 	sc->sc_state  = SBIC_CONNECTED;
    296 
    297 	/* setup correct sync mode for this target */
    298 	wd33c93_setsync(sc);
    299 	SET_SBIC_rselid(sc, SBIC_RID_ER);
    300 
    301 	/*
    302 	 * We only really need to do anything when the target goes to MSG out
    303 	 * If the device ignored ATN, it's probably old and brain-dead,
    304 	 * but we'll try to support it anyhow.
    305 	 * If it doesn't support message out, it definitely doesn't
    306 	 * support synchronous transfers, so no point in even asking...
    307 	 */
    308 
    309 	if (csr == (SBIC_CSR_MIS_2 | MESG_OUT_PHASE)) {
    310 		if (i < 6) {
    311 			SEND_BYTE(sc, MSG_IDENTIFY(lun, 0));
    312 			DELAY(200000);
    313 			i++;
    314 		} else {
    315 			/*
    316 		 	 * setup scsi message sync message request
    317 		 	 */
    318 			sc->sc_omsg[0] = MSG_IDENTIFY(lun, 0);
    319 			sc->sc_omsg[1] = MSG_EXTENDED;
    320 			sc->sc_omsg[2] = MSG_EXT_SDTR_LEN;
    321 			sc->sc_omsg[3] = MSG_EXT_SDTR;
    322 			sc->sc_omsg[4] = sc->sc_syncperiods;
    323 			sc->sc_omsg[5] = SBIC_SYN_93AB_MAX_OFFSET;
    324 
    325 			size_t foo = 6;
    326 			size_t *bar;
    327 			bar = &foo;
    328 
    329 			wd33c93_xfout(sc, sc->sc_omsg, bar);
    330 			sc->sc_flags  |= SBICF_SYNCNEGO;
    331 		}
    332 
    333 		SBIC_WAIT(sc, SBIC_ASR_INT , 0);
    334 		GET_SBIC_csr(sc, csr);
    335 	}
    336 	return csr;
    337 }
    338 
    339 /*
    340  * Setup sync mode for given target
    341  */
    342 void
    343 wd33c93_setsync(struct wd33c93_softc *sc)
    344 {
    345 	uint8_t syncreg;
    346 
    347 	syncreg = SBIC_SYN(0, 0, 0);
    348 
    349 	SET_SBIC_syn(sc, syncreg);
    350 }
    351 
    352 /*
    353  * wd33c93_nextstate()
    354  * return:
    355  *	SBIC_STATE_DONE		== done
    356  *	SBIC_STATE_RUNNING	== working
    357  *	SBIC_STATE_DISCONNECT	== disconnected
    358  *	SBIC_STATE_ERROR	== error
    359  */
    360 int
    361 wd33c93_nextstate(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
    362     uint8_t *buf, size_t *lenp, uint8_t csr, uint8_t asr)
    363 {
    364 	size_t *clenp;
    365 	size_t resid;
    366 
    367 	switch (csr) {
    368 	case SBIC_CSR_XFERRED | CMD_PHASE:
    369 	case SBIC_CSR_MIS     | CMD_PHASE:
    370 	case SBIC_CSR_MIS_1   | CMD_PHASE:
    371 	case SBIC_CSR_MIS_2   | CMD_PHASE:
    372 		clenp = &clen;
    373 
    374 		if (wd33c93_xfout(sc, cbuf, clenp))
    375 			goto abort;
    376 		break;
    377 
    378 	case SBIC_CSR_XFERRED | STATUS_PHASE:
    379 	case SBIC_CSR_MIS     | STATUS_PHASE:
    380 	case SBIC_CSR_MIS_1   | STATUS_PHASE:
    381 	case SBIC_CSR_MIS_2   | STATUS_PHASE:
    382 		SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
    383 
    384 		/*
    385 		 * this should be the normal i/o completion case.
    386 		 * get the status & cmd complete msg then let the
    387 		 * device driver look at what happened.
    388 		 */
    389 		wd33c93_xferdone(sc);
    390 		wd33c93_scsidone(sc);
    391 
    392 		return SBIC_STATE_DONE;
    393 
    394 	case SBIC_CSR_XFERRED | DATA_IN_PHASE:
    395 	case SBIC_CSR_MIS     | DATA_IN_PHASE:
    396 	case SBIC_CSR_MIS_1   | DATA_IN_PHASE:
    397 	case SBIC_CSR_MIS_2   | DATA_IN_PHASE:
    398 	case SBIC_CSR_XFERRED | DATA_OUT_PHASE:
    399 	case SBIC_CSR_MIS     | DATA_OUT_PHASE:
    400 	case SBIC_CSR_MIS_1   | DATA_OUT_PHASE:
    401 	case SBIC_CSR_MIS_2   | DATA_OUT_PHASE:
    402 		/*
    403 		 * Should we transfer using PIO or DMA ?
    404 		 */
    405 		/* Perform transfer using PIO */
    406 		if (SBIC_PHASE(csr) == DATA_IN_PHASE){
    407 			/* data in */
    408 			resid = wd33c93_xfin(sc, buf, lenp);
    409 			*lenp = resid;
    410 			wd33c93_intr(sc, cbuf, clen, buf, lenp);
    411 		} else {	/* data out */
    412 			resid = wd33c93_xfout(sc, buf, lenp);
    413 			*lenp = resid;
    414 		}
    415 		break;
    416 
    417 	case SBIC_CSR_XFERRED | MESG_IN_PHASE:
    418 	case SBIC_CSR_MIS     | MESG_IN_PHASE:
    419 	case SBIC_CSR_MIS_1   | MESG_IN_PHASE:
    420 	case SBIC_CSR_MIS_2   | MESG_IN_PHASE:
    421 		/* Handle a single message in... */
    422 		return wd33c93_msgin_phase(sc);
    423 
    424 	case SBIC_CSR_MSGIN_W_ACK:
    425 		/*
    426 		 * We should never see this since it's handled in
    427 		 * 'wd33c93_msgin_phase()' but just for the sake of paranoia...
    428 		 */
    429 		SET_SBIC_cmd(sc, SBIC_CMD_CLR_ACK);
    430 		break;
    431 
    432 	case SBIC_CSR_XFERRED | MESG_OUT_PHASE:
    433 	case SBIC_CSR_MIS     | MESG_OUT_PHASE:
    434 	case SBIC_CSR_MIS_1   | MESG_OUT_PHASE:
    435 	case SBIC_CSR_MIS_2   | MESG_OUT_PHASE:
    436 		/*
    437 		 * Message out phase.  ATN signal has been asserted
    438 		 */
    439 		return SBIC_STATE_RUNNING;
    440 
    441 	case SBIC_CSR_DISC:
    442 	case SBIC_CSR_DISC_1:
    443 		sc->sc_state = SBIC_IDLE;
    444 		sc->sc_flags = 0;
    445 
    446 		return SBIC_STATE_DISCONNECT;
    447 
    448 	case SBIC_CSR_RSLT_NI:
    449 	case SBIC_CSR_RSLT_IFY:
    450 	{
    451 		sc->sc_state = SBIC_RESELECTED;
    452 
    453 		if (csr == SBIC_CSR_RSLT_IFY)
    454 			SET_SBIC_cmd(sc, SBIC_CMD_CLR_ACK);
    455 		break;
    456 	}
    457 
    458 	default:
    459 	abort:
    460 		/* Something unexpected happend -- deal with it. */
    461 		printf("wd33c93_nextstate:abort\n");
    462 		printf("Boot failed!  Halting...\n");
    463 		reboot();
    464 	}
    465 	return SBIC_STATE_RUNNING;
    466 }
    467 
    468 /*
    469  * Information Transfer *to* a SCSI Target.
    470  *
    471  * Note: Don't expect there to be an interrupt immediately after all
    472  * the data is transferred out. The WD spec sheet says that the Transfer-
    473  * Info command for non-MSG_IN phases only completes when the target
    474  * next asserts 'REQ'. That is, when the SCSI bus changes to a new state.
    475  *
    476  * This can have a nasty effect on commands which take a relatively long
    477  * time to complete, for example a START/STOP unit command may remain in
    478  * CMD phase until the disk has spun up. Only then will the target change
    479  * to STATUS phase. This is really only a problem for immediate commands
    480  * since we don't allow disconnection for them (yet).
    481  */
    482 size_t
    483 wd33c93_xfout(struct wd33c93_softc *sc, void *bp, size_t *lenp)
    484 {
    485 
    486 	int wait = wd33c93_data_wait;
    487 	uint8_t asr, *buf = bp;
    488 	size_t len = *lenp;
    489 
    490 	/*
    491 	 * sigh.. WD-PROTO strikes again.. sending the command in one go
    492 	 * causes the chip to lock up if talking to certain (misbehaving?)
    493 	 * targets. Anyway, this procedure should work for all targets, but
    494 	 * it's slightly slower due to the overhead
    495 	 */
    496 
    497 	SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
    498 	SBIC_TC_PUT(sc, (unsigned int)len);
    499 
    500 	WAIT_CIP(sc);
    501 	SET_SBIC_cmd(sc, SBIC_CMD_XFER_INFO);
    502 
    503 	/*
    504 	 * Loop for each byte transferred
    505 	 */
    506 	do {
    507 		GET_SBIC_asr(sc, asr);
    508 
    509 		if ((asr & SBIC_ASR_DBR) != 0) {
    510 			if (len != 0) {
    511 				SET_SBIC_data(sc, *buf);
    512 				buf++;
    513 				len--;
    514 			} else {
    515 				SET_SBIC_data(sc, 0);
    516 			}
    517 			wait = wd33c93_data_wait;
    518 		}
    519 	} while (len != 0 && (asr & SBIC_ASR_INT) == 0 && wait-- > 0);
    520 
    521 	/*
    522 	 * Normally, an interrupt will be pending when this routing returns.
    523 	 */
    524 	return len;
    525 }
    526 
    527 int
    528 wd33c93_intr(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
    529     uint8_t *buf, size_t *lenp)
    530 {
    531 	uint8_t	asr, csr;
    532 
    533 	/*
    534 	 * pending interrupt?
    535 	 */
    536 	GET_SBIC_asr(sc, asr);
    537 	if ((asr & SBIC_ASR_INT) == 0)
    538 		return 0;
    539 
    540 	GET_SBIC_csr(sc, csr);
    541 
    542 	do {
    543 
    544 		(void)wd33c93_nextstate(sc, cbuf, clen, buf, lenp, csr, asr);
    545 		WAIT_CIP(sc);
    546 		if (sc->sc_state == SBIC_CONNECTED) {
    547 			GET_SBIC_asr(sc, asr);
    548 
    549 			if ((asr & SBIC_ASR_INT) != 0)
    550 				GET_SBIC_csr(sc, csr);
    551 		}
    552 	} while (sc->sc_state == SBIC_CONNECTED &&
    553 	    (asr & (SBIC_ASR_INT|SBIC_ASR_LCI)) != 0);
    554 
    555 	return 1;
    556 }
    557 
    558 /*
    559  * Information Transfer *from* a Scsi Target
    560  * returns # bytes left to read
    561  */
    562 size_t
    563 wd33c93_xfin(struct wd33c93_softc *sc, void *bp, size_t *lenp)
    564 {
    565 	size_t len = *lenp;
    566 
    567 	int 	wait = wd33c93_data_wait;
    568 	uint8_t	*buf = bp;
    569 	uint8_t	asr;
    570 
    571 	SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
    572 	SBIC_TC_PUT(sc, (unsigned int)len);
    573 
    574 	WAIT_CIP(sc);
    575 	SET_SBIC_cmd(sc, SBIC_CMD_XFER_INFO);
    576 
    577 	/*
    578 	 * Loop for each byte transferred
    579 	 */
    580 	do {
    581 		GET_SBIC_asr(sc, asr);
    582 
    583 		if ((asr & SBIC_ASR_DBR) != 0) {
    584 			if (len != 0) {
    585 				GET_SBIC_data(sc, *buf);
    586 				buf++;
    587 				len--;
    588 			} else {
    589 				uint8_t foo;
    590 				GET_SBIC_data(sc, foo);
    591 				__USE(foo);
    592 			}
    593 			wait = wd33c93_data_wait;
    594 		}
    595 
    596 	} while ((asr & SBIC_ASR_INT) == 0 && wait-- > 0);
    597 
    598 	SBIC_TC_PUT(sc, 0);
    599 
    600 	/*
    601 	 * this leaves with one csr to be read
    602 	 */
    603 	return len;
    604 }
    605 
    606 /*
    607  * Finish SCSI xfer command:  After the completion interrupt from
    608  * a read/write operation, sequence through the final phases in
    609  * programmed i/o.
    610  */
    611 void
    612 wd33c93_xferdone(struct wd33c93_softc *sc)
    613 {
    614 	uint8_t	phase, csr;
    615 
    616 	/*
    617 	 * have the wd33c93 complete on its own
    618 	 */
    619 	SBIC_TC_PUT(sc, 0);
    620 	SET_SBIC_cmd_phase(sc, 0x46);
    621 	SET_SBIC_cmd(sc, SBIC_CMD_SEL_ATN_XFER);
    622 
    623 	do {
    624 		SBIC_WAIT(sc, SBIC_ASR_INT, 0);
    625 		GET_SBIC_csr(sc, csr);
    626 	} while ((csr != SBIC_CSR_DISC) &&
    627 		 (csr != SBIC_CSR_DISC_1) &&
    628 		 (csr != SBIC_CSR_S_XFERRED));
    629 
    630 	sc->sc_flags &= ~SBICF_SELECTED;
    631 	sc->sc_state = SBIC_DISCONNECT;
    632 
    633 	GET_SBIC_cmd_phase(sc, phase);
    634 
    635 	if (phase == 0x60)
    636 		GET_SBIC_tlun(sc, sc->sc_status);
    637 	else
    638 		wd33c93_error(sc);
    639 }
    640 
    641 int
    642 wd33c93_abort(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
    643     uint8_t *buf, size_t *lenp)
    644 {
    645 	uint8_t csr, asr;
    646 
    647 	GET_SBIC_asr(sc, asr);
    648 	GET_SBIC_csr(sc, csr);
    649 
    650 	/*
    651 	 * Clean up chip itself
    652 	 */
    653 	wd33c93_timeout(sc, cbuf, clen, buf, lenp);
    654 
    655 	while ((asr & SBIC_ASR_DBR) != 0) {
    656 		/*
    657 		 * wd33c93 is jammed w/data. need to clear it
    658 		 * But we don't know what direction it needs to go
    659 		 */
    660 		GET_SBIC_data(sc, asr);
    661 		GET_SBIC_asr(sc, asr);
    662 		if ((asr & SBIC_ASR_DBR) != 0)
    663 			 /* Not the read direction */
    664 			SET_SBIC_data(sc, asr);
    665 		GET_SBIC_asr(sc, asr);
    666 	}
    667 
    668 	WAIT_CIP(sc);
    669 	SET_SBIC_cmd(sc, SBIC_CMD_ABORT);
    670 	WAIT_CIP(sc);
    671 
    672 	GET_SBIC_asr(sc, asr);
    673 
    674 	if ((asr & (SBIC_ASR_BSY|SBIC_ASR_LCI)) != 0) {
    675 		/*
    676 		 * ok, get more drastic..
    677 		 */
    678 		wd33c93_reset(sc);
    679 	} else {
    680 		SET_SBIC_cmd(sc, SBIC_CMD_DISC);
    681 		WAIT_CIP(sc);
    682 
    683 		do {
    684 			SBIC_WAIT(sc, SBIC_ASR_INT, 0);
    685 			GET_SBIC_asr(sc, asr);
    686 			GET_SBIC_csr(sc, csr);
    687 		} while ((csr != SBIC_CSR_DISC) &&
    688 		    (csr != SBIC_CSR_DISC_1) &&
    689 		    (csr != SBIC_CSR_CMD_INVALID));
    690 
    691 	sc->sc_state = SBIC_ERROR;
    692 	sc->sc_flags = 0;
    693 	}
    694 	return SBIC_STATE_ERROR;
    695 }
    696 
    697 void
    698 wd33c93_timeout(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
    699     uint8_t *buf, size_t *lenp)
    700 {
    701 	uint8_t asr;
    702 
    703 	GET_SBIC_asr(sc, asr);
    704 
    705 	if ((asr & SBIC_ASR_INT) != 0) {
    706 		/* We need to service a missed IRQ */
    707 		wd33c93_intr(sc, cbuf, clen, buf, lenp);
    708 	} else {
    709 		wd33c93_abort(sc, cbuf, clen, buf, lenp);
    710 	}
    711 }
    712 
    713 /*
    714  * Complete current command using polled I/O.Used when interrupt driven
    715  * I/O is not allowed (ie. during boot and shutdown)
    716  *
    717  * Polled I/O is very processor intensive
    718  */
    719 int
    720 wd33c93_poll(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
    721     uint8_t *buf, size_t *lenp)
    722 {
    723 	uint8_t	asr, csr = 0;
    724 	int	count;
    725 
    726 	SBIC_WAIT(sc, SBIC_ASR_INT, wd33c93_cmd_wait);
    727 	for (count = SBIC_ABORT_TIMEOUT; count;) {
    728 		GET_SBIC_asr(sc, asr);
    729 		if ((asr & SBIC_ASR_LCI) != 0)
    730 			DELAY(5000);
    731 
    732 		if ((asr & SBIC_ASR_INT) != 0) {
    733 			GET_SBIC_csr(sc, csr);
    734 			(void)wd33c93_nextstate(sc, cbuf, clen, buf, lenp, csr,
    735 			    asr);
    736 			WAIT_CIP(sc);
    737 		} else {
    738 			DELAY(5000);
    739 			count--;
    740 		}
    741 
    742 		if ((sc->xs_status & XS_STS_DONE) != 0)
    743 			return 0;
    744 	}
    745 	return 1;
    746 }
    747 
    748 static inline int
    749 __verify_msg_format(uint8_t *p, int len)
    750 {
    751 
    752 	if (len == 1 && MSG_IS1BYTE(p[0]))
    753 		return 1;
    754 	if (len == 2 && MSG_IS2BYTE(p[0]))
    755 		return 1;
    756 	if (len >= 3 && MSG_ISEXTENDED(p[0]) &&
    757 	    len == p[1] + 2)
    758 		return 1;
    759 	return 0;
    760 }
    761 
    762 /*
    763  * Handle message_in phase
    764  */
    765 int
    766 wd33c93_msgin_phase(struct wd33c93_softc *sc)
    767 {
    768 	int len;
    769 	uint8_t asr, csr, *msg;
    770 
    771 	GET_SBIC_asr(sc, asr);
    772 	__USE(asr);
    773 
    774 	GET_SBIC_selid(sc, csr);
    775 	SET_SBIC_selid(sc, csr | SBIC_SID_FROM_SCSI);
    776 
    777 	SBIC_TC_PUT(sc, 0);
    778 
    779 	SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
    780 
    781 	msg = sc->sc_imsg;
    782 	len = 0;
    783 
    784 	do {
    785 		/* Fetch the next byte of the message */
    786 		RECV_BYTE(sc, *msg++);
    787 		len++;
    788 
    789 		/*
    790 		 * get the command completion interrupt, or we
    791 		 * can't send a new command (LCI)
    792 		 */
    793 		SBIC_WAIT(sc, SBIC_ASR_INT, 0);
    794 		GET_SBIC_csr(sc, csr);
    795 
    796 		if (__verify_msg_format(sc->sc_imsg, len))
    797 			/* Complete message received */
    798 			break;
    799 
    800 		/*
    801 		 * Clear ACK, and wait for the interrupt
    802 		 * for the next byte or phase change
    803 		 */
    804 		SET_SBIC_cmd(sc, SBIC_CMD_CLR_ACK);
    805 		SBIC_WAIT(sc, SBIC_ASR_INT, 0);
    806 
    807 		GET_SBIC_csr(sc, csr);
    808 	} while (len < SBIC_MAX_MSGLEN);
    809 
    810 	/*
    811 	 * Clear ACK, and wait for the interrupt
    812 	 * for the phase change
    813 	 */
    814 	SET_SBIC_cmd(sc, SBIC_CMD_CLR_ACK);
    815 	SBIC_WAIT(sc, SBIC_ASR_INT, 0);
    816 
    817 	/* Should still have one CSR to read */
    818 	return SBIC_STATE_RUNNING;
    819 }
    820 
    821 void
    822 wd33c93_scsistart(struct wd33c93_softc *sc)
    823 {
    824 
    825 	sc->xs_status = 0;
    826 }
    827 
    828 void
    829 wd33c93_scsidone(struct wd33c93_softc *sc)
    830 {
    831 
    832 	sc->xs_status = XS_STS_DONE;
    833 }
    834 
    835 void
    836 wd33c93_error(struct wd33c93_softc *sc)
    837 {
    838 }
    839