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