Home | History | Annotate | Line # | Download | only in ic
ncr53c9x.c revision 1.37
      1  1.37  mycroft /*	$NetBSD: ncr53c9x.c,v 1.37 1999/11/10 00:42:37 mycroft Exp $	*/
      2   1.1  thorpej 
      3  1.27  mycroft /*-
      4  1.27  mycroft  * Copyright (c) 1998 The NetBSD Foundation, Inc.
      5  1.27  mycroft  * All rights reserved.
      6  1.27  mycroft  *
      7  1.27  mycroft  * This code is derived from software contributed to The NetBSD Foundation
      8  1.27  mycroft  * by Charles M. Hannum.
      9   1.1  thorpej  *
     10   1.1  thorpej  * Redistribution and use in source and binary forms, with or without
     11   1.1  thorpej  * modification, are permitted provided that the following conditions
     12   1.1  thorpej  * are met:
     13   1.1  thorpej  * 1. Redistributions of source code must retain the above copyright
     14   1.1  thorpej  *    notice, this list of conditions and the following disclaimer.
     15   1.1  thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1  thorpej  *    notice, this list of conditions and the following disclaimer in the
     17   1.1  thorpej  *    documentation and/or other materials provided with the distribution.
     18   1.1  thorpej  * 3. All advertising materials mentioning features or use of this software
     19   1.1  thorpej  *    must display the following acknowledgement:
     20  1.27  mycroft  *        This product includes software developed by the NetBSD
     21  1.27  mycroft  *        Foundation, Inc. and its contributors.
     22  1.27  mycroft  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  1.27  mycroft  *    contributors may be used to endorse or promote products derived
     24  1.27  mycroft  *    from this software without specific prior written permission.
     25   1.1  thorpej  *
     26  1.27  mycroft  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  1.27  mycroft  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  1.27  mycroft  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  1.27  mycroft  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  1.27  mycroft  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.27  mycroft  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.27  mycroft  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.27  mycroft  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.27  mycroft  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.27  mycroft  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  1.27  mycroft  * POSSIBILITY OF SUCH DAMAGE.
     37   1.1  thorpej  */
     38   1.1  thorpej 
     39   1.1  thorpej /*
     40   1.1  thorpej  * Copyright (c) 1994 Peter Galbavy
     41   1.1  thorpej  * Copyright (c) 1995 Paul Kranenburg
     42   1.1  thorpej  * All rights reserved.
     43   1.1  thorpej  *
     44   1.1  thorpej  * Redistribution and use in source and binary forms, with or without
     45   1.1  thorpej  * modification, are permitted provided that the following conditions
     46   1.1  thorpej  * are met:
     47   1.1  thorpej  * 1. Redistributions of source code must retain the above copyright
     48   1.1  thorpej  *    notice, this list of conditions and the following disclaimer.
     49   1.1  thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     50   1.1  thorpej  *    notice, this list of conditions and the following disclaimer in the
     51   1.1  thorpej  *    documentation and/or other materials provided with the distribution.
     52   1.1  thorpej  * 3. All advertising materials mentioning features or use of this software
     53   1.1  thorpej  *    must display the following acknowledgement:
     54   1.1  thorpej  *	This product includes software developed by Peter Galbavy
     55   1.1  thorpej  * 4. The name of the author may not be used to endorse or promote products
     56   1.1  thorpej  *    derived from this software without specific prior written permission.
     57   1.1  thorpej  *
     58   1.1  thorpej  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     59   1.1  thorpej  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     60   1.1  thorpej  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     61   1.1  thorpej  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     62   1.1  thorpej  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     63   1.1  thorpej  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     64   1.1  thorpej  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     65   1.1  thorpej  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     66   1.1  thorpej  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     67   1.1  thorpej  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     68   1.1  thorpej  * POSSIBILITY OF SUCH DAMAGE.
     69   1.1  thorpej  */
     70   1.1  thorpej 
     71   1.1  thorpej /*
     72   1.1  thorpej  * Based on aic6360 by Jarle Greipsland
     73   1.1  thorpej  *
     74   1.1  thorpej  * Acknowledgements: Many of the algorithms used in this driver are
     75   1.1  thorpej  * inspired by the work of Julian Elischer (julian (at) tfs.com) and
     76   1.1  thorpej  * Charles Hannum (mycroft (at) duality.gnu.ai.mit.edu).  Thanks a million!
     77   1.1  thorpej  */
     78   1.1  thorpej 
     79   1.1  thorpej #include <sys/types.h>
     80   1.1  thorpej #include <sys/param.h>
     81   1.1  thorpej #include <sys/systm.h>
     82   1.1  thorpej #include <sys/kernel.h>
     83   1.1  thorpej #include <sys/errno.h>
     84   1.1  thorpej #include <sys/ioctl.h>
     85   1.1  thorpej #include <sys/device.h>
     86   1.1  thorpej #include <sys/buf.h>
     87  1.24       pk #include <sys/malloc.h>
     88   1.1  thorpej #include <sys/proc.h>
     89   1.1  thorpej #include <sys/user.h>
     90   1.1  thorpej #include <sys/queue.h>
     91   1.1  thorpej 
     92  1.18   bouyer #include <dev/scsipi/scsi_all.h>
     93  1.18   bouyer #include <dev/scsipi/scsipi_all.h>
     94  1.18   bouyer #include <dev/scsipi/scsiconf.h>
     95  1.18   bouyer #include <dev/scsipi/scsi_message.h>
     96   1.1  thorpej 
     97   1.1  thorpej #include <machine/cpu.h>
     98   1.1  thorpej 
     99   1.1  thorpej #include <dev/ic/ncr53c9xreg.h>
    100   1.1  thorpej #include <dev/ic/ncr53c9xvar.h>
    101   1.1  thorpej 
    102   1.1  thorpej int ncr53c9x_debug = 0; /*NCR_SHOWPHASE|NCR_SHOWMISC|NCR_SHOWTRAC|NCR_SHOWCMDS;*/
    103   1.1  thorpej 
    104   1.1  thorpej /*static*/ void	ncr53c9x_readregs	__P((struct ncr53c9x_softc *));
    105   1.1  thorpej /*static*/ void	ncr53c9x_select		__P((struct ncr53c9x_softc *,
    106   1.1  thorpej 					    struct ncr53c9x_ecb *));
    107   1.1  thorpej /*static*/ int ncr53c9x_reselect	__P((struct ncr53c9x_softc *, int));
    108   1.1  thorpej /*static*/ void	ncr53c9x_scsi_reset	__P((struct ncr53c9x_softc *));
    109   1.1  thorpej /*static*/ void	ncr53c9x_init		__P((struct ncr53c9x_softc *, int));
    110   1.1  thorpej /*static*/ int	ncr53c9x_poll		__P((struct ncr53c9x_softc *,
    111  1.18   bouyer 					    struct scsipi_xfer *, int));
    112   1.1  thorpej /*static*/ void	ncr53c9x_sched		__P((struct ncr53c9x_softc *));
    113   1.1  thorpej /*static*/ void	ncr53c9x_done		__P((struct ncr53c9x_softc *,
    114   1.1  thorpej 					    struct ncr53c9x_ecb *));
    115   1.1  thorpej /*static*/ void	ncr53c9x_msgin		__P((struct ncr53c9x_softc *));
    116   1.1  thorpej /*static*/ void	ncr53c9x_msgout		__P((struct ncr53c9x_softc *));
    117   1.1  thorpej /*static*/ void	ncr53c9x_timeout	__P((void *arg));
    118   1.1  thorpej /*static*/ void	ncr53c9x_abort		__P((struct ncr53c9x_softc *,
    119   1.1  thorpej 					    struct ncr53c9x_ecb *));
    120   1.1  thorpej /*static*/ void ncr53c9x_dequeue	__P((struct ncr53c9x_softc *,
    121   1.1  thorpej 					    struct ncr53c9x_ecb *));
    122   1.1  thorpej 
    123   1.1  thorpej void ncr53c9x_sense			__P((struct ncr53c9x_softc *,
    124   1.1  thorpej 					    struct ncr53c9x_ecb *));
    125   1.1  thorpej void ncr53c9x_free_ecb			__P((struct ncr53c9x_softc *,
    126   1.1  thorpej 					    struct ncr53c9x_ecb *, int));
    127   1.1  thorpej struct ncr53c9x_ecb *ncr53c9x_get_ecb	__P((struct ncr53c9x_softc *, int));
    128   1.1  thorpej 
    129   1.1  thorpej static inline int ncr53c9x_stp2cpb	__P((struct ncr53c9x_softc *, int));
    130   1.1  thorpej static inline void ncr53c9x_setsync	__P((struct ncr53c9x_softc *,
    131   1.1  thorpej 					    struct ncr53c9x_tinfo *));
    132   1.1  thorpej 
    133   1.1  thorpej /*
    134   1.1  thorpej  * Names for the NCR53c9x variants, correspnding to the variant tags
    135   1.1  thorpej  * in ncr53c9xvar.h.
    136   1.1  thorpej  */
    137   1.1  thorpej const char *ncr53c9x_variant_names[] = {
    138   1.1  thorpej 	"ESP100",
    139   1.1  thorpej 	"ESP100A",
    140   1.1  thorpej 	"ESP200",
    141   1.1  thorpej 	"NCR53C94",
    142   1.2   briggs 	"NCR53C96",
    143  1.10       pk 	"ESP406",
    144  1.10       pk 	"FAS408",
    145  1.20   mhitch 	"FAS216",
    146  1.33  thorpej 	"AM53C974",
    147   1.1  thorpej };
    148   1.1  thorpej 
    149   1.1  thorpej /*
    150   1.1  thorpej  * Attach this instance, and then all the sub-devices
    151   1.1  thorpej  */
    152   1.1  thorpej void
    153  1.28  thorpej ncr53c9x_attach(sc, dev)
    154   1.1  thorpej 	struct ncr53c9x_softc *sc;
    155  1.18   bouyer 	struct scsipi_device *dev;
    156   1.1  thorpej {
    157   1.1  thorpej 
    158   1.1  thorpej 	/*
    159  1.24       pk 	 * Allocate SCSI message buffers.
    160  1.24       pk 	 * Front-ends can override allocation to avoid alignment
    161  1.24       pk 	 * handling in the DMA engines. Note that that ncr53c9x_msgout()
    162  1.24       pk 	 * can request a 1 byte DMA transfer.
    163  1.24       pk 	 */
    164  1.24       pk 	if (sc->sc_omess == NULL)
    165  1.24       pk 		sc->sc_omess = malloc(NCR_MAX_MSG_LEN, M_DEVBUF, M_NOWAIT);
    166  1.24       pk 
    167  1.24       pk 	if (sc->sc_imess == NULL)
    168  1.24       pk 		sc->sc_imess = malloc(NCR_MAX_MSG_LEN+1, M_DEVBUF, M_NOWAIT);
    169  1.24       pk 
    170  1.24       pk 	if (sc->sc_omess == NULL || sc->sc_imess == NULL) {
    171  1.24       pk 		printf("out of memory\n");
    172  1.24       pk 		return;
    173  1.24       pk 	}
    174  1.24       pk 
    175  1.24       pk 	/*
    176   1.1  thorpej 	 * Note, the front-end has set us up to print the chip variation.
    177   1.1  thorpej 	 */
    178   1.1  thorpej 	if (sc->sc_rev >= NCR_VARIANT_MAX) {
    179   1.1  thorpej 		printf("\n%s: unknown variant %d, devices not attached\n",
    180   1.1  thorpej 		    sc->sc_dev.dv_xname, sc->sc_rev);
    181   1.1  thorpej 		return;
    182   1.1  thorpej 	}
    183   1.1  thorpej 
    184   1.1  thorpej 	printf(": %s, %dMHz, SCSI ID %d\n",
    185   1.1  thorpej 	    ncr53c9x_variant_names[sc->sc_rev], sc->sc_freq, sc->sc_id);
    186   1.1  thorpej 
    187   1.1  thorpej 	sc->sc_ccf = FREQTOCCF(sc->sc_freq);
    188   1.1  thorpej 
    189   1.1  thorpej 	/* The value *must not* be == 1. Make it 2 */
    190   1.1  thorpej 	if (sc->sc_ccf == 1)
    191   1.1  thorpej 		sc->sc_ccf = 2;
    192   1.1  thorpej 
    193   1.1  thorpej 	/*
    194   1.1  thorpej 	 * The recommended timeout is 250ms. This register is loaded
    195   1.1  thorpej 	 * with a value calculated as follows, from the docs:
    196   1.1  thorpej 	 *
    197   1.1  thorpej 	 *		(timout period) x (CLK frequency)
    198   1.1  thorpej 	 *	reg = -------------------------------------
    199   1.1  thorpej 	 *		 8192 x (Clock Conversion Factor)
    200   1.1  thorpej 	 *
    201   1.1  thorpej 	 * Since CCF has a linear relation to CLK, this generally computes
    202   1.1  thorpej 	 * to the constant of 153.
    203   1.1  thorpej 	 */
    204   1.1  thorpej 	sc->sc_timeout = ((250 * 1000) * sc->sc_freq) / (8192 * sc->sc_ccf);
    205   1.1  thorpej 
    206   1.1  thorpej 	/* CCF register only has 3 bits; 0 is actually 8 */
    207   1.1  thorpej 	sc->sc_ccf &= 7;
    208   1.1  thorpej 
    209   1.1  thorpej 	/* Reset state & bus */
    210  1.16       pk 	sc->sc_cfflags = sc->sc_dev.dv_cfdata->cf_flags;
    211   1.1  thorpej 	sc->sc_state = 0;
    212   1.1  thorpej 	ncr53c9x_init(sc, 1);
    213   1.1  thorpej 
    214   1.1  thorpej 	/*
    215  1.18   bouyer 	 * fill in the prototype scsipi_link.
    216   1.1  thorpej 	 */
    217  1.18   bouyer 	sc->sc_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
    218   1.1  thorpej 	sc->sc_link.adapter_softc = sc;
    219  1.18   bouyer 	sc->sc_link.scsipi_scsi.adapter_target = sc->sc_id;
    220  1.28  thorpej 	sc->sc_link.adapter = &sc->sc_adapter;
    221   1.1  thorpej 	sc->sc_link.device = dev;
    222   1.1  thorpej 	sc->sc_link.openings = 2;
    223  1.18   bouyer 	sc->sc_link.scsipi_scsi.max_target = 7;
    224  1.32   mjacob 	sc->sc_link.scsipi_scsi.max_lun = 7;
    225  1.18   bouyer 	sc->sc_link.type = BUS_SCSI;
    226   1.1  thorpej 
    227   1.1  thorpej 	/*
    228   1.1  thorpej 	 * Now try to attach all the sub-devices
    229   1.1  thorpej 	 */
    230   1.1  thorpej 	config_found(&sc->sc_dev, &sc->sc_link, scsiprint);
    231  1.10       pk 
    232  1.10       pk 	/*
    233  1.10       pk 	 * Enable interupts from the SCSI core
    234  1.10       pk 	 */
    235  1.10       pk 	if ((sc->sc_rev == NCR_VARIANT_ESP406) ||
    236  1.10       pk 	    (sc->sc_rev == NCR_VARIANT_FAS408)) {
    237  1.10       pk 		NCR_PIOREGS(sc);
    238  1.10       pk 		NCR_WRITE_REG(sc, NCR_CFG5, NCRCFG5_SINT |
    239  1.10       pk 		    NCR_READ_REG(sc, NCR_CFG5));
    240  1.10       pk 		NCR_SCSIREGS(sc);
    241  1.10       pk 	}
    242  1.24       pk 
    243   1.1  thorpej }
    244   1.1  thorpej 
    245   1.1  thorpej /*
    246  1.30       pk  * This is the generic ncr53c9x reset function. It does not reset the SCSI bus,
    247  1.30       pk  * only this controller, but kills any on-going commands, and also stops
    248   1.1  thorpej  * and resets the DMA.
    249   1.1  thorpej  *
    250   1.1  thorpej  * After reset, registers are loaded with the defaults from the attach
    251   1.1  thorpej  * routine above.
    252   1.1  thorpej  */
    253   1.1  thorpej void
    254   1.1  thorpej ncr53c9x_reset(sc)
    255   1.1  thorpej 	struct ncr53c9x_softc *sc;
    256   1.1  thorpej {
    257   1.1  thorpej 
    258   1.1  thorpej 	/* reset DMA first */
    259   1.1  thorpej 	NCRDMA_RESET(sc);
    260   1.1  thorpej 
    261   1.1  thorpej 	/* reset SCSI chip */
    262   1.1  thorpej 	NCRCMD(sc, NCRCMD_RSTCHIP);
    263   1.1  thorpej 	NCRCMD(sc, NCRCMD_NOP);
    264   1.1  thorpej 	DELAY(500);
    265   1.1  thorpej 
    266   1.1  thorpej 	/* do these backwards, and fall through */
    267   1.1  thorpej 	switch (sc->sc_rev) {
    268  1.10       pk 	case NCR_VARIANT_ESP406:
    269  1.10       pk 	case NCR_VARIANT_FAS408:
    270  1.10       pk 		NCR_SCSIREGS(sc);
    271  1.33  thorpej 	case NCR_VARIANT_AM53C974:
    272  1.20   mhitch 	case NCR_VARIANT_FAS216:
    273   1.1  thorpej 	case NCR_VARIANT_NCR53C94:
    274   1.2   briggs 	case NCR_VARIANT_NCR53C96:
    275   1.1  thorpej 	case NCR_VARIANT_ESP200:
    276  1.26  thorpej 		sc->sc_features |= NCR_F_HASCFG3;
    277   1.1  thorpej 		NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
    278   1.1  thorpej 	case NCR_VARIANT_ESP100A:
    279   1.1  thorpej 		NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
    280   1.1  thorpej 	case NCR_VARIANT_ESP100:
    281   1.1  thorpej 		NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1);
    282   1.1  thorpej 		NCR_WRITE_REG(sc, NCR_CCF, sc->sc_ccf);
    283   1.1  thorpej 		NCR_WRITE_REG(sc, NCR_SYNCOFF, 0);
    284   1.1  thorpej 		NCR_WRITE_REG(sc, NCR_TIMEOUT, sc->sc_timeout);
    285   1.1  thorpej 		break;
    286   1.1  thorpej 	default:
    287   1.1  thorpej 		printf("%s: unknown revision code, assuming ESP100\n",
    288   1.1  thorpej 		    sc->sc_dev.dv_xname);
    289   1.1  thorpej 		NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1);
    290   1.1  thorpej 		NCR_WRITE_REG(sc, NCR_CCF, sc->sc_ccf);
    291   1.1  thorpej 		NCR_WRITE_REG(sc, NCR_SYNCOFF, 0);
    292   1.1  thorpej 		NCR_WRITE_REG(sc, NCR_TIMEOUT, sc->sc_timeout);
    293   1.1  thorpej 	}
    294  1.33  thorpej 
    295  1.33  thorpej 	if (sc->sc_rev == NCR_VARIANT_AM53C974)
    296  1.33  thorpej 		NCR_WRITE_REG(sc, NCR_AMDCFG4,
    297  1.33  thorpej 		    NCRAMDCFG4_GE12NS | NCRAMDCFG4_RADE);
    298   1.1  thorpej }
    299   1.1  thorpej 
    300   1.1  thorpej /*
    301   1.1  thorpej  * Reset the SCSI bus, but not the chip
    302   1.1  thorpej  */
    303   1.1  thorpej void
    304   1.1  thorpej ncr53c9x_scsi_reset(sc)
    305   1.1  thorpej 	struct ncr53c9x_softc *sc;
    306   1.1  thorpej {
    307   1.1  thorpej 
    308   1.1  thorpej 	(*sc->sc_glue->gl_dma_stop)(sc);
    309   1.1  thorpej 
    310   1.1  thorpej 	printf("%s: resetting SCSI bus\n", sc->sc_dev.dv_xname);
    311   1.1  thorpej 	NCRCMD(sc, NCRCMD_RSTSCSI);
    312   1.1  thorpej }
    313   1.1  thorpej 
    314   1.1  thorpej /*
    315  1.30       pk  * Initialize ncr53c9x state machine
    316   1.1  thorpej  */
    317   1.1  thorpej void
    318   1.1  thorpej ncr53c9x_init(sc, doreset)
    319   1.1  thorpej 	struct ncr53c9x_softc *sc;
    320   1.1  thorpej 	int doreset;
    321   1.1  thorpej {
    322   1.1  thorpej 	struct ncr53c9x_ecb *ecb;
    323   1.1  thorpej 	int r;
    324   1.1  thorpej 
    325   1.1  thorpej 	NCR_TRACE(("[NCR_INIT(%d)] ", doreset));
    326   1.1  thorpej 
    327   1.1  thorpej 	if (sc->sc_state == 0) {
    328   1.1  thorpej 		/* First time through; initialize. */
    329   1.1  thorpej 		TAILQ_INIT(&sc->ready_list);
    330   1.1  thorpej 		TAILQ_INIT(&sc->nexus_list);
    331   1.1  thorpej 		TAILQ_INIT(&sc->free_list);
    332   1.1  thorpej 		sc->sc_nexus = NULL;
    333   1.1  thorpej 		ecb = sc->sc_ecb;
    334   1.1  thorpej 		bzero(ecb, sizeof(sc->sc_ecb));
    335   1.1  thorpej 		for (r = 0; r < sizeof(sc->sc_ecb) / sizeof(*ecb); r++) {
    336   1.1  thorpej 			TAILQ_INSERT_TAIL(&sc->free_list, ecb, chain);
    337   1.1  thorpej 			ecb++;
    338   1.1  thorpej 		}
    339   1.1  thorpej 		bzero(sc->sc_tinfo, sizeof(sc->sc_tinfo));
    340   1.1  thorpej 	} else {
    341   1.1  thorpej 		/* Cancel any active commands. */
    342   1.1  thorpej 		sc->sc_state = NCR_CLEANING;
    343   1.1  thorpej 		if ((ecb = sc->sc_nexus) != NULL) {
    344  1.16       pk 			ecb->xs->error = XS_TIMEOUT;
    345   1.1  thorpej 			ncr53c9x_done(sc, ecb);
    346   1.1  thorpej 		}
    347   1.1  thorpej 		while ((ecb = sc->nexus_list.tqh_first) != NULL) {
    348  1.16       pk 			ecb->xs->error = XS_TIMEOUT;
    349   1.1  thorpej 			ncr53c9x_done(sc, ecb);
    350   1.1  thorpej 		}
    351   1.1  thorpej 	}
    352   1.1  thorpej 
    353   1.1  thorpej 	/*
    354   1.1  thorpej 	 * reset the chip to a known state
    355   1.1  thorpej 	 */
    356   1.1  thorpej 	ncr53c9x_reset(sc);
    357   1.1  thorpej 
    358   1.1  thorpej 	sc->sc_phase = sc->sc_prevphase = INVALID_PHASE;
    359   1.1  thorpej 	for (r = 0; r < 8; r++) {
    360   1.1  thorpej 		struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[r];
    361   1.1  thorpej /* XXX - config flags per target: low bits: no reselect; high bits: no synch */
    362   1.1  thorpej 
    363  1.16       pk 		ti->flags = ((sc->sc_minsync && !(sc->sc_cfflags & (1<<(r+8))))
    364   1.1  thorpej 				? T_NEGOTIATE : 0) |
    365  1.16       pk 				((sc->sc_cfflags & (1<<r)) ? T_RSELECTOFF : 0) |
    366   1.1  thorpej 				T_NEED_TO_RESET;
    367   1.1  thorpej 		ti->period = sc->sc_minsync;
    368   1.1  thorpej 		ti->offset = 0;
    369   1.1  thorpej 	}
    370   1.1  thorpej 
    371   1.1  thorpej 	if (doreset) {
    372   1.1  thorpej 		sc->sc_state = NCR_SBR;
    373   1.1  thorpej 		NCRCMD(sc, NCRCMD_RSTSCSI);
    374   1.1  thorpej 	} else {
    375   1.1  thorpej 		sc->sc_state = NCR_IDLE;
    376  1.15       pk 		ncr53c9x_sched(sc);
    377   1.1  thorpej 	}
    378   1.1  thorpej }
    379   1.1  thorpej 
    380   1.1  thorpej /*
    381   1.1  thorpej  * Read the NCR registers, and save their contents for later use.
    382   1.1  thorpej  * NCR_STAT, NCR_STEP & NCR_INTR are mostly zeroed out when reading
    383   1.1  thorpej  * NCR_INTR - so make sure it is the last read.
    384   1.1  thorpej  *
    385   1.1  thorpej  * I think that (from reading the docs) most bits in these registers
    386   1.1  thorpej  * only make sense when he DMA CSR has an interrupt showing. Call only
    387   1.1  thorpej  * if an interrupt is pending.
    388   1.1  thorpej  */
    389  1.25       pk __inline__ void
    390   1.1  thorpej ncr53c9x_readregs(sc)
    391   1.1  thorpej 	struct ncr53c9x_softc *sc;
    392   1.1  thorpej {
    393   1.1  thorpej 
    394   1.1  thorpej 	sc->sc_espstat = NCR_READ_REG(sc, NCR_STAT);
    395   1.1  thorpej 	/* Only the stepo bits are of interest */
    396   1.1  thorpej 	sc->sc_espstep = NCR_READ_REG(sc, NCR_STEP) & NCRSTEP_MASK;
    397   1.1  thorpej 	sc->sc_espintr = NCR_READ_REG(sc, NCR_INTR);
    398   1.1  thorpej 
    399   1.1  thorpej 	if (sc->sc_glue->gl_clear_latched_intr != NULL)
    400   1.1  thorpej 		(*sc->sc_glue->gl_clear_latched_intr)(sc);
    401   1.1  thorpej 
    402   1.1  thorpej 	/*
    403   1.1  thorpej 	 * Determine the SCSI bus phase, return either a real SCSI bus phase
    404   1.1  thorpej 	 * or some pseudo phase we use to detect certain exceptions.
    405   1.1  thorpej 	 */
    406   1.1  thorpej 
    407   1.1  thorpej 	sc->sc_phase = (sc->sc_espintr & NCRINTR_DIS)
    408   1.1  thorpej 			? /* Disconnected */ BUSFREE_PHASE
    409   1.1  thorpej 			: sc->sc_espstat & NCRSTAT_PHASE;
    410   1.1  thorpej 
    411   1.1  thorpej 	NCR_MISC(("regs[intr=%02x,stat=%02x,step=%02x] ",
    412   1.1  thorpej 		sc->sc_espintr, sc->sc_espstat, sc->sc_espstep));
    413   1.1  thorpej }
    414   1.1  thorpej 
    415   1.1  thorpej /*
    416   1.1  thorpej  * Convert Synchronous Transfer Period to chip register Clock Per Byte value.
    417   1.1  thorpej  */
    418   1.1  thorpej static inline int
    419   1.1  thorpej ncr53c9x_stp2cpb(sc, period)
    420   1.1  thorpej 	struct ncr53c9x_softc *sc;
    421   1.1  thorpej 	int period;
    422   1.1  thorpej {
    423   1.1  thorpej 	int v;
    424   1.1  thorpej 	v = (sc->sc_freq * period) / 250;
    425   1.1  thorpej 	if (ncr53c9x_cpb2stp(sc, v) < period)
    426   1.1  thorpej 		/* Correct round-down error */
    427   1.1  thorpej 		v++;
    428  1.25       pk 	return (v);
    429   1.1  thorpej }
    430   1.1  thorpej 
    431   1.1  thorpej static inline void
    432   1.1  thorpej ncr53c9x_setsync(sc, ti)
    433   1.1  thorpej 	struct ncr53c9x_softc *sc;
    434   1.1  thorpej 	struct ncr53c9x_tinfo *ti;
    435   1.1  thorpej {
    436  1.26  thorpej 	u_char syncoff, synctp, cfg3 = sc->sc_cfg3;
    437   1.1  thorpej 
    438   1.1  thorpej 	if (ti->flags & T_SYNCMODE) {
    439  1.26  thorpej 		syncoff = ti->offset;
    440  1.26  thorpej 		synctp = ncr53c9x_stp2cpb(sc, ti->period);
    441  1.26  thorpej 		if (sc->sc_features & NCR_F_FASTSCSI) {
    442  1.26  thorpej 			/*
    443  1.26  thorpej 			 * If the period is 200ns or less (ti->period <= 50),
    444  1.26  thorpej 			 * put the chip in Fast SCSI mode.
    445  1.26  thorpej 			 */
    446  1.26  thorpej 			if (ti->period <= 50)
    447  1.35   mhitch 				/*
    448  1.35   mhitch 				 * There are (at least) 4 variations of the
    449  1.35   mhitch 				 * configuration 3 register.  The drive attach
    450  1.35   mhitch 				 * routine sets the appropriate bit to put the
    451  1.35   mhitch 				 * chip into Fast SCSI mode so that it doesn't
    452  1.35   mhitch 				 * have to be figured out here each time.
    453  1.35   mhitch 				 */
    454  1.35   mhitch 				cfg3 |= sc->sc_cfg3_fscsi;
    455  1.26  thorpej 		}
    456  1.33  thorpej 
    457  1.33  thorpej 		/*
    458  1.33  thorpej 		 * Am53c974 requires different SYNCTP values when the
    459  1.33  thorpej 		 * FSCSI bit is off.
    460  1.33  thorpej 		 */
    461  1.33  thorpej 		if (sc->sc_rev == NCR_VARIANT_AM53C974 &&
    462  1.33  thorpej 		    (cfg3 & NCRAMDCFG3_FSCSI) == 0)
    463  1.33  thorpej 			synctp--;
    464   1.1  thorpej 	} else {
    465  1.26  thorpej 		syncoff = 0;
    466  1.26  thorpej 		synctp = 0;
    467   1.1  thorpej 	}
    468  1.26  thorpej 
    469  1.26  thorpej 	if (sc->sc_features & NCR_F_HASCFG3)
    470  1.26  thorpej 		NCR_WRITE_REG(sc, NCR_CFG3, cfg3);
    471  1.26  thorpej 
    472  1.26  thorpej 	NCR_WRITE_REG(sc, NCR_SYNCOFF, syncoff);
    473  1.26  thorpej 	NCR_WRITE_REG(sc, NCR_SYNCTP, synctp);
    474   1.1  thorpej }
    475   1.1  thorpej 
    476   1.8       pk int ncr53c9x_dmaselect = 0;
    477   1.1  thorpej /*
    478   1.1  thorpej  * Send a command to a target, set the driver state to NCR_SELECTING
    479   1.1  thorpej  * and let the caller take care of the rest.
    480   1.1  thorpej  *
    481   1.1  thorpej  * Keeping this as a function allows me to say that this may be done
    482   1.1  thorpej  * by DMA instead of programmed I/O soon.
    483   1.1  thorpej  */
    484   1.1  thorpej void
    485   1.1  thorpej ncr53c9x_select(sc, ecb)
    486   1.1  thorpej 	struct ncr53c9x_softc *sc;
    487   1.1  thorpej 	struct ncr53c9x_ecb *ecb;
    488   1.1  thorpej {
    489  1.18   bouyer 	struct scsipi_link *sc_link = ecb->xs->sc_link;
    490  1.18   bouyer 	int target = sc_link->scsipi_scsi.target;
    491  1.22       pk 	int lun = sc_link->scsipi_scsi.lun;
    492   1.1  thorpej 	struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[target];
    493  1.22       pk 	int tiflags = ti->flags;
    494   1.1  thorpej 	u_char *cmd;
    495   1.1  thorpej 	int clen;
    496   1.1  thorpej 
    497   1.1  thorpej 	NCR_TRACE(("[ncr53c9x_select(t%d,l%d,cmd:%x)] ",
    498  1.22       pk 		   target, lun, ecb->cmd.cmd.opcode));
    499   1.1  thorpej 
    500   1.1  thorpej 	sc->sc_state = NCR_SELECTING;
    501   1.1  thorpej 
    502   1.7      gwr 	/*
    503   1.7      gwr 	 * Schedule the timeout now, the first time we will go away
    504   1.7      gwr 	 * expecting to come back due to an interrupt, because it is
    505   1.7      gwr 	 * always possible that the interrupt may never happen.
    506   1.7      gwr 	 */
    507  1.36  thorpej 	if ((ecb->xs->xs_control & XS_CTL_POLL) == 0)
    508   1.7      gwr 		timeout(ncr53c9x_timeout, ecb,
    509   1.7      gwr 		    (ecb->timeout * hz) / 1000);
    510   1.7      gwr 
    511   1.1  thorpej 	/*
    512   1.1  thorpej 	 * The docs say the target register is never reset, and I
    513   1.1  thorpej 	 * can't think of a better place to set it
    514   1.1  thorpej 	 */
    515   1.1  thorpej 	NCR_WRITE_REG(sc, NCR_SELID, target);
    516   1.1  thorpej 	ncr53c9x_setsync(sc, ti);
    517   1.1  thorpej 
    518  1.22       pk 	if (ncr53c9x_dmaselect && (tiflags & T_NEGOTIATE) == 0) {
    519  1.22       pk 		size_t dmasize;
    520  1.22       pk 
    521   1.8       pk 		ecb->cmd.id =
    522  1.22       pk 		    MSG_IDENTIFY(lun, (tiflags & T_RSELECTOFF)?0:1);
    523  1.22       pk 
    524   1.8       pk 
    525   1.8       pk 		/* setup DMA transfer for command */
    526  1.22       pk 		dmasize = clen = ecb->clen + 1;
    527   1.8       pk 		sc->sc_cmdlen = clen;
    528   1.8       pk 		sc->sc_cmdp = (caddr_t)&ecb->cmd;
    529  1.22       pk 		NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0, &dmasize);
    530  1.22       pk 
    531   1.8       pk 		/* Program the SCSI counter */
    532  1.22       pk 		NCR_WRITE_REG(sc, NCR_TCL, dmasize);
    533  1.22       pk 		NCR_WRITE_REG(sc, NCR_TCM, dmasize >> 8);
    534   1.8       pk 		if (sc->sc_cfg2 & NCRCFG2_FE) {
    535  1.22       pk 			NCR_WRITE_REG(sc, NCR_TCH, dmasize >> 16);
    536   1.8       pk 		}
    537   1.8       pk 
    538  1.22       pk 		/* load the count in */
    539  1.22       pk 		NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA);
    540  1.22       pk 
    541   1.8       pk 		/* And get the targets attention */
    542   1.8       pk 		NCRCMD(sc, NCRCMD_SELATN | NCRCMD_DMA);
    543   1.8       pk 		NCRDMA_GO(sc);
    544   1.8       pk 		return;
    545   1.8       pk 	}
    546  1.22       pk 
    547   1.1  thorpej 	/*
    548   1.1  thorpej 	 * Who am I. This is where we tell the target that we are
    549   1.1  thorpej 	 * happy for it to disconnect etc.
    550   1.1  thorpej 	 */
    551   1.1  thorpej 	NCR_WRITE_REG(sc, NCR_FIFO,
    552  1.22       pk 		      MSG_IDENTIFY(lun, (tiflags & T_RSELECTOFF)?0:1));
    553   1.1  thorpej 
    554   1.1  thorpej 	if (ti->flags & T_NEGOTIATE) {
    555   1.1  thorpej 		/* Arbitrate, select and stop after IDENTIFY message */
    556   1.1  thorpej 		NCRCMD(sc, NCRCMD_SELATNS);
    557   1.1  thorpej 		return;
    558   1.1  thorpej 	}
    559   1.1  thorpej 
    560   1.1  thorpej 	/* Now the command into the FIFO */
    561   1.8       pk 	cmd = (u_char *)&ecb->cmd.cmd;
    562   1.1  thorpej 	clen = ecb->clen;
    563   1.1  thorpej 	while (clen--)
    564   1.1  thorpej 		NCR_WRITE_REG(sc, NCR_FIFO, *cmd++);
    565   1.1  thorpej 
    566   1.1  thorpej 	/* And get the targets attention */
    567   1.1  thorpej 	NCRCMD(sc, NCRCMD_SELATN);
    568   1.1  thorpej }
    569   1.1  thorpej 
    570   1.1  thorpej void
    571   1.1  thorpej ncr53c9x_free_ecb(sc, ecb, flags)
    572   1.1  thorpej 	struct ncr53c9x_softc *sc;
    573   1.1  thorpej 	struct ncr53c9x_ecb *ecb;
    574   1.1  thorpej 	int flags;
    575   1.1  thorpej {
    576   1.1  thorpej 	int s;
    577   1.1  thorpej 
    578   1.1  thorpej 	s = splbio();
    579   1.1  thorpej 
    580   1.1  thorpej 	ecb->flags = 0;
    581   1.1  thorpej 	TAILQ_INSERT_HEAD(&sc->free_list, ecb, chain);
    582   1.1  thorpej 
    583   1.1  thorpej 	/*
    584   1.1  thorpej 	 * If there were none, wake anybody waiting for one to come free,
    585   1.1  thorpej 	 * starting with queued entries.
    586   1.1  thorpej 	 */
    587   1.1  thorpej 	if (ecb->chain.tqe_next == 0)
    588   1.1  thorpej 		wakeup(&sc->free_list);
    589   1.1  thorpej 
    590   1.1  thorpej 	splx(s);
    591   1.1  thorpej }
    592   1.1  thorpej 
    593   1.1  thorpej struct ncr53c9x_ecb *
    594   1.1  thorpej ncr53c9x_get_ecb(sc, flags)
    595   1.1  thorpej 	struct ncr53c9x_softc *sc;
    596   1.1  thorpej 	int flags;
    597   1.1  thorpej {
    598   1.1  thorpej 	struct ncr53c9x_ecb *ecb;
    599   1.1  thorpej 	int s;
    600   1.1  thorpej 
    601   1.1  thorpej 	s = splbio();
    602   1.1  thorpej 
    603   1.1  thorpej 	while ((ecb = sc->free_list.tqh_first) == NULL &&
    604  1.36  thorpej 	       (flags & XS_CTL_NOSLEEP) == 0)
    605   1.1  thorpej 		tsleep(&sc->free_list, PRIBIO, "especb", 0);
    606   1.1  thorpej 	if (ecb) {
    607   1.1  thorpej 		TAILQ_REMOVE(&sc->free_list, ecb, chain);
    608   1.1  thorpej 		ecb->flags |= ECB_ALLOC;
    609   1.1  thorpej 	}
    610   1.1  thorpej 
    611   1.1  thorpej 	splx(s);
    612  1.25       pk 	return (ecb);
    613   1.1  thorpej }
    614   1.1  thorpej 
    615   1.1  thorpej /*
    616   1.1  thorpej  * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
    617   1.1  thorpej  */
    618   1.1  thorpej 
    619   1.1  thorpej /*
    620   1.1  thorpej  * Start a SCSI-command
    621   1.1  thorpej  * This function is called by the higher level SCSI-driver to queue/run
    622   1.1  thorpej  * SCSI-commands.
    623   1.1  thorpej  */
    624   1.1  thorpej int
    625   1.1  thorpej ncr53c9x_scsi_cmd(xs)
    626  1.18   bouyer 	struct scsipi_xfer *xs;
    627   1.1  thorpej {
    628  1.18   bouyer 	struct scsipi_link *sc_link = xs->sc_link;
    629   1.1  thorpej 	struct ncr53c9x_softc *sc = sc_link->adapter_softc;
    630   1.1  thorpej 	struct ncr53c9x_ecb *ecb;
    631   1.1  thorpej 	int s, flags;
    632   1.1  thorpej 
    633   1.1  thorpej 	NCR_TRACE(("[ncr53c9x_scsi_cmd] "));
    634   1.1  thorpej 	NCR_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
    635  1.18   bouyer 	    sc_link->scsipi_scsi.target));
    636   1.1  thorpej 
    637  1.36  thorpej 	flags = xs->xs_control;
    638  1.16       pk 	if ((ecb = ncr53c9x_get_ecb(sc, flags)) == NULL)
    639  1.25       pk 		return (TRY_AGAIN_LATER);
    640   1.1  thorpej 
    641   1.1  thorpej 	/* Initialize ecb */
    642   1.1  thorpej 	ecb->xs = xs;
    643   1.1  thorpej 	ecb->timeout = xs->timeout;
    644   1.1  thorpej 
    645  1.36  thorpej 	if (flags & XS_CTL_RESET) {
    646   1.1  thorpej 		ecb->flags |= ECB_RESET;
    647   1.1  thorpej 		ecb->clen = 0;
    648   1.1  thorpej 		ecb->dleft = 0;
    649   1.1  thorpej 	} else {
    650   1.8       pk 		bcopy(xs->cmd, &ecb->cmd.cmd, xs->cmdlen);
    651   1.1  thorpej 		ecb->clen = xs->cmdlen;
    652   1.1  thorpej 		ecb->daddr = xs->data;
    653   1.1  thorpej 		ecb->dleft = xs->datalen;
    654   1.1  thorpej 	}
    655   1.1  thorpej 	ecb->stat = 0;
    656   1.1  thorpej 
    657   1.1  thorpej 	s = splbio();
    658   1.1  thorpej 
    659   1.1  thorpej 	TAILQ_INSERT_TAIL(&sc->ready_list, ecb, chain);
    660   1.1  thorpej 	if (sc->sc_state == NCR_IDLE)
    661   1.1  thorpej 		ncr53c9x_sched(sc);
    662   1.1  thorpej 
    663   1.1  thorpej 	splx(s);
    664   1.1  thorpej 
    665  1.36  thorpej 	if ((flags & XS_CTL_POLL) == 0)
    666  1.25       pk 		return (SUCCESSFULLY_QUEUED);
    667   1.1  thorpej 
    668   1.1  thorpej 	/* Not allowed to use interrupts, use polling instead */
    669   1.1  thorpej 	if (ncr53c9x_poll(sc, xs, ecb->timeout)) {
    670   1.1  thorpej 		ncr53c9x_timeout(ecb);
    671   1.1  thorpej 		if (ncr53c9x_poll(sc, xs, ecb->timeout))
    672   1.1  thorpej 			ncr53c9x_timeout(ecb);
    673   1.1  thorpej 	}
    674  1.25       pk 	return (COMPLETE);
    675   1.1  thorpej }
    676   1.1  thorpej 
    677   1.1  thorpej /*
    678   1.1  thorpej  * Used when interrupt driven I/O isn't allowed, e.g. during boot.
    679   1.1  thorpej  */
    680   1.1  thorpej int
    681   1.1  thorpej ncr53c9x_poll(sc, xs, count)
    682   1.1  thorpej 	struct ncr53c9x_softc *sc;
    683  1.18   bouyer 	struct scsipi_xfer *xs;
    684   1.1  thorpej 	int count;
    685   1.1  thorpej {
    686   1.1  thorpej 
    687   1.1  thorpej 	NCR_TRACE(("[ncr53c9x_poll] "));
    688   1.1  thorpej 	while (count) {
    689   1.1  thorpej 		if (NCRDMA_ISINTR(sc)) {
    690   1.1  thorpej 			ncr53c9x_intr(sc);
    691   1.1  thorpej 		}
    692   1.1  thorpej #if alternatively
    693   1.1  thorpej 		if (NCR_READ_REG(sc, NCR_STAT) & NCRSTAT_INT)
    694   1.1  thorpej 			ncr53c9x_intr(sc);
    695   1.1  thorpej #endif
    696  1.36  thorpej 		if ((xs->xs_status & XS_STS_DONE) != 0)
    697  1.25       pk 			return (0);
    698   1.1  thorpej 		if (sc->sc_state == NCR_IDLE) {
    699   1.1  thorpej 			NCR_TRACE(("[ncr53c9x_poll: rescheduling] "));
    700   1.1  thorpej 			ncr53c9x_sched(sc);
    701   1.1  thorpej 		}
    702   1.1  thorpej 		DELAY(1000);
    703   1.1  thorpej 		count--;
    704   1.1  thorpej 	}
    705  1.25       pk 	return (1);
    706   1.1  thorpej }
    707   1.1  thorpej 
    708   1.1  thorpej 
    709   1.1  thorpej /*
    710   1.1  thorpej  * LOW LEVEL SCSI UTILITIES
    711   1.1  thorpej  */
    712   1.1  thorpej 
    713   1.1  thorpej /*
    714   1.1  thorpej  * Schedule a scsi operation.  This has now been pulled out of the interrupt
    715   1.1  thorpej  * handler so that we may call it from ncr53c9x_scsi_cmd and ncr53c9x_done.
    716   1.1  thorpej  * This may save us an unecessary interrupt just to get things going.
    717   1.1  thorpej  * Should only be called when state == NCR_IDLE and at bio pl.
    718   1.1  thorpej  */
    719   1.1  thorpej void
    720   1.1  thorpej ncr53c9x_sched(sc)
    721   1.1  thorpej 	struct ncr53c9x_softc *sc;
    722   1.1  thorpej {
    723   1.1  thorpej 	struct ncr53c9x_ecb *ecb;
    724  1.18   bouyer 	struct scsipi_link *sc_link;
    725   1.1  thorpej 	struct ncr53c9x_tinfo *ti;
    726   1.1  thorpej 
    727   1.1  thorpej 	NCR_TRACE(("[ncr53c9x_sched] "));
    728   1.1  thorpej 	if (sc->sc_state != NCR_IDLE)
    729   1.1  thorpej 		panic("ncr53c9x_sched: not IDLE (state=%d)", sc->sc_state);
    730   1.1  thorpej 
    731   1.1  thorpej 	/*
    732   1.1  thorpej 	 * Find first ecb in ready queue that is for a target/lunit
    733   1.1  thorpej 	 * combinations that is not busy.
    734   1.1  thorpej 	 */
    735   1.1  thorpej 	for (ecb = sc->ready_list.tqh_first; ecb; ecb = ecb->chain.tqe_next) {
    736   1.1  thorpej 		sc_link = ecb->xs->sc_link;
    737  1.18   bouyer 		ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
    738  1.18   bouyer 		if ((ti->lubusy & (1 << sc_link->scsipi_scsi.lun)) == 0) {
    739   1.1  thorpej 			TAILQ_REMOVE(&sc->ready_list, ecb, chain);
    740   1.1  thorpej 			sc->sc_nexus = ecb;
    741   1.1  thorpej 			ncr53c9x_select(sc, ecb);
    742   1.1  thorpej 			break;
    743   1.1  thorpej 		} else
    744   1.1  thorpej 			NCR_MISC(("%d:%d busy\n",
    745  1.22       pk 				  sc_link->scsipi_scsi.target,
    746  1.22       pk 				  sc_link->scsipi_scsi.lun));
    747   1.1  thorpej 	}
    748   1.1  thorpej }
    749   1.1  thorpej 
    750   1.1  thorpej void
    751   1.1  thorpej ncr53c9x_sense(sc, ecb)
    752   1.1  thorpej 	struct ncr53c9x_softc *sc;
    753   1.1  thorpej 	struct ncr53c9x_ecb *ecb;
    754   1.1  thorpej {
    755  1.18   bouyer 	struct scsipi_xfer *xs = ecb->xs;
    756  1.18   bouyer 	struct scsipi_link *sc_link = xs->sc_link;
    757  1.18   bouyer 	struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
    758  1.18   bouyer 	struct scsipi_sense *ss = (void *)&ecb->cmd.cmd;
    759   1.1  thorpej 
    760   1.1  thorpej 	NCR_MISC(("requesting sense "));
    761   1.1  thorpej 	/* Next, setup a request sense command block */
    762   1.1  thorpej 	bzero(ss, sizeof(*ss));
    763   1.1  thorpej 	ss->opcode = REQUEST_SENSE;
    764  1.18   bouyer 	ss->byte2 = sc_link->scsipi_scsi.lun << 5;
    765  1.18   bouyer 	ss->length = sizeof(struct scsipi_sense_data);
    766   1.1  thorpej 	ecb->clen = sizeof(*ss);
    767  1.18   bouyer 	ecb->daddr = (char *)&xs->sense.scsi_sense;
    768  1.18   bouyer 	ecb->dleft = sizeof(struct scsipi_sense_data);
    769   1.1  thorpej 	ecb->flags |= ECB_SENSE;
    770   1.7      gwr 	ecb->timeout = NCR_SENSE_TIMEOUT;
    771   1.1  thorpej 	ti->senses++;
    772   1.1  thorpej 	if (ecb->flags & ECB_NEXUS)
    773  1.18   bouyer 		ti->lubusy &= ~(1 << sc_link->scsipi_scsi.lun);
    774   1.1  thorpej 	if (ecb == sc->sc_nexus) {
    775  1.23       pk 		ecb->flags &= ~ECB_NEXUS;
    776   1.1  thorpej 		ncr53c9x_select(sc, ecb);
    777   1.1  thorpej 	} else {
    778   1.1  thorpej 		ncr53c9x_dequeue(sc, ecb);
    779   1.1  thorpej 		TAILQ_INSERT_HEAD(&sc->ready_list, ecb, chain);
    780   1.1  thorpej 		if (sc->sc_state == NCR_IDLE)
    781   1.1  thorpej 			ncr53c9x_sched(sc);
    782   1.1  thorpej 	}
    783   1.1  thorpej }
    784   1.1  thorpej 
    785   1.1  thorpej /*
    786   1.1  thorpej  * POST PROCESSING OF SCSI_CMD (usually current)
    787   1.1  thorpej  */
    788   1.1  thorpej void
    789   1.1  thorpej ncr53c9x_done(sc, ecb)
    790   1.1  thorpej 	struct ncr53c9x_softc *sc;
    791   1.1  thorpej 	struct ncr53c9x_ecb *ecb;
    792   1.1  thorpej {
    793  1.18   bouyer 	struct scsipi_xfer *xs = ecb->xs;
    794  1.18   bouyer 	struct scsipi_link *sc_link = xs->sc_link;
    795  1.18   bouyer 	struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
    796   1.1  thorpej 
    797   1.1  thorpej 	NCR_TRACE(("[ncr53c9x_done(error:%x)] ", xs->error));
    798   1.1  thorpej 
    799   1.7      gwr 	untimeout(ncr53c9x_timeout, ecb);
    800   1.7      gwr 
    801   1.1  thorpej 	/*
    802   1.1  thorpej 	 * Now, if we've come here with no error code, i.e. we've kept the
    803   1.1  thorpej 	 * initial XS_NOERROR, and the status code signals that we should
    804   1.1  thorpej 	 * check sense, we'll need to set up a request sense cmd block and
    805   1.1  thorpej 	 * push the command back into the ready queue *before* any other
    806   1.1  thorpej 	 * commands for this target/lunit, else we lose the sense info.
    807   1.1  thorpej 	 * We don't support chk sense conditions for the request sense cmd.
    808   1.1  thorpej 	 */
    809   1.1  thorpej 	if (xs->error == XS_NOERROR) {
    810  1.12       pk 		xs->status = ecb->stat;
    811   1.1  thorpej 		if ((ecb->flags & ECB_ABORT) != 0) {
    812  1.16       pk 			xs->error = XS_TIMEOUT;
    813   1.1  thorpej 		} else if ((ecb->flags & ECB_SENSE) != 0) {
    814   1.1  thorpej 			xs->error = XS_SENSE;
    815   1.1  thorpej 		} else if ((ecb->stat & ST_MASK) == SCSI_CHECK) {
    816   1.1  thorpej 			/* First, save the return values */
    817   1.1  thorpej 			xs->resid = ecb->dleft;
    818   1.1  thorpej 			ncr53c9x_sense(sc, ecb);
    819   1.1  thorpej 			return;
    820   1.1  thorpej 		} else {
    821   1.1  thorpej 			xs->resid = ecb->dleft;
    822   1.1  thorpej 		}
    823   1.1  thorpej 	}
    824   1.1  thorpej 
    825  1.36  thorpej 	xs->xs_status |= XS_STS_DONE;
    826   1.1  thorpej 
    827   1.1  thorpej #ifdef NCR53C9X_DEBUG
    828   1.1  thorpej 	if (ncr53c9x_debug & NCR_SHOWMISC) {
    829   1.1  thorpej 		if (xs->resid != 0)
    830   1.1  thorpej 			printf("resid=%d ", xs->resid);
    831   1.1  thorpej 		if (xs->error == XS_SENSE)
    832  1.18   bouyer 			printf("sense=0x%02x\n", xs->sense.scsi_sense.error_code);
    833   1.1  thorpej 		else
    834   1.1  thorpej 			printf("error=%d\n", xs->error);
    835   1.1  thorpej 	}
    836   1.1  thorpej #endif
    837   1.1  thorpej 
    838   1.1  thorpej 	/*
    839   1.1  thorpej 	 * Remove the ECB from whatever queue it's on.
    840   1.1  thorpej 	 */
    841   1.1  thorpej 	if (ecb->flags & ECB_NEXUS)
    842  1.18   bouyer 		ti->lubusy &= ~(1 << sc_link->scsipi_scsi.lun);
    843   1.1  thorpej 	if (ecb == sc->sc_nexus) {
    844   1.1  thorpej 		sc->sc_nexus = NULL;
    845  1.15       pk 		if (sc->sc_state != NCR_CLEANING) {
    846  1.15       pk 			sc->sc_state = NCR_IDLE;
    847  1.15       pk 			ncr53c9x_sched(sc);
    848  1.15       pk 		}
    849   1.1  thorpej 	} else
    850   1.1  thorpej 		ncr53c9x_dequeue(sc, ecb);
    851   1.1  thorpej 
    852  1.36  thorpej 	ncr53c9x_free_ecb(sc, ecb, xs->xs_control);
    853   1.1  thorpej 	ti->cmds++;
    854  1.18   bouyer 	scsipi_done(xs);
    855   1.1  thorpej }
    856   1.1  thorpej 
    857   1.1  thorpej void
    858   1.1  thorpej ncr53c9x_dequeue(sc, ecb)
    859   1.1  thorpej 	struct ncr53c9x_softc *sc;
    860   1.1  thorpej 	struct ncr53c9x_ecb *ecb;
    861   1.1  thorpej {
    862   1.1  thorpej 
    863   1.1  thorpej 	if (ecb->flags & ECB_NEXUS) {
    864   1.1  thorpej 		TAILQ_REMOVE(&sc->nexus_list, ecb, chain);
    865  1.23       pk 		ecb->flags &= ~ECB_NEXUS;
    866   1.1  thorpej 	} else {
    867   1.1  thorpej 		TAILQ_REMOVE(&sc->ready_list, ecb, chain);
    868   1.1  thorpej 	}
    869   1.1  thorpej }
    870   1.1  thorpej 
    871   1.1  thorpej /*
    872   1.1  thorpej  * INTERRUPT/PROTOCOL ENGINE
    873   1.1  thorpej  */
    874   1.1  thorpej 
    875   1.1  thorpej /*
    876   1.1  thorpej  * Schedule an outgoing message by prioritizing it, and asserting
    877   1.1  thorpej  * attention on the bus. We can only do this when we are the initiator
    878   1.1  thorpej  * else there will be an illegal command interrupt.
    879   1.1  thorpej  */
    880   1.1  thorpej #define ncr53c9x_sched_msgout(m) \
    881   1.1  thorpej 	do {							\
    882   1.1  thorpej 		NCR_MISC(("ncr53c9x_sched_msgout %d ", m));	\
    883   1.1  thorpej 		NCRCMD(sc, NCRCMD_SETATN);			\
    884   1.1  thorpej 		sc->sc_flags |= NCR_ATN;			\
    885   1.1  thorpej 		sc->sc_msgpriq |= (m);				\
    886   1.1  thorpej 	} while (0)
    887   1.1  thorpej 
    888   1.1  thorpej int
    889   1.1  thorpej ncr53c9x_reselect(sc, message)
    890   1.1  thorpej 	struct ncr53c9x_softc *sc;
    891   1.1  thorpej 	int message;
    892   1.1  thorpej {
    893   1.1  thorpej 	u_char selid, target, lun;
    894   1.1  thorpej 	struct ncr53c9x_ecb *ecb;
    895  1.18   bouyer 	struct scsipi_link *sc_link;
    896   1.1  thorpej 	struct ncr53c9x_tinfo *ti;
    897   1.1  thorpej 
    898   1.1  thorpej 	/*
    899   1.1  thorpej 	 * The SCSI chip made a snapshot of the data bus while the reselection
    900   1.1  thorpej 	 * was being negotiated.  This enables us to determine which target did
    901   1.1  thorpej 	 * the reselect.
    902   1.1  thorpej 	 */
    903   1.1  thorpej 	selid = sc->sc_selid & ~(1 << sc->sc_id);
    904   1.1  thorpej 	if (selid & (selid - 1)) {
    905   1.1  thorpej 		printf("%s: reselect with invalid selid %02x;"
    906   1.1  thorpej 		    " sending DEVICE RESET\n", sc->sc_dev.dv_xname, selid);
    907   1.1  thorpej 		goto reset;
    908   1.1  thorpej 	}
    909   1.1  thorpej 
    910   1.1  thorpej 	/*
    911   1.1  thorpej 	 * Search wait queue for disconnected cmd
    912   1.1  thorpej 	 * The list should be short, so I haven't bothered with
    913   1.1  thorpej 	 * any more sophisticated structures than a simple
    914   1.1  thorpej 	 * singly linked list.
    915   1.1  thorpej 	 */
    916   1.1  thorpej 	target = ffs(selid) - 1;
    917   1.1  thorpej 	lun = message & 0x07;
    918   1.1  thorpej 	for (ecb = sc->nexus_list.tqh_first; ecb != NULL;
    919   1.1  thorpej 	     ecb = ecb->chain.tqe_next) {
    920   1.1  thorpej 		sc_link = ecb->xs->sc_link;
    921  1.23       pk 		if (sc_link->scsipi_scsi.target == target &&
    922  1.23       pk 		    sc_link->scsipi_scsi.lun == lun)
    923   1.1  thorpej 			break;
    924   1.1  thorpej 	}
    925   1.1  thorpej 	if (ecb == NULL) {
    926   1.1  thorpej 		printf("%s: reselect from target %d lun %d with no nexus;"
    927   1.1  thorpej 		    " sending ABORT\n", sc->sc_dev.dv_xname, target, lun);
    928   1.1  thorpej 		goto abort;
    929   1.1  thorpej 	}
    930   1.1  thorpej 
    931   1.1  thorpej 	/* Make this nexus active again. */
    932   1.1  thorpej 	TAILQ_REMOVE(&sc->nexus_list, ecb, chain);
    933   1.1  thorpej 	sc->sc_state = NCR_CONNECTED;
    934   1.1  thorpej 	sc->sc_nexus = ecb;
    935   1.1  thorpej 	ti = &sc->sc_tinfo[target];
    936  1.23       pk #ifdef NCR53C9X_DEBUG
    937  1.23       pk 	if ((ti->lubusy & (1 << lun)) == 0) {
    938  1.23       pk 		printf("%s: reselect: target %d, lun %d: should be busy\n",
    939  1.23       pk 			sc->sc_dev.dv_xname, target, lun);
    940  1.23       pk 		ti->lubusy |= (1 << lun);
    941  1.23       pk 	}
    942  1.23       pk #endif
    943   1.1  thorpej 	ncr53c9x_setsync(sc, ti);
    944   1.1  thorpej 
    945   1.1  thorpej 	if (ecb->flags & ECB_RESET)
    946   1.1  thorpej 		ncr53c9x_sched_msgout(SEND_DEV_RESET);
    947   1.1  thorpej 	else if (ecb->flags & ECB_ABORT)
    948   1.1  thorpej 		ncr53c9x_sched_msgout(SEND_ABORT);
    949   1.1  thorpej 
    950   1.1  thorpej 	/* Do an implicit RESTORE POINTERS. */
    951   1.1  thorpej 	sc->sc_dp = ecb->daddr;
    952   1.1  thorpej 	sc->sc_dleft = ecb->dleft;
    953   1.1  thorpej 
    954   1.1  thorpej 	return (0);
    955   1.1  thorpej 
    956   1.1  thorpej reset:
    957   1.1  thorpej 	ncr53c9x_sched_msgout(SEND_DEV_RESET);
    958   1.1  thorpej 	return (1);
    959   1.1  thorpej 
    960   1.1  thorpej abort:
    961   1.1  thorpej 	ncr53c9x_sched_msgout(SEND_ABORT);
    962   1.1  thorpej 	return (1);
    963   1.1  thorpej }
    964   1.1  thorpej 
    965   1.1  thorpej #define IS1BYTEMSG(m) (((m) != 1 && (m) < 0x20) || (m) & 0x80)
    966   1.1  thorpej #define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
    967   1.1  thorpej #define ISEXTMSG(m) ((m) == 1)
    968   1.1  thorpej 
    969   1.1  thorpej /*
    970   1.1  thorpej  * Get an incoming message as initiator.
    971   1.1  thorpej  *
    972   1.1  thorpej  * The SCSI bus must already be in MESSAGE_IN_PHASE and there is a
    973   1.1  thorpej  * byte in the FIFO
    974   1.1  thorpej  */
    975   1.1  thorpej void
    976   1.1  thorpej ncr53c9x_msgin(sc)
    977   1.1  thorpej 	register struct ncr53c9x_softc *sc;
    978   1.1  thorpej {
    979   1.1  thorpej 	register int v;
    980   1.1  thorpej 
    981   1.1  thorpej 	NCR_TRACE(("[ncr53c9x_msgin(curmsglen:%ld)] ", (long)sc->sc_imlen));
    982   1.1  thorpej 
    983   1.1  thorpej 	if ((NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) == 0) {
    984   1.1  thorpej 		printf("%s: msgin: no msg byte available\n",
    985   1.1  thorpej 			sc->sc_dev.dv_xname);
    986   1.1  thorpej 		return;
    987   1.1  thorpej 	}
    988   1.1  thorpej 
    989   1.1  thorpej 	/*
    990   1.1  thorpej 	 * Prepare for a new message.  A message should (according
    991   1.1  thorpej 	 * to the SCSI standard) be transmitted in one single
    992   1.1  thorpej 	 * MESSAGE_IN_PHASE. If we have been in some other phase,
    993   1.1  thorpej 	 * then this is a new message.
    994   1.1  thorpej 	 */
    995   1.1  thorpej 	if (sc->sc_prevphase != MESSAGE_IN_PHASE) {
    996   1.1  thorpej 		sc->sc_flags &= ~NCR_DROP_MSGI;
    997   1.1  thorpej 		sc->sc_imlen = 0;
    998   1.1  thorpej 	}
    999   1.1  thorpej 
   1000   1.1  thorpej 	v = NCR_READ_REG(sc, NCR_FIFO);
   1001   1.1  thorpej 	NCR_MISC(("<msgbyte:0x%02x>", v));
   1002   1.1  thorpej 
   1003   1.1  thorpej #if 0
   1004   1.1  thorpej 	if (sc->sc_state == NCR_RESELECTED && sc->sc_imlen == 0) {
   1005   1.1  thorpej 		/*
   1006   1.1  thorpej 		 * Which target is reselecting us? (The ID bit really)
   1007   1.1  thorpej 		 */
   1008   1.1  thorpej 		sc->sc_selid = v;
   1009   1.1  thorpej 		NCR_MISC(("selid=0x%2x ", sc->sc_selid));
   1010   1.1  thorpej 		return;
   1011   1.1  thorpej 	}
   1012   1.1  thorpej #endif
   1013   1.1  thorpej 
   1014   1.1  thorpej 	sc->sc_imess[sc->sc_imlen] = v;
   1015   1.1  thorpej 
   1016   1.1  thorpej 	/*
   1017   1.1  thorpej 	 * If we're going to reject the message, don't bother storing
   1018   1.1  thorpej 	 * the incoming bytes.  But still, we need to ACK them.
   1019   1.1  thorpej 	 */
   1020   1.1  thorpej 
   1021   1.1  thorpej 	if ((sc->sc_flags & NCR_DROP_MSGI)) {
   1022   1.1  thorpej 		NCRCMD(sc, NCRCMD_MSGOK);
   1023   1.1  thorpej 		printf("<dropping msg byte %x>",
   1024   1.1  thorpej 			sc->sc_imess[sc->sc_imlen]);
   1025   1.1  thorpej 		return;
   1026   1.1  thorpej 	}
   1027   1.1  thorpej 
   1028   1.1  thorpej 	if (sc->sc_imlen >= NCR_MAX_MSG_LEN) {
   1029   1.1  thorpej 		ncr53c9x_sched_msgout(SEND_REJECT);
   1030   1.1  thorpej 		sc->sc_flags |= NCR_DROP_MSGI;
   1031   1.1  thorpej 	} else {
   1032   1.1  thorpej 		sc->sc_imlen++;
   1033   1.1  thorpej 		/*
   1034   1.1  thorpej 		 * This testing is suboptimal, but most
   1035   1.1  thorpej 		 * messages will be of the one byte variety, so
   1036   1.1  thorpej 		 * it should not effect performance
   1037   1.1  thorpej 		 * significantly.
   1038   1.1  thorpej 		 */
   1039   1.1  thorpej 		if (sc->sc_imlen == 1 && IS1BYTEMSG(sc->sc_imess[0]))
   1040   1.1  thorpej 			goto gotit;
   1041   1.1  thorpej 		if (sc->sc_imlen == 2 && IS2BYTEMSG(sc->sc_imess[0]))
   1042   1.1  thorpej 			goto gotit;
   1043   1.1  thorpej 		if (sc->sc_imlen >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
   1044   1.1  thorpej 		    sc->sc_imlen == sc->sc_imess[1] + 2)
   1045   1.1  thorpej 			goto gotit;
   1046   1.1  thorpej 	}
   1047   1.1  thorpej 	/* Ack what we have so far */
   1048   1.1  thorpej 	NCRCMD(sc, NCRCMD_MSGOK);
   1049   1.1  thorpej 	return;
   1050   1.1  thorpej 
   1051   1.1  thorpej gotit:
   1052   1.1  thorpej 	NCR_MSGS(("gotmsg(%x)", sc->sc_imess[0]));
   1053   1.1  thorpej 	/*
   1054   1.1  thorpej 	 * Now we should have a complete message (1 byte, 2 byte
   1055   1.1  thorpej 	 * and moderately long extended messages).  We only handle
   1056   1.1  thorpej 	 * extended messages which total length is shorter than
   1057   1.1  thorpej 	 * NCR_MAX_MSG_LEN.  Longer messages will be amputated.
   1058   1.1  thorpej 	 */
   1059   1.1  thorpej 	switch (sc->sc_state) {
   1060   1.1  thorpej 		struct ncr53c9x_ecb *ecb;
   1061   1.1  thorpej 		struct ncr53c9x_tinfo *ti;
   1062   1.1  thorpej 
   1063   1.1  thorpej 	case NCR_CONNECTED:
   1064   1.1  thorpej 		ecb = sc->sc_nexus;
   1065  1.18   bouyer 		ti = &sc->sc_tinfo[ecb->xs->sc_link->scsipi_scsi.target];
   1066   1.1  thorpej 
   1067   1.1  thorpej 		switch (sc->sc_imess[0]) {
   1068   1.1  thorpej 		case MSG_CMDCOMPLETE:
   1069   1.1  thorpej 			NCR_MSGS(("cmdcomplete "));
   1070   1.1  thorpej 			if (sc->sc_dleft < 0) {
   1071  1.30       pk 				scsi_print_addr(ecb->xs->sc_link);
   1072  1.30       pk 				printf("got %ld extra bytes\n",
   1073  1.31       pk 				       -(long)sc->sc_dleft);
   1074   1.1  thorpej 				sc->sc_dleft = 0;
   1075   1.1  thorpej 			}
   1076  1.13       pk 			ecb->dleft = (ecb->flags & ECB_TENTATIVE_DONE)
   1077  1.13       pk 				? 0
   1078  1.13       pk 				: sc->sc_dleft;
   1079  1.13       pk 			if ((ecb->flags & ECB_SENSE) == 0)
   1080  1.13       pk 				ecb->xs->resid = ecb->dleft;
   1081   1.1  thorpej 			sc->sc_state = NCR_CMDCOMPLETE;
   1082   1.1  thorpej 			break;
   1083   1.1  thorpej 
   1084   1.1  thorpej 		case MSG_MESSAGE_REJECT:
   1085  1.23       pk 			NCR_MSGS(("msg reject (msgout=%x) ", sc->sc_msgout));
   1086   1.1  thorpej 			switch (sc->sc_msgout) {
   1087   1.1  thorpej 			case SEND_SDTR:
   1088   1.1  thorpej 				sc->sc_flags &= ~NCR_SYNCHNEGO;
   1089   1.1  thorpej 				ti->flags &= ~(T_NEGOTIATE | T_SYNCMODE);
   1090   1.1  thorpej 				ncr53c9x_setsync(sc, ti);
   1091   1.1  thorpej 				break;
   1092   1.1  thorpej 			case SEND_INIT_DET_ERR:
   1093   1.1  thorpej 				goto abort;
   1094   1.1  thorpej 			}
   1095   1.1  thorpej 			break;
   1096   1.1  thorpej 
   1097   1.1  thorpej 		case MSG_NOOP:
   1098   1.1  thorpej 			NCR_MSGS(("noop "));
   1099   1.1  thorpej 			break;
   1100   1.1  thorpej 
   1101   1.1  thorpej 		case MSG_DISCONNECT:
   1102   1.1  thorpej 			NCR_MSGS(("disconnect "));
   1103   1.1  thorpej 			ti->dconns++;
   1104   1.1  thorpej 			sc->sc_state = NCR_DISCONNECT;
   1105   1.8       pk 
   1106  1.13       pk 			/*
   1107  1.13       pk 			 * Mark the fact that all bytes have moved. The
   1108  1.13       pk 			 * target may not bother to do a SAVE POINTERS
   1109  1.13       pk 			 * at this stage. This flag will set the residual
   1110  1.13       pk 			 * count to zero on MSG COMPLETE.
   1111  1.13       pk 			 */
   1112  1.13       pk 			if (sc->sc_dleft == 0)
   1113  1.13       pk 				ecb->flags |= ECB_TENTATIVE_DONE;
   1114  1.13       pk 
   1115  1.13       pk 			break;
   1116   1.1  thorpej 
   1117   1.1  thorpej 		case MSG_SAVEDATAPOINTER:
   1118   1.1  thorpej 			NCR_MSGS(("save datapointer "));
   1119   1.1  thorpej 			ecb->daddr = sc->sc_dp;
   1120   1.1  thorpej 			ecb->dleft = sc->sc_dleft;
   1121   1.1  thorpej 			break;
   1122   1.1  thorpej 
   1123   1.1  thorpej 		case MSG_RESTOREPOINTERS:
   1124   1.1  thorpej 			NCR_MSGS(("restore datapointer "));
   1125   1.1  thorpej 			sc->sc_dp = ecb->daddr;
   1126   1.1  thorpej 			sc->sc_dleft = ecb->dleft;
   1127   1.1  thorpej 			break;
   1128   1.1  thorpej 
   1129   1.1  thorpej 		case MSG_EXTENDED:
   1130   1.1  thorpej 			NCR_MSGS(("extended(%x) ", sc->sc_imess[2]));
   1131   1.1  thorpej 			switch (sc->sc_imess[2]) {
   1132   1.1  thorpej 			case MSG_EXT_SDTR:
   1133   1.1  thorpej 				NCR_MSGS(("SDTR period %d, offset %d ",
   1134   1.1  thorpej 					sc->sc_imess[3], sc->sc_imess[4]));
   1135   1.1  thorpej 				if (sc->sc_imess[1] != 3)
   1136   1.1  thorpej 					goto reject;
   1137   1.1  thorpej 				ti->period = sc->sc_imess[3];
   1138   1.1  thorpej 				ti->offset = sc->sc_imess[4];
   1139   1.1  thorpej 				ti->flags &= ~T_NEGOTIATE;
   1140   1.1  thorpej 				if (sc->sc_minsync == 0 ||
   1141   1.1  thorpej 				    ti->offset == 0 ||
   1142   1.1  thorpej 				    ti->period > 124) {
   1143  1.29       pk #ifdef NCR53C9X_DEBUG
   1144  1.29       pk 					scsi_print_addr(ecb->xs->sc_link);
   1145  1.29       pk 					printf("async mode\n");
   1146  1.29       pk #endif
   1147   1.1  thorpej 					if ((sc->sc_flags&NCR_SYNCHNEGO)
   1148   1.1  thorpej 					    == 0) {
   1149   1.1  thorpej 						/*
   1150   1.1  thorpej 						 * target initiated negotiation
   1151   1.1  thorpej 						 */
   1152   1.1  thorpej 						ti->offset = 0;
   1153   1.1  thorpej 						ti->flags &= ~T_SYNCMODE;
   1154   1.1  thorpej 						ncr53c9x_sched_msgout(
   1155   1.1  thorpej 						    SEND_SDTR);
   1156   1.1  thorpej 					} else {
   1157   1.1  thorpej 						/* we are async */
   1158   1.1  thorpej 						ti->flags &= ~T_SYNCMODE;
   1159   1.1  thorpej 					}
   1160   1.1  thorpej 				} else {
   1161   1.1  thorpej 					int r = 250/ti->period;
   1162   1.1  thorpej 					int s = (100*250)/ti->period - 100*r;
   1163   1.1  thorpej 					int p;
   1164   1.1  thorpej 
   1165   1.1  thorpej 					p = ncr53c9x_stp2cpb(sc, ti->period);
   1166   1.1  thorpej 					ti->period = ncr53c9x_cpb2stp(sc, p);
   1167   1.1  thorpej #ifdef NCR53C9X_DEBUG
   1168  1.18   bouyer 					scsi_print_addr(ecb->xs->sc_link);
   1169  1.18   bouyer 					printf("max sync rate %d.%02dMb/s\n",
   1170   1.1  thorpej 						r, s);
   1171   1.1  thorpej #endif
   1172  1.22       pk 					if ((sc->sc_flags&NCR_SYNCHNEGO) == 0) {
   1173   1.1  thorpej 						/*
   1174   1.1  thorpej 						 * target initiated negotiation
   1175   1.1  thorpej 						 */
   1176   1.1  thorpej 						if (ti->period <
   1177   1.1  thorpej 						    sc->sc_minsync)
   1178   1.1  thorpej 							ti->period =
   1179   1.1  thorpej 							    sc->sc_minsync;
   1180   1.1  thorpej 						if (ti->offset > 15)
   1181   1.1  thorpej 							ti->offset = 15;
   1182   1.1  thorpej 						ti->flags &= ~T_SYNCMODE;
   1183   1.1  thorpej 						ncr53c9x_sched_msgout(
   1184   1.1  thorpej 						    SEND_SDTR);
   1185   1.1  thorpej 					} else {
   1186   1.1  thorpej 						/* we are sync */
   1187   1.1  thorpej 						ti->flags |= T_SYNCMODE;
   1188   1.1  thorpej 					}
   1189   1.1  thorpej 				}
   1190   1.1  thorpej 				sc->sc_flags &= ~NCR_SYNCHNEGO;
   1191   1.1  thorpej 				ncr53c9x_setsync(sc, ti);
   1192   1.1  thorpej 				break;
   1193   1.1  thorpej 
   1194   1.1  thorpej 			default:
   1195  1.30       pk 				scsi_print_addr(ecb->xs->sc_link);
   1196  1.30       pk 				printf("unrecognized MESSAGE EXTENDED;"
   1197  1.30       pk 				       " sending REJECT\n");
   1198   1.1  thorpej 				goto reject;
   1199   1.1  thorpej 			}
   1200   1.1  thorpej 			break;
   1201   1.1  thorpej 
   1202   1.1  thorpej 		default:
   1203   1.1  thorpej 			NCR_MSGS(("ident "));
   1204  1.30       pk 			scsi_print_addr(ecb->xs->sc_link);
   1205  1.30       pk 			printf("unrecognized MESSAGE; sending REJECT\n");
   1206   1.1  thorpej 		reject:
   1207   1.1  thorpej 			ncr53c9x_sched_msgout(SEND_REJECT);
   1208   1.1  thorpej 			break;
   1209   1.1  thorpej 		}
   1210   1.1  thorpej 		break;
   1211   1.1  thorpej 
   1212   1.1  thorpej 	case NCR_RESELECTED:
   1213   1.1  thorpej 		if (!MSG_ISIDENTIFY(sc->sc_imess[0])) {
   1214  1.31       pk 			printf("%s: reselect without IDENTIFY;"
   1215  1.31       pk 			       " sending DEVICE RESET\n",
   1216  1.31       pk 			       sc->sc_dev.dv_xname);
   1217   1.1  thorpej 			goto reset;
   1218   1.1  thorpej 		}
   1219   1.1  thorpej 
   1220   1.1  thorpej 		(void) ncr53c9x_reselect(sc, sc->sc_imess[0]);
   1221   1.1  thorpej 		break;
   1222   1.1  thorpej 
   1223   1.1  thorpej 	default:
   1224  1.31       pk 		printf("%s: unexpected MESSAGE IN; sending DEVICE RESET\n",
   1225  1.31       pk 			sc->sc_dev.dv_xname);
   1226   1.1  thorpej 	reset:
   1227   1.1  thorpej 		ncr53c9x_sched_msgout(SEND_DEV_RESET);
   1228   1.1  thorpej 		break;
   1229   1.1  thorpej 
   1230   1.1  thorpej 	abort:
   1231   1.1  thorpej 		ncr53c9x_sched_msgout(SEND_ABORT);
   1232   1.1  thorpej 		break;
   1233   1.1  thorpej 	}
   1234   1.1  thorpej 
   1235   1.1  thorpej 	/* Ack last message byte */
   1236   1.1  thorpej 	NCRCMD(sc, NCRCMD_MSGOK);
   1237   1.1  thorpej 
   1238   1.1  thorpej 	/* Done, reset message pointer. */
   1239   1.1  thorpej 	sc->sc_flags &= ~NCR_DROP_MSGI;
   1240   1.1  thorpej 	sc->sc_imlen = 0;
   1241   1.1  thorpej }
   1242   1.1  thorpej 
   1243   1.1  thorpej 
   1244   1.1  thorpej /*
   1245   1.1  thorpej  * Send the highest priority, scheduled message
   1246   1.1  thorpej  */
   1247   1.1  thorpej void
   1248   1.1  thorpej ncr53c9x_msgout(sc)
   1249   1.1  thorpej 	register struct ncr53c9x_softc *sc;
   1250   1.1  thorpej {
   1251   1.1  thorpej 	struct ncr53c9x_tinfo *ti;
   1252   1.1  thorpej 	struct ncr53c9x_ecb *ecb;
   1253   1.1  thorpej 	size_t size;
   1254   1.1  thorpej 
   1255   1.1  thorpej 	NCR_TRACE(("[ncr53c9x_msgout(priq:%x, prevphase:%x)]",
   1256   1.1  thorpej 	    sc->sc_msgpriq, sc->sc_prevphase));
   1257   1.1  thorpej 
   1258  1.22       pk 	/*
   1259  1.22       pk 	 * XXX - the NCR_ATN flag is not in sync with the actual ATN
   1260  1.22       pk 	 *	 condition on the SCSI bus. The 53c9x chip
   1261  1.22       pk 	 *	 automatically turns off ATN before sending the
   1262  1.22       pk 	 *	 message byte.  (see also the comment below in the
   1263  1.22       pk 	 *	 default case when picking out a message to send)
   1264  1.22       pk 	 */
   1265   1.1  thorpej 	if (sc->sc_flags & NCR_ATN) {
   1266   1.1  thorpej 		if (sc->sc_prevphase != MESSAGE_OUT_PHASE) {
   1267   1.1  thorpej 		new:
   1268   1.1  thorpej 			NCRCMD(sc, NCRCMD_FLUSH);
   1269   1.1  thorpej 			DELAY(1);
   1270   1.1  thorpej 			sc->sc_msgoutq = 0;
   1271   1.1  thorpej 			sc->sc_omlen = 0;
   1272   1.1  thorpej 		}
   1273   1.1  thorpej 	} else {
   1274   1.1  thorpej 		if (sc->sc_prevphase == MESSAGE_OUT_PHASE) {
   1275   1.1  thorpej 			ncr53c9x_sched_msgout(sc->sc_msgoutq);
   1276   1.1  thorpej 			goto new;
   1277   1.1  thorpej 		} else {
   1278   1.1  thorpej 			printf("%s at line %d: unexpected MESSAGE OUT phase\n",
   1279   1.1  thorpej 			    sc->sc_dev.dv_xname, __LINE__);
   1280   1.1  thorpej 		}
   1281   1.1  thorpej 	}
   1282   1.1  thorpej 
   1283   1.1  thorpej 	if (sc->sc_omlen == 0) {
   1284   1.1  thorpej 		/* Pick up highest priority message */
   1285   1.1  thorpej 		sc->sc_msgout = sc->sc_msgpriq & -sc->sc_msgpriq;
   1286   1.1  thorpej 		sc->sc_msgoutq |= sc->sc_msgout;
   1287   1.1  thorpej 		sc->sc_msgpriq &= ~sc->sc_msgout;
   1288   1.1  thorpej 		sc->sc_omlen = 1;		/* "Default" message len */
   1289   1.1  thorpej 		switch (sc->sc_msgout) {
   1290   1.1  thorpej 		case SEND_SDTR:
   1291   1.1  thorpej 			ecb = sc->sc_nexus;
   1292  1.18   bouyer 			ti = &sc->sc_tinfo[ecb->xs->sc_link->scsipi_scsi.target];
   1293   1.1  thorpej 			sc->sc_omess[0] = MSG_EXTENDED;
   1294   1.1  thorpej 			sc->sc_omess[1] = 3;
   1295   1.1  thorpej 			sc->sc_omess[2] = MSG_EXT_SDTR;
   1296   1.1  thorpej 			sc->sc_omess[3] = ti->period;
   1297   1.1  thorpej 			sc->sc_omess[4] = ti->offset;
   1298   1.1  thorpej 			sc->sc_omlen = 5;
   1299   1.1  thorpej 			if ((sc->sc_flags & NCR_SYNCHNEGO) == 0) {
   1300   1.1  thorpej 				ti->flags |= T_SYNCMODE;
   1301   1.1  thorpej 				ncr53c9x_setsync(sc, ti);
   1302   1.1  thorpej 			}
   1303   1.1  thorpej 			break;
   1304   1.1  thorpej 		case SEND_IDENTIFY:
   1305   1.1  thorpej 			if (sc->sc_state != NCR_CONNECTED) {
   1306   1.1  thorpej 				printf("%s at line %d: no nexus\n",
   1307   1.1  thorpej 				    sc->sc_dev.dv_xname, __LINE__);
   1308   1.1  thorpej 			}
   1309   1.1  thorpej 			ecb = sc->sc_nexus;
   1310   1.1  thorpej 			sc->sc_omess[0] =
   1311  1.18   bouyer 			    MSG_IDENTIFY(ecb->xs->sc_link->scsipi_scsi.lun, 0);
   1312   1.1  thorpej 			break;
   1313   1.1  thorpej 		case SEND_DEV_RESET:
   1314   1.1  thorpej 			sc->sc_flags |= NCR_ABORTING;
   1315   1.1  thorpej 			sc->sc_omess[0] = MSG_BUS_DEV_RESET;
   1316   1.1  thorpej 			ecb = sc->sc_nexus;
   1317  1.18   bouyer 			ti = &sc->sc_tinfo[ecb->xs->sc_link->scsipi_scsi.target];
   1318   1.1  thorpej 			ti->flags &= ~T_SYNCMODE;
   1319   1.1  thorpej 			ti->flags |= T_NEGOTIATE;
   1320   1.1  thorpej 			break;
   1321   1.1  thorpej 		case SEND_PARITY_ERROR:
   1322   1.1  thorpej 			sc->sc_omess[0] = MSG_PARITY_ERROR;
   1323   1.1  thorpej 			break;
   1324   1.1  thorpej 		case SEND_ABORT:
   1325   1.1  thorpej 			sc->sc_flags |= NCR_ABORTING;
   1326   1.1  thorpej 			sc->sc_omess[0] = MSG_ABORT;
   1327   1.1  thorpej 			break;
   1328   1.1  thorpej 		case SEND_INIT_DET_ERR:
   1329   1.1  thorpej 			sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
   1330   1.1  thorpej 			break;
   1331   1.1  thorpej 		case SEND_REJECT:
   1332   1.1  thorpej 			sc->sc_omess[0] = MSG_MESSAGE_REJECT;
   1333   1.1  thorpej 			break;
   1334   1.1  thorpej 		default:
   1335  1.22       pk 			/*
   1336  1.22       pk 			 * We normally do not get here, since the chip
   1337  1.22       pk 			 * automatically turns off ATN before the last
   1338  1.22       pk 			 * byte of a message is sent to the target.
   1339  1.22       pk 			 * However, if the target rejects our (multi-byte)
   1340  1.22       pk 			 * message early by switching to MSG IN phase
   1341  1.22       pk 			 * ATN remains on, so the target may return to
   1342  1.22       pk 			 * MSG OUT phase. If there are no scheduled messages
   1343  1.22       pk 			 * left we send a NO-OP.
   1344  1.22       pk 			 *
   1345  1.22       pk 			 * XXX - Note that this leaves no useful purpose for
   1346  1.22       pk 			 * the NCR_ATN flag.
   1347  1.22       pk 			 */
   1348   1.1  thorpej 			sc->sc_flags &= ~NCR_ATN;
   1349   1.1  thorpej 			sc->sc_omess[0] = MSG_NOOP;
   1350   1.1  thorpej 			break;
   1351   1.1  thorpej 		}
   1352   1.1  thorpej 		sc->sc_omp = sc->sc_omess;
   1353   1.1  thorpej 	}
   1354   1.1  thorpej 
   1355   1.1  thorpej 	/* (re)send the message */
   1356   1.1  thorpej 	size = min(sc->sc_omlen, sc->sc_maxxfer);
   1357   1.1  thorpej 	NCRDMA_SETUP(sc, &sc->sc_omp, &sc->sc_omlen, 0, &size);
   1358   1.1  thorpej 	/* Program the SCSI counter */
   1359   1.1  thorpej 	NCR_WRITE_REG(sc, NCR_TCL, size);
   1360   1.1  thorpej 	NCR_WRITE_REG(sc, NCR_TCM, size >> 8);
   1361   1.1  thorpej 	if (sc->sc_cfg2 & NCRCFG2_FE) {
   1362   1.1  thorpej 		NCR_WRITE_REG(sc, NCR_TCH, size >> 16);
   1363   1.1  thorpej 	}
   1364  1.22       pk 	/* Load the count in and start the message-out transfer */
   1365   1.1  thorpej 	NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA);
   1366   1.1  thorpej 	NCRCMD(sc, NCRCMD_TRANS|NCRCMD_DMA);
   1367   1.1  thorpej 	NCRDMA_GO(sc);
   1368   1.1  thorpej }
   1369   1.1  thorpej 
   1370   1.1  thorpej /*
   1371   1.1  thorpej  * This is the most critical part of the driver, and has to know
   1372   1.1  thorpej  * how to deal with *all* error conditions and phases from the SCSI
   1373   1.1  thorpej  * bus. If there are no errors and the DMA was active, then call the
   1374   1.1  thorpej  * DMA pseudo-interrupt handler. If this returns 1, then that was it
   1375   1.1  thorpej  * and we can return from here without further processing.
   1376   1.1  thorpej  *
   1377   1.1  thorpej  * Most of this needs verifying.
   1378   1.1  thorpej  */
   1379  1.25       pk int sdebug = 0;
   1380   1.1  thorpej int
   1381   1.1  thorpej ncr53c9x_intr(sc)
   1382   1.1  thorpej 	register struct ncr53c9x_softc *sc;
   1383   1.1  thorpej {
   1384   1.1  thorpej 	register struct ncr53c9x_ecb *ecb;
   1385  1.18   bouyer 	register struct scsipi_link *sc_link;
   1386   1.1  thorpej 	struct ncr53c9x_tinfo *ti;
   1387   1.1  thorpej 	size_t size;
   1388   1.5       pk 	int nfifo;
   1389   1.1  thorpej 
   1390  1.10       pk 	NCR_TRACE(("[ncr53c9x_intr] "));
   1391   1.1  thorpej 
   1392  1.25       pk 	if (!NCRDMA_ISINTR(sc))
   1393  1.25       pk 		return (0);
   1394  1.25       pk 
   1395  1.25       pk again:
   1396  1.25       pk 	/* and what do the registers say... */
   1397  1.25       pk 	ncr53c9x_readregs(sc);
   1398  1.25       pk 
   1399  1.25       pk 	sc->sc_intrcnt.ev_count++;
   1400  1.25       pk 
   1401   1.1  thorpej 	/*
   1402  1.25       pk 	 * At the moment, only a SCSI Bus Reset or Illegal
   1403  1.25       pk 	 * Command are classed as errors. A disconnect is a
   1404  1.25       pk 	 * valid condition, and we let the code check is the
   1405  1.25       pk 	 * "NCR_BUSFREE_OK" flag was set before declaring it
   1406  1.25       pk 	 * and error.
   1407   1.1  thorpej 	 *
   1408  1.25       pk 	 * Also, the status register tells us about "Gross
   1409  1.25       pk 	 * Errors" and "Parity errors". Only the Gross Error
   1410  1.25       pk 	 * is really bad, and the parity errors are dealt
   1411  1.25       pk 	 * with later
   1412   1.1  thorpej 	 *
   1413  1.25       pk 	 * TODO
   1414  1.25       pk 	 *	If there are too many parity error, go to slow
   1415  1.25       pk 	 *	cable mode ?
   1416   1.1  thorpej 	 */
   1417  1.25       pk 
   1418  1.25       pk 	/* SCSI Reset */
   1419  1.25       pk 	if (sc->sc_espintr & NCRINTR_SBR) {
   1420  1.25       pk 		if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) {
   1421  1.25       pk 			NCRCMD(sc, NCRCMD_FLUSH);
   1422  1.25       pk 			DELAY(1);
   1423  1.25       pk 		}
   1424  1.25       pk 		if (sc->sc_state != NCR_SBR) {
   1425  1.25       pk 			printf("%s: SCSI bus reset\n",
   1426  1.25       pk 				sc->sc_dev.dv_xname);
   1427  1.25       pk 			ncr53c9x_init(sc, 0); /* Restart everything */
   1428  1.25       pk 			return (1);
   1429  1.25       pk 		}
   1430   1.1  thorpej #if 0
   1431  1.25       pk /*XXX*/		printf("<expected bus reset: "
   1432  1.25       pk 			"[intr %x, stat %x, step %d]>\n",
   1433  1.25       pk 			sc->sc_espintr, sc->sc_espstat,
   1434  1.25       pk 			sc->sc_espstep);
   1435   1.1  thorpej #endif
   1436  1.25       pk 		if (sc->sc_nexus)
   1437  1.25       pk 			panic("%s: nexus in reset state",
   1438  1.25       pk 			      sc->sc_dev.dv_xname);
   1439  1.25       pk 		goto sched;
   1440  1.25       pk 	}
   1441   1.1  thorpej 
   1442  1.25       pk 	ecb = sc->sc_nexus;
   1443   1.1  thorpej 
   1444  1.25       pk #define NCRINTR_ERR (NCRINTR_SBR|NCRINTR_ILL)
   1445  1.25       pk 	if (sc->sc_espintr & NCRINTR_ERR ||
   1446  1.25       pk 	    sc->sc_espstat & NCRSTAT_GE) {
   1447   1.1  thorpej 
   1448  1.25       pk 		if (sc->sc_espstat & NCRSTAT_GE) {
   1449  1.25       pk 			/* Gross Error; no target ? */
   1450   1.1  thorpej 			if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) {
   1451   1.1  thorpej 				NCRCMD(sc, NCRCMD_FLUSH);
   1452   1.1  thorpej 				DELAY(1);
   1453   1.1  thorpej 			}
   1454  1.25       pk 			if (sc->sc_state == NCR_CONNECTED ||
   1455  1.25       pk 			    sc->sc_state == NCR_SELECTING) {
   1456  1.25       pk 				ecb->xs->error = XS_TIMEOUT;
   1457  1.25       pk 				ncr53c9x_done(sc, ecb);
   1458   1.1  thorpej 			}
   1459  1.25       pk 			return (1);
   1460   1.1  thorpej 		}
   1461   1.1  thorpej 
   1462  1.25       pk 		if (sc->sc_espintr & NCRINTR_ILL) {
   1463  1.25       pk 			if (sc->sc_flags & NCR_EXPECT_ILLCMD) {
   1464  1.25       pk 				/*
   1465  1.25       pk 				 * Eat away "Illegal command" interrupt
   1466  1.25       pk 				 * on a ESP100 caused by a re-selection
   1467  1.25       pk 				 * while we were trying to select
   1468  1.25       pk 				 * another target.
   1469  1.25       pk 				 */
   1470  1.19       pk #ifdef DEBUG
   1471  1.25       pk 				printf("%s: ESP100 work-around activated\n",
   1472  1.25       pk 					sc->sc_dev.dv_xname);
   1473  1.19       pk #endif
   1474  1.25       pk 				sc->sc_flags &= ~NCR_EXPECT_ILLCMD;
   1475  1.25       pk 				return (1);
   1476  1.25       pk 			}
   1477  1.25       pk 			/* illegal command, out of sync ? */
   1478  1.25       pk 			printf("%s: illegal command: 0x%x "
   1479  1.25       pk 			    "(state %d, phase %x, prevphase %x)\n",
   1480  1.25       pk 				sc->sc_dev.dv_xname, sc->sc_lastcmd,
   1481  1.25       pk 				sc->sc_state, sc->sc_phase,
   1482  1.25       pk 				sc->sc_prevphase);
   1483  1.25       pk 			if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) {
   1484  1.25       pk 				NCRCMD(sc, NCRCMD_FLUSH);
   1485  1.25       pk 				DELAY(1);
   1486   1.1  thorpej 			}
   1487  1.25       pk 			ncr53c9x_init(sc, 1); /* Restart everything */
   1488  1.25       pk 			return (1);
   1489   1.1  thorpej 		}
   1490  1.25       pk 	}
   1491  1.25       pk 	sc->sc_flags &= ~NCR_EXPECT_ILLCMD;
   1492   1.1  thorpej 
   1493  1.25       pk 	/*
   1494  1.25       pk 	 * Call if DMA is active.
   1495  1.25       pk 	 *
   1496  1.25       pk 	 * If DMA_INTR returns true, then maybe go 'round the loop
   1497  1.25       pk 	 * again in case there is no more DMA queued, but a phase
   1498  1.25       pk 	 * change is expected.
   1499  1.25       pk 	 */
   1500  1.25       pk 	if (NCRDMA_ISACTIVE(sc)) {
   1501  1.25       pk 		int r = NCRDMA_INTR(sc);
   1502  1.25       pk 		if (r == -1) {
   1503  1.25       pk 			printf("%s: DMA error; resetting\n",
   1504  1.25       pk 				sc->sc_dev.dv_xname);
   1505  1.25       pk 			ncr53c9x_init(sc, 1);
   1506  1.25       pk 		}
   1507  1.25       pk 		/* If DMA active here, then go back to work... */
   1508  1.25       pk 		if (NCRDMA_ISACTIVE(sc))
   1509  1.25       pk 			return (1);
   1510   1.1  thorpej 
   1511  1.25       pk 		if ((sc->sc_espstat & NCRSTAT_TC) == 0) {
   1512  1.25       pk 			/*
   1513  1.25       pk 			 * DMA not completed.  If we can not find a
   1514  1.25       pk 			 * acceptable explanation, print a diagnostic.
   1515  1.25       pk 			 */
   1516  1.25       pk 			if (sc->sc_state == NCR_SELECTING)
   1517  1.25       pk 				/*
   1518  1.25       pk 				 * This can happen if we are reselected
   1519  1.25       pk 				 * while using DMA to select a target.
   1520  1.25       pk 				 */
   1521  1.25       pk 				/*void*/;
   1522  1.25       pk 			else if (sc->sc_prevphase == MESSAGE_OUT_PHASE) {
   1523  1.25       pk 				/*
   1524  1.25       pk 				 * Our (multi-byte) message (eg SDTR) was
   1525  1.25       pk 				 * interrupted by the target to send
   1526  1.25       pk 				 * a MSG REJECT.
   1527  1.25       pk 				 * Print diagnostic if current phase
   1528  1.25       pk 				 * is not MESSAGE IN.
   1529  1.25       pk 				 */
   1530  1.25       pk 				if (sc->sc_phase != MESSAGE_IN_PHASE)
   1531  1.25       pk 				    printf("%s: !TC on MSG OUT"
   1532  1.25       pk 				       " [intr %x, stat %x, step %d]"
   1533  1.34  thorpej 				       " prevphase %x, resid %lx\n",
   1534  1.25       pk 					sc->sc_dev.dv_xname,
   1535  1.25       pk 					sc->sc_espintr,
   1536  1.25       pk 					sc->sc_espstat,
   1537  1.25       pk 					sc->sc_espstep,
   1538  1.25       pk 					sc->sc_prevphase,
   1539  1.34  thorpej 					(u_long)sc->sc_omlen);
   1540  1.25       pk 			} else if (sc->sc_dleft == 0) {
   1541  1.22       pk 				/*
   1542  1.25       pk 				 * The DMA operation was started for
   1543  1.25       pk 				 * a DATA transfer. Print a diagnostic
   1544  1.25       pk 				 * if the DMA counter and TC bit
   1545  1.25       pk 				 * appear to be out of sync.
   1546  1.22       pk 				 */
   1547  1.25       pk 				printf("%s: !TC on DATA XFER"
   1548  1.25       pk 				       " [intr %x, stat %x, step %d]"
   1549  1.25       pk 				       " prevphase %x, resid %x\n",
   1550  1.25       pk 					sc->sc_dev.dv_xname,
   1551  1.25       pk 					sc->sc_espintr,
   1552  1.25       pk 					sc->sc_espstat,
   1553  1.25       pk 					sc->sc_espstep,
   1554  1.25       pk 					sc->sc_prevphase,
   1555  1.25       pk 					ecb?ecb->dleft:-1);
   1556  1.22       pk 			}
   1557   1.1  thorpej 		}
   1558  1.25       pk 	}
   1559  1.25       pk 
   1560  1.25       pk 	/*
   1561  1.25       pk 	 * Check for less serious errors.
   1562  1.25       pk 	 */
   1563  1.25       pk 	if (sc->sc_espstat & NCRSTAT_PE) {
   1564  1.25       pk 		printf("%s: SCSI bus parity error\n", sc->sc_dev.dv_xname);
   1565  1.25       pk 		if (sc->sc_prevphase == MESSAGE_IN_PHASE)
   1566  1.25       pk 			ncr53c9x_sched_msgout(SEND_PARITY_ERROR);
   1567  1.25       pk 		else
   1568  1.25       pk 			ncr53c9x_sched_msgout(SEND_INIT_DET_ERR);
   1569  1.25       pk 	}
   1570   1.1  thorpej 
   1571  1.25       pk 	if (sc->sc_espintr & NCRINTR_DIS) {
   1572  1.25       pk 		NCR_MISC(("<DISC [intr %x, stat %x, step %d]>",
   1573  1.25       pk 			sc->sc_espintr,sc->sc_espstat,sc->sc_espstep));
   1574  1.25       pk 		if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) {
   1575  1.25       pk 			NCRCMD(sc, NCRCMD_FLUSH);
   1576  1.25       pk 			DELAY(1);
   1577   1.1  thorpej 		}
   1578   1.1  thorpej 		/*
   1579  1.25       pk 		 * This command must (apparently) be issued within
   1580  1.25       pk 		 * 250mS of a disconnect. So here you are...
   1581   1.1  thorpej 		 */
   1582  1.25       pk 		NCRCMD(sc, NCRCMD_ENSEL);
   1583   1.1  thorpej 
   1584  1.25       pk 		switch (sc->sc_state) {
   1585  1.25       pk 		case NCR_RESELECTED:
   1586  1.25       pk 			goto sched;
   1587  1.22       pk 
   1588  1.25       pk 		case NCR_SELECTING:
   1589  1.25       pk 			ecb->xs->error = XS_SELTIMEOUT;
   1590  1.25       pk 			goto finish;
   1591   1.1  thorpej 
   1592  1.25       pk 		case NCR_CONNECTED:
   1593  1.25       pk 			if ((sc->sc_flags & NCR_SYNCHNEGO)) {
   1594   1.1  thorpej #ifdef NCR53C9X_DEBUG
   1595  1.25       pk 				if (ecb)
   1596  1.25       pk 					scsi_print_addr(ecb->xs->sc_link);
   1597  1.25       pk 				printf("sync nego not completed!\n");
   1598   1.1  thorpej #endif
   1599  1.25       pk 				ti = &sc->sc_tinfo[ecb->xs->sc_link->scsipi_scsi.target];
   1600  1.25       pk 				sc->sc_flags &= ~NCR_SYNCHNEGO;
   1601  1.25       pk 				ti->flags &= ~(T_NEGOTIATE | T_SYNCMODE);
   1602  1.25       pk 			}
   1603   1.1  thorpej 
   1604  1.25       pk 			/* it may be OK to disconnect */
   1605  1.25       pk 			if ((sc->sc_flags & NCR_ABORTING) == 0) {
   1606  1.25       pk 				/*
   1607  1.25       pk 				 * Section 5.1.1 of the SCSI 2 spec
   1608  1.25       pk 				 * suggests issuing a REQUEST SENSE
   1609  1.25       pk 				 * following an unexpected disconnect.
   1610  1.25       pk 				 * Some devices go into a contingent
   1611  1.25       pk 				 * allegiance condition when
   1612  1.25       pk 				 * disconnecting, and this is necessary
   1613  1.25       pk 				 * to clean up their state.
   1614  1.25       pk 				 */
   1615  1.25       pk 				printf("%s: unexpected disconnect; ",
   1616  1.25       pk 				    sc->sc_dev.dv_xname);
   1617  1.25       pk 				if (ecb->flags & ECB_SENSE) {
   1618  1.25       pk 					printf("resetting\n");
   1619  1.25       pk 					goto reset;
   1620   1.1  thorpej 				}
   1621  1.25       pk 				printf("sending REQUEST SENSE\n");
   1622  1.25       pk 				untimeout(ncr53c9x_timeout, ecb);
   1623  1.25       pk 				ncr53c9x_sense(sc, ecb);
   1624  1.25       pk 				goto out;
   1625  1.25       pk 			}
   1626   1.1  thorpej 
   1627  1.25       pk 			ecb->xs->error = XS_TIMEOUT;
   1628  1.25       pk 			goto finish;
   1629   1.1  thorpej 
   1630  1.25       pk 		case NCR_DISCONNECT:
   1631  1.25       pk 			TAILQ_INSERT_HEAD(&sc->nexus_list, ecb, chain);
   1632  1.25       pk 			sc->sc_nexus = NULL;
   1633  1.25       pk 			goto sched;
   1634   1.1  thorpej 
   1635  1.25       pk 		case NCR_CMDCOMPLETE:
   1636  1.25       pk 			goto finish;
   1637   1.1  thorpej 		}
   1638  1.25       pk 	}
   1639   1.1  thorpej 
   1640  1.25       pk 	switch (sc->sc_state) {
   1641  1.25       pk 
   1642  1.25       pk 	case NCR_SBR:
   1643  1.25       pk 		printf("%s: waiting for SCSI Bus Reset to happen\n",
   1644  1.25       pk 			sc->sc_dev.dv_xname);
   1645  1.25       pk 		return (1);
   1646   1.1  thorpej 
   1647  1.25       pk 	case NCR_RESELECTED:
   1648  1.25       pk 		/*
   1649  1.25       pk 		 * we must be continuing a message ?
   1650  1.25       pk 		 */
   1651  1.25       pk 		if (sc->sc_phase != MESSAGE_IN_PHASE) {
   1652  1.25       pk 			printf("%s: target didn't identify\n",
   1653   1.1  thorpej 				sc->sc_dev.dv_xname);
   1654  1.25       pk 			ncr53c9x_init(sc, 1);
   1655  1.25       pk 			return (1);
   1656  1.25       pk 		}
   1657  1.25       pk printf("<<RESELECT CONT'd>>");
   1658  1.25       pk #if XXXX
   1659  1.25       pk 		ncr53c9x_msgin(sc);
   1660  1.25       pk 		if (sc->sc_state != NCR_CONNECTED) {
   1661  1.25       pk 			/* IDENTIFY fail?! */
   1662  1.25       pk 			printf("%s: identify failed\n",
   1663  1.25       pk 				sc->sc_dev.dv_xname);
   1664  1.25       pk 			ncr53c9x_init(sc, 1);
   1665  1.25       pk 			return (1);
   1666  1.25       pk 		}
   1667  1.25       pk #endif
   1668  1.25       pk 		break;
   1669  1.25       pk 
   1670  1.25       pk 	case NCR_IDLE:
   1671  1.25       pk 	case NCR_SELECTING:
   1672  1.25       pk 		sc->sc_msgpriq = sc->sc_msgout = sc->sc_msgoutq = 0;
   1673  1.25       pk 		sc->sc_flags = 0;
   1674  1.25       pk 		ecb = sc->sc_nexus;
   1675  1.25       pk 		if (ecb != NULL && (ecb->flags & ECB_NEXUS)) {
   1676  1.25       pk 			scsi_print_addr(ecb->xs->sc_link);
   1677  1.25       pk 			printf("ECB_NEXUS while in state %x\n", sc->sc_state);
   1678  1.25       pk 		}
   1679   1.1  thorpej 
   1680  1.25       pk 		if (sc->sc_espintr & NCRINTR_RESEL) {
   1681   1.1  thorpej 			/*
   1682  1.25       pk 			 * If we're trying to select a
   1683  1.25       pk 			 * target ourselves, push our command
   1684  1.25       pk 			 * back into the ready list.
   1685   1.1  thorpej 			 */
   1686  1.25       pk 			if (sc->sc_state == NCR_SELECTING) {
   1687  1.25       pk 				NCR_MISC(("backoff selector "));
   1688  1.25       pk 				untimeout(ncr53c9x_timeout, ecb);
   1689  1.25       pk 				sc_link = ecb->xs->sc_link;
   1690  1.25       pk 				ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
   1691  1.25       pk 				TAILQ_INSERT_HEAD(&sc->ready_list, ecb, chain);
   1692  1.25       pk 				ecb = sc->sc_nexus = NULL;
   1693  1.25       pk 			}
   1694  1.25       pk 			sc->sc_state = NCR_RESELECTED;
   1695   1.1  thorpej 			if (sc->sc_phase != MESSAGE_IN_PHASE) {
   1696  1.25       pk 				/*
   1697  1.25       pk 				 * Things are seriously fucked up.
   1698  1.25       pk 				 * Pull the brakes, i.e. reset
   1699  1.25       pk 				 */
   1700   1.1  thorpej 				printf("%s: target didn't identify\n",
   1701   1.1  thorpej 					sc->sc_dev.dv_xname);
   1702   1.1  thorpej 				ncr53c9x_init(sc, 1);
   1703  1.25       pk 				return (1);
   1704   1.1  thorpej 			}
   1705  1.25       pk 			/*
   1706  1.25       pk 			 * The C90 only inhibits FIFO writes until
   1707  1.25       pk 			 * reselection is complete, instead of
   1708  1.25       pk 			 * waiting until the interrupt status register
   1709  1.25       pk 			 * has been read. So, if the reselect happens
   1710  1.25       pk 			 * while we were entering a command bytes (for
   1711  1.25       pk 			 * another target) some of those bytes can
   1712  1.25       pk 			 * appear in the FIFO here, after the
   1713  1.25       pk 			 * interrupt is taken.
   1714  1.25       pk 			 */
   1715  1.25       pk 			nfifo = NCR_READ_REG(sc,NCR_FFLAG) & NCRFIFO_FF;
   1716  1.25       pk 			if (nfifo < 2 ||
   1717  1.25       pk 			    (nfifo > 2 &&
   1718  1.25       pk 			     sc->sc_rev != NCR_VARIANT_ESP100)) {
   1719  1.25       pk 				printf("%s: RESELECT: %d bytes in FIFO! "
   1720  1.25       pk 				    "[intr %x, stat %x, step %d, prevphase %x]\n",
   1721  1.25       pk 					sc->sc_dev.dv_xname,
   1722  1.25       pk 					nfifo,
   1723  1.25       pk 					sc->sc_espintr,
   1724  1.25       pk 					sc->sc_espstat,
   1725  1.25       pk 					sc->sc_espstep,
   1726  1.25       pk 					sc->sc_prevphase);
   1727  1.25       pk 				ncr53c9x_init(sc, 1);
   1728  1.25       pk 				return (1);
   1729  1.25       pk 			}
   1730  1.25       pk 			sc->sc_selid = NCR_READ_REG(sc, NCR_FIFO);
   1731  1.25       pk 			NCR_MISC(("selid=0x%2x ", sc->sc_selid));
   1732  1.25       pk 
   1733  1.25       pk 			/* Handle identify message */
   1734   1.1  thorpej 			ncr53c9x_msgin(sc);
   1735  1.25       pk 			if (nfifo != 2) {
   1736  1.25       pk 				/*
   1737  1.25       pk 				 * Note: this should not happen
   1738  1.25       pk 				 * with `dmaselect' on.
   1739  1.25       pk 				 */
   1740  1.25       pk 				sc->sc_flags |= NCR_EXPECT_ILLCMD;
   1741  1.25       pk 				NCRCMD(sc, NCRCMD_FLUSH);
   1742  1.25       pk 			} else if (ncr53c9x_dmaselect &&
   1743  1.25       pk 				   sc->sc_rev == NCR_VARIANT_ESP100) {
   1744  1.25       pk 				sc->sc_flags |= NCR_EXPECT_ILLCMD;
   1745  1.25       pk 			}
   1746  1.25       pk 
   1747   1.1  thorpej 			if (sc->sc_state != NCR_CONNECTED) {
   1748   1.1  thorpej 				/* IDENTIFY fail?! */
   1749   1.1  thorpej 				printf("%s: identify failed\n",
   1750   1.1  thorpej 					sc->sc_dev.dv_xname);
   1751   1.1  thorpej 				ncr53c9x_init(sc, 1);
   1752  1.25       pk 				return (1);
   1753   1.1  thorpej 			}
   1754  1.25       pk 			goto shortcut; /* ie. next phase expected soon */
   1755  1.25       pk 		}
   1756   1.1  thorpej 
   1757  1.25       pk #define	NCRINTR_DONE	(NCRINTR_FC|NCRINTR_BS)
   1758  1.25       pk 		if ((sc->sc_espintr & NCRINTR_DONE) == NCRINTR_DONE) {
   1759  1.25       pk 			/*
   1760  1.25       pk 			 * Arbitration won; examine the `step' register
   1761  1.25       pk 			 * to determine how far the selection could progress.
   1762  1.25       pk 			 */
   1763   1.7      gwr 			ecb = sc->sc_nexus;
   1764  1.25       pk 			if (!ecb)
   1765  1.30       pk 				panic("ncr53c9x: no nexus");
   1766  1.25       pk 
   1767  1.25       pk 			sc_link = ecb->xs->sc_link;
   1768  1.25       pk 			ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
   1769   1.1  thorpej 
   1770  1.25       pk 			switch (sc->sc_espstep) {
   1771  1.25       pk 			case 0:
   1772   1.1  thorpej 				/*
   1773  1.25       pk 				 * The target did not respond with a
   1774  1.25       pk 				 * message out phase - probably an old
   1775  1.25       pk 				 * device that doesn't recognize ATN.
   1776  1.25       pk 				 * Clear ATN and just continue, the
   1777  1.25       pk 				 * target should be in the command
   1778  1.25       pk 				 * phase.
   1779  1.25       pk 				 * XXXX check for command phase?
   1780   1.1  thorpej 				 */
   1781  1.25       pk 				NCRCMD(sc, NCRCMD_RSTATN);
   1782  1.25       pk 				break;
   1783  1.25       pk 			case 1:
   1784  1.25       pk 				if ((ti->flags & T_NEGOTIATE) == 0) {
   1785  1.25       pk 					printf("%s: step 1 & !NEG\n",
   1786  1.25       pk 						sc->sc_dev.dv_xname);
   1787  1.25       pk 					goto reset;
   1788   1.1  thorpej 				}
   1789  1.25       pk 				if (sc->sc_phase != MESSAGE_OUT_PHASE) {
   1790  1.25       pk 					printf("%s: !MSGOUT\n",
   1791   1.1  thorpej 						sc->sc_dev.dv_xname);
   1792  1.25       pk 					goto reset;
   1793   1.1  thorpej 				}
   1794  1.25       pk 				/* Start negotiating */
   1795  1.25       pk 				ti->period = sc->sc_minsync;
   1796  1.25       pk 				ti->offset = 15;
   1797  1.25       pk 				sc->sc_flags |= NCR_SYNCHNEGO;
   1798  1.25       pk 				ncr53c9x_sched_msgout(SEND_SDTR);
   1799  1.25       pk 				break;
   1800  1.25       pk 			case 3:
   1801   1.5       pk 				/*
   1802  1.25       pk 				 * Grr, this is supposed to mean
   1803  1.25       pk 				 * "target left command phase  prematurely".
   1804  1.25       pk 				 * It seems to happen regularly when
   1805  1.25       pk 				 * sync mode is on.
   1806  1.25       pk 				 * Look at FIFO to see if command went out.
   1807  1.25       pk 				 * (Timing problems?)
   1808   1.5       pk 				 */
   1809  1.25       pk 				if (ncr53c9x_dmaselect) {
   1810  1.25       pk 					if (sc->sc_cmdlen == 0)
   1811   1.8       pk 						/* Hope for the best.. */
   1812   1.8       pk 						break;
   1813  1.25       pk 				} else if ((NCR_READ_REG(sc, NCR_FFLAG)
   1814   1.1  thorpej 					    & NCRFIFO_FF) == 0) {
   1815  1.25       pk 					/* Hope for the best.. */
   1816   1.1  thorpej 					break;
   1817   1.1  thorpej 				}
   1818  1.25       pk 				printf("(%s:%d:%d): selection failed;"
   1819  1.25       pk 					" %d left in FIFO "
   1820  1.25       pk 					"[intr %x, stat %x, step %d]\n",
   1821   1.1  thorpej 					sc->sc_dev.dv_xname,
   1822  1.25       pk 					sc_link->scsipi_scsi.target,
   1823  1.25       pk 					sc_link->scsipi_scsi.lun,
   1824  1.25       pk 					NCR_READ_REG(sc, NCR_FFLAG)
   1825  1.25       pk 					 & NCRFIFO_FF,
   1826   1.1  thorpej 					sc->sc_espintr, sc->sc_espstat,
   1827   1.1  thorpej 					sc->sc_espstep);
   1828   1.1  thorpej 				NCRCMD(sc, NCRCMD_FLUSH);
   1829  1.25       pk 				ncr53c9x_sched_msgout(SEND_ABORT);
   1830  1.25       pk 				return (1);
   1831  1.25       pk 			case 2:
   1832  1.25       pk 				/* Select stuck at Command Phase */
   1833  1.25       pk 				NCRCMD(sc, NCRCMD_FLUSH);
   1834  1.37  mycroft 				break;
   1835  1.25       pk 			case 4:
   1836  1.25       pk 				if (ncr53c9x_dmaselect &&
   1837  1.25       pk 				    sc->sc_cmdlen != 0)
   1838  1.25       pk 					printf("(%s:%d:%d): select; "
   1839  1.34  thorpej 					       "%lu left in DMA buffer "
   1840  1.25       pk 					"[intr %x, stat %x, step %d]\n",
   1841  1.25       pk 						sc->sc_dev.dv_xname,
   1842  1.25       pk 						sc_link->scsipi_scsi.target,
   1843  1.25       pk 						sc_link->scsipi_scsi.lun,
   1844  1.34  thorpej 						(u_long)sc->sc_cmdlen,
   1845  1.25       pk 						sc->sc_espintr,
   1846  1.25       pk 						sc->sc_espstat,
   1847  1.25       pk 						sc->sc_espstep);
   1848  1.25       pk 				/* So far, everything went fine */
   1849  1.25       pk 				break;
   1850   1.1  thorpej 			}
   1851  1.25       pk 
   1852  1.25       pk 			ecb->flags |= ECB_NEXUS;
   1853  1.25       pk 			ti->lubusy |= (1 << sc_link->scsipi_scsi.lun);
   1854  1.25       pk 
   1855  1.25       pk 			sc->sc_prevphase = INVALID_PHASE; /* ?? */
   1856  1.25       pk 			/* Do an implicit RESTORE POINTERS. */
   1857  1.25       pk 			sc->sc_dp = ecb->daddr;
   1858  1.25       pk 			sc->sc_dleft = ecb->dleft;
   1859  1.25       pk 			sc->sc_state = NCR_CONNECTED;
   1860   1.1  thorpej 			break;
   1861   1.1  thorpej 
   1862  1.25       pk 		} else {
   1863   1.1  thorpej 
   1864  1.25       pk 			printf("%s: unexpected status after select"
   1865  1.25       pk 				": [intr %x, stat %x, step %x]\n",
   1866  1.25       pk 				sc->sc_dev.dv_xname,
   1867  1.25       pk 				sc->sc_espintr, sc->sc_espstat,
   1868  1.25       pk 				sc->sc_espstep);
   1869  1.25       pk 			NCRCMD(sc, NCRCMD_FLUSH);
   1870  1.25       pk 			DELAY(1);
   1871  1.25       pk 			goto reset;
   1872   1.1  thorpej 		}
   1873  1.25       pk 		if (sc->sc_state == NCR_IDLE) {
   1874  1.25       pk 			printf("%s: stray interrupt\n",
   1875  1.25       pk 			    sc->sc_dev.dv_xname);
   1876  1.25       pk 				return (0);
   1877   1.1  thorpej 		}
   1878  1.25       pk 		break;
   1879   1.1  thorpej 
   1880  1.25       pk 	case NCR_CONNECTED:
   1881  1.25       pk 		if (sc->sc_flags & NCR_ICCS) {
   1882  1.25       pk 			/* "Initiate Command Complete Steps" in progress */
   1883  1.25       pk 			u_char msg;
   1884  1.25       pk 
   1885  1.25       pk 			sc->sc_flags &= ~NCR_ICCS;
   1886  1.25       pk 
   1887  1.25       pk 			if (!(sc->sc_espintr & NCRINTR_DONE)) {
   1888  1.25       pk 				printf("%s: ICCS: "
   1889  1.25       pk 				      ": [intr %x, stat %x, step %x]\n",
   1890   1.1  thorpej 					sc->sc_dev.dv_xname,
   1891   1.1  thorpej 					sc->sc_espintr, sc->sc_espstat,
   1892   1.1  thorpej 					sc->sc_espstep);
   1893   1.1  thorpej 			}
   1894  1.25       pk 			if ((NCR_READ_REG(sc, NCR_FFLAG)
   1895  1.25       pk 			    & NCRFIFO_FF) != 2) {
   1896  1.25       pk 				int i = (NCR_READ_REG(sc, NCR_FFLAG)
   1897  1.25       pk 					    & NCRFIFO_FF) - 2;
   1898  1.25       pk 				while (i--)
   1899  1.25       pk 					(void) NCR_READ_REG(sc, NCR_FIFO);
   1900   1.1  thorpej 			}
   1901  1.25       pk 			ecb->stat = NCR_READ_REG(sc, NCR_FIFO);
   1902  1.25       pk 			msg = NCR_READ_REG(sc, NCR_FIFO);
   1903  1.25       pk 			NCR_PHASE(("<stat:(%x,%x)>", ecb->stat, msg));
   1904  1.25       pk 			if (msg == MSG_CMDCOMPLETE) {
   1905  1.25       pk 				ecb->dleft = (ecb->flags & ECB_TENTATIVE_DONE)
   1906  1.25       pk 					? 0
   1907  1.25       pk 					: sc->sc_dleft;
   1908  1.25       pk 				if ((ecb->flags & ECB_SENSE) == 0)
   1909  1.25       pk 					ecb->xs->resid = ecb->dleft;
   1910  1.25       pk 				sc->sc_state = NCR_CMDCOMPLETE;
   1911  1.25       pk 			} else
   1912  1.25       pk 				printf("%s: STATUS_PHASE: msg %d\n",
   1913  1.25       pk 					sc->sc_dev.dv_xname, msg);
   1914  1.25       pk 			NCRCMD(sc, NCRCMD_MSGOK);
   1915  1.25       pk 			goto shortcut; /* ie. wait for disconnect */
   1916  1.25       pk 		}
   1917  1.25       pk 		break;
   1918  1.25       pk 	default:
   1919  1.25       pk 		panic("%s: invalid state: %d",
   1920  1.25       pk 		      sc->sc_dev.dv_xname,
   1921  1.25       pk 		      sc->sc_state);
   1922  1.25       pk 	}
   1923   1.8       pk 
   1924  1.25       pk 	/*
   1925  1.25       pk 	 * Driver is now in state NCR_CONNECTED, i.e. we
   1926  1.25       pk 	 * have a current command working the SCSI bus.
   1927  1.25       pk 	 */
   1928  1.25       pk 	if (sc->sc_state != NCR_CONNECTED || ecb == NULL) {
   1929  1.30       pk 		panic("ncr53c9x: no nexus");
   1930  1.25       pk 	}
   1931  1.22       pk 
   1932  1.25       pk 	switch (sc->sc_phase) {
   1933  1.25       pk 	case MESSAGE_OUT_PHASE:
   1934  1.25       pk 		NCR_PHASE(("MESSAGE_OUT_PHASE "));
   1935  1.25       pk 		ncr53c9x_msgout(sc);
   1936  1.25       pk 		sc->sc_prevphase = MESSAGE_OUT_PHASE;
   1937  1.25       pk 		break;
   1938  1.25       pk 	case MESSAGE_IN_PHASE:
   1939  1.25       pk 		NCR_PHASE(("MESSAGE_IN_PHASE "));
   1940  1.25       pk 		sc->sc_prevphase = MESSAGE_IN_PHASE;
   1941  1.25       pk 		if (sc->sc_espintr & NCRINTR_BS) {
   1942  1.25       pk 			NCRCMD(sc, NCRCMD_FLUSH);
   1943  1.25       pk 			sc->sc_flags |= NCR_WAITI;
   1944  1.25       pk 			NCRCMD(sc, NCRCMD_TRANS);
   1945  1.25       pk 		} else if (sc->sc_espintr & NCRINTR_FC) {
   1946  1.25       pk 			if ((sc->sc_flags & NCR_WAITI) == 0) {
   1947  1.25       pk 				printf("%s: MSGIN: unexpected FC bit: "
   1948  1.25       pk 					"[intr %x, stat %x, step %x]\n",
   1949  1.25       pk 				sc->sc_dev.dv_xname,
   1950  1.25       pk 				sc->sc_espintr, sc->sc_espstat,
   1951  1.25       pk 				sc->sc_espstep);
   1952   1.8       pk 			}
   1953  1.25       pk 			sc->sc_flags &= ~NCR_WAITI;
   1954  1.25       pk 			ncr53c9x_msgin(sc);
   1955  1.25       pk 		} else {
   1956  1.25       pk 			printf("%s: MSGIN: weird bits: "
   1957  1.25       pk 				"[intr %x, stat %x, step %x]\n",
   1958  1.25       pk 				sc->sc_dev.dv_xname,
   1959  1.25       pk 				sc->sc_espintr, sc->sc_espstat,
   1960  1.25       pk 				sc->sc_espstep);
   1961  1.25       pk 		}
   1962  1.25       pk 		goto shortcut;	/* i.e. expect data to be ready */
   1963  1.25       pk 		break;
   1964  1.25       pk 	case COMMAND_PHASE:
   1965  1.25       pk 		/*
   1966  1.25       pk 		 * Send the command block. Normally we don't see this
   1967  1.25       pk 		 * phase because the SEL_ATN command takes care of
   1968  1.25       pk 		 * all this. However, we end up here if either the
   1969  1.25       pk 		 * target or we wanted to exchange some more messages
   1970  1.25       pk 		 * first (e.g. to start negotiations).
   1971  1.25       pk 		 */
   1972  1.25       pk 
   1973  1.25       pk 		NCR_PHASE(("COMMAND_PHASE 0x%02x (%d) ",
   1974  1.25       pk 			ecb->cmd.cmd.opcode, ecb->clen));
   1975  1.25       pk 		if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) {
   1976   1.1  thorpej 			NCRCMD(sc, NCRCMD_FLUSH);
   1977  1.25       pk 			DELAY(1);
   1978  1.25       pk 		}
   1979  1.25       pk 		if (ncr53c9x_dmaselect) {
   1980  1.25       pk 			size_t size;
   1981  1.25       pk 			/* setup DMA transfer for command */
   1982  1.25       pk 			size = ecb->clen;
   1983  1.25       pk 			sc->sc_cmdlen = size;
   1984  1.25       pk 			sc->sc_cmdp = (caddr_t)&ecb->cmd.cmd;
   1985  1.25       pk 			NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen,
   1986  1.25       pk 				     0, &size);
   1987   1.1  thorpej 			/* Program the SCSI counter */
   1988   1.1  thorpej 			NCR_WRITE_REG(sc, NCR_TCL, size);
   1989   1.1  thorpej 			NCR_WRITE_REG(sc, NCR_TCM, size >> 8);
   1990   1.1  thorpej 			if (sc->sc_cfg2 & NCRCFG2_FE) {
   1991   1.1  thorpej 				NCR_WRITE_REG(sc, NCR_TCH, size >> 16);
   1992   1.1  thorpej 			}
   1993  1.25       pk 
   1994   1.1  thorpej 			/* load the count in */
   1995   1.1  thorpej 			NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA);
   1996   1.1  thorpej 
   1997  1.25       pk 			/* start the command transfer */
   1998  1.25       pk 			NCRCMD(sc, NCRCMD_TRANS | NCRCMD_DMA);
   1999   1.1  thorpej 			NCRDMA_GO(sc);
   2000  1.25       pk 		} else {
   2001  1.25       pk 			u_char *cmd = (u_char *)&ecb->cmd.cmd;
   2002  1.25       pk 			int i;
   2003  1.25       pk 			/* Now the command into the FIFO */
   2004  1.25       pk 			for (i = 0; i < ecb->clen; i++)
   2005  1.25       pk 				NCR_WRITE_REG(sc, NCR_FIFO, *cmd++);
   2006  1.25       pk 			NCRCMD(sc, NCRCMD_TRANS);
   2007  1.25       pk 		}
   2008  1.25       pk 		sc->sc_prevphase = COMMAND_PHASE;
   2009  1.25       pk 		break;
   2010  1.25       pk 	case DATA_OUT_PHASE:
   2011  1.25       pk 		NCR_PHASE(("DATA_OUT_PHASE [%ld] ",(long)sc->sc_dleft));
   2012  1.25       pk 		NCRCMD(sc, NCRCMD_FLUSH);
   2013  1.25       pk 		size = min(sc->sc_dleft, sc->sc_maxxfer);
   2014  1.25       pk 		NCRDMA_SETUP(sc, &sc->sc_dp, &sc->sc_dleft,
   2015  1.25       pk 			  0, &size);
   2016  1.25       pk 		sc->sc_prevphase = DATA_OUT_PHASE;
   2017  1.25       pk 		goto setup_xfer;
   2018  1.25       pk 	case DATA_IN_PHASE:
   2019  1.25       pk 		NCR_PHASE(("DATA_IN_PHASE "));
   2020  1.25       pk 		if (sc->sc_rev == NCR_VARIANT_ESP100)
   2021  1.25       pk 			NCRCMD(sc, NCRCMD_FLUSH);
   2022  1.25       pk 		size = min(sc->sc_dleft, sc->sc_maxxfer);
   2023  1.25       pk 		NCRDMA_SETUP(sc, &sc->sc_dp, &sc->sc_dleft,
   2024  1.25       pk 			  1, &size);
   2025  1.25       pk 		sc->sc_prevphase = DATA_IN_PHASE;
   2026  1.25       pk 	setup_xfer:
   2027  1.25       pk 		/* Target returned to data phase: wipe "done" memory */
   2028  1.25       pk 		ecb->flags &= ~ECB_TENTATIVE_DONE;
   2029  1.25       pk 
   2030  1.25       pk 		/* Program the SCSI counter */
   2031  1.25       pk 		NCR_WRITE_REG(sc, NCR_TCL, size);
   2032  1.25       pk 		NCR_WRITE_REG(sc, NCR_TCM, size >> 8);
   2033  1.25       pk 		if (sc->sc_cfg2 & NCRCFG2_FE) {
   2034  1.25       pk 			NCR_WRITE_REG(sc, NCR_TCH, size >> 16);
   2035   1.1  thorpej 		}
   2036  1.25       pk 		/* load the count in */
   2037  1.25       pk 		NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA);
   2038  1.25       pk 
   2039  1.25       pk 		/*
   2040  1.25       pk 		 * Note that if `size' is 0, we've already transceived
   2041  1.25       pk 		 * all the bytes we want but we're still in DATA PHASE.
   2042  1.25       pk 		 * Apparently, the device needs padding. Also, a
   2043  1.25       pk 		 * transfer size of 0 means "maximum" to the chip
   2044  1.25       pk 		 * DMA logic.
   2045  1.25       pk 		 */
   2046  1.25       pk 		NCRCMD(sc,
   2047  1.25       pk 		       (size==0?NCRCMD_TRPAD:NCRCMD_TRANS)|NCRCMD_DMA);
   2048  1.25       pk 		NCRDMA_GO(sc);
   2049  1.25       pk 		return (1);
   2050  1.25       pk 	case STATUS_PHASE:
   2051  1.25       pk 		NCR_PHASE(("STATUS_PHASE "));
   2052  1.25       pk 		sc->sc_flags |= NCR_ICCS;
   2053  1.25       pk 		NCRCMD(sc, NCRCMD_ICCS);
   2054  1.25       pk 		sc->sc_prevphase = STATUS_PHASE;
   2055  1.25       pk 		goto shortcut;	/* i.e. expect status results soon */
   2056  1.25       pk 		break;
   2057  1.25       pk 	case INVALID_PHASE:
   2058  1.25       pk 		break;
   2059  1.25       pk 	default:
   2060  1.25       pk 		printf("%s: unexpected bus phase; resetting\n",
   2061  1.25       pk 		    sc->sc_dev.dv_xname);
   2062  1.25       pk 		goto reset;
   2063   1.1  thorpej 	}
   2064  1.25       pk 
   2065  1.25       pk out:
   2066  1.25       pk 	return (1);
   2067   1.1  thorpej 
   2068   1.1  thorpej reset:
   2069   1.1  thorpej 	ncr53c9x_init(sc, 1);
   2070  1.25       pk 	goto out;
   2071   1.1  thorpej 
   2072   1.1  thorpej finish:
   2073   1.1  thorpej 	ncr53c9x_done(sc, ecb);
   2074   1.1  thorpej 	goto out;
   2075   1.1  thorpej 
   2076   1.1  thorpej sched:
   2077   1.1  thorpej 	sc->sc_state = NCR_IDLE;
   2078   1.1  thorpej 	ncr53c9x_sched(sc);
   2079   1.1  thorpej 	goto out;
   2080   1.1  thorpej 
   2081  1.25       pk shortcut:
   2082  1.25       pk 	/*
   2083  1.25       pk 	 * The idea is that many of the SCSI operations take very little
   2084  1.25       pk 	 * time, and going away and getting interrupted is too high an
   2085  1.25       pk 	 * overhead to pay. For example, selecting, sending a message
   2086  1.25       pk 	 * and command and then doing some work can be done in one "pass".
   2087  1.25       pk 	 *
   2088  1.25       pk 	 * The delay is a heuristic. It is 2 when at 20Mhz, 2 at 25Mhz and 1
   2089  1.25       pk 	 * at 40Mhz. This needs testing.
   2090  1.25       pk 	 */
   2091  1.25       pk 	DELAY(50/sc->sc_freq);
   2092  1.25       pk 	if (NCRDMA_ISINTR(sc))
   2093  1.25       pk 		goto again;
   2094  1.25       pk 	goto out;
   2095   1.1  thorpej }
   2096   1.1  thorpej 
   2097   1.1  thorpej void
   2098   1.1  thorpej ncr53c9x_abort(sc, ecb)
   2099   1.1  thorpej 	struct ncr53c9x_softc *sc;
   2100   1.1  thorpej 	struct ncr53c9x_ecb *ecb;
   2101   1.1  thorpej {
   2102   1.1  thorpej 
   2103   1.1  thorpej 	/* 2 secs for the abort */
   2104   1.1  thorpej 	ecb->timeout = NCR_ABORT_TIMEOUT;
   2105   1.1  thorpej 	ecb->flags |= ECB_ABORT;
   2106   1.1  thorpej 
   2107   1.1  thorpej 	if (ecb == sc->sc_nexus) {
   2108   1.1  thorpej 		/*
   2109   1.1  thorpej 		 * If we're still selecting, the message will be scheduled
   2110   1.1  thorpej 		 * after selection is complete.
   2111   1.1  thorpej 		 */
   2112   1.1  thorpej 		if (sc->sc_state == NCR_CONNECTED)
   2113   1.1  thorpej 			ncr53c9x_sched_msgout(SEND_ABORT);
   2114   1.1  thorpej 
   2115   1.1  thorpej 		/*
   2116   1.1  thorpej 		 * Reschedule timeout. First, cancel a queued timeout (if any)
   2117   1.1  thorpej 		 * in case someone decides to call ncr53c9x_abort() from
   2118   1.1  thorpej 		 * elsewhere.
   2119   1.1  thorpej 		 */
   2120   1.1  thorpej 		untimeout(ncr53c9x_timeout, ecb);
   2121   1.1  thorpej 		timeout(ncr53c9x_timeout, ecb, (ecb->timeout * hz) / 1000);
   2122   1.1  thorpej 	} else {
   2123  1.23       pk 		/* The command should be on the nexus list */
   2124  1.23       pk 		if ((ecb->flags & ECB_NEXUS) == 0) {
   2125  1.23       pk 			scsi_print_addr(ecb->xs->sc_link);
   2126  1.23       pk 			printf("ncr53c9x_abort: not NEXUS\n");
   2127  1.23       pk 			ncr53c9x_init(sc, 1);
   2128  1.23       pk 		}
   2129  1.23       pk 		/*
   2130  1.23       pk 		 * Just leave the command on the nexus list.
   2131  1.23       pk 		 * XXX - what choice do we have but to reset the SCSI
   2132  1.23       pk 		 *	 eventually?
   2133  1.23       pk 		 */
   2134   1.1  thorpej 		if (sc->sc_state == NCR_IDLE)
   2135   1.1  thorpej 			ncr53c9x_sched(sc);
   2136   1.1  thorpej 	}
   2137   1.1  thorpej }
   2138   1.1  thorpej 
   2139   1.1  thorpej void
   2140   1.1  thorpej ncr53c9x_timeout(arg)
   2141   1.1  thorpej 	void *arg;
   2142   1.1  thorpej {
   2143   1.1  thorpej 	struct ncr53c9x_ecb *ecb = arg;
   2144  1.18   bouyer 	struct scsipi_xfer *xs = ecb->xs;
   2145  1.18   bouyer 	struct scsipi_link *sc_link = xs->sc_link;
   2146   1.1  thorpej 	struct ncr53c9x_softc *sc = sc_link->adapter_softc;
   2147  1.18   bouyer 	struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
   2148   1.1  thorpej 	int s;
   2149   1.1  thorpej 
   2150  1.18   bouyer 	scsi_print_addr(sc_link);
   2151   1.1  thorpej 	printf("%s: timed out [ecb %p (flags 0x%x, dleft %x, stat %x)], "
   2152  1.23       pk 	       "<state %d, nexus %p, phase(l %x, c %x, p %x), resid %lx, "
   2153   1.1  thorpej 	       "msg(q %x,o %x) %s>",
   2154   1.1  thorpej 		sc->sc_dev.dv_xname,
   2155   1.1  thorpej 		ecb, ecb->flags, ecb->dleft, ecb->stat,
   2156  1.23       pk 		sc->sc_state, sc->sc_nexus,
   2157  1.23       pk 		NCR_READ_REG(sc, NCR_STAT),
   2158  1.23       pk 		sc->sc_phase, sc->sc_prevphase,
   2159   1.1  thorpej 		(long)sc->sc_dleft, sc->sc_msgpriq, sc->sc_msgout,
   2160   1.1  thorpej 		NCRDMA_ISACTIVE(sc) ? "DMA active" : "");
   2161   1.7      gwr #if NCR53C9X_DEBUG > 1
   2162   1.1  thorpej 	printf("TRACE: %s.", ecb->trace);
   2163   1.1  thorpej #endif
   2164   1.1  thorpej 
   2165   1.1  thorpej 	s = splbio();
   2166   1.1  thorpej 
   2167   1.1  thorpej 	if (ecb->flags & ECB_ABORT) {
   2168   1.1  thorpej 		/* abort timed out */
   2169   1.1  thorpej 		printf(" AGAIN\n");
   2170  1.16       pk 
   2171   1.1  thorpej 		ncr53c9x_init(sc, 1);
   2172   1.1  thorpej 	} else {
   2173   1.1  thorpej 		/* abort the operation that has timed out */
   2174   1.1  thorpej 		printf("\n");
   2175   1.1  thorpej 		xs->error = XS_TIMEOUT;
   2176   1.1  thorpej 		ncr53c9x_abort(sc, ecb);
   2177  1.16       pk 
   2178  1.16       pk 		/* Disable sync mode if stuck in a data phase */
   2179  1.16       pk 		if (ecb == sc->sc_nexus &&
   2180  1.16       pk 		    (ti->flags & T_SYNCMODE) != 0 &&
   2181  1.16       pk 		    (sc->sc_phase & (MSGI|CDI)) == 0) {
   2182  1.18   bouyer 			scsi_print_addr(sc_link);
   2183  1.16       pk 			printf("sync negotiation disabled\n");
   2184  1.18   bouyer 			sc->sc_cfflags |= (1<<(sc_link->scsipi_scsi.target+8));
   2185  1.16       pk 		}
   2186   1.1  thorpej 	}
   2187   1.1  thorpej 
   2188   1.1  thorpej 	splx(s);
   2189   1.1  thorpej }
   2190