Home | History | Annotate | Line # | Download | only in ic
ncr53c9x.c revision 1.70
      1  1.70       eeh /*	$NetBSD: ncr53c9x.c,v 1.70 2001/01/19 23:04:23 eeh 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.48   thorpej #include <sys/callout.h>
     83   1.1   thorpej #include <sys/kernel.h>
     84   1.1   thorpej #include <sys/errno.h>
     85   1.1   thorpej #include <sys/ioctl.h>
     86   1.1   thorpej #include <sys/device.h>
     87   1.1   thorpej #include <sys/buf.h>
     88  1.24        pk #include <sys/malloc.h>
     89  1.60  augustss #include <sys/proc.h>
     90   1.1   thorpej #include <sys/queue.h>
     91  1.54       eeh #include <sys/pool.h>
     92  1.53        pk #include <sys/scsiio.h>
     93   1.1   thorpej 
     94  1.18    bouyer #include <dev/scsipi/scsi_all.h>
     95  1.18    bouyer #include <dev/scsipi/scsipi_all.h>
     96  1.18    bouyer #include <dev/scsipi/scsiconf.h>
     97  1.18    bouyer #include <dev/scsipi/scsi_message.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.54       eeh #ifdef DEBUG
    104  1.54       eeh int ncr53c9x_notag = 0;
    105  1.54       eeh #endif
    106   1.1   thorpej 
    107  1.58        pk /*static*/ void	ncr53c9x_readregs(struct ncr53c9x_softc *);
    108  1.58        pk /*static*/ void	ncr53c9x_select(struct ncr53c9x_softc *, struct ncr53c9x_ecb *);
    109  1.58        pk /*static*/ int ncr53c9x_reselect(struct ncr53c9x_softc *, int, int, int);
    110  1.58        pk /*static*/ void	ncr53c9x_scsi_reset(struct ncr53c9x_softc *);
    111  1.58        pk /*static*/ int	ncr53c9x_poll(struct ncr53c9x_softc *,
    112  1.58        pk 			      struct scsipi_xfer *, int);
    113  1.58        pk /*static*/ void	ncr53c9x_sched(struct ncr53c9x_softc *);
    114  1.58        pk /*static*/ void	ncr53c9x_done(struct ncr53c9x_softc *, struct ncr53c9x_ecb *);
    115  1.58        pk /*static*/ void	ncr53c9x_msgin(struct ncr53c9x_softc *);
    116  1.58        pk /*static*/ void	ncr53c9x_msgout(struct ncr53c9x_softc *);
    117  1.58        pk /*static*/ void	ncr53c9x_timeout(void *arg);
    118  1.58        pk /*static*/ void	ncr53c9x_watch(void *arg);
    119  1.58        pk /*static*/ void	ncr53c9x_abort(struct ncr53c9x_softc *, struct ncr53c9x_ecb *);
    120  1.58        pk /*static*/ void ncr53c9x_dequeue(struct ncr53c9x_softc *, struct ncr53c9x_ecb *);
    121  1.58        pk /*static*/ int	ncr53c9x_ioctl(struct scsipi_link *, u_long,
    122  1.58        pk 			       caddr_t, int, struct proc *);
    123  1.58        pk 
    124  1.58        pk void ncr53c9x_sense(struct ncr53c9x_softc *, struct ncr53c9x_ecb *);
    125  1.58        pk void ncr53c9x_free_ecb(struct ncr53c9x_softc *, struct ncr53c9x_ecb *, int);
    126  1.58        pk struct ncr53c9x_ecb *ncr53c9x_get_ecb(struct ncr53c9x_softc *, int);
    127  1.58        pk 
    128  1.58        pk static inline int ncr53c9x_stp2cpb(struct ncr53c9x_softc *, int);
    129  1.58        pk static inline void ncr53c9x_setsync(struct ncr53c9x_softc *,
    130  1.58        pk 				    struct ncr53c9x_tinfo *);
    131  1.58        pk static struct ncr53c9x_linfo *ncr53c9x_lunsearch(struct ncr53c9x_tinfo *,
    132  1.58        pk 						 int64_t lun);
    133  1.58        pk 
    134  1.54       eeh static int ecb_pool_initialized = 0;
    135  1.54       eeh static struct pool ecb_pool;
    136   1.1   thorpej 
    137   1.1   thorpej /*
    138   1.1   thorpej  * Names for the NCR53c9x variants, correspnding to the variant tags
    139   1.1   thorpej  * in ncr53c9xvar.h.
    140   1.1   thorpej  */
    141  1.50  nisimura static const char *ncr53c9x_variant_names[] = {
    142   1.1   thorpej 	"ESP100",
    143   1.1   thorpej 	"ESP100A",
    144   1.1   thorpej 	"ESP200",
    145   1.1   thorpej 	"NCR53C94",
    146   1.2    briggs 	"NCR53C96",
    147  1.10        pk 	"ESP406",
    148  1.10        pk 	"FAS408",
    149  1.20    mhitch 	"FAS216",
    150  1.33   thorpej 	"AM53C974",
    151   1.1   thorpej };
    152   1.1   thorpej 
    153  1.50  nisimura static struct scsipi_adapter ncr53c9x_adapter = {
    154  1.50  nisimura 	0,			/* adapter refcnt */
    155  1.50  nisimura 	ncr53c9x_scsi_cmd,	/* cmd */
    156  1.50  nisimura 	minphys,		/* minphys */
    157  1.53        pk 	ncr53c9x_ioctl,		/* ioctl */
    158  1.51   tsutsui 	NULL,			/* enable */
    159  1.50  nisimura 	NULL,			/* getgeom */
    160  1.50  nisimura };
    161  1.50  nisimura 
    162  1.50  nisimura static struct scsipi_device ncr53c9x_device = {
    163  1.50  nisimura 	NULL,			/* use default error handler */
    164  1.50  nisimura 	NULL,			/* have a queue, served by this */
    165  1.50  nisimura 	NULL,			/* have no async handler */
    166  1.50  nisimura 	NULL,			/* use default 'done' routine */
    167  1.50  nisimura };
    168  1.50  nisimura 
    169   1.1   thorpej /*
    170  1.54       eeh  * Search linked list for LUN info by LUN id.
    171  1.54       eeh  */
    172  1.54       eeh static struct ncr53c9x_linfo *
    173  1.54       eeh ncr53c9x_lunsearch(ti, lun)
    174  1.54       eeh 	struct ncr53c9x_tinfo *ti;
    175  1.54       eeh 	int64_t lun;
    176  1.54       eeh {
    177  1.54       eeh 	struct ncr53c9x_linfo *li;
    178  1.54       eeh 	LIST_FOREACH(li, &ti->luns, link)
    179  1.54       eeh 		if (li->lun == lun)
    180  1.54       eeh 			return (li);
    181  1.54       eeh 	return (NULL);
    182  1.54       eeh }
    183  1.54       eeh 
    184  1.54       eeh /*
    185   1.1   thorpej  * Attach this instance, and then all the sub-devices
    186   1.1   thorpej  */
    187   1.1   thorpej void
    188  1.50  nisimura ncr53c9x_attach(sc, adapter, device)
    189   1.1   thorpej 	struct ncr53c9x_softc *sc;
    190  1.50  nisimura 	struct scsipi_adapter *adapter;
    191  1.50  nisimura 	struct scsipi_device *device;
    192   1.1   thorpej {
    193   1.1   thorpej 
    194  1.54       eeh 	callout_init(&sc->sc_watchdog);
    195   1.1   thorpej 	/*
    196  1.24        pk 	 * Allocate SCSI message buffers.
    197  1.24        pk 	 * Front-ends can override allocation to avoid alignment
    198  1.24        pk 	 * handling in the DMA engines. Note that that ncr53c9x_msgout()
    199  1.24        pk 	 * can request a 1 byte DMA transfer.
    200  1.24        pk 	 */
    201  1.24        pk 	if (sc->sc_omess == NULL)
    202  1.24        pk 		sc->sc_omess = malloc(NCR_MAX_MSG_LEN, M_DEVBUF, M_NOWAIT);
    203  1.24        pk 
    204  1.24        pk 	if (sc->sc_imess == NULL)
    205  1.24        pk 		sc->sc_imess = malloc(NCR_MAX_MSG_LEN+1, M_DEVBUF, M_NOWAIT);
    206  1.24        pk 
    207  1.24        pk 	if (sc->sc_omess == NULL || sc->sc_imess == NULL) {
    208  1.24        pk 		printf("out of memory\n");
    209  1.24        pk 		return;
    210  1.24        pk 	}
    211  1.24        pk 
    212  1.24        pk 	/*
    213   1.1   thorpej 	 * Note, the front-end has set us up to print the chip variation.
    214   1.1   thorpej 	 */
    215   1.1   thorpej 	if (sc->sc_rev >= NCR_VARIANT_MAX) {
    216   1.1   thorpej 		printf("\n%s: unknown variant %d, devices not attached\n",
    217   1.1   thorpej 		    sc->sc_dev.dv_xname, sc->sc_rev);
    218   1.1   thorpej 		return;
    219   1.1   thorpej 	}
    220   1.1   thorpej 
    221   1.1   thorpej 	printf(": %s, %dMHz, SCSI ID %d\n",
    222   1.1   thorpej 	    ncr53c9x_variant_names[sc->sc_rev], sc->sc_freq, sc->sc_id);
    223   1.1   thorpej 
    224   1.1   thorpej 	sc->sc_ccf = FREQTOCCF(sc->sc_freq);
    225   1.1   thorpej 
    226   1.1   thorpej 	/* The value *must not* be == 1. Make it 2 */
    227   1.1   thorpej 	if (sc->sc_ccf == 1)
    228   1.1   thorpej 		sc->sc_ccf = 2;
    229   1.1   thorpej 
    230   1.1   thorpej 	/*
    231   1.1   thorpej 	 * The recommended timeout is 250ms. This register is loaded
    232   1.1   thorpej 	 * with a value calculated as follows, from the docs:
    233   1.1   thorpej 	 *
    234   1.1   thorpej 	 *		(timout period) x (CLK frequency)
    235   1.1   thorpej 	 *	reg = -------------------------------------
    236   1.1   thorpej 	 *		 8192 x (Clock Conversion Factor)
    237   1.1   thorpej 	 *
    238   1.1   thorpej 	 * Since CCF has a linear relation to CLK, this generally computes
    239   1.1   thorpej 	 * to the constant of 153.
    240   1.1   thorpej 	 */
    241   1.1   thorpej 	sc->sc_timeout = ((250 * 1000) * sc->sc_freq) / (8192 * sc->sc_ccf);
    242   1.1   thorpej 
    243   1.1   thorpej 	/* CCF register only has 3 bits; 0 is actually 8 */
    244   1.1   thorpej 	sc->sc_ccf &= 7;
    245   1.1   thorpej 
    246   1.1   thorpej 	/*
    247  1.18    bouyer 	 * fill in the prototype scsipi_link.
    248   1.1   thorpej 	 */
    249  1.18    bouyer 	sc->sc_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
    250   1.1   thorpej 	sc->sc_link.adapter_softc = sc;
    251  1.18    bouyer 	sc->sc_link.scsipi_scsi.adapter_target = sc->sc_id;
    252  1.50  nisimura 	sc->sc_link.adapter = (adapter) ? adapter : &ncr53c9x_adapter;
    253  1.50  nisimura 	sc->sc_link.device = (device) ? device : &ncr53c9x_device;
    254  1.70       eeh 	sc->sc_link.openings = 2;
    255  1.18    bouyer 	sc->sc_link.scsipi_scsi.max_target = 7;
    256  1.32    mjacob 	sc->sc_link.scsipi_scsi.max_lun = 7;
    257  1.18    bouyer 	sc->sc_link.type = BUS_SCSI;
    258   1.1   thorpej 
    259   1.1   thorpej 	/*
    260  1.44   mycroft 	 * Add reference to adapter so that we drop the reference after
    261  1.44   mycroft 	 * config_found() to make sure the adatper is disabled.
    262   1.1   thorpej 	 */
    263  1.44   mycroft 	if (scsipi_adapter_addref(&sc->sc_link) != 0) {
    264  1.44   mycroft 		printf("%s: unable to enable controller\n",
    265  1.44   mycroft 		    sc->sc_dev.dv_xname);
    266  1.44   mycroft 		return;
    267  1.44   mycroft 	}
    268  1.44   mycroft 
    269  1.44   mycroft 	/* Reset state & bus */
    270  1.44   mycroft 	sc->sc_cfflags = sc->sc_dev.dv_cfdata->cf_flags;
    271  1.44   mycroft 	sc->sc_state = 0;
    272  1.44   mycroft 	ncr53c9x_init(sc, 1);
    273  1.10        pk 
    274  1.10        pk 	/*
    275  1.44   mycroft 	 * Now try to attach all the sub-devices
    276  1.10        pk 	 */
    277  1.44   mycroft 	sc->sc_child = config_found(&sc->sc_dev, &sc->sc_link, scsiprint);
    278  1.44   mycroft 
    279  1.44   mycroft 	scsipi_adapter_delref(&sc->sc_link);
    280  1.54       eeh 	callout_reset(&sc->sc_watchdog, 60*hz, ncr53c9x_watch, sc);
    281  1.44   mycroft }
    282  1.44   mycroft 
    283  1.44   mycroft int
    284  1.44   mycroft ncr53c9x_detach(sc, flags)
    285  1.44   mycroft 	struct ncr53c9x_softc *sc;
    286  1.44   mycroft 	int flags;
    287  1.44   mycroft {
    288  1.44   mycroft 	int error;
    289  1.44   mycroft 
    290  1.44   mycroft 	if (sc->sc_child) {
    291  1.44   mycroft 		error = config_detach(sc->sc_child, flags);
    292  1.44   mycroft 		if (error)
    293  1.44   mycroft 			return (error);
    294  1.44   mycroft 	}
    295  1.44   mycroft 
    296  1.44   mycroft 	free(sc->sc_imess, M_DEVBUF);
    297  1.44   mycroft 	free(sc->sc_omess, M_DEVBUF);
    298  1.24        pk 
    299  1.44   mycroft 	return (0);
    300   1.1   thorpej }
    301   1.1   thorpej 
    302   1.1   thorpej /*
    303  1.30        pk  * This is the generic ncr53c9x reset function. It does not reset the SCSI bus,
    304  1.30        pk  * only this controller, but kills any on-going commands, and also stops
    305   1.1   thorpej  * and resets the DMA.
    306   1.1   thorpej  *
    307   1.1   thorpej  * After reset, registers are loaded with the defaults from the attach
    308   1.1   thorpej  * routine above.
    309   1.1   thorpej  */
    310   1.1   thorpej void
    311   1.1   thorpej ncr53c9x_reset(sc)
    312   1.1   thorpej 	struct ncr53c9x_softc *sc;
    313   1.1   thorpej {
    314   1.1   thorpej 
    315   1.1   thorpej 	/* reset DMA first */
    316   1.1   thorpej 	NCRDMA_RESET(sc);
    317   1.1   thorpej 
    318   1.1   thorpej 	/* reset SCSI chip */
    319   1.1   thorpej 	NCRCMD(sc, NCRCMD_RSTCHIP);
    320   1.1   thorpej 	NCRCMD(sc, NCRCMD_NOP);
    321   1.1   thorpej 	DELAY(500);
    322   1.1   thorpej 
    323   1.1   thorpej 	/* do these backwards, and fall through */
    324   1.1   thorpej 	switch (sc->sc_rev) {
    325  1.10        pk 	case NCR_VARIANT_ESP406:
    326  1.10        pk 	case NCR_VARIANT_FAS408:
    327  1.45   mycroft 		NCR_WRITE_REG(sc, NCR_CFG5, sc->sc_cfg5 | NCRCFG5_SINT);
    328  1.45   mycroft 		NCR_WRITE_REG(sc, NCR_CFG4, sc->sc_cfg4);
    329  1.33   thorpej 	case NCR_VARIANT_AM53C974:
    330  1.20    mhitch 	case NCR_VARIANT_FAS216:
    331   1.1   thorpej 	case NCR_VARIANT_NCR53C94:
    332   1.2    briggs 	case NCR_VARIANT_NCR53C96:
    333   1.1   thorpej 	case NCR_VARIANT_ESP200:
    334  1.26   thorpej 		sc->sc_features |= NCR_F_HASCFG3;
    335   1.1   thorpej 		NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
    336   1.1   thorpej 	case NCR_VARIANT_ESP100A:
    337   1.1   thorpej 		NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
    338   1.1   thorpej 	case NCR_VARIANT_ESP100:
    339   1.1   thorpej 		NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1);
    340   1.1   thorpej 		NCR_WRITE_REG(sc, NCR_CCF, sc->sc_ccf);
    341   1.1   thorpej 		NCR_WRITE_REG(sc, NCR_SYNCOFF, 0);
    342   1.1   thorpej 		NCR_WRITE_REG(sc, NCR_TIMEOUT, sc->sc_timeout);
    343   1.1   thorpej 		break;
    344   1.1   thorpej 	default:
    345   1.1   thorpej 		printf("%s: unknown revision code, assuming ESP100\n",
    346   1.1   thorpej 		    sc->sc_dev.dv_xname);
    347   1.1   thorpej 		NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1);
    348   1.1   thorpej 		NCR_WRITE_REG(sc, NCR_CCF, sc->sc_ccf);
    349   1.1   thorpej 		NCR_WRITE_REG(sc, NCR_SYNCOFF, 0);
    350   1.1   thorpej 		NCR_WRITE_REG(sc, NCR_TIMEOUT, sc->sc_timeout);
    351   1.1   thorpej 	}
    352  1.33   thorpej 
    353  1.33   thorpej 	if (sc->sc_rev == NCR_VARIANT_AM53C974)
    354  1.46   tsutsui 		NCR_WRITE_REG(sc, NCR_AMDCFG4, sc->sc_cfg4);
    355   1.1   thorpej }
    356   1.1   thorpej 
    357   1.1   thorpej /*
    358   1.1   thorpej  * Reset the SCSI bus, but not the chip
    359   1.1   thorpej  */
    360   1.1   thorpej void
    361   1.1   thorpej ncr53c9x_scsi_reset(sc)
    362   1.1   thorpej 	struct ncr53c9x_softc *sc;
    363   1.1   thorpej {
    364   1.1   thorpej 
    365   1.1   thorpej 	(*sc->sc_glue->gl_dma_stop)(sc);
    366   1.1   thorpej 
    367   1.1   thorpej 	printf("%s: resetting SCSI bus\n", sc->sc_dev.dv_xname);
    368   1.1   thorpej 	NCRCMD(sc, NCRCMD_RSTSCSI);
    369   1.1   thorpej }
    370   1.1   thorpej 
    371   1.1   thorpej /*
    372  1.30        pk  * Initialize ncr53c9x state machine
    373   1.1   thorpej  */
    374   1.1   thorpej void
    375   1.1   thorpej ncr53c9x_init(sc, doreset)
    376   1.1   thorpej 	struct ncr53c9x_softc *sc;
    377   1.1   thorpej 	int doreset;
    378   1.1   thorpej {
    379   1.1   thorpej 	struct ncr53c9x_ecb *ecb;
    380  1.54       eeh 	struct ncr53c9x_linfo *li;
    381  1.54       eeh 	int i, r;
    382   1.1   thorpej 
    383   1.1   thorpej 	NCR_TRACE(("[NCR_INIT(%d)] ", doreset));
    384   1.1   thorpej 
    385  1.54       eeh 	if (!ecb_pool_initialized) {
    386  1.54       eeh 		/* All instances share this pool */
    387  1.54       eeh 		pool_init(&ecb_pool, sizeof(struct ncr53c9x_ecb), 0, 0, 0,
    388  1.54       eeh 			  "ncr53c9x_ecb", 0, NULL, NULL, 0);
    389  1.54       eeh 		ecb_pool_initialized = 1;
    390  1.54       eeh 	}
    391  1.54       eeh 
    392   1.1   thorpej 	if (sc->sc_state == 0) {
    393   1.1   thorpej 		/* First time through; initialize. */
    394  1.54       eeh 
    395   1.1   thorpej 		TAILQ_INIT(&sc->ready_list);
    396   1.1   thorpej 		sc->sc_nexus = NULL;
    397  1.54       eeh 		bzero(sc->sc_tinfo, sizeof(sc->sc_tinfo));
    398  1.57        pk 		for (r = 0; r < NCR_NTARG; r++) {
    399  1.54       eeh 			LIST_INIT(&sc->sc_tinfo[r].luns);
    400   1.1   thorpej 		}
    401   1.1   thorpej 	} else {
    402   1.1   thorpej 		/* Cancel any active commands. */
    403   1.1   thorpej 		sc->sc_state = NCR_CLEANING;
    404  1.54       eeh 		sc->sc_msgify = 0;
    405   1.1   thorpej 		if ((ecb = sc->sc_nexus) != NULL) {
    406  1.16        pk 			ecb->xs->error = XS_TIMEOUT;
    407   1.1   thorpej 			ncr53c9x_done(sc, ecb);
    408   1.1   thorpej 		}
    409  1.54       eeh 		/* Cancel outstanding disconnected commands on each LUN */
    410  1.57        pk 		for (r = 0; r < 8; r++) {
    411  1.54       eeh 			LIST_FOREACH(li, &sc->sc_tinfo[r].luns, link) {
    412  1.57        pk 				if ((ecb = li->untagged) != NULL) {
    413  1.54       eeh 					li->untagged = NULL;
    414  1.54       eeh 					/*
    415  1.54       eeh 					 * XXXXXXX
    416  1.54       eeh 					 *
    417  1.54       eeh 					 * Should we terminate a command
    418  1.54       eeh 					 * that never reached the disk?
    419  1.54       eeh 					 */
    420  1.54       eeh 					li->busy = 0;
    421  1.54       eeh 					ecb->xs->error = XS_TIMEOUT;
    422  1.54       eeh 					ncr53c9x_done(sc, ecb);
    423  1.54       eeh 				}
    424  1.57        pk 				for (i = 0; i < 256; i++)
    425  1.54       eeh 					if ((ecb = li->queued[i])) {
    426  1.54       eeh 						li->queued[i] = NULL;
    427  1.54       eeh 						ecb->xs->error = XS_TIMEOUT;
    428  1.54       eeh 						ncr53c9x_done(sc, ecb);
    429  1.54       eeh 					}
    430  1.54       eeh 				li->used = 0;
    431  1.54       eeh 			}
    432   1.1   thorpej 		}
    433   1.1   thorpej 	}
    434   1.1   thorpej 
    435   1.1   thorpej 	/*
    436   1.1   thorpej 	 * reset the chip to a known state
    437   1.1   thorpej 	 */
    438   1.1   thorpej 	ncr53c9x_reset(sc);
    439   1.1   thorpej 
    440   1.1   thorpej 	sc->sc_phase = sc->sc_prevphase = INVALID_PHASE;
    441   1.1   thorpej 	for (r = 0; r < 8; r++) {
    442   1.1   thorpej 		struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[r];
    443   1.1   thorpej /* XXX - config flags per target: low bits: no reselect; high bits: no synch */
    444   1.1   thorpej 
    445  1.70       eeh 		ti->flags = ((sc->sc_minsync && !(sc->sc_cfflags & (1<<(r+8))))
    446  1.67        pk 			 ? 0 : T_SYNCHOFF) |
    447  1.54       eeh 			((sc->sc_cfflags & (1<<r)) ? T_RSELECTOFF : 0) |
    448  1.54       eeh 			T_NEED_TO_RESET;
    449  1.54       eeh #ifdef DEBUG
    450  1.55        pk 		if (ncr53c9x_notag)
    451  1.70       eeh 			ti->flags &= ~T_TAG;
    452  1.54       eeh #endif
    453   1.1   thorpej 		ti->period = sc->sc_minsync;
    454   1.1   thorpej 		ti->offset = 0;
    455   1.1   thorpej 	}
    456   1.1   thorpej 
    457   1.1   thorpej 	if (doreset) {
    458   1.1   thorpej 		sc->sc_state = NCR_SBR;
    459   1.1   thorpej 		NCRCMD(sc, NCRCMD_RSTSCSI);
    460   1.1   thorpej 	} else {
    461   1.1   thorpej 		sc->sc_state = NCR_IDLE;
    462  1.15        pk 		ncr53c9x_sched(sc);
    463   1.1   thorpej 	}
    464   1.1   thorpej }
    465   1.1   thorpej 
    466   1.1   thorpej /*
    467   1.1   thorpej  * Read the NCR registers, and save their contents for later use.
    468   1.1   thorpej  * NCR_STAT, NCR_STEP & NCR_INTR are mostly zeroed out when reading
    469   1.1   thorpej  * NCR_INTR - so make sure it is the last read.
    470   1.1   thorpej  *
    471   1.1   thorpej  * I think that (from reading the docs) most bits in these registers
    472   1.1   thorpej  * only make sense when he DMA CSR has an interrupt showing. Call only
    473   1.1   thorpej  * if an interrupt is pending.
    474   1.1   thorpej  */
    475  1.25        pk __inline__ void
    476   1.1   thorpej ncr53c9x_readregs(sc)
    477   1.1   thorpej 	struct ncr53c9x_softc *sc;
    478   1.1   thorpej {
    479   1.1   thorpej 
    480   1.1   thorpej 	sc->sc_espstat = NCR_READ_REG(sc, NCR_STAT);
    481   1.1   thorpej 	/* Only the stepo bits are of interest */
    482   1.1   thorpej 	sc->sc_espstep = NCR_READ_REG(sc, NCR_STEP) & NCRSTEP_MASK;
    483   1.1   thorpej 	sc->sc_espintr = NCR_READ_REG(sc, NCR_INTR);
    484   1.1   thorpej 
    485   1.1   thorpej 	if (sc->sc_glue->gl_clear_latched_intr != NULL)
    486   1.1   thorpej 		(*sc->sc_glue->gl_clear_latched_intr)(sc);
    487   1.1   thorpej 
    488   1.1   thorpej 	/*
    489   1.1   thorpej 	 * Determine the SCSI bus phase, return either a real SCSI bus phase
    490   1.1   thorpej 	 * or some pseudo phase we use to detect certain exceptions.
    491   1.1   thorpej 	 */
    492   1.1   thorpej 
    493   1.1   thorpej 	sc->sc_phase = (sc->sc_espintr & NCRINTR_DIS)
    494   1.1   thorpej 			? /* Disconnected */ BUSFREE_PHASE
    495   1.1   thorpej 			: sc->sc_espstat & NCRSTAT_PHASE;
    496   1.1   thorpej 
    497   1.1   thorpej 	NCR_MISC(("regs[intr=%02x,stat=%02x,step=%02x] ",
    498   1.1   thorpej 		sc->sc_espintr, sc->sc_espstat, sc->sc_espstep));
    499   1.1   thorpej }
    500   1.1   thorpej 
    501   1.1   thorpej /*
    502   1.1   thorpej  * Convert Synchronous Transfer Period to chip register Clock Per Byte value.
    503   1.1   thorpej  */
    504   1.1   thorpej static inline int
    505   1.1   thorpej ncr53c9x_stp2cpb(sc, period)
    506   1.1   thorpej 	struct ncr53c9x_softc *sc;
    507   1.1   thorpej 	int period;
    508   1.1   thorpej {
    509   1.1   thorpej 	int v;
    510   1.1   thorpej 	v = (sc->sc_freq * period) / 250;
    511   1.1   thorpej 	if (ncr53c9x_cpb2stp(sc, v) < period)
    512   1.1   thorpej 		/* Correct round-down error */
    513   1.1   thorpej 		v++;
    514  1.25        pk 	return (v);
    515   1.1   thorpej }
    516   1.1   thorpej 
    517   1.1   thorpej static inline void
    518   1.1   thorpej ncr53c9x_setsync(sc, ti)
    519   1.1   thorpej 	struct ncr53c9x_softc *sc;
    520   1.1   thorpej 	struct ncr53c9x_tinfo *ti;
    521   1.1   thorpej {
    522  1.26   thorpej 	u_char syncoff, synctp, cfg3 = sc->sc_cfg3;
    523   1.1   thorpej 
    524   1.1   thorpej 	if (ti->flags & T_SYNCMODE) {
    525  1.26   thorpej 		syncoff = ti->offset;
    526  1.26   thorpej 		synctp = ncr53c9x_stp2cpb(sc, ti->period);
    527  1.26   thorpej 		if (sc->sc_features & NCR_F_FASTSCSI) {
    528  1.26   thorpej 			/*
    529  1.26   thorpej 			 * If the period is 200ns or less (ti->period <= 50),
    530  1.26   thorpej 			 * put the chip in Fast SCSI mode.
    531  1.26   thorpej 			 */
    532  1.26   thorpej 			if (ti->period <= 50)
    533  1.35    mhitch 				/*
    534  1.35    mhitch 				 * There are (at least) 4 variations of the
    535  1.35    mhitch 				 * configuration 3 register.  The drive attach
    536  1.35    mhitch 				 * routine sets the appropriate bit to put the
    537  1.35    mhitch 				 * chip into Fast SCSI mode so that it doesn't
    538  1.35    mhitch 				 * have to be figured out here each time.
    539  1.35    mhitch 				 */
    540  1.35    mhitch 				cfg3 |= sc->sc_cfg3_fscsi;
    541  1.26   thorpej 		}
    542  1.33   thorpej 
    543  1.33   thorpej 		/*
    544  1.33   thorpej 		 * Am53c974 requires different SYNCTP values when the
    545  1.33   thorpej 		 * FSCSI bit is off.
    546  1.33   thorpej 		 */
    547  1.33   thorpej 		if (sc->sc_rev == NCR_VARIANT_AM53C974 &&
    548  1.33   thorpej 		    (cfg3 & NCRAMDCFG3_FSCSI) == 0)
    549  1.33   thorpej 			synctp--;
    550   1.1   thorpej 	} else {
    551  1.26   thorpej 		syncoff = 0;
    552  1.26   thorpej 		synctp = 0;
    553   1.1   thorpej 	}
    554  1.26   thorpej 
    555  1.26   thorpej 	if (sc->sc_features & NCR_F_HASCFG3)
    556  1.26   thorpej 		NCR_WRITE_REG(sc, NCR_CFG3, cfg3);
    557  1.26   thorpej 
    558  1.26   thorpej 	NCR_WRITE_REG(sc, NCR_SYNCOFF, syncoff);
    559  1.26   thorpej 	NCR_WRITE_REG(sc, NCR_SYNCTP, synctp);
    560   1.1   thorpej }
    561   1.1   thorpej 
    562   1.8        pk int ncr53c9x_dmaselect = 0;
    563   1.1   thorpej /*
    564   1.1   thorpej  * Send a command to a target, set the driver state to NCR_SELECTING
    565   1.1   thorpej  * and let the caller take care of the rest.
    566   1.1   thorpej  *
    567   1.1   thorpej  * Keeping this as a function allows me to say that this may be done
    568   1.1   thorpej  * by DMA instead of programmed I/O soon.
    569   1.1   thorpej  */
    570   1.1   thorpej void
    571   1.1   thorpej ncr53c9x_select(sc, ecb)
    572   1.1   thorpej 	struct ncr53c9x_softc *sc;
    573   1.1   thorpej 	struct ncr53c9x_ecb *ecb;
    574   1.1   thorpej {
    575  1.18    bouyer 	struct scsipi_link *sc_link = ecb->xs->sc_link;
    576  1.18    bouyer 	int target = sc_link->scsipi_scsi.target;
    577  1.22        pk 	int lun = sc_link->scsipi_scsi.lun;
    578   1.1   thorpej 	struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[target];
    579  1.22        pk 	int tiflags = ti->flags;
    580   1.1   thorpej 	u_char *cmd;
    581   1.1   thorpej 	int clen;
    582  1.63       eeh 	int selatn3 = 1;
    583  1.63       eeh 	int selandstop = 0;
    584  1.39   mycroft 	size_t dmasize;
    585   1.1   thorpej 
    586  1.54       eeh 	NCR_TRACE(("[ncr53c9x_select(t%d,l%d,cmd:%x,tag:%x,%x)] ",
    587  1.54       eeh 		   target, lun, ecb->cmd.cmd.opcode, ecb->tag[0], ecb->tag[1]));
    588   1.1   thorpej 
    589   1.1   thorpej 	sc->sc_state = NCR_SELECTING;
    590   1.7       gwr 	/*
    591   1.7       gwr 	 * Schedule the timeout now, the first time we will go away
    592   1.7       gwr 	 * expecting to come back due to an interrupt, because it is
    593   1.7       gwr 	 * always possible that the interrupt may never happen.
    594   1.7       gwr 	 */
    595  1.52  nisimura 	if ((ecb->xs->xs_control & XS_CTL_POLL) == 0) {
    596  1.52  nisimura 		int timeout = ecb->timeout;
    597  1.52  nisimura 
    598  1.52  nisimura 		if (hz > 100 && timeout > 1000)
    599  1.52  nisimura 			timeout = (timeout / 1000) * hz;
    600  1.52  nisimura 		else
    601  1.52  nisimura 			timeout = (timeout * hz) / 1000;
    602  1.57        pk 
    603  1.52  nisimura 		callout_reset(&ecb->xs->xs_callout, timeout,
    604  1.57        pk 			      ncr53c9x_timeout, ecb);
    605  1.52  nisimura 	}
    606   1.7       gwr 
    607   1.1   thorpej 	/*
    608   1.1   thorpej 	 * The docs say the target register is never reset, and I
    609   1.1   thorpej 	 * can't think of a better place to set it
    610   1.1   thorpej 	 */
    611   1.1   thorpej 	NCR_WRITE_REG(sc, NCR_SELID, target);
    612   1.1   thorpej 	ncr53c9x_setsync(sc, ti);
    613  1.38   mycroft 
    614  1.63       eeh 	/*
    615  1.63       eeh 	 * Check to see if we can use SELATN3.
    616  1.63       eeh 	 */
    617  1.63       eeh 	switch (sc->sc_rev) {
    618  1.63       eeh 	case NCR_VARIANT_ESP100:
    619  1.63       eeh 		/* Don't have NCRCMD_SELATN3 */
    620  1.63       eeh 		selatn3 = 0;
    621  1.63       eeh 		break;
    622  1.63       eeh 	default:
    623  1.63       eeh 		break;
    624  1.63       eeh 	}
    625  1.63       eeh 
    626  1.57        pk 	if ((ecb->flags & ECB_SENSE) != 0) {
    627  1.38   mycroft 		/*
    628  1.38   mycroft 		 * For REQUEST SENSE, we should not send an IDENTIFY or
    629  1.38   mycroft 		 * otherwise mangle the target.  There should be no MESSAGE IN
    630  1.38   mycroft 		 * phase.
    631  1.38   mycroft 		 */
    632  1.39   mycroft 		if (ncr53c9x_dmaselect) {
    633  1.39   mycroft 			/* setup DMA transfer for command */
    634  1.39   mycroft 			dmasize = clen = ecb->clen;
    635  1.39   mycroft 			sc->sc_cmdlen = clen;
    636  1.54       eeh 			sc->sc_cmdp = (caddr_t)&ecb->cmd.cmd;
    637  1.57        pk 			NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0,
    638  1.57        pk 				     &dmasize);
    639  1.39   mycroft 
    640  1.39   mycroft 			/* Program the SCSI counter */
    641  1.39   mycroft 			NCR_WRITE_REG(sc, NCR_TCL, dmasize);
    642  1.39   mycroft 			NCR_WRITE_REG(sc, NCR_TCM, dmasize >> 8);
    643  1.39   mycroft 			if (sc->sc_cfg2 & NCRCFG2_FE) {
    644  1.39   mycroft 				NCR_WRITE_REG(sc, NCR_TCH, dmasize >> 16);
    645  1.39   mycroft 			}
    646  1.39   mycroft 
    647  1.39   mycroft 			/* load the count in */
    648  1.39   mycroft 			NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA);
    649  1.39   mycroft 
    650  1.39   mycroft 			/* And get the targets attention */
    651  1.39   mycroft 			NCRCMD(sc, NCRCMD_SELNATN | NCRCMD_DMA);
    652  1.39   mycroft 			NCRDMA_GO(sc);
    653  1.39   mycroft 		} else {
    654  1.54       eeh 			/* Now get the command into the FIFO */
    655  1.39   mycroft 			cmd = (u_char *)&ecb->cmd.cmd;
    656  1.39   mycroft 			clen = ecb->clen;
    657  1.39   mycroft 			while (clen--)
    658  1.39   mycroft 				NCR_WRITE_REG(sc, NCR_FIFO, *cmd++);
    659  1.39   mycroft 
    660  1.39   mycroft 			NCRCMD(sc, NCRCMD_SELNATN);
    661  1.39   mycroft 		}
    662  1.38   mycroft 		return;
    663  1.38   mycroft 	}
    664   1.1   thorpej 
    665  1.63       eeh 	if (tiflags & T_NEGOTIATE) selandstop = 1;
    666  1.66    briggs 	cmd = (u_char *)&ecb->cmd.cmd;
    667  1.69    briggs 
    668  1.69    briggs 	if (ecb->tag[0] && !selatn3)
    669  1.69    briggs 		selandstop = 1;
    670  1.69    briggs 
    671  1.66    briggs 	if (ecb->tag[0] && selatn3 && !selandstop) {
    672  1.54       eeh 		/* We'll use tags */
    673  1.54       eeh 		clen = ecb->clen + 3;
    674  1.66    briggs 		cmd -= 3;
    675  1.66    briggs 		cmd[0] = MSG_IDENTIFY(lun, 1);	/* msg[0] */
    676  1.66    briggs 		cmd[1] = ecb->tag[0];		/* msg[1] */
    677  1.66    briggs 		cmd[2] = ecb->tag[1];		/* msg[2] */
    678  1.54       eeh 	} else {
    679  1.69    briggs 		selatn3 = 0;	/* Do not use selatn3 even if we have it */
    680  1.54       eeh 		clen = ecb->clen + 1;
    681  1.66    briggs 		cmd -= 1;
    682  1.66    briggs 		cmd[0] = MSG_IDENTIFY(lun, (tiflags & T_RSELECTOFF)?0:1);
    683  1.54       eeh 	}
    684  1.54       eeh 
    685  1.63       eeh 	if (ncr53c9x_dmaselect && !selandstop) {
    686   1.8        pk 
    687   1.8        pk 		/* setup DMA transfer for command */
    688  1.54       eeh 		dmasize = clen;
    689   1.8        pk 		sc->sc_cmdlen = clen;
    690  1.54       eeh 		sc->sc_cmdp = cmd;
    691  1.22        pk 		NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0, &dmasize);
    692  1.22        pk 
    693   1.8        pk 		/* Program the SCSI counter */
    694  1.22        pk 		NCR_WRITE_REG(sc, NCR_TCL, dmasize);
    695  1.22        pk 		NCR_WRITE_REG(sc, NCR_TCM, dmasize >> 8);
    696   1.8        pk 		if (sc->sc_cfg2 & NCRCFG2_FE) {
    697  1.22        pk 			NCR_WRITE_REG(sc, NCR_TCH, dmasize >> 16);
    698   1.8        pk 		}
    699   1.8        pk 
    700  1.22        pk 		/* load the count in */
    701  1.22        pk 		NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA);
    702  1.22        pk 
    703   1.8        pk 		/* And get the targets attention */
    704  1.69    briggs 		if (selatn3) {
    705  1.66    briggs 			sc->sc_msgout = SEND_TAG;
    706  1.66    briggs 			sc->sc_flags |= NCR_ATN;
    707  1.54       eeh 			NCRCMD(sc, NCRCMD_SELATN3 | NCRCMD_DMA);
    708  1.66    briggs 		} else
    709  1.54       eeh 			NCRCMD(sc, NCRCMD_SELATN | NCRCMD_DMA);
    710   1.8        pk 		NCRDMA_GO(sc);
    711   1.8        pk 		return;
    712   1.8        pk 	}
    713  1.22        pk 
    714   1.1   thorpej 	/*
    715   1.1   thorpej 	 * Who am I. This is where we tell the target that we are
    716   1.1   thorpej 	 * happy for it to disconnect etc.
    717   1.1   thorpej 	 */
    718  1.54       eeh 	NCR_WRITE_REG(sc, NCR_FIFO, *cmd++);
    719  1.54       eeh 	clen --;
    720   1.1   thorpej 
    721  1.63       eeh 	if (selandstop) {
    722   1.1   thorpej 		/* Arbitrate, select and stop after IDENTIFY message */
    723   1.1   thorpej 		NCRCMD(sc, NCRCMD_SELATNS);
    724   1.1   thorpej 		return;
    725   1.1   thorpej 	}
    726   1.1   thorpej 
    727  1.54       eeh 	/* If we want to send a tag, get it into the fifo */
    728  1.54       eeh 	if (ecb->tag[0]) {
    729  1.54       eeh 		NCR_WRITE_REG(sc, NCR_FIFO, *cmd++);
    730  1.54       eeh 		clen --;
    731  1.54       eeh 		NCR_WRITE_REG(sc, NCR_FIFO, *cmd++);
    732  1.54       eeh 		clen --;
    733  1.54       eeh 	}
    734  1.54       eeh 
    735  1.54       eeh 	/* Now get the command into the FIFO */
    736   1.1   thorpej 	while (clen--)
    737   1.1   thorpej 		NCR_WRITE_REG(sc, NCR_FIFO, *cmd++);
    738   1.1   thorpej 
    739   1.1   thorpej 	/* And get the targets attention */
    740  1.69    briggs 	if (selatn3) {
    741  1.66    briggs 		sc->sc_msgout = SEND_TAG;
    742  1.66    briggs 		sc->sc_flags |= NCR_ATN;
    743  1.61       eeh 		NCRCMD(sc, NCRCMD_SELATN3);
    744  1.66    briggs 	} else
    745  1.61       eeh 		NCRCMD(sc, NCRCMD_SELATN);
    746   1.1   thorpej }
    747   1.1   thorpej 
    748   1.1   thorpej void
    749   1.1   thorpej ncr53c9x_free_ecb(sc, ecb, flags)
    750   1.1   thorpej 	struct ncr53c9x_softc *sc;
    751   1.1   thorpej 	struct ncr53c9x_ecb *ecb;
    752   1.1   thorpej 	int flags;
    753   1.1   thorpej {
    754   1.1   thorpej 	int s;
    755   1.1   thorpej 
    756   1.1   thorpej 	s = splbio();
    757   1.1   thorpej 	ecb->flags = 0;
    758  1.54       eeh 	pool_put(&ecb_pool, (void *)ecb);
    759   1.1   thorpej 	splx(s);
    760  1.54       eeh 	return;
    761   1.1   thorpej }
    762   1.1   thorpej 
    763   1.1   thorpej struct ncr53c9x_ecb *
    764   1.1   thorpej ncr53c9x_get_ecb(sc, flags)
    765   1.1   thorpej 	struct ncr53c9x_softc *sc;
    766   1.1   thorpej 	int flags;
    767   1.1   thorpej {
    768   1.1   thorpej 	struct ncr53c9x_ecb *ecb;
    769  1.54       eeh 	int s, wait = 0;
    770  1.54       eeh 
    771  1.54       eeh 	if ((curproc != NULL) && ((flags & XS_CTL_NOSLEEP) == 0))
    772  1.54       eeh 		wait = PR_WAITOK;
    773   1.1   thorpej 
    774   1.1   thorpej 	s = splbio();
    775  1.54       eeh 	ecb = (struct ncr53c9x_ecb *)pool_get(&ecb_pool, wait);
    776  1.54       eeh 	splx(s);
    777  1.54       eeh 	bzero(ecb, sizeof(*ecb));
    778  1.54       eeh 	if (ecb)
    779   1.1   thorpej 		ecb->flags |= ECB_ALLOC;
    780  1.25        pk 	return (ecb);
    781   1.1   thorpej }
    782   1.1   thorpej 
    783   1.1   thorpej /*
    784   1.1   thorpej  * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
    785   1.1   thorpej  */
    786   1.1   thorpej 
    787   1.1   thorpej /*
    788   1.1   thorpej  * Start a SCSI-command
    789   1.1   thorpej  * This function is called by the higher level SCSI-driver to queue/run
    790   1.1   thorpej  * SCSI-commands.
    791   1.1   thorpej  */
    792   1.1   thorpej int
    793   1.1   thorpej ncr53c9x_scsi_cmd(xs)
    794  1.18    bouyer 	struct scsipi_xfer *xs;
    795   1.1   thorpej {
    796  1.18    bouyer 	struct scsipi_link *sc_link = xs->sc_link;
    797   1.1   thorpej 	struct ncr53c9x_softc *sc = sc_link->adapter_softc;
    798   1.1   thorpej 	struct ncr53c9x_ecb *ecb;
    799  1.54       eeh 	struct ncr53c9x_tinfo *ti;
    800  1.54       eeh 	struct ncr53c9x_linfo *li;
    801  1.54       eeh 	int64_t lun = sc_link->scsipi_scsi.lun;
    802   1.1   thorpej 	int s, flags;
    803   1.1   thorpej 
    804   1.1   thorpej 	NCR_TRACE(("[ncr53c9x_scsi_cmd] "));
    805   1.1   thorpej 	NCR_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
    806  1.18    bouyer 	    sc_link->scsipi_scsi.target));
    807   1.1   thorpej 
    808  1.54       eeh 	/*
    809  1.54       eeh 	 * Find the LUN info structure and allocate one if it does
    810  1.54       eeh 	 * not exist.
    811  1.54       eeh 	 */
    812  1.36   thorpej 	flags = xs->xs_control;
    813  1.54       eeh 	ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
    814  1.54       eeh 	li = TINFO_LUN(ti, lun);
    815  1.54       eeh 	if (li == NULL) {
    816  1.54       eeh 		int wait = M_NOWAIT;
    817  1.54       eeh 
    818  1.54       eeh 		/* Initialize LUN info and add to list. */
    819  1.54       eeh 		if ((curproc != NULL) && ((flags & XS_CTL_NOSLEEP) == 0))
    820  1.54       eeh 			wait = M_WAITOK;
    821  1.54       eeh 		if ((li = malloc(sizeof(*li), M_DEVBUF, M_NOWAIT)) == NULL) {
    822  1.54       eeh 		    return (TRY_AGAIN_LATER);
    823  1.54       eeh 		}
    824  1.54       eeh 		bzero(li, sizeof(*li));
    825  1.54       eeh 		li->last_used = time.tv_sec;
    826  1.54       eeh 		li->lun = lun;
    827  1.54       eeh 		s = splbio();
    828  1.54       eeh 		LIST_INSERT_HEAD(&ti->luns, li, link);
    829  1.54       eeh 		if (lun < NCR_NLUN)
    830  1.54       eeh 			ti->lun[lun] = li;
    831  1.54       eeh 		splx(s);
    832  1.54       eeh 	}
    833  1.54       eeh 
    834  1.16        pk 	if ((ecb = ncr53c9x_get_ecb(sc, flags)) == NULL)
    835  1.25        pk 		return (TRY_AGAIN_LATER);
    836   1.1   thorpej 
    837   1.1   thorpej 	/* Initialize ecb */
    838   1.1   thorpej 	ecb->xs = xs;
    839   1.1   thorpej 	ecb->timeout = xs->timeout;
    840   1.1   thorpej 
    841  1.36   thorpej 	if (flags & XS_CTL_RESET) {
    842   1.1   thorpej 		ecb->flags |= ECB_RESET;
    843   1.1   thorpej 		ecb->clen = 0;
    844   1.1   thorpej 		ecb->dleft = 0;
    845   1.1   thorpej 	} else {
    846   1.8        pk 		bcopy(xs->cmd, &ecb->cmd.cmd, xs->cmdlen);
    847   1.1   thorpej 		ecb->clen = xs->cmdlen;
    848   1.1   thorpej 		ecb->daddr = xs->data;
    849   1.1   thorpej 		ecb->dleft = xs->datalen;
    850   1.1   thorpej 	}
    851   1.1   thorpej 	ecb->stat = 0;
    852   1.1   thorpej 
    853   1.1   thorpej 	s = splbio();
    854   1.1   thorpej 
    855   1.1   thorpej 	TAILQ_INSERT_TAIL(&sc->ready_list, ecb, chain);
    856  1.54       eeh 	ecb->flags |= ECB_READY;
    857   1.1   thorpej 	if (sc->sc_state == NCR_IDLE)
    858   1.1   thorpej 		ncr53c9x_sched(sc);
    859   1.1   thorpej 
    860   1.1   thorpej 	splx(s);
    861   1.1   thorpej 
    862  1.36   thorpej 	if ((flags & XS_CTL_POLL) == 0)
    863  1.25        pk 		return (SUCCESSFULLY_QUEUED);
    864   1.1   thorpej 
    865   1.1   thorpej 	/* Not allowed to use interrupts, use polling instead */
    866   1.1   thorpej 	if (ncr53c9x_poll(sc, xs, ecb->timeout)) {
    867   1.1   thorpej 		ncr53c9x_timeout(ecb);
    868   1.1   thorpej 		if (ncr53c9x_poll(sc, xs, ecb->timeout))
    869   1.1   thorpej 			ncr53c9x_timeout(ecb);
    870   1.1   thorpej 	}
    871  1.25        pk 	return (COMPLETE);
    872   1.1   thorpej }
    873   1.1   thorpej 
    874   1.1   thorpej /*
    875   1.1   thorpej  * Used when interrupt driven I/O isn't allowed, e.g. during boot.
    876   1.1   thorpej  */
    877   1.1   thorpej int
    878   1.1   thorpej ncr53c9x_poll(sc, xs, count)
    879   1.1   thorpej 	struct ncr53c9x_softc *sc;
    880  1.18    bouyer 	struct scsipi_xfer *xs;
    881   1.1   thorpej 	int count;
    882   1.1   thorpej {
    883   1.1   thorpej 
    884   1.1   thorpej 	NCR_TRACE(("[ncr53c9x_poll] "));
    885   1.1   thorpej 	while (count) {
    886   1.1   thorpej 		if (NCRDMA_ISINTR(sc)) {
    887   1.1   thorpej 			ncr53c9x_intr(sc);
    888   1.1   thorpej 		}
    889   1.1   thorpej #if alternatively
    890   1.1   thorpej 		if (NCR_READ_REG(sc, NCR_STAT) & NCRSTAT_INT)
    891   1.1   thorpej 			ncr53c9x_intr(sc);
    892   1.1   thorpej #endif
    893  1.36   thorpej 		if ((xs->xs_status & XS_STS_DONE) != 0)
    894  1.25        pk 			return (0);
    895   1.1   thorpej 		if (sc->sc_state == NCR_IDLE) {
    896   1.1   thorpej 			NCR_TRACE(("[ncr53c9x_poll: rescheduling] "));
    897   1.1   thorpej 			ncr53c9x_sched(sc);
    898   1.1   thorpej 		}
    899   1.1   thorpej 		DELAY(1000);
    900   1.1   thorpej 		count--;
    901   1.1   thorpej 	}
    902  1.25        pk 	return (1);
    903   1.1   thorpej }
    904   1.1   thorpej 
    905  1.53        pk int
    906  1.53        pk ncr53c9x_ioctl(link, cmd, arg, flag, p)
    907  1.53        pk 	struct scsipi_link *link;
    908  1.53        pk 	u_long cmd;
    909  1.53        pk 	caddr_t arg;
    910  1.53        pk 	int flag;
    911  1.53        pk 	struct proc *p;
    912  1.53        pk {
    913  1.53        pk 	struct ncr53c9x_softc *sc = link->adapter_softc;
    914  1.62      fvdl 	int s, error = 0;
    915  1.53        pk 
    916  1.53        pk 	s = splbio();
    917  1.53        pk 
    918  1.53        pk 	switch (cmd) {
    919  1.53        pk 	case SCBUSACCEL: {
    920  1.53        pk 		struct scbusaccel_args *sp = (struct scbusaccel_args *)arg;
    921  1.53        pk 		struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[sp->sa_target];
    922  1.53        pk 
    923  1.53        pk 		if (sp->sa_lun != 0)
    924  1.53        pk 			break;
    925  1.53        pk 
    926  1.53        pk 		if ((sp->sa_flags & SC_ACCEL_SYNC) != 0) {
    927  1.53        pk 			/* If this adapter can't do sync; drop it */
    928  1.53        pk 			if (sc->sc_minsync == 0)
    929  1.53        pk 				break;
    930  1.53        pk 
    931  1.53        pk 			/*
    932  1.53        pk 			 * Check whether target is already clamped at
    933  1.53        pk 			 * non-sync operation on user request.
    934  1.53        pk 			 */
    935  1.53        pk 			if ((ti->flags & T_SYNCHOFF) != 0)
    936  1.53        pk 				break;
    937  1.53        pk 
    938  1.53        pk 			printf("%s: target %d: sync negotiation\n",
    939  1.53        pk 					sc->sc_dev.dv_xname, sp->sa_target);
    940  1.53        pk 			ti->flags |= T_NEGOTIATE;
    941  1.53        pk 		}
    942  1.70       eeh 		if ((sp->sa_flags & SC_ACCEL_TAGS) != 0) {
    943  1.70       eeh 			if ((sc->sc_cfflags & (1<<((sp->sa_target)+16))) == 0) {
    944  1.70       eeh 				ti->flags |= T_TAG;
    945  1.70       eeh 				link->openings = 255;
    946  1.70       eeh 			}
    947  1.70       eeh 		}
    948  1.70       eeh 	break;
    949  1.53        pk 	}
    950  1.53        pk 	default:
    951  1.53        pk 		error = ENOTTY;
    952  1.53        pk 		break;
    953  1.53        pk 	}
    954  1.53        pk 	splx(s);
    955  1.53        pk 	return (error);
    956  1.53        pk }
    957  1.53        pk 
    958   1.1   thorpej 
    959   1.1   thorpej /*
    960   1.1   thorpej  * LOW LEVEL SCSI UTILITIES
    961   1.1   thorpej  */
    962   1.1   thorpej 
    963   1.1   thorpej /*
    964   1.1   thorpej  * Schedule a scsi operation.  This has now been pulled out of the interrupt
    965   1.1   thorpej  * handler so that we may call it from ncr53c9x_scsi_cmd and ncr53c9x_done.
    966   1.1   thorpej  * This may save us an unecessary interrupt just to get things going.
    967   1.1   thorpej  * Should only be called when state == NCR_IDLE and at bio pl.
    968   1.1   thorpej  */
    969   1.1   thorpej void
    970   1.1   thorpej ncr53c9x_sched(sc)
    971   1.1   thorpej 	struct ncr53c9x_softc *sc;
    972   1.1   thorpej {
    973   1.1   thorpej 	struct ncr53c9x_ecb *ecb;
    974  1.18    bouyer 	struct scsipi_link *sc_link;
    975   1.1   thorpej 	struct ncr53c9x_tinfo *ti;
    976  1.54       eeh 	int lun;
    977  1.54       eeh 	struct ncr53c9x_linfo *li;
    978  1.54       eeh 	int s, tag;
    979   1.1   thorpej 
    980   1.1   thorpej 	NCR_TRACE(("[ncr53c9x_sched] "));
    981   1.1   thorpej 	if (sc->sc_state != NCR_IDLE)
    982   1.1   thorpej 		panic("ncr53c9x_sched: not IDLE (state=%d)", sc->sc_state);
    983   1.1   thorpej 
    984   1.1   thorpej 	/*
    985   1.1   thorpej 	 * Find first ecb in ready queue that is for a target/lunit
    986   1.1   thorpej 	 * combinations that is not busy.
    987   1.1   thorpej 	 */
    988  1.57        pk 	for (ecb = TAILQ_FIRST(&sc->ready_list); ecb != NULL;
    989  1.57        pk 	     ecb = TAILQ_NEXT(ecb, chain)) {
    990   1.1   thorpej 		sc_link = ecb->xs->sc_link;
    991  1.18    bouyer 		ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
    992  1.54       eeh 		lun = sc_link->scsipi_scsi.lun;
    993  1.54       eeh 
    994  1.54       eeh 		/* Select type of tag for this command */
    995  1.70       eeh 		if ((ti->flags & (T_RSELECTOFF)) != 0)
    996  1.70       eeh 			tag = 0;
    997  1.70       eeh 		else if ((ti->flags & (T_TAG)) == 0)
    998  1.57        pk 			tag = 0;
    999  1.57        pk 		else if ((ecb->flags & ECB_SENSE) != 0)
   1000  1.57        pk 			tag = 0;
   1001  1.57        pk 		else if (ecb->xs->xs_control & XS_CTL_URGENT)
   1002  1.54       eeh 			tag = MSG_HEAD_OF_Q_TAG;
   1003  1.54       eeh 		else
   1004  1.54       eeh 			tag = MSG_SIMPLE_Q_TAG;
   1005  1.54       eeh #if 0
   1006  1.54       eeh 		/* XXXX Use tags for polled commands? */
   1007  1.54       eeh 		if (ecb->xs->xs_control & XS_CTL_POLL)
   1008  1.54       eeh 			tag = 0;
   1009  1.54       eeh #endif
   1010  1.57        pk 
   1011  1.54       eeh 		s = splbio();
   1012  1.54       eeh 		li = TINFO_LUN(ti, lun);
   1013  1.57        pk 		if (li == NULL) {
   1014  1.54       eeh 			int wait = M_NOWAIT;
   1015  1.54       eeh 			int flags = ecb->xs->xs_control;
   1016  1.54       eeh 
   1017  1.54       eeh 			/* Initialize LUN info and add to list. */
   1018  1.54       eeh 			if ((curproc != NULL) && ((flags & XS_CTL_NOSLEEP) == 0))
   1019  1.54       eeh 				wait = M_WAITOK;
   1020  1.54       eeh 			if ((li = malloc(sizeof(*li), M_DEVBUF, M_NOWAIT)) == NULL) {
   1021  1.54       eeh 				splx(s);
   1022  1.54       eeh 				continue;
   1023  1.54       eeh 			}
   1024  1.54       eeh 			bzero(li, sizeof(*li));
   1025  1.54       eeh 			li->lun = lun;
   1026  1.54       eeh 
   1027  1.54       eeh 			LIST_INSERT_HEAD(&ti->luns, li, link);
   1028  1.54       eeh 			if (lun < NCR_NLUN)
   1029  1.54       eeh 				ti->lun[lun] = li;
   1030  1.54       eeh 		}
   1031  1.54       eeh 		li->last_used = time.tv_sec;
   1032  1.57        pk 		if (tag == 0) {
   1033  1.54       eeh 			/* Try to issue this as an un-tagged command */
   1034  1.57        pk 			if (li->untagged == NULL)
   1035  1.54       eeh 				li->untagged = ecb;
   1036  1.54       eeh 		}
   1037  1.57        pk 		if (li->untagged != NULL) {
   1038  1.54       eeh 			tag = 0;
   1039  1.57        pk 			if ((li->busy != 1) && li->used == 0) {
   1040  1.54       eeh 				/* We need to issue this untagged command now */
   1041  1.54       eeh 				ecb = li->untagged;
   1042  1.54       eeh 				sc_link = ecb->xs->sc_link;
   1043  1.54       eeh 			}
   1044  1.54       eeh 			else {
   1045  1.54       eeh 				/* Not ready yet */
   1046  1.54       eeh 				splx(s);
   1047  1.54       eeh 				continue;
   1048  1.54       eeh 			}
   1049  1.54       eeh 		}
   1050  1.54       eeh 		ecb->tag[0] = tag;
   1051  1.57        pk 		if (tag != 0) {
   1052  1.54       eeh 			int i;
   1053  1.54       eeh 
   1054  1.54       eeh 			/* Allocate a tag */
   1055  1.54       eeh 			if (li->used == 255) {
   1056  1.54       eeh 				/* no free tags */
   1057  1.54       eeh 				splx(s);
   1058  1.54       eeh 				continue;
   1059  1.54       eeh 			}
   1060  1.54       eeh 			/* Start from the last used location */
   1061  1.57        pk 			for (i = li->avail; i < 256; i++) {
   1062  1.54       eeh 				if (li->queued[i] == NULL)
   1063  1.54       eeh 					break;
   1064  1.54       eeh 			}
   1065  1.54       eeh 			/* Couldn't find one, start again from the beginning */
   1066  1.54       eeh 			if (i == 256) {
   1067  1.57        pk 				for (i = 0; i < 256; i++) {
   1068  1.54       eeh 					if (li->queued[i] == NULL)
   1069  1.54       eeh 						break;
   1070  1.54       eeh 				}
   1071  1.54       eeh 			}
   1072  1.54       eeh #ifdef DIAGNOSTIC
   1073  1.54       eeh 			/* There's supposed to be at least 1 tag avail */
   1074  1.54       eeh 			if (i == 256)
   1075  1.54       eeh 				panic("ncr53c9x_sched: tag alloc failure\n");
   1076  1.54       eeh #endif
   1077  1.54       eeh 
   1078  1.54       eeh 			/* Save where to start next time. */
   1079  1.54       eeh 			li->avail = i+1;
   1080  1.54       eeh 			li->used ++;
   1081  1.54       eeh 
   1082  1.54       eeh 			li->queued[i] = ecb;
   1083  1.54       eeh 			ecb->tag[1] = i;
   1084  1.54       eeh 		}
   1085  1.54       eeh 		splx(s);
   1086  1.57        pk 		if (li->untagged != NULL && (li->busy != 1)) {
   1087  1.54       eeh 			li->busy = 1;
   1088   1.1   thorpej 			TAILQ_REMOVE(&sc->ready_list, ecb, chain);
   1089  1.54       eeh 			ecb->flags &= ~ECB_READY;
   1090  1.54       eeh 			sc->sc_nexus = ecb;
   1091  1.54       eeh 			ncr53c9x_select(sc, ecb);
   1092  1.54       eeh 			break;
   1093  1.54       eeh 		}
   1094  1.57        pk 		if (li->untagged == NULL && tag != 0) {
   1095  1.54       eeh 			TAILQ_REMOVE(&sc->ready_list, ecb, chain);
   1096  1.54       eeh 			ecb->flags &= ~ECB_READY;
   1097   1.1   thorpej 			sc->sc_nexus = ecb;
   1098   1.1   thorpej 			ncr53c9x_select(sc, ecb);
   1099   1.1   thorpej 			break;
   1100   1.1   thorpej 		} else
   1101   1.1   thorpej 			NCR_MISC(("%d:%d busy\n",
   1102  1.22        pk 				  sc_link->scsipi_scsi.target,
   1103  1.22        pk 				  sc_link->scsipi_scsi.lun));
   1104   1.1   thorpej 	}
   1105   1.1   thorpej }
   1106   1.1   thorpej 
   1107   1.1   thorpej void
   1108   1.1   thorpej ncr53c9x_sense(sc, ecb)
   1109   1.1   thorpej 	struct ncr53c9x_softc *sc;
   1110   1.1   thorpej 	struct ncr53c9x_ecb *ecb;
   1111   1.1   thorpej {
   1112  1.18    bouyer 	struct scsipi_xfer *xs = ecb->xs;
   1113  1.18    bouyer 	struct scsipi_link *sc_link = xs->sc_link;
   1114  1.18    bouyer 	struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
   1115  1.18    bouyer 	struct scsipi_sense *ss = (void *)&ecb->cmd.cmd;
   1116  1.54       eeh 	struct ncr53c9x_linfo *li;
   1117  1.54       eeh 	int lun = sc_link->scsipi_scsi.lun;
   1118   1.1   thorpej 
   1119   1.1   thorpej 	NCR_MISC(("requesting sense "));
   1120   1.1   thorpej 	/* Next, setup a request sense command block */
   1121   1.1   thorpej 	bzero(ss, sizeof(*ss));
   1122   1.1   thorpej 	ss->opcode = REQUEST_SENSE;
   1123  1.18    bouyer 	ss->byte2 = sc_link->scsipi_scsi.lun << 5;
   1124  1.18    bouyer 	ss->length = sizeof(struct scsipi_sense_data);
   1125   1.1   thorpej 	ecb->clen = sizeof(*ss);
   1126  1.18    bouyer 	ecb->daddr = (char *)&xs->sense.scsi_sense;
   1127  1.18    bouyer 	ecb->dleft = sizeof(struct scsipi_sense_data);
   1128   1.1   thorpej 	ecb->flags |= ECB_SENSE;
   1129   1.7       gwr 	ecb->timeout = NCR_SENSE_TIMEOUT;
   1130   1.1   thorpej 	ti->senses++;
   1131  1.54       eeh 	li = TINFO_LUN(ti, lun);
   1132  1.54       eeh 	if (li->busy) li->busy = 0;
   1133  1.54       eeh 	ncr53c9x_dequeue(sc, ecb);
   1134  1.54       eeh 	li->untagged = ecb; /* must be executed first to fix C/A */
   1135  1.54       eeh 	li->busy = 2;
   1136   1.1   thorpej 	if (ecb == sc->sc_nexus) {
   1137   1.1   thorpej 		ncr53c9x_select(sc, ecb);
   1138   1.1   thorpej 	} else {
   1139   1.1   thorpej 		TAILQ_INSERT_HEAD(&sc->ready_list, ecb, chain);
   1140  1.54       eeh 		ecb->flags |= ECB_READY;
   1141   1.1   thorpej 		if (sc->sc_state == NCR_IDLE)
   1142   1.1   thorpej 			ncr53c9x_sched(sc);
   1143   1.1   thorpej 	}
   1144   1.1   thorpej }
   1145   1.1   thorpej 
   1146   1.1   thorpej /*
   1147   1.1   thorpej  * POST PROCESSING OF SCSI_CMD (usually current)
   1148   1.1   thorpej  */
   1149   1.1   thorpej void
   1150   1.1   thorpej ncr53c9x_done(sc, ecb)
   1151   1.1   thorpej 	struct ncr53c9x_softc *sc;
   1152   1.1   thorpej 	struct ncr53c9x_ecb *ecb;
   1153   1.1   thorpej {
   1154  1.18    bouyer 	struct scsipi_xfer *xs = ecb->xs;
   1155  1.18    bouyer 	struct scsipi_link *sc_link = xs->sc_link;
   1156  1.18    bouyer 	struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
   1157  1.54       eeh 	int lun = sc_link->scsipi_scsi.lun;
   1158  1.54       eeh 	struct ncr53c9x_linfo *li = TINFO_LUN(ti, lun);
   1159   1.1   thorpej 
   1160   1.1   thorpej 	NCR_TRACE(("[ncr53c9x_done(error:%x)] ", xs->error));
   1161   1.1   thorpej 
   1162  1.48   thorpej 	callout_stop(&ecb->xs->xs_callout);
   1163   1.7       gwr 
   1164  1.54       eeh 	if (ecb->stat == SCSI_QUEUE_FULL) {
   1165  1.54       eeh 		/*
   1166  1.54       eeh 		 * Set current throttle -- we should reset
   1167  1.54       eeh 		 * this periodically
   1168  1.54       eeh 		 */
   1169  1.54       eeh 		sc_link->openings = li->used - 1;
   1170  1.54       eeh 		printf("\n%s: QFULL -- throttling to %d commands\n",
   1171  1.54       eeh 		    sc->sc_dev.dv_xname, sc_link->openings);
   1172  1.54       eeh 
   1173  1.54       eeh 	}
   1174  1.54       eeh 
   1175   1.1   thorpej 	/*
   1176   1.1   thorpej 	 * Now, if we've come here with no error code, i.e. we've kept the
   1177   1.1   thorpej 	 * initial XS_NOERROR, and the status code signals that we should
   1178   1.1   thorpej 	 * check sense, we'll need to set up a request sense cmd block and
   1179   1.1   thorpej 	 * push the command back into the ready queue *before* any other
   1180   1.1   thorpej 	 * commands for this target/lunit, else we lose the sense info.
   1181   1.1   thorpej 	 * We don't support chk sense conditions for the request sense cmd.
   1182   1.1   thorpej 	 */
   1183   1.1   thorpej 	if (xs->error == XS_NOERROR) {
   1184  1.12        pk 		xs->status = ecb->stat;
   1185   1.1   thorpej 		if ((ecb->flags & ECB_ABORT) != 0) {
   1186  1.16        pk 			xs->error = XS_TIMEOUT;
   1187   1.1   thorpej 		} else if ((ecb->flags & ECB_SENSE) != 0) {
   1188   1.1   thorpej 			xs->error = XS_SENSE;
   1189   1.1   thorpej 		} else if ((ecb->stat & ST_MASK) == SCSI_CHECK) {
   1190   1.1   thorpej 			/* First, save the return values */
   1191   1.1   thorpej 			xs->resid = ecb->dleft;
   1192   1.1   thorpej 			ncr53c9x_sense(sc, ecb);
   1193   1.1   thorpej 			return;
   1194   1.1   thorpej 		} else {
   1195   1.1   thorpej 			xs->resid = ecb->dleft;
   1196   1.1   thorpej 		}
   1197   1.1   thorpej 	}
   1198   1.1   thorpej 
   1199  1.36   thorpej 	xs->xs_status |= XS_STS_DONE;
   1200   1.1   thorpej 
   1201   1.1   thorpej #ifdef NCR53C9X_DEBUG
   1202   1.1   thorpej 	if (ncr53c9x_debug & NCR_SHOWMISC) {
   1203   1.1   thorpej 		if (xs->resid != 0)
   1204   1.1   thorpej 			printf("resid=%d ", xs->resid);
   1205   1.1   thorpej 		if (xs->error == XS_SENSE)
   1206  1.18    bouyer 			printf("sense=0x%02x\n", xs->sense.scsi_sense.error_code);
   1207   1.1   thorpej 		else
   1208   1.1   thorpej 			printf("error=%d\n", xs->error);
   1209   1.1   thorpej 	}
   1210   1.1   thorpej #endif
   1211   1.1   thorpej 
   1212   1.1   thorpej 	/*
   1213   1.1   thorpej 	 * Remove the ECB from whatever queue it's on.
   1214   1.1   thorpej 	 */
   1215  1.54       eeh 	ncr53c9x_dequeue(sc, ecb);
   1216   1.1   thorpej 	if (ecb == sc->sc_nexus) {
   1217   1.1   thorpej 		sc->sc_nexus = NULL;
   1218  1.15        pk 		if (sc->sc_state != NCR_CLEANING) {
   1219  1.15        pk 			sc->sc_state = NCR_IDLE;
   1220  1.15        pk 			ncr53c9x_sched(sc);
   1221  1.15        pk 		}
   1222  1.54       eeh 	}
   1223  1.54       eeh 
   1224  1.54       eeh 	if (xs->error == XS_SELTIMEOUT) {
   1225  1.54       eeh 		/* Selection timeout -- discard this LUN if empty */
   1226  1.57        pk 		if (li->untagged == NULL && li->used == 0) {
   1227  1.54       eeh 			if (lun < NCR_NLUN)
   1228  1.54       eeh 				ti->lun[lun] = NULL;
   1229  1.54       eeh 			LIST_REMOVE(li, link);
   1230  1.54       eeh 			free(li, M_DEVBUF);
   1231  1.54       eeh 		}
   1232  1.54       eeh 	}
   1233  1.54       eeh 
   1234  1.36   thorpej 	ncr53c9x_free_ecb(sc, ecb, xs->xs_control);
   1235   1.1   thorpej 	ti->cmds++;
   1236  1.18    bouyer 	scsipi_done(xs);
   1237   1.1   thorpej }
   1238   1.1   thorpej 
   1239   1.1   thorpej void
   1240   1.1   thorpej ncr53c9x_dequeue(sc, ecb)
   1241   1.1   thorpej 	struct ncr53c9x_softc *sc;
   1242   1.1   thorpej 	struct ncr53c9x_ecb *ecb;
   1243   1.1   thorpej {
   1244  1.54       eeh 	struct ncr53c9x_tinfo *ti =
   1245  1.54       eeh 		&sc->sc_tinfo[ecb->xs->sc_link->scsipi_scsi.target];
   1246  1.54       eeh 	struct ncr53c9x_linfo *li;
   1247  1.54       eeh 	int64_t lun = ecb->xs->sc_link->scsipi_scsi.lun;
   1248  1.54       eeh 
   1249  1.54       eeh 	li = TINFO_LUN(ti, lun);
   1250  1.54       eeh #ifdef DIAGNOSTIC
   1251  1.57        pk 	if (li == NULL || li->lun != lun)
   1252  1.54       eeh 		panic("ncr53c9x_dequeue: lun %qx for ecb %p does not exist\n",
   1253  1.56   thorpej 		      (long long) lun, ecb);
   1254  1.54       eeh #endif
   1255  1.54       eeh 	if (li->untagged == ecb) {
   1256  1.54       eeh 		li->busy = 0;
   1257  1.54       eeh 		li->untagged = NULL;
   1258  1.54       eeh 	}
   1259  1.57        pk 	if (ecb->tag[0] && li->queued[ecb->tag[1]] != NULL) {
   1260  1.54       eeh #ifdef DIAGNOSTIC
   1261  1.57        pk 		if (li->queued[ecb->tag[1]] != NULL &&
   1262  1.57        pk 		    (li->queued[ecb->tag[1]] != ecb))
   1263  1.54       eeh 			panic("ncr53c9x_dequeue: slot %d for lun %qx has %p "
   1264  1.56   thorpej 			      "instead of ecb %p\n", ecb->tag[1],
   1265  1.56   thorpej 			      (long long) lun,
   1266  1.54       eeh 			      li->queued[ecb->tag[1]], ecb);
   1267  1.54       eeh #endif
   1268  1.54       eeh 		li->queued[ecb->tag[1]] = NULL;
   1269  1.54       eeh 		li->used --;
   1270  1.57        pk 	}
   1271   1.1   thorpej 
   1272  1.57        pk 	if ((ecb->flags & ECB_READY) != 0) {
   1273  1.54       eeh 		ecb->flags &= ~ECB_READY;
   1274   1.1   thorpej 		TAILQ_REMOVE(&sc->ready_list, ecb, chain);
   1275   1.1   thorpej 	}
   1276   1.1   thorpej }
   1277   1.1   thorpej 
   1278   1.1   thorpej /*
   1279   1.1   thorpej  * INTERRUPT/PROTOCOL ENGINE
   1280   1.1   thorpej  */
   1281   1.1   thorpej 
   1282   1.1   thorpej /*
   1283   1.1   thorpej  * Schedule an outgoing message by prioritizing it, and asserting
   1284   1.1   thorpej  * attention on the bus. We can only do this when we are the initiator
   1285   1.1   thorpej  * else there will be an illegal command interrupt.
   1286   1.1   thorpej  */
   1287   1.1   thorpej #define ncr53c9x_sched_msgout(m) \
   1288   1.1   thorpej 	do {							\
   1289  1.54       eeh 		NCR_MISC(("ncr53c9x_sched_msgout %x %d", m, __LINE__));	\
   1290   1.1   thorpej 		NCRCMD(sc, NCRCMD_SETATN);			\
   1291   1.1   thorpej 		sc->sc_flags |= NCR_ATN;			\
   1292   1.1   thorpej 		sc->sc_msgpriq |= (m);				\
   1293   1.1   thorpej 	} while (0)
   1294   1.1   thorpej 
   1295   1.1   thorpej int
   1296  1.54       eeh ncr53c9x_reselect(sc, message, tagtype, tagid)
   1297   1.1   thorpej 	struct ncr53c9x_softc *sc;
   1298   1.1   thorpej 	int message;
   1299  1.54       eeh 	int tagtype, tagid;
   1300   1.1   thorpej {
   1301   1.1   thorpej 	u_char selid, target, lun;
   1302  1.54       eeh 	struct ncr53c9x_ecb *ecb = NULL;
   1303   1.1   thorpej 	struct ncr53c9x_tinfo *ti;
   1304  1.54       eeh 	struct ncr53c9x_linfo *li;
   1305   1.1   thorpej 
   1306   1.1   thorpej 	/*
   1307   1.1   thorpej 	 * The SCSI chip made a snapshot of the data bus while the reselection
   1308   1.1   thorpej 	 * was being negotiated.  This enables us to determine which target did
   1309   1.1   thorpej 	 * the reselect.
   1310   1.1   thorpej 	 */
   1311   1.1   thorpej 	selid = sc->sc_selid & ~(1 << sc->sc_id);
   1312   1.1   thorpej 	if (selid & (selid - 1)) {
   1313   1.1   thorpej 		printf("%s: reselect with invalid selid %02x;"
   1314   1.1   thorpej 		    " sending DEVICE RESET\n", sc->sc_dev.dv_xname, selid);
   1315   1.1   thorpej 		goto reset;
   1316   1.1   thorpej 	}
   1317   1.1   thorpej 
   1318   1.1   thorpej 	/*
   1319   1.1   thorpej 	 * Search wait queue for disconnected cmd
   1320   1.1   thorpej 	 * The list should be short, so I haven't bothered with
   1321   1.1   thorpej 	 * any more sophisticated structures than a simple
   1322   1.1   thorpej 	 * singly linked list.
   1323   1.1   thorpej 	 */
   1324   1.1   thorpej 	target = ffs(selid) - 1;
   1325   1.1   thorpej 	lun = message & 0x07;
   1326  1.54       eeh 	ti = &sc->sc_tinfo[target];
   1327  1.54       eeh 	li = TINFO_LUN(ti, lun);
   1328  1.54       eeh 
   1329  1.54       eeh 	/*
   1330  1.54       eeh 	 * We can get as far as the LUN with the IDENTIFY
   1331  1.54       eeh 	 * message.  Check to see if we're running an
   1332  1.54       eeh 	 * un-tagged command.  Otherwise ack the IDENTIFY
   1333  1.54       eeh 	 * and wait for a tag message.
   1334  1.54       eeh 	 */
   1335  1.54       eeh 
   1336  1.57        pk 	if (li != NULL) {
   1337  1.57        pk 		if (li->untagged != NULL && li->busy)
   1338  1.57        pk 			ecb = li->untagged;
   1339  1.54       eeh 		else if (tagtype != MSG_SIMPLE_Q_TAG) {
   1340  1.54       eeh 			/* Wait for tag to come by */
   1341  1.54       eeh 			sc->sc_state = NCR_IDENTIFIED;
   1342  1.54       eeh 			return (0);
   1343  1.57        pk 		} else if (tagtype)
   1344  1.57        pk 			ecb = li->queued[tagid];
   1345   1.1   thorpej 	}
   1346   1.1   thorpej 	if (ecb == NULL) {
   1347  1.54       eeh 		printf("%s: reselect from target %d lun %d tag %x:%x with no nexus;"
   1348  1.57        pk 		    " sending ABORT\n",
   1349  1.57        pk 			sc->sc_dev.dv_xname, target, lun, tagtype, tagid);
   1350   1.1   thorpej 		goto abort;
   1351   1.1   thorpej 	}
   1352   1.1   thorpej 
   1353   1.1   thorpej 	/* Make this nexus active again. */
   1354   1.1   thorpej 	sc->sc_state = NCR_CONNECTED;
   1355   1.1   thorpej 	sc->sc_nexus = ecb;
   1356   1.1   thorpej 	ncr53c9x_setsync(sc, ti);
   1357   1.1   thorpej 
   1358   1.1   thorpej 	if (ecb->flags & ECB_RESET)
   1359   1.1   thorpej 		ncr53c9x_sched_msgout(SEND_DEV_RESET);
   1360   1.1   thorpej 	else if (ecb->flags & ECB_ABORT)
   1361   1.1   thorpej 		ncr53c9x_sched_msgout(SEND_ABORT);
   1362   1.1   thorpej 
   1363   1.1   thorpej 	/* Do an implicit RESTORE POINTERS. */
   1364   1.1   thorpej 	sc->sc_dp = ecb->daddr;
   1365   1.1   thorpej 	sc->sc_dleft = ecb->dleft;
   1366   1.1   thorpej 
   1367   1.1   thorpej 	return (0);
   1368   1.1   thorpej 
   1369   1.1   thorpej reset:
   1370   1.1   thorpej 	ncr53c9x_sched_msgout(SEND_DEV_RESET);
   1371   1.1   thorpej 	return (1);
   1372   1.1   thorpej 
   1373   1.1   thorpej abort:
   1374   1.1   thorpej 	ncr53c9x_sched_msgout(SEND_ABORT);
   1375   1.1   thorpej 	return (1);
   1376   1.1   thorpej }
   1377   1.1   thorpej 
   1378   1.1   thorpej #define IS1BYTEMSG(m) (((m) != 1 && (m) < 0x20) || (m) & 0x80)
   1379   1.1   thorpej #define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
   1380   1.1   thorpej #define ISEXTMSG(m) ((m) == 1)
   1381   1.1   thorpej 
   1382   1.1   thorpej /*
   1383   1.1   thorpej  * Get an incoming message as initiator.
   1384   1.1   thorpej  *
   1385   1.1   thorpej  * The SCSI bus must already be in MESSAGE_IN_PHASE and there is a
   1386   1.1   thorpej  * byte in the FIFO
   1387   1.1   thorpej  */
   1388   1.1   thorpej void
   1389   1.1   thorpej ncr53c9x_msgin(sc)
   1390  1.49   tsutsui 	struct ncr53c9x_softc *sc;
   1391   1.1   thorpej {
   1392  1.49   tsutsui 	int v;
   1393   1.1   thorpej 
   1394  1.54       eeh 	v = (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF);
   1395  1.54       eeh 	NCR_TRACE(("[ncr53c9x_msgin(curmsglen:%ld fifo:%d)] ",
   1396  1.54       eeh 		   (long)sc->sc_imlen, v));
   1397   1.1   thorpej 
   1398  1.54       eeh 	if (v == 0) {
   1399   1.1   thorpej 		printf("%s: msgin: no msg byte available\n",
   1400   1.1   thorpej 			sc->sc_dev.dv_xname);
   1401   1.1   thorpej 		return;
   1402   1.1   thorpej 	}
   1403   1.1   thorpej 
   1404   1.1   thorpej 	/*
   1405   1.1   thorpej 	 * Prepare for a new message.  A message should (according
   1406   1.1   thorpej 	 * to the SCSI standard) be transmitted in one single
   1407   1.1   thorpej 	 * MESSAGE_IN_PHASE. If we have been in some other phase,
   1408   1.1   thorpej 	 * then this is a new message.
   1409   1.1   thorpej 	 */
   1410   1.1   thorpej 	if (sc->sc_prevphase != MESSAGE_IN_PHASE) {
   1411   1.1   thorpej 		sc->sc_flags &= ~NCR_DROP_MSGI;
   1412   1.1   thorpej 		sc->sc_imlen = 0;
   1413   1.1   thorpej 	}
   1414   1.1   thorpej 
   1415   1.1   thorpej 	v = NCR_READ_REG(sc, NCR_FIFO);
   1416   1.1   thorpej 	NCR_MISC(("<msgbyte:0x%02x>", v));
   1417   1.1   thorpej 
   1418   1.1   thorpej #if 0
   1419   1.1   thorpej 	if (sc->sc_state == NCR_RESELECTED && sc->sc_imlen == 0) {
   1420   1.1   thorpej 		/*
   1421   1.1   thorpej 		 * Which target is reselecting us? (The ID bit really)
   1422   1.1   thorpej 		 */
   1423   1.1   thorpej 		sc->sc_selid = v;
   1424   1.1   thorpej 		NCR_MISC(("selid=0x%2x ", sc->sc_selid));
   1425   1.1   thorpej 		return;
   1426   1.1   thorpej 	}
   1427   1.1   thorpej #endif
   1428   1.1   thorpej 
   1429   1.1   thorpej 	sc->sc_imess[sc->sc_imlen] = v;
   1430   1.1   thorpej 
   1431   1.1   thorpej 	/*
   1432   1.1   thorpej 	 * If we're going to reject the message, don't bother storing
   1433   1.1   thorpej 	 * the incoming bytes.  But still, we need to ACK them.
   1434   1.1   thorpej 	 */
   1435   1.1   thorpej 
   1436  1.57        pk 	if ((sc->sc_flags & NCR_DROP_MSGI) != 0) {
   1437   1.1   thorpej 		NCRCMD(sc, NCRCMD_MSGOK);
   1438   1.1   thorpej 		printf("<dropping msg byte %x>",
   1439   1.1   thorpej 			sc->sc_imess[sc->sc_imlen]);
   1440   1.1   thorpej 		return;
   1441   1.1   thorpej 	}
   1442   1.1   thorpej 
   1443   1.1   thorpej 	if (sc->sc_imlen >= NCR_MAX_MSG_LEN) {
   1444   1.1   thorpej 		ncr53c9x_sched_msgout(SEND_REJECT);
   1445   1.1   thorpej 		sc->sc_flags |= NCR_DROP_MSGI;
   1446   1.1   thorpej 	} else {
   1447   1.1   thorpej 		sc->sc_imlen++;
   1448   1.1   thorpej 		/*
   1449   1.1   thorpej 		 * This testing is suboptimal, but most
   1450   1.1   thorpej 		 * messages will be of the one byte variety, so
   1451   1.1   thorpej 		 * it should not effect performance
   1452   1.1   thorpej 		 * significantly.
   1453   1.1   thorpej 		 */
   1454   1.1   thorpej 		if (sc->sc_imlen == 1 && IS1BYTEMSG(sc->sc_imess[0]))
   1455   1.1   thorpej 			goto gotit;
   1456   1.1   thorpej 		if (sc->sc_imlen == 2 && IS2BYTEMSG(sc->sc_imess[0]))
   1457   1.1   thorpej 			goto gotit;
   1458   1.1   thorpej 		if (sc->sc_imlen >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
   1459   1.1   thorpej 		    sc->sc_imlen == sc->sc_imess[1] + 2)
   1460   1.1   thorpej 			goto gotit;
   1461   1.1   thorpej 	}
   1462   1.1   thorpej 	/* Ack what we have so far */
   1463   1.1   thorpej 	NCRCMD(sc, NCRCMD_MSGOK);
   1464   1.1   thorpej 	return;
   1465   1.1   thorpej 
   1466   1.1   thorpej gotit:
   1467   1.1   thorpej 	NCR_MSGS(("gotmsg(%x)", sc->sc_imess[0]));
   1468   1.1   thorpej 	/*
   1469   1.1   thorpej 	 * Now we should have a complete message (1 byte, 2 byte
   1470   1.1   thorpej 	 * and moderately long extended messages).  We only handle
   1471   1.1   thorpej 	 * extended messages which total length is shorter than
   1472   1.1   thorpej 	 * NCR_MAX_MSG_LEN.  Longer messages will be amputated.
   1473   1.1   thorpej 	 */
   1474   1.1   thorpej 	switch (sc->sc_state) {
   1475   1.1   thorpej 		struct ncr53c9x_ecb *ecb;
   1476   1.1   thorpej 		struct ncr53c9x_tinfo *ti;
   1477  1.66    briggs 		struct ncr53c9x_linfo *li;
   1478  1.66    briggs 		int lun;
   1479   1.1   thorpej 
   1480   1.1   thorpej 	case NCR_CONNECTED:
   1481   1.1   thorpej 		ecb = sc->sc_nexus;
   1482  1.18    bouyer 		ti = &sc->sc_tinfo[ecb->xs->sc_link->scsipi_scsi.target];
   1483   1.1   thorpej 
   1484   1.1   thorpej 		switch (sc->sc_imess[0]) {
   1485   1.1   thorpej 		case MSG_CMDCOMPLETE:
   1486   1.1   thorpej 			NCR_MSGS(("cmdcomplete "));
   1487   1.1   thorpej 			if (sc->sc_dleft < 0) {
   1488  1.30        pk 				scsi_print_addr(ecb->xs->sc_link);
   1489  1.30        pk 				printf("got %ld extra bytes\n",
   1490  1.31        pk 				       -(long)sc->sc_dleft);
   1491   1.1   thorpej 				sc->sc_dleft = 0;
   1492   1.1   thorpej 			}
   1493  1.13        pk 			ecb->dleft = (ecb->flags & ECB_TENTATIVE_DONE)
   1494  1.13        pk 				? 0
   1495  1.13        pk 				: sc->sc_dleft;
   1496  1.13        pk 			if ((ecb->flags & ECB_SENSE) == 0)
   1497  1.13        pk 				ecb->xs->resid = ecb->dleft;
   1498   1.1   thorpej 			sc->sc_state = NCR_CMDCOMPLETE;
   1499   1.1   thorpej 			break;
   1500   1.1   thorpej 
   1501   1.1   thorpej 		case MSG_MESSAGE_REJECT:
   1502  1.23        pk 			NCR_MSGS(("msg reject (msgout=%x) ", sc->sc_msgout));
   1503   1.1   thorpej 			switch (sc->sc_msgout) {
   1504  1.66    briggs 			case SEND_TAG:
   1505  1.66    briggs 				/*
   1506  1.66    briggs 				 * Target does not like tagged queuing.
   1507  1.66    briggs 				 *  - Flush the command queue
   1508  1.66    briggs 				 *  - Disable tagged queuing for the target
   1509  1.66    briggs 				 *  - Dequeue ecb from the queued array.
   1510  1.66    briggs 				 */
   1511  1.66    briggs 				NCR_MSGS(("(rejected sent tag)"));
   1512  1.66    briggs 				NCRCMD(sc, NCRCMD_FLUSH);
   1513  1.66    briggs 				DELAY(1);
   1514  1.70       eeh 				ti->flags &= ~T_TAG;
   1515  1.66    briggs 				lun = ecb->xs->sc_link->scsipi_scsi.lun;
   1516  1.66    briggs 				li = TINFO_LUN(ti, lun);
   1517  1.66    briggs 				if (ecb->tag[0] &&
   1518  1.66    briggs 				    li->queued[ecb->tag[1]] != NULL) {
   1519  1.66    briggs 					li->queued[ecb->tag[1]] = NULL;
   1520  1.66    briggs 					li->used --;
   1521  1.66    briggs 				}
   1522  1.66    briggs 				ecb->tag[0] = ecb->tag[1] = 0;
   1523  1.66    briggs 				li->untagged = ecb;
   1524  1.66    briggs 				li->busy = 1;
   1525  1.66    briggs 				break;
   1526  1.66    briggs 
   1527   1.1   thorpej 			case SEND_SDTR:
   1528   1.1   thorpej 				sc->sc_flags &= ~NCR_SYNCHNEGO;
   1529   1.1   thorpej 				ti->flags &= ~(T_NEGOTIATE | T_SYNCMODE);
   1530   1.1   thorpej 				ncr53c9x_setsync(sc, ti);
   1531   1.1   thorpej 				break;
   1532  1.66    briggs 
   1533   1.1   thorpej 			case SEND_INIT_DET_ERR:
   1534   1.1   thorpej 				goto abort;
   1535   1.1   thorpej 			}
   1536   1.1   thorpej 			break;
   1537   1.1   thorpej 
   1538   1.1   thorpej 		case MSG_NOOP:
   1539   1.1   thorpej 			NCR_MSGS(("noop "));
   1540   1.1   thorpej 			break;
   1541   1.1   thorpej 
   1542  1.54       eeh 		case MSG_HEAD_OF_Q_TAG:
   1543  1.54       eeh 		case MSG_SIMPLE_Q_TAG:
   1544  1.54       eeh 		case MSG_ORDERED_Q_TAG:
   1545  1.54       eeh 			NCR_MSGS(("TAG %x:%x", sc->sc_imess[0], sc->sc_imess[1]));
   1546  1.54       eeh 			break;
   1547  1.54       eeh 
   1548   1.1   thorpej 		case MSG_DISCONNECT:
   1549   1.1   thorpej 			NCR_MSGS(("disconnect "));
   1550   1.1   thorpej 			ti->dconns++;
   1551   1.1   thorpej 			sc->sc_state = NCR_DISCONNECT;
   1552   1.8        pk 
   1553  1.13        pk 			/*
   1554  1.13        pk 			 * Mark the fact that all bytes have moved. The
   1555  1.13        pk 			 * target may not bother to do a SAVE POINTERS
   1556  1.13        pk 			 * at this stage. This flag will set the residual
   1557  1.13        pk 			 * count to zero on MSG COMPLETE.
   1558  1.13        pk 			 */
   1559  1.13        pk 			if (sc->sc_dleft == 0)
   1560  1.13        pk 				ecb->flags |= ECB_TENTATIVE_DONE;
   1561  1.13        pk 
   1562  1.13        pk 			break;
   1563   1.1   thorpej 
   1564   1.1   thorpej 		case MSG_SAVEDATAPOINTER:
   1565   1.1   thorpej 			NCR_MSGS(("save datapointer "));
   1566   1.1   thorpej 			ecb->daddr = sc->sc_dp;
   1567   1.1   thorpej 			ecb->dleft = sc->sc_dleft;
   1568   1.1   thorpej 			break;
   1569   1.1   thorpej 
   1570   1.1   thorpej 		case MSG_RESTOREPOINTERS:
   1571   1.1   thorpej 			NCR_MSGS(("restore datapointer "));
   1572   1.1   thorpej 			sc->sc_dp = ecb->daddr;
   1573   1.1   thorpej 			sc->sc_dleft = ecb->dleft;
   1574   1.1   thorpej 			break;
   1575   1.1   thorpej 
   1576   1.1   thorpej 		case MSG_EXTENDED:
   1577   1.1   thorpej 			NCR_MSGS(("extended(%x) ", sc->sc_imess[2]));
   1578   1.1   thorpej 			switch (sc->sc_imess[2]) {
   1579   1.1   thorpej 			case MSG_EXT_SDTR:
   1580   1.1   thorpej 				NCR_MSGS(("SDTR period %d, offset %d ",
   1581   1.1   thorpej 					sc->sc_imess[3], sc->sc_imess[4]));
   1582   1.1   thorpej 				if (sc->sc_imess[1] != 3)
   1583   1.1   thorpej 					goto reject;
   1584   1.1   thorpej 				ti->period = sc->sc_imess[3];
   1585   1.1   thorpej 				ti->offset = sc->sc_imess[4];
   1586   1.1   thorpej 				ti->flags &= ~T_NEGOTIATE;
   1587   1.1   thorpej 				if (sc->sc_minsync == 0 ||
   1588   1.1   thorpej 				    ti->offset == 0 ||
   1589   1.1   thorpej 				    ti->period > 124) {
   1590  1.29        pk #ifdef NCR53C9X_DEBUG
   1591  1.29        pk 					scsi_print_addr(ecb->xs->sc_link);
   1592  1.29        pk 					printf("async mode\n");
   1593  1.29        pk #endif
   1594  1.57        pk 					if ((sc->sc_flags&NCR_SYNCHNEGO) == 0) {
   1595   1.1   thorpej 						/*
   1596   1.1   thorpej 						 * target initiated negotiation
   1597   1.1   thorpej 						 */
   1598   1.1   thorpej 						ti->offset = 0;
   1599   1.1   thorpej 						ti->flags &= ~T_SYNCMODE;
   1600   1.1   thorpej 						ncr53c9x_sched_msgout(
   1601   1.1   thorpej 						    SEND_SDTR);
   1602   1.1   thorpej 					} else {
   1603   1.1   thorpej 						/* we are async */
   1604   1.1   thorpej 						ti->flags &= ~T_SYNCMODE;
   1605   1.1   thorpej 					}
   1606   1.1   thorpej 				} else {
   1607   1.1   thorpej 					int r = 250/ti->period;
   1608   1.1   thorpej 					int s = (100*250)/ti->period - 100*r;
   1609   1.1   thorpej 					int p;
   1610   1.1   thorpej 
   1611   1.1   thorpej 					p = ncr53c9x_stp2cpb(sc, ti->period);
   1612   1.1   thorpej 					ti->period = ncr53c9x_cpb2stp(sc, p);
   1613   1.1   thorpej #ifdef NCR53C9X_DEBUG
   1614  1.18    bouyer 					scsi_print_addr(ecb->xs->sc_link);
   1615  1.41      matt 					printf("max sync rate %d.%02dMB/s\n",
   1616   1.1   thorpej 						r, s);
   1617   1.1   thorpej #endif
   1618  1.22        pk 					if ((sc->sc_flags&NCR_SYNCHNEGO) == 0) {
   1619   1.1   thorpej 						/*
   1620   1.1   thorpej 						 * target initiated negotiation
   1621   1.1   thorpej 						 */
   1622   1.1   thorpej 						if (ti->period <
   1623   1.1   thorpej 						    sc->sc_minsync)
   1624   1.1   thorpej 							ti->period =
   1625   1.1   thorpej 							    sc->sc_minsync;
   1626   1.1   thorpej 						if (ti->offset > 15)
   1627   1.1   thorpej 							ti->offset = 15;
   1628   1.1   thorpej 						ti->flags &= ~T_SYNCMODE;
   1629   1.1   thorpej 						ncr53c9x_sched_msgout(
   1630   1.1   thorpej 						    SEND_SDTR);
   1631   1.1   thorpej 					} else {
   1632   1.1   thorpej 						/* we are sync */
   1633   1.1   thorpej 						ti->flags |= T_SYNCMODE;
   1634   1.1   thorpej 					}
   1635   1.1   thorpej 				}
   1636   1.1   thorpej 				sc->sc_flags &= ~NCR_SYNCHNEGO;
   1637   1.1   thorpej 				ncr53c9x_setsync(sc, ti);
   1638   1.1   thorpej 				break;
   1639   1.1   thorpej 
   1640   1.1   thorpej 			default:
   1641  1.30        pk 				scsi_print_addr(ecb->xs->sc_link);
   1642  1.30        pk 				printf("unrecognized MESSAGE EXTENDED;"
   1643  1.30        pk 				       " sending REJECT\n");
   1644   1.1   thorpej 				goto reject;
   1645   1.1   thorpej 			}
   1646   1.1   thorpej 			break;
   1647   1.1   thorpej 
   1648   1.1   thorpej 		default:
   1649   1.1   thorpej 			NCR_MSGS(("ident "));
   1650  1.30        pk 			scsi_print_addr(ecb->xs->sc_link);
   1651  1.30        pk 			printf("unrecognized MESSAGE; sending REJECT\n");
   1652   1.1   thorpej 		reject:
   1653   1.1   thorpej 			ncr53c9x_sched_msgout(SEND_REJECT);
   1654   1.1   thorpej 			break;
   1655   1.1   thorpej 		}
   1656   1.1   thorpej 		break;
   1657   1.1   thorpej 
   1658   1.1   thorpej 	case NCR_RESELECTED:
   1659  1.54       eeh 	case NCR_IDENTIFIED:
   1660  1.54       eeh 		if (MSG_ISIDENTIFY(sc->sc_imess[0])) {
   1661  1.54       eeh 			sc->sc_msgify = sc->sc_imess[0];
   1662  1.54       eeh 		} else if (sc->sc_imess[0] == MSG_SIMPLE_Q_TAG) {
   1663  1.57        pk 			if (sc->sc_msgify == 0) {
   1664  1.54       eeh 				printf("%s: TAG reselect without IDENTIFY;"
   1665  1.54       eeh 				       " MSG %x;"
   1666  1.54       eeh 				       " sending DEVICE RESET\n",
   1667  1.55        pk 				       sc->sc_dev.dv_xname,
   1668  1.55        pk 				       sc->sc_imess[0]);
   1669  1.54       eeh 				goto reset;
   1670  1.54       eeh 			}
   1671  1.54       eeh 		} else {
   1672  1.31        pk 			printf("%s: reselect without IDENTIFY;"
   1673  1.54       eeh 			       " MSG %x;"
   1674  1.31        pk 			       " sending DEVICE RESET\n",
   1675  1.55        pk 			       sc->sc_dev.dv_xname,
   1676  1.55        pk 			       sc->sc_imess[0]);
   1677   1.1   thorpej 			goto reset;
   1678   1.1   thorpej 		}
   1679   1.1   thorpej 
   1680  1.54       eeh 		(void) ncr53c9x_reselect(sc, sc->sc_msgify,
   1681  1.54       eeh 					 sc->sc_imess[0],
   1682  1.54       eeh 					 sc->sc_imess[1]);
   1683   1.1   thorpej 		break;
   1684   1.1   thorpej 
   1685   1.1   thorpej 	default:
   1686  1.31        pk 		printf("%s: unexpected MESSAGE IN; sending DEVICE RESET\n",
   1687  1.31        pk 			sc->sc_dev.dv_xname);
   1688   1.1   thorpej 	reset:
   1689   1.1   thorpej 		ncr53c9x_sched_msgout(SEND_DEV_RESET);
   1690   1.1   thorpej 		break;
   1691   1.1   thorpej 
   1692   1.1   thorpej 	abort:
   1693   1.1   thorpej 		ncr53c9x_sched_msgout(SEND_ABORT);
   1694   1.1   thorpej 		break;
   1695   1.1   thorpej 	}
   1696   1.1   thorpej 
   1697  1.68       eeh 	/* if we have more messages to send set ATN */
   1698  1.68       eeh 	if (sc->sc_msgpriq) NCRCMD(sc, NCRCMD_SETATN);
   1699  1.68       eeh 
   1700   1.1   thorpej 	/* Ack last message byte */
   1701   1.1   thorpej 	NCRCMD(sc, NCRCMD_MSGOK);
   1702   1.1   thorpej 
   1703   1.1   thorpej 	/* Done, reset message pointer. */
   1704   1.1   thorpej 	sc->sc_flags &= ~NCR_DROP_MSGI;
   1705   1.1   thorpej 	sc->sc_imlen = 0;
   1706   1.1   thorpej }
   1707   1.1   thorpej 
   1708   1.1   thorpej 
   1709   1.1   thorpej /*
   1710   1.1   thorpej  * Send the highest priority, scheduled message
   1711   1.1   thorpej  */
   1712   1.1   thorpej void
   1713   1.1   thorpej ncr53c9x_msgout(sc)
   1714  1.49   tsutsui 	struct ncr53c9x_softc *sc;
   1715   1.1   thorpej {
   1716   1.1   thorpej 	struct ncr53c9x_tinfo *ti;
   1717   1.1   thorpej 	struct ncr53c9x_ecb *ecb;
   1718   1.1   thorpej 	size_t size;
   1719   1.1   thorpej 
   1720   1.1   thorpej 	NCR_TRACE(("[ncr53c9x_msgout(priq:%x, prevphase:%x)]",
   1721   1.1   thorpej 	    sc->sc_msgpriq, sc->sc_prevphase));
   1722   1.1   thorpej 
   1723  1.22        pk 	/*
   1724  1.22        pk 	 * XXX - the NCR_ATN flag is not in sync with the actual ATN
   1725  1.22        pk 	 *	 condition on the SCSI bus. The 53c9x chip
   1726  1.22        pk 	 *	 automatically turns off ATN before sending the
   1727  1.22        pk 	 *	 message byte.  (see also the comment below in the
   1728  1.22        pk 	 *	 default case when picking out a message to send)
   1729  1.22        pk 	 */
   1730   1.1   thorpej 	if (sc->sc_flags & NCR_ATN) {
   1731   1.1   thorpej 		if (sc->sc_prevphase != MESSAGE_OUT_PHASE) {
   1732   1.1   thorpej 		new:
   1733   1.1   thorpej 			NCRCMD(sc, NCRCMD_FLUSH);
   1734  1.68       eeh /*			DELAY(1); */
   1735   1.1   thorpej 			sc->sc_msgoutq = 0;
   1736   1.1   thorpej 			sc->sc_omlen = 0;
   1737   1.1   thorpej 		}
   1738   1.1   thorpej 	} else {
   1739   1.1   thorpej 		if (sc->sc_prevphase == MESSAGE_OUT_PHASE) {
   1740   1.1   thorpej 			ncr53c9x_sched_msgout(sc->sc_msgoutq);
   1741   1.1   thorpej 			goto new;
   1742   1.1   thorpej 		} else {
   1743   1.1   thorpej 			printf("%s at line %d: unexpected MESSAGE OUT phase\n",
   1744   1.1   thorpej 			    sc->sc_dev.dv_xname, __LINE__);
   1745   1.1   thorpej 		}
   1746   1.1   thorpej 	}
   1747   1.1   thorpej 
   1748   1.1   thorpej 	if (sc->sc_omlen == 0) {
   1749   1.1   thorpej 		/* Pick up highest priority message */
   1750   1.1   thorpej 		sc->sc_msgout = sc->sc_msgpriq & -sc->sc_msgpriq;
   1751   1.1   thorpej 		sc->sc_msgoutq |= sc->sc_msgout;
   1752   1.1   thorpej 		sc->sc_msgpriq &= ~sc->sc_msgout;
   1753   1.1   thorpej 		sc->sc_omlen = 1;		/* "Default" message len */
   1754   1.1   thorpej 		switch (sc->sc_msgout) {
   1755   1.1   thorpej 		case SEND_SDTR:
   1756   1.1   thorpej 			ecb = sc->sc_nexus;
   1757  1.18    bouyer 			ti = &sc->sc_tinfo[ecb->xs->sc_link->scsipi_scsi.target];
   1758   1.1   thorpej 			sc->sc_omess[0] = MSG_EXTENDED;
   1759   1.1   thorpej 			sc->sc_omess[1] = 3;
   1760   1.1   thorpej 			sc->sc_omess[2] = MSG_EXT_SDTR;
   1761   1.1   thorpej 			sc->sc_omess[3] = ti->period;
   1762   1.1   thorpej 			sc->sc_omess[4] = ti->offset;
   1763   1.1   thorpej 			sc->sc_omlen = 5;
   1764   1.1   thorpej 			if ((sc->sc_flags & NCR_SYNCHNEGO) == 0) {
   1765   1.1   thorpej 				ti->flags |= T_SYNCMODE;
   1766   1.1   thorpej 				ncr53c9x_setsync(sc, ti);
   1767   1.1   thorpej 			}
   1768   1.1   thorpej 			break;
   1769  1.54       eeh                 case SEND_IDENTIFY:
   1770  1.54       eeh                         if (sc->sc_state != NCR_CONNECTED) {
   1771  1.54       eeh                                 printf("%s at line %d: no nexus\n",
   1772  1.54       eeh                                     sc->sc_dev.dv_xname, __LINE__);
   1773  1.54       eeh                         }
   1774  1.54       eeh                         ecb = sc->sc_nexus;
   1775  1.54       eeh                         sc->sc_omess[0] =
   1776  1.54       eeh                             MSG_IDENTIFY(ecb->xs->sc_link->scsipi_scsi.lun, 0);
   1777  1.54       eeh                         break;
   1778  1.54       eeh 		case SEND_TAG:
   1779   1.1   thorpej 			if (sc->sc_state != NCR_CONNECTED) {
   1780   1.1   thorpej 				printf("%s at line %d: no nexus\n",
   1781   1.1   thorpej 				    sc->sc_dev.dv_xname, __LINE__);
   1782   1.1   thorpej 			}
   1783   1.1   thorpej 			ecb = sc->sc_nexus;
   1784  1.54       eeh 			sc->sc_omess[0] = ecb->tag[0];
   1785  1.54       eeh 			sc->sc_omess[1] = ecb->tag[1];
   1786  1.54       eeh 			sc->sc_omlen = 2;
   1787   1.1   thorpej 			break;
   1788   1.1   thorpej 		case SEND_DEV_RESET:
   1789   1.1   thorpej 			sc->sc_flags |= NCR_ABORTING;
   1790   1.1   thorpej 			sc->sc_omess[0] = MSG_BUS_DEV_RESET;
   1791   1.1   thorpej 			ecb = sc->sc_nexus;
   1792  1.18    bouyer 			ti = &sc->sc_tinfo[ecb->xs->sc_link->scsipi_scsi.target];
   1793   1.1   thorpej 			ti->flags &= ~T_SYNCMODE;
   1794  1.53        pk 			if ((ti->flags & T_SYNCHOFF) == 0)
   1795  1.53        pk 				/* We can re-start sync negotiation */
   1796  1.53        pk 				ti->flags |= T_NEGOTIATE;
   1797   1.1   thorpej 			break;
   1798   1.1   thorpej 		case SEND_PARITY_ERROR:
   1799   1.1   thorpej 			sc->sc_omess[0] = MSG_PARITY_ERROR;
   1800   1.1   thorpej 			break;
   1801   1.1   thorpej 		case SEND_ABORT:
   1802   1.1   thorpej 			sc->sc_flags |= NCR_ABORTING;
   1803   1.1   thorpej 			sc->sc_omess[0] = MSG_ABORT;
   1804   1.1   thorpej 			break;
   1805   1.1   thorpej 		case SEND_INIT_DET_ERR:
   1806   1.1   thorpej 			sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
   1807   1.1   thorpej 			break;
   1808   1.1   thorpej 		case SEND_REJECT:
   1809   1.1   thorpej 			sc->sc_omess[0] = MSG_MESSAGE_REJECT;
   1810   1.1   thorpej 			break;
   1811   1.1   thorpej 		default:
   1812  1.22        pk 			/*
   1813  1.22        pk 			 * We normally do not get here, since the chip
   1814  1.22        pk 			 * automatically turns off ATN before the last
   1815  1.22        pk 			 * byte of a message is sent to the target.
   1816  1.22        pk 			 * However, if the target rejects our (multi-byte)
   1817  1.22        pk 			 * message early by switching to MSG IN phase
   1818  1.22        pk 			 * ATN remains on, so the target may return to
   1819  1.22        pk 			 * MSG OUT phase. If there are no scheduled messages
   1820  1.22        pk 			 * left we send a NO-OP.
   1821  1.22        pk 			 *
   1822  1.22        pk 			 * XXX - Note that this leaves no useful purpose for
   1823  1.22        pk 			 * the NCR_ATN flag.
   1824  1.22        pk 			 */
   1825   1.1   thorpej 			sc->sc_flags &= ~NCR_ATN;
   1826   1.1   thorpej 			sc->sc_omess[0] = MSG_NOOP;
   1827   1.1   thorpej 			break;
   1828   1.1   thorpej 		}
   1829   1.1   thorpej 		sc->sc_omp = sc->sc_omess;
   1830   1.1   thorpej 	}
   1831   1.1   thorpej 
   1832  1.54       eeh #ifdef DEBUG
   1833  1.54       eeh 	{
   1834  1.54       eeh 		int i;
   1835  1.54       eeh 
   1836  1.57        pk 		for (i = 0; i < sc->sc_omlen; i++)
   1837  1.54       eeh 			NCR_MISC(("<msgbyte:0x%02x>", sc->sc_omess[i]));
   1838  1.54       eeh 	}
   1839  1.54       eeh #endif
   1840   1.1   thorpej 	/* (re)send the message */
   1841   1.1   thorpej 	size = min(sc->sc_omlen, sc->sc_maxxfer);
   1842   1.1   thorpej 	NCRDMA_SETUP(sc, &sc->sc_omp, &sc->sc_omlen, 0, &size);
   1843   1.1   thorpej 	/* Program the SCSI counter */
   1844   1.1   thorpej 	NCR_WRITE_REG(sc, NCR_TCL, size);
   1845   1.1   thorpej 	NCR_WRITE_REG(sc, NCR_TCM, size >> 8);
   1846   1.1   thorpej 	if (sc->sc_cfg2 & NCRCFG2_FE) {
   1847   1.1   thorpej 		NCR_WRITE_REG(sc, NCR_TCH, size >> 16);
   1848   1.1   thorpej 	}
   1849  1.22        pk 	/* Load the count in and start the message-out transfer */
   1850   1.1   thorpej 	NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA);
   1851   1.1   thorpej 	NCRCMD(sc, NCRCMD_TRANS|NCRCMD_DMA);
   1852   1.1   thorpej 	NCRDMA_GO(sc);
   1853   1.1   thorpej }
   1854   1.1   thorpej 
   1855   1.1   thorpej /*
   1856   1.1   thorpej  * This is the most critical part of the driver, and has to know
   1857   1.1   thorpej  * how to deal with *all* error conditions and phases from the SCSI
   1858   1.1   thorpej  * bus. If there are no errors and the DMA was active, then call the
   1859   1.1   thorpej  * DMA pseudo-interrupt handler. If this returns 1, then that was it
   1860   1.1   thorpej  * and we can return from here without further processing.
   1861   1.1   thorpej  *
   1862   1.1   thorpej  * Most of this needs verifying.
   1863   1.1   thorpej  */
   1864   1.1   thorpej int
   1865  1.42   mycroft ncr53c9x_intr(arg)
   1866  1.42   mycroft 	void *arg;
   1867   1.1   thorpej {
   1868  1.49   tsutsui 	struct ncr53c9x_softc *sc = arg;
   1869  1.49   tsutsui 	struct ncr53c9x_ecb *ecb;
   1870  1.49   tsutsui 	struct scsipi_link *sc_link;
   1871   1.1   thorpej 	struct ncr53c9x_tinfo *ti;
   1872   1.1   thorpej 	size_t size;
   1873   1.5        pk 	int nfifo;
   1874   1.1   thorpej 
   1875  1.10        pk 	NCR_TRACE(("[ncr53c9x_intr] "));
   1876   1.1   thorpej 
   1877  1.25        pk 	if (!NCRDMA_ISINTR(sc))
   1878  1.25        pk 		return (0);
   1879  1.25        pk 
   1880  1.25        pk again:
   1881  1.25        pk 	/* and what do the registers say... */
   1882  1.25        pk 	ncr53c9x_readregs(sc);
   1883  1.25        pk 
   1884  1.25        pk 	sc->sc_intrcnt.ev_count++;
   1885  1.25        pk 
   1886   1.1   thorpej 	/*
   1887  1.25        pk 	 * At the moment, only a SCSI Bus Reset or Illegal
   1888  1.25        pk 	 * Command are classed as errors. A disconnect is a
   1889  1.25        pk 	 * valid condition, and we let the code check is the
   1890  1.25        pk 	 * "NCR_BUSFREE_OK" flag was set before declaring it
   1891  1.25        pk 	 * and error.
   1892   1.1   thorpej 	 *
   1893  1.25        pk 	 * Also, the status register tells us about "Gross
   1894  1.25        pk 	 * Errors" and "Parity errors". Only the Gross Error
   1895  1.25        pk 	 * is really bad, and the parity errors are dealt
   1896  1.25        pk 	 * with later
   1897   1.1   thorpej 	 *
   1898  1.25        pk 	 * TODO
   1899  1.25        pk 	 *	If there are too many parity error, go to slow
   1900  1.25        pk 	 *	cable mode ?
   1901   1.1   thorpej 	 */
   1902  1.25        pk 
   1903  1.25        pk 	/* SCSI Reset */
   1904  1.57        pk 	if ((sc->sc_espintr & NCRINTR_SBR) != 0) {
   1905  1.57        pk 		if ((NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) != 0) {
   1906  1.25        pk 			NCRCMD(sc, NCRCMD_FLUSH);
   1907  1.25        pk 			DELAY(1);
   1908  1.25        pk 		}
   1909  1.25        pk 		if (sc->sc_state != NCR_SBR) {
   1910  1.25        pk 			printf("%s: SCSI bus reset\n",
   1911  1.25        pk 				sc->sc_dev.dv_xname);
   1912  1.25        pk 			ncr53c9x_init(sc, 0); /* Restart everything */
   1913  1.25        pk 			return (1);
   1914  1.25        pk 		}
   1915   1.1   thorpej #if 0
   1916  1.25        pk /*XXX*/		printf("<expected bus reset: "
   1917  1.25        pk 			"[intr %x, stat %x, step %d]>\n",
   1918  1.25        pk 			sc->sc_espintr, sc->sc_espstat,
   1919  1.25        pk 			sc->sc_espstep);
   1920   1.1   thorpej #endif
   1921  1.57        pk 		if (sc->sc_nexus != NULL)
   1922  1.25        pk 			panic("%s: nexus in reset state",
   1923  1.25        pk 			      sc->sc_dev.dv_xname);
   1924  1.25        pk 		goto sched;
   1925  1.25        pk 	}
   1926   1.1   thorpej 
   1927  1.25        pk 	ecb = sc->sc_nexus;
   1928   1.1   thorpej 
   1929  1.25        pk #define NCRINTR_ERR (NCRINTR_SBR|NCRINTR_ILL)
   1930  1.25        pk 	if (sc->sc_espintr & NCRINTR_ERR ||
   1931  1.25        pk 	    sc->sc_espstat & NCRSTAT_GE) {
   1932   1.1   thorpej 
   1933  1.57        pk 		if ((sc->sc_espstat & NCRSTAT_GE) != 0) {
   1934  1.25        pk 			/* Gross Error; no target ? */
   1935   1.1   thorpej 			if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) {
   1936   1.1   thorpej 				NCRCMD(sc, NCRCMD_FLUSH);
   1937   1.1   thorpej 				DELAY(1);
   1938   1.1   thorpej 			}
   1939  1.25        pk 			if (sc->sc_state == NCR_CONNECTED ||
   1940  1.25        pk 			    sc->sc_state == NCR_SELECTING) {
   1941  1.25        pk 				ecb->xs->error = XS_TIMEOUT;
   1942  1.25        pk 				ncr53c9x_done(sc, ecb);
   1943   1.1   thorpej 			}
   1944  1.25        pk 			return (1);
   1945   1.1   thorpej 		}
   1946   1.1   thorpej 
   1947  1.57        pk 		if ((sc->sc_espintr & NCRINTR_ILL) != 0) {
   1948  1.57        pk 			if ((sc->sc_flags & NCR_EXPECT_ILLCMD) != 0) {
   1949  1.25        pk 				/*
   1950  1.25        pk 				 * Eat away "Illegal command" interrupt
   1951  1.25        pk 				 * on a ESP100 caused by a re-selection
   1952  1.25        pk 				 * while we were trying to select
   1953  1.25        pk 				 * another target.
   1954  1.25        pk 				 */
   1955  1.19        pk #ifdef DEBUG
   1956  1.25        pk 				printf("%s: ESP100 work-around activated\n",
   1957  1.25        pk 					sc->sc_dev.dv_xname);
   1958  1.19        pk #endif
   1959  1.25        pk 				sc->sc_flags &= ~NCR_EXPECT_ILLCMD;
   1960  1.25        pk 				return (1);
   1961  1.25        pk 			}
   1962  1.25        pk 			/* illegal command, out of sync ? */
   1963  1.25        pk 			printf("%s: illegal command: 0x%x "
   1964  1.25        pk 			    "(state %d, phase %x, prevphase %x)\n",
   1965  1.25        pk 				sc->sc_dev.dv_xname, sc->sc_lastcmd,
   1966  1.25        pk 				sc->sc_state, sc->sc_phase,
   1967  1.25        pk 				sc->sc_prevphase);
   1968  1.25        pk 			if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) {
   1969  1.25        pk 				NCRCMD(sc, NCRCMD_FLUSH);
   1970  1.25        pk 				DELAY(1);
   1971   1.1   thorpej 			}
   1972  1.25        pk 			ncr53c9x_init(sc, 1); /* Restart everything */
   1973  1.25        pk 			return (1);
   1974   1.1   thorpej 		}
   1975  1.25        pk 	}
   1976  1.25        pk 	sc->sc_flags &= ~NCR_EXPECT_ILLCMD;
   1977   1.1   thorpej 
   1978  1.25        pk 	/*
   1979  1.25        pk 	 * Call if DMA is active.
   1980  1.25        pk 	 *
   1981  1.25        pk 	 * If DMA_INTR returns true, then maybe go 'round the loop
   1982  1.25        pk 	 * again in case there is no more DMA queued, but a phase
   1983  1.25        pk 	 * change is expected.
   1984  1.25        pk 	 */
   1985  1.25        pk 	if (NCRDMA_ISACTIVE(sc)) {
   1986  1.25        pk 		int r = NCRDMA_INTR(sc);
   1987  1.25        pk 		if (r == -1) {
   1988  1.25        pk 			printf("%s: DMA error; resetting\n",
   1989  1.25        pk 				sc->sc_dev.dv_xname);
   1990  1.25        pk 			ncr53c9x_init(sc, 1);
   1991  1.25        pk 		}
   1992  1.25        pk 		/* If DMA active here, then go back to work... */
   1993  1.25        pk 		if (NCRDMA_ISACTIVE(sc))
   1994  1.25        pk 			return (1);
   1995   1.1   thorpej 
   1996  1.25        pk 		if ((sc->sc_espstat & NCRSTAT_TC) == 0) {
   1997  1.25        pk 			/*
   1998  1.25        pk 			 * DMA not completed.  If we can not find a
   1999  1.25        pk 			 * acceptable explanation, print a diagnostic.
   2000  1.25        pk 			 */
   2001  1.25        pk 			if (sc->sc_state == NCR_SELECTING)
   2002  1.25        pk 				/*
   2003  1.25        pk 				 * This can happen if we are reselected
   2004  1.25        pk 				 * while using DMA to select a target.
   2005  1.25        pk 				 */
   2006  1.25        pk 				/*void*/;
   2007  1.25        pk 			else if (sc->sc_prevphase == MESSAGE_OUT_PHASE) {
   2008  1.25        pk 				/*
   2009  1.25        pk 				 * Our (multi-byte) message (eg SDTR) was
   2010  1.25        pk 				 * interrupted by the target to send
   2011  1.25        pk 				 * a MSG REJECT.
   2012  1.25        pk 				 * Print diagnostic if current phase
   2013  1.25        pk 				 * is not MESSAGE IN.
   2014  1.25        pk 				 */
   2015  1.25        pk 				if (sc->sc_phase != MESSAGE_IN_PHASE)
   2016  1.25        pk 				    printf("%s: !TC on MSG OUT"
   2017  1.25        pk 				       " [intr %x, stat %x, step %d]"
   2018  1.34   thorpej 				       " prevphase %x, resid %lx\n",
   2019  1.25        pk 					sc->sc_dev.dv_xname,
   2020  1.25        pk 					sc->sc_espintr,
   2021  1.25        pk 					sc->sc_espstat,
   2022  1.25        pk 					sc->sc_espstep,
   2023  1.25        pk 					sc->sc_prevphase,
   2024  1.34   thorpej 					(u_long)sc->sc_omlen);
   2025  1.25        pk 			} else if (sc->sc_dleft == 0) {
   2026  1.22        pk 				/*
   2027  1.25        pk 				 * The DMA operation was started for
   2028  1.25        pk 				 * a DATA transfer. Print a diagnostic
   2029  1.25        pk 				 * if the DMA counter and TC bit
   2030  1.25        pk 				 * appear to be out of sync.
   2031  1.22        pk 				 */
   2032  1.25        pk 				printf("%s: !TC on DATA XFER"
   2033  1.25        pk 				       " [intr %x, stat %x, step %d]"
   2034  1.25        pk 				       " prevphase %x, resid %x\n",
   2035  1.25        pk 					sc->sc_dev.dv_xname,
   2036  1.25        pk 					sc->sc_espintr,
   2037  1.25        pk 					sc->sc_espstat,
   2038  1.25        pk 					sc->sc_espstep,
   2039  1.25        pk 					sc->sc_prevphase,
   2040  1.25        pk 					ecb?ecb->dleft:-1);
   2041  1.22        pk 			}
   2042   1.1   thorpej 		}
   2043  1.25        pk 	}
   2044  1.25        pk 
   2045  1.25        pk 	/*
   2046  1.25        pk 	 * Check for less serious errors.
   2047  1.25        pk 	 */
   2048  1.57        pk 	if ((sc->sc_espstat & NCRSTAT_PE) != 0) {
   2049  1.25        pk 		printf("%s: SCSI bus parity error\n", sc->sc_dev.dv_xname);
   2050  1.25        pk 		if (sc->sc_prevphase == MESSAGE_IN_PHASE)
   2051  1.25        pk 			ncr53c9x_sched_msgout(SEND_PARITY_ERROR);
   2052  1.25        pk 		else
   2053  1.25        pk 			ncr53c9x_sched_msgout(SEND_INIT_DET_ERR);
   2054  1.25        pk 	}
   2055   1.1   thorpej 
   2056  1.57        pk 	if ((sc->sc_espintr & NCRINTR_DIS) != 0) {
   2057  1.54       eeh 		sc->sc_msgify = 0;
   2058  1.25        pk 		NCR_MISC(("<DISC [intr %x, stat %x, step %d]>",
   2059  1.25        pk 			sc->sc_espintr,sc->sc_espstat,sc->sc_espstep));
   2060  1.25        pk 		if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) {
   2061  1.25        pk 			NCRCMD(sc, NCRCMD_FLUSH);
   2062  1.68       eeh /*			DELAY(1); */
   2063   1.1   thorpej 		}
   2064   1.1   thorpej 		/*
   2065  1.25        pk 		 * This command must (apparently) be issued within
   2066  1.25        pk 		 * 250mS of a disconnect. So here you are...
   2067   1.1   thorpej 		 */
   2068  1.25        pk 		NCRCMD(sc, NCRCMD_ENSEL);
   2069   1.1   thorpej 
   2070  1.25        pk 		switch (sc->sc_state) {
   2071  1.25        pk 		case NCR_RESELECTED:
   2072  1.25        pk 			goto sched;
   2073  1.22        pk 
   2074  1.54       eeh 		case NCR_SELECTING:
   2075  1.54       eeh 		{
   2076  1.54       eeh 			struct ncr53c9x_linfo *li;
   2077  1.54       eeh 
   2078  1.25        pk 			ecb->xs->error = XS_SELTIMEOUT;
   2079  1.54       eeh 
   2080  1.54       eeh 			/* Selection timeout -- discard all LUNs if empty */
   2081  1.54       eeh 			sc_link = ecb->xs->sc_link;
   2082  1.54       eeh 			ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
   2083  1.57        pk 			li = LIST_FIRST(&ti->luns);
   2084  1.57        pk 			while (li != NULL) {
   2085  1.57        pk 				if (li->untagged == NULL && li->used == 0) {
   2086  1.54       eeh 					if (li->lun < NCR_NLUN)
   2087  1.54       eeh 						ti->lun[li->lun] = NULL;
   2088  1.54       eeh 					LIST_REMOVE(li, link);
   2089  1.54       eeh 					free(li, M_DEVBUF);
   2090  1.54       eeh 					/* Restart the search at the beginning */
   2091  1.57        pk 					li = LIST_FIRST(&ti->luns);
   2092  1.54       eeh 					continue;
   2093  1.54       eeh 				}
   2094  1.57        pk 				li = LIST_NEXT(li, link);
   2095  1.54       eeh 			}
   2096  1.25        pk 			goto finish;
   2097  1.54       eeh 		}
   2098  1.25        pk 		case NCR_CONNECTED:
   2099  1.57        pk 			if ((sc->sc_flags & NCR_SYNCHNEGO) != 0) {
   2100   1.1   thorpej #ifdef NCR53C9X_DEBUG
   2101  1.57        pk 				if (ecb != NULL)
   2102  1.25        pk 					scsi_print_addr(ecb->xs->sc_link);
   2103  1.25        pk 				printf("sync nego not completed!\n");
   2104   1.1   thorpej #endif
   2105  1.25        pk 				ti = &sc->sc_tinfo[ecb->xs->sc_link->scsipi_scsi.target];
   2106  1.25        pk 				sc->sc_flags &= ~NCR_SYNCHNEGO;
   2107  1.25        pk 				ti->flags &= ~(T_NEGOTIATE | T_SYNCMODE);
   2108  1.25        pk 			}
   2109   1.1   thorpej 
   2110  1.25        pk 			/* it may be OK to disconnect */
   2111  1.25        pk 			if ((sc->sc_flags & NCR_ABORTING) == 0) {
   2112  1.25        pk 				/*
   2113  1.25        pk 				 * Section 5.1.1 of the SCSI 2 spec
   2114  1.25        pk 				 * suggests issuing a REQUEST SENSE
   2115  1.25        pk 				 * following an unexpected disconnect.
   2116  1.25        pk 				 * Some devices go into a contingent
   2117  1.25        pk 				 * allegiance condition when
   2118  1.25        pk 				 * disconnecting, and this is necessary
   2119  1.25        pk 				 * to clean up their state.
   2120  1.25        pk 				 */
   2121  1.25        pk 				printf("%s: unexpected disconnect; ",
   2122  1.25        pk 				    sc->sc_dev.dv_xname);
   2123  1.57        pk 				if ((ecb->flags & ECB_SENSE) != 0) {
   2124  1.25        pk 					printf("resetting\n");
   2125  1.25        pk 					goto reset;
   2126   1.1   thorpej 				}
   2127  1.25        pk 				printf("sending REQUEST SENSE\n");
   2128  1.48   thorpej 				callout_stop(&ecb->xs->xs_callout);
   2129  1.25        pk 				ncr53c9x_sense(sc, ecb);
   2130  1.25        pk 				goto out;
   2131  1.25        pk 			}
   2132   1.1   thorpej 
   2133  1.25        pk 			ecb->xs->error = XS_TIMEOUT;
   2134  1.25        pk 			goto finish;
   2135   1.1   thorpej 
   2136  1.25        pk 		case NCR_DISCONNECT:
   2137  1.25        pk 			sc->sc_nexus = NULL;
   2138  1.25        pk 			goto sched;
   2139   1.1   thorpej 
   2140  1.25        pk 		case NCR_CMDCOMPLETE:
   2141  1.25        pk 			goto finish;
   2142   1.1   thorpej 		}
   2143  1.25        pk 	}
   2144   1.1   thorpej 
   2145  1.25        pk 	switch (sc->sc_state) {
   2146  1.25        pk 
   2147  1.25        pk 	case NCR_SBR:
   2148  1.25        pk 		printf("%s: waiting for SCSI Bus Reset to happen\n",
   2149  1.25        pk 			sc->sc_dev.dv_xname);
   2150  1.25        pk 		return (1);
   2151   1.1   thorpej 
   2152  1.25        pk 	case NCR_RESELECTED:
   2153  1.25        pk 		/*
   2154  1.25        pk 		 * we must be continuing a message ?
   2155  1.25        pk 		 */
   2156  1.25        pk 		if (sc->sc_phase != MESSAGE_IN_PHASE) {
   2157  1.25        pk 			printf("%s: target didn't identify\n",
   2158   1.1   thorpej 				sc->sc_dev.dv_xname);
   2159  1.25        pk 			ncr53c9x_init(sc, 1);
   2160  1.25        pk 			return (1);
   2161  1.25        pk 		}
   2162  1.25        pk printf("<<RESELECT CONT'd>>");
   2163  1.25        pk #if XXXX
   2164  1.25        pk 		ncr53c9x_msgin(sc);
   2165  1.25        pk 		if (sc->sc_state != NCR_CONNECTED) {
   2166  1.25        pk 			/* IDENTIFY fail?! */
   2167  1.25        pk 			printf("%s: identify failed\n",
   2168  1.25        pk 				sc->sc_dev.dv_xname);
   2169  1.25        pk 			ncr53c9x_init(sc, 1);
   2170  1.25        pk 			return (1);
   2171  1.25        pk 		}
   2172  1.25        pk #endif
   2173  1.25        pk 		break;
   2174  1.25        pk 
   2175  1.54       eeh 	case NCR_IDENTIFIED:
   2176  1.54       eeh 		ecb = sc->sc_nexus;
   2177  1.54       eeh 		if (sc->sc_phase != MESSAGE_IN_PHASE) {
   2178  1.54       eeh 			int i = (NCR_READ_REG(sc, NCR_FFLAG)
   2179  1.54       eeh 				 & NCRFIFO_FF);
   2180  1.54       eeh  			/*
   2181  1.54       eeh 			 * Things are seriously fucked up.
   2182  1.54       eeh 			 * Pull the brakes, i.e. reset
   2183  1.54       eeh 			 */
   2184  1.54       eeh 			printf("%s: target didn't send tag: %d bytes in fifo\n",
   2185  1.54       eeh 			       sc->sc_dev.dv_xname, i);
   2186  1.54       eeh 			/* Drain and display fifo */
   2187  1.54       eeh 			while (i-- > 0)
   2188  1.54       eeh 				printf("[%d] ", NCR_READ_REG(sc, NCR_FIFO));
   2189  1.54       eeh 
   2190  1.54       eeh 			ncr53c9x_init(sc, 1);
   2191  1.54       eeh 			return (1);
   2192  1.54       eeh 		} else
   2193  1.54       eeh 			goto msgin;
   2194  1.54       eeh 
   2195  1.54       eeh 		break;
   2196  1.57        pk 
   2197  1.25        pk 	case NCR_IDLE:
   2198  1.25        pk 	case NCR_SELECTING:
   2199  1.25        pk 		ecb = sc->sc_nexus;
   2200  1.25        pk 		if (sc->sc_espintr & NCRINTR_RESEL) {
   2201  1.66    briggs 			sc->sc_msgpriq = sc->sc_msgout = sc->sc_msgoutq = 0;
   2202  1.66    briggs 			sc->sc_flags = 0;
   2203   1.1   thorpej 			/*
   2204  1.25        pk 			 * If we're trying to select a
   2205  1.25        pk 			 * target ourselves, push our command
   2206  1.25        pk 			 * back into the ready list.
   2207   1.1   thorpej 			 */
   2208  1.25        pk 			if (sc->sc_state == NCR_SELECTING) {
   2209  1.25        pk 				NCR_MISC(("backoff selector "));
   2210  1.48   thorpej 				callout_stop(&ecb->xs->xs_callout);
   2211  1.54       eeh 				ncr53c9x_dequeue(sc, ecb);
   2212  1.25        pk 				TAILQ_INSERT_HEAD(&sc->ready_list, ecb, chain);
   2213  1.54       eeh 				ecb->flags |= ECB_READY;
   2214  1.25        pk 				ecb = sc->sc_nexus = NULL;
   2215  1.25        pk 			}
   2216  1.25        pk 			sc->sc_state = NCR_RESELECTED;
   2217   1.1   thorpej 			if (sc->sc_phase != MESSAGE_IN_PHASE) {
   2218  1.25        pk 				/*
   2219  1.25        pk 				 * Things are seriously fucked up.
   2220  1.25        pk 				 * Pull the brakes, i.e. reset
   2221  1.25        pk 				 */
   2222   1.1   thorpej 				printf("%s: target didn't identify\n",
   2223   1.1   thorpej 					sc->sc_dev.dv_xname);
   2224   1.1   thorpej 				ncr53c9x_init(sc, 1);
   2225  1.25        pk 				return (1);
   2226   1.1   thorpej 			}
   2227  1.25        pk 			/*
   2228  1.25        pk 			 * The C90 only inhibits FIFO writes until
   2229  1.25        pk 			 * reselection is complete, instead of
   2230  1.25        pk 			 * waiting until the interrupt status register
   2231  1.25        pk 			 * has been read. So, if the reselect happens
   2232  1.25        pk 			 * while we were entering a command bytes (for
   2233  1.25        pk 			 * another target) some of those bytes can
   2234  1.25        pk 			 * appear in the FIFO here, after the
   2235  1.25        pk 			 * interrupt is taken.
   2236  1.25        pk 			 */
   2237  1.25        pk 			nfifo = NCR_READ_REG(sc,NCR_FFLAG) & NCRFIFO_FF;
   2238  1.25        pk 			if (nfifo < 2 ||
   2239  1.25        pk 			    (nfifo > 2 &&
   2240  1.25        pk 			     sc->sc_rev != NCR_VARIANT_ESP100)) {
   2241  1.25        pk 				printf("%s: RESELECT: %d bytes in FIFO! "
   2242  1.25        pk 				    "[intr %x, stat %x, step %d, prevphase %x]\n",
   2243  1.25        pk 					sc->sc_dev.dv_xname,
   2244  1.25        pk 					nfifo,
   2245  1.25        pk 					sc->sc_espintr,
   2246  1.25        pk 					sc->sc_espstat,
   2247  1.25        pk 					sc->sc_espstep,
   2248  1.25        pk 					sc->sc_prevphase);
   2249  1.25        pk 				ncr53c9x_init(sc, 1);
   2250  1.25        pk 				return (1);
   2251  1.25        pk 			}
   2252  1.25        pk 			sc->sc_selid = NCR_READ_REG(sc, NCR_FIFO);
   2253  1.25        pk 			NCR_MISC(("selid=0x%2x ", sc->sc_selid));
   2254  1.25        pk 
   2255  1.25        pk 			/* Handle identify message */
   2256   1.1   thorpej 			ncr53c9x_msgin(sc);
   2257  1.25        pk 			if (nfifo != 2) {
   2258  1.25        pk 				/*
   2259  1.25        pk 				 * Note: this should not happen
   2260  1.25        pk 				 * with `dmaselect' on.
   2261  1.25        pk 				 */
   2262  1.25        pk 				sc->sc_flags |= NCR_EXPECT_ILLCMD;
   2263  1.25        pk 				NCRCMD(sc, NCRCMD_FLUSH);
   2264  1.25        pk 			} else if (ncr53c9x_dmaselect &&
   2265  1.25        pk 				   sc->sc_rev == NCR_VARIANT_ESP100) {
   2266  1.25        pk 				sc->sc_flags |= NCR_EXPECT_ILLCMD;
   2267  1.25        pk 			}
   2268  1.25        pk 
   2269  1.54       eeh 			if (sc->sc_state != NCR_CONNECTED &&
   2270  1.54       eeh 			    sc->sc_state != NCR_IDENTIFIED) {
   2271   1.1   thorpej 				/* IDENTIFY fail?! */
   2272   1.1   thorpej 				printf("%s: identify failed\n",
   2273   1.1   thorpej 					sc->sc_dev.dv_xname);
   2274   1.1   thorpej 				ncr53c9x_init(sc, 1);
   2275  1.25        pk 				return (1);
   2276   1.1   thorpej 			}
   2277  1.25        pk 			goto shortcut; /* ie. next phase expected soon */
   2278  1.25        pk 		}
   2279   1.1   thorpej 
   2280  1.25        pk #define	NCRINTR_DONE	(NCRINTR_FC|NCRINTR_BS)
   2281  1.25        pk 		if ((sc->sc_espintr & NCRINTR_DONE) == NCRINTR_DONE) {
   2282  1.25        pk 			/*
   2283  1.25        pk 			 * Arbitration won; examine the `step' register
   2284  1.25        pk 			 * to determine how far the selection could progress.
   2285  1.25        pk 			 */
   2286   1.7       gwr 			ecb = sc->sc_nexus;
   2287  1.57        pk 			if (ecb == NULL)
   2288  1.30        pk 				panic("ncr53c9x: no nexus");
   2289  1.25        pk 
   2290  1.25        pk 			sc_link = ecb->xs->sc_link;
   2291  1.25        pk 			ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
   2292   1.1   thorpej 
   2293  1.25        pk 			switch (sc->sc_espstep) {
   2294  1.25        pk 			case 0:
   2295   1.1   thorpej 				/*
   2296  1.25        pk 				 * The target did not respond with a
   2297  1.25        pk 				 * message out phase - probably an old
   2298  1.25        pk 				 * device that doesn't recognize ATN.
   2299  1.25        pk 				 * Clear ATN and just continue, the
   2300  1.25        pk 				 * target should be in the command
   2301  1.25        pk 				 * phase.
   2302  1.25        pk 				 * XXXX check for command phase?
   2303   1.1   thorpej 				 */
   2304  1.25        pk 				NCRCMD(sc, NCRCMD_RSTATN);
   2305  1.25        pk 				break;
   2306  1.25        pk 			case 1:
   2307  1.63       eeh 				if ((ti->flags & T_NEGOTIATE) == 0 &&
   2308  1.63       eeh 				    ecb->tag[0] == 0) {
   2309  1.25        pk 					printf("%s: step 1 & !NEG\n",
   2310  1.25        pk 						sc->sc_dev.dv_xname);
   2311  1.25        pk 					goto reset;
   2312   1.1   thorpej 				}
   2313  1.25        pk 				if (sc->sc_phase != MESSAGE_OUT_PHASE) {
   2314  1.25        pk 					printf("%s: !MSGOUT\n",
   2315   1.1   thorpej 						sc->sc_dev.dv_xname);
   2316  1.25        pk 					goto reset;
   2317   1.1   thorpej 				}
   2318  1.63       eeh 				if (ti->flags & T_NEGOTIATE) {
   2319  1.63       eeh 					/* Start negotiating */
   2320  1.63       eeh 					ti->period = sc->sc_minsync;
   2321  1.63       eeh 					ti->offset = 15;
   2322  1.63       eeh 					sc->sc_flags |= NCR_SYNCHNEGO;
   2323  1.63       eeh 					if (ecb->tag[0])
   2324  1.63       eeh 						ncr53c9x_sched_msgout(SEND_TAG|SEND_SDTR);
   2325  1.63       eeh 					else
   2326  1.63       eeh 						ncr53c9x_sched_msgout(SEND_SDTR);
   2327  1.63       eeh 				} else {
   2328  1.63       eeh 					/* Could not do ATN3 so send TAG */
   2329  1.63       eeh 					ncr53c9x_sched_msgout(SEND_TAG);
   2330  1.63       eeh 				}
   2331  1.54       eeh 				sc->sc_prevphase = MESSAGE_OUT_PHASE; /* XXXX */
   2332  1.25        pk 				break;
   2333  1.25        pk 			case 3:
   2334   1.5        pk 				/*
   2335  1.25        pk 				 * Grr, this is supposed to mean
   2336  1.25        pk 				 * "target left command phase  prematurely".
   2337  1.25        pk 				 * It seems to happen regularly when
   2338  1.25        pk 				 * sync mode is on.
   2339  1.25        pk 				 * Look at FIFO to see if command went out.
   2340  1.25        pk 				 * (Timing problems?)
   2341   1.5        pk 				 */
   2342  1.25        pk 				if (ncr53c9x_dmaselect) {
   2343  1.25        pk 					if (sc->sc_cmdlen == 0)
   2344   1.8        pk 						/* Hope for the best.. */
   2345   1.8        pk 						break;
   2346  1.25        pk 				} else if ((NCR_READ_REG(sc, NCR_FFLAG)
   2347   1.1   thorpej 					    & NCRFIFO_FF) == 0) {
   2348  1.25        pk 					/* Hope for the best.. */
   2349   1.1   thorpej 					break;
   2350   1.1   thorpej 				}
   2351  1.25        pk 				printf("(%s:%d:%d): selection failed;"
   2352  1.25        pk 					" %d left in FIFO "
   2353  1.25        pk 					"[intr %x, stat %x, step %d]\n",
   2354   1.1   thorpej 					sc->sc_dev.dv_xname,
   2355  1.25        pk 					sc_link->scsipi_scsi.target,
   2356  1.25        pk 					sc_link->scsipi_scsi.lun,
   2357  1.25        pk 					NCR_READ_REG(sc, NCR_FFLAG)
   2358  1.25        pk 					 & NCRFIFO_FF,
   2359   1.1   thorpej 					sc->sc_espintr, sc->sc_espstat,
   2360   1.1   thorpej 					sc->sc_espstep);
   2361   1.1   thorpej 				NCRCMD(sc, NCRCMD_FLUSH);
   2362  1.25        pk 				ncr53c9x_sched_msgout(SEND_ABORT);
   2363  1.25        pk 				return (1);
   2364  1.25        pk 			case 2:
   2365  1.25        pk 				/* Select stuck at Command Phase */
   2366  1.25        pk 				NCRCMD(sc, NCRCMD_FLUSH);
   2367  1.37   mycroft 				break;
   2368  1.25        pk 			case 4:
   2369  1.25        pk 				if (ncr53c9x_dmaselect &&
   2370  1.25        pk 				    sc->sc_cmdlen != 0)
   2371  1.25        pk 					printf("(%s:%d:%d): select; "
   2372  1.34   thorpej 					       "%lu left in DMA buffer "
   2373  1.25        pk 					"[intr %x, stat %x, step %d]\n",
   2374  1.25        pk 						sc->sc_dev.dv_xname,
   2375  1.25        pk 						sc_link->scsipi_scsi.target,
   2376  1.25        pk 						sc_link->scsipi_scsi.lun,
   2377  1.34   thorpej 						(u_long)sc->sc_cmdlen,
   2378  1.25        pk 						sc->sc_espintr,
   2379  1.25        pk 						sc->sc_espstat,
   2380  1.25        pk 						sc->sc_espstep);
   2381  1.25        pk 				/* So far, everything went fine */
   2382  1.25        pk 				break;
   2383   1.1   thorpej 			}
   2384  1.25        pk 
   2385  1.25        pk 			sc->sc_prevphase = INVALID_PHASE; /* ?? */
   2386  1.25        pk 			/* Do an implicit RESTORE POINTERS. */
   2387  1.25        pk 			sc->sc_dp = ecb->daddr;
   2388  1.25        pk 			sc->sc_dleft = ecb->dleft;
   2389  1.25        pk 			sc->sc_state = NCR_CONNECTED;
   2390   1.1   thorpej 			break;
   2391   1.1   thorpej 
   2392  1.25        pk 		} else {
   2393   1.1   thorpej 
   2394  1.25        pk 			printf("%s: unexpected status after select"
   2395  1.25        pk 				": [intr %x, stat %x, step %x]\n",
   2396  1.25        pk 				sc->sc_dev.dv_xname,
   2397  1.25        pk 				sc->sc_espintr, sc->sc_espstat,
   2398  1.25        pk 				sc->sc_espstep);
   2399  1.25        pk 			NCRCMD(sc, NCRCMD_FLUSH);
   2400  1.25        pk 			DELAY(1);
   2401  1.25        pk 			goto reset;
   2402   1.1   thorpej 		}
   2403  1.25        pk 		if (sc->sc_state == NCR_IDLE) {
   2404  1.57        pk 			printf("%s: stray interrupt\n", sc->sc_dev.dv_xname);
   2405  1.57        pk 			return (0);
   2406   1.1   thorpej 		}
   2407  1.25        pk 		break;
   2408   1.1   thorpej 
   2409  1.25        pk 	case NCR_CONNECTED:
   2410  1.57        pk 		if ((sc->sc_flags & NCR_ICCS) != 0) {
   2411  1.25        pk 			/* "Initiate Command Complete Steps" in progress */
   2412  1.25        pk 			u_char msg;
   2413  1.25        pk 
   2414  1.25        pk 			sc->sc_flags &= ~NCR_ICCS;
   2415  1.25        pk 
   2416  1.25        pk 			if (!(sc->sc_espintr & NCRINTR_DONE)) {
   2417  1.25        pk 				printf("%s: ICCS: "
   2418  1.25        pk 				      ": [intr %x, stat %x, step %x]\n",
   2419   1.1   thorpej 					sc->sc_dev.dv_xname,
   2420   1.1   thorpej 					sc->sc_espintr, sc->sc_espstat,
   2421   1.1   thorpej 					sc->sc_espstep);
   2422   1.1   thorpej 			}
   2423  1.25        pk 			if ((NCR_READ_REG(sc, NCR_FFLAG)
   2424  1.25        pk 			    & NCRFIFO_FF) != 2) {
   2425  1.40        pk 				/* Drop excess bytes from the queue */
   2426  1.25        pk 				int i = (NCR_READ_REG(sc, NCR_FFLAG)
   2427  1.25        pk 					    & NCRFIFO_FF) - 2;
   2428  1.40        pk 				while (i-- > 0)
   2429  1.25        pk 					(void) NCR_READ_REG(sc, NCR_FIFO);
   2430   1.1   thorpej 			}
   2431  1.25        pk 			ecb->stat = NCR_READ_REG(sc, NCR_FIFO);
   2432  1.25        pk 			msg = NCR_READ_REG(sc, NCR_FIFO);
   2433  1.25        pk 			NCR_PHASE(("<stat:(%x,%x)>", ecb->stat, msg));
   2434  1.25        pk 			if (msg == MSG_CMDCOMPLETE) {
   2435  1.25        pk 				ecb->dleft = (ecb->flags & ECB_TENTATIVE_DONE)
   2436  1.25        pk 					? 0
   2437  1.25        pk 					: sc->sc_dleft;
   2438  1.25        pk 				if ((ecb->flags & ECB_SENSE) == 0)
   2439  1.25        pk 					ecb->xs->resid = ecb->dleft;
   2440  1.25        pk 				sc->sc_state = NCR_CMDCOMPLETE;
   2441  1.25        pk 			} else
   2442  1.25        pk 				printf("%s: STATUS_PHASE: msg %d\n",
   2443  1.25        pk 					sc->sc_dev.dv_xname, msg);
   2444  1.25        pk 			NCRCMD(sc, NCRCMD_MSGOK);
   2445  1.25        pk 			goto shortcut; /* ie. wait for disconnect */
   2446  1.25        pk 		}
   2447  1.25        pk 		break;
   2448  1.57        pk 
   2449  1.25        pk 	default:
   2450  1.25        pk 		panic("%s: invalid state: %d",
   2451  1.25        pk 		      sc->sc_dev.dv_xname,
   2452  1.25        pk 		      sc->sc_state);
   2453  1.25        pk 	}
   2454   1.8        pk 
   2455  1.25        pk 	/*
   2456  1.25        pk 	 * Driver is now in state NCR_CONNECTED, i.e. we
   2457  1.25        pk 	 * have a current command working the SCSI bus.
   2458  1.25        pk 	 */
   2459  1.25        pk 	if (sc->sc_state != NCR_CONNECTED || ecb == NULL) {
   2460  1.30        pk 		panic("ncr53c9x: no nexus");
   2461  1.25        pk 	}
   2462  1.22        pk 
   2463  1.25        pk 	switch (sc->sc_phase) {
   2464  1.25        pk 	case MESSAGE_OUT_PHASE:
   2465  1.25        pk 		NCR_PHASE(("MESSAGE_OUT_PHASE "));
   2466  1.25        pk 		ncr53c9x_msgout(sc);
   2467  1.25        pk 		sc->sc_prevphase = MESSAGE_OUT_PHASE;
   2468  1.25        pk 		break;
   2469  1.57        pk 
   2470  1.25        pk 	case MESSAGE_IN_PHASE:
   2471  1.54       eeh msgin:
   2472  1.25        pk 		NCR_PHASE(("MESSAGE_IN_PHASE "));
   2473  1.25        pk 		sc->sc_prevphase = MESSAGE_IN_PHASE;
   2474  1.57        pk 		if ((sc->sc_espintr & NCRINTR_BS) != 0) {
   2475  1.25        pk 			NCRCMD(sc, NCRCMD_FLUSH);
   2476  1.25        pk 			sc->sc_flags |= NCR_WAITI;
   2477  1.25        pk 			NCRCMD(sc, NCRCMD_TRANS);
   2478  1.57        pk 		} else if ((sc->sc_espintr & NCRINTR_FC) != 0) {
   2479  1.25        pk 			if ((sc->sc_flags & NCR_WAITI) == 0) {
   2480  1.25        pk 				printf("%s: MSGIN: unexpected FC bit: "
   2481  1.25        pk 					"[intr %x, stat %x, step %x]\n",
   2482  1.25        pk 				sc->sc_dev.dv_xname,
   2483  1.25        pk 				sc->sc_espintr, sc->sc_espstat,
   2484  1.25        pk 				sc->sc_espstep);
   2485   1.8        pk 			}
   2486  1.25        pk 			sc->sc_flags &= ~NCR_WAITI;
   2487  1.25        pk 			ncr53c9x_msgin(sc);
   2488  1.25        pk 		} else {
   2489  1.25        pk 			printf("%s: MSGIN: weird bits: "
   2490  1.25        pk 				"[intr %x, stat %x, step %x]\n",
   2491  1.25        pk 				sc->sc_dev.dv_xname,
   2492  1.25        pk 				sc->sc_espintr, sc->sc_espstat,
   2493  1.25        pk 				sc->sc_espstep);
   2494  1.25        pk 		}
   2495  1.25        pk 		goto shortcut;	/* i.e. expect data to be ready */
   2496  1.25        pk 		break;
   2497  1.57        pk 
   2498  1.25        pk 	case COMMAND_PHASE:
   2499  1.25        pk 		/*
   2500  1.25        pk 		 * Send the command block. Normally we don't see this
   2501  1.25        pk 		 * phase because the SEL_ATN command takes care of
   2502  1.25        pk 		 * all this. However, we end up here if either the
   2503  1.25        pk 		 * target or we wanted to exchange some more messages
   2504  1.25        pk 		 * first (e.g. to start negotiations).
   2505  1.25        pk 		 */
   2506  1.25        pk 
   2507  1.25        pk 		NCR_PHASE(("COMMAND_PHASE 0x%02x (%d) ",
   2508  1.25        pk 			ecb->cmd.cmd.opcode, ecb->clen));
   2509  1.25        pk 		if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) {
   2510   1.1   thorpej 			NCRCMD(sc, NCRCMD_FLUSH);
   2511  1.68       eeh /*			DELAY(1);*/
   2512  1.25        pk 		}
   2513  1.25        pk 		if (ncr53c9x_dmaselect) {
   2514  1.25        pk 			size_t size;
   2515  1.25        pk 			/* setup DMA transfer for command */
   2516  1.25        pk 			size = ecb->clen;
   2517  1.25        pk 			sc->sc_cmdlen = size;
   2518  1.25        pk 			sc->sc_cmdp = (caddr_t)&ecb->cmd.cmd;
   2519  1.25        pk 			NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen,
   2520  1.25        pk 				     0, &size);
   2521   1.1   thorpej 			/* Program the SCSI counter */
   2522   1.1   thorpej 			NCR_WRITE_REG(sc, NCR_TCL, size);
   2523   1.1   thorpej 			NCR_WRITE_REG(sc, NCR_TCM, size >> 8);
   2524   1.1   thorpej 			if (sc->sc_cfg2 & NCRCFG2_FE) {
   2525   1.1   thorpej 				NCR_WRITE_REG(sc, NCR_TCH, size >> 16);
   2526   1.1   thorpej 			}
   2527  1.25        pk 
   2528   1.1   thorpej 			/* load the count in */
   2529   1.1   thorpej 			NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA);
   2530   1.1   thorpej 
   2531  1.25        pk 			/* start the command transfer */
   2532  1.25        pk 			NCRCMD(sc, NCRCMD_TRANS | NCRCMD_DMA);
   2533   1.1   thorpej 			NCRDMA_GO(sc);
   2534  1.25        pk 		} else {
   2535  1.25        pk 			u_char *cmd = (u_char *)&ecb->cmd.cmd;
   2536  1.25        pk 			int i;
   2537  1.25        pk 			/* Now the command into the FIFO */
   2538  1.25        pk 			for (i = 0; i < ecb->clen; i++)
   2539  1.25        pk 				NCR_WRITE_REG(sc, NCR_FIFO, *cmd++);
   2540  1.25        pk 			NCRCMD(sc, NCRCMD_TRANS);
   2541  1.25        pk 		}
   2542  1.25        pk 		sc->sc_prevphase = COMMAND_PHASE;
   2543  1.25        pk 		break;
   2544  1.57        pk 
   2545  1.25        pk 	case DATA_OUT_PHASE:
   2546  1.25        pk 		NCR_PHASE(("DATA_OUT_PHASE [%ld] ",(long)sc->sc_dleft));
   2547  1.25        pk 		NCRCMD(sc, NCRCMD_FLUSH);
   2548  1.25        pk 		size = min(sc->sc_dleft, sc->sc_maxxfer);
   2549  1.25        pk 		NCRDMA_SETUP(sc, &sc->sc_dp, &sc->sc_dleft,
   2550  1.25        pk 			  0, &size);
   2551  1.25        pk 		sc->sc_prevphase = DATA_OUT_PHASE;
   2552  1.25        pk 		goto setup_xfer;
   2553  1.57        pk 
   2554  1.25        pk 	case DATA_IN_PHASE:
   2555  1.25        pk 		NCR_PHASE(("DATA_IN_PHASE "));
   2556  1.25        pk 		if (sc->sc_rev == NCR_VARIANT_ESP100)
   2557  1.25        pk 			NCRCMD(sc, NCRCMD_FLUSH);
   2558  1.25        pk 		size = min(sc->sc_dleft, sc->sc_maxxfer);
   2559  1.25        pk 		NCRDMA_SETUP(sc, &sc->sc_dp, &sc->sc_dleft,
   2560  1.25        pk 			  1, &size);
   2561  1.25        pk 		sc->sc_prevphase = DATA_IN_PHASE;
   2562  1.25        pk 	setup_xfer:
   2563  1.25        pk 		/* Target returned to data phase: wipe "done" memory */
   2564  1.25        pk 		ecb->flags &= ~ECB_TENTATIVE_DONE;
   2565  1.25        pk 
   2566  1.25        pk 		/* Program the SCSI counter */
   2567  1.25        pk 		NCR_WRITE_REG(sc, NCR_TCL, size);
   2568  1.25        pk 		NCR_WRITE_REG(sc, NCR_TCM, size >> 8);
   2569  1.57        pk 		if ((sc->sc_cfg2 & NCRCFG2_FE) != 0) {
   2570  1.25        pk 			NCR_WRITE_REG(sc, NCR_TCH, size >> 16);
   2571   1.1   thorpej 		}
   2572  1.25        pk 		/* load the count in */
   2573  1.25        pk 		NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA);
   2574  1.25        pk 
   2575  1.25        pk 		/*
   2576  1.25        pk 		 * Note that if `size' is 0, we've already transceived
   2577  1.25        pk 		 * all the bytes we want but we're still in DATA PHASE.
   2578  1.25        pk 		 * Apparently, the device needs padding. Also, a
   2579  1.25        pk 		 * transfer size of 0 means "maximum" to the chip
   2580  1.25        pk 		 * DMA logic.
   2581  1.25        pk 		 */
   2582  1.25        pk 		NCRCMD(sc,
   2583  1.25        pk 		       (size==0?NCRCMD_TRPAD:NCRCMD_TRANS)|NCRCMD_DMA);
   2584  1.25        pk 		NCRDMA_GO(sc);
   2585  1.25        pk 		return (1);
   2586  1.57        pk 
   2587  1.25        pk 	case STATUS_PHASE:
   2588  1.25        pk 		NCR_PHASE(("STATUS_PHASE "));
   2589  1.25        pk 		sc->sc_flags |= NCR_ICCS;
   2590  1.25        pk 		NCRCMD(sc, NCRCMD_ICCS);
   2591  1.25        pk 		sc->sc_prevphase = STATUS_PHASE;
   2592  1.25        pk 		goto shortcut;	/* i.e. expect status results soon */
   2593  1.25        pk 		break;
   2594  1.57        pk 
   2595  1.25        pk 	case INVALID_PHASE:
   2596  1.25        pk 		break;
   2597  1.57        pk 
   2598  1.25        pk 	default:
   2599  1.25        pk 		printf("%s: unexpected bus phase; resetting\n",
   2600  1.57        pk 		       sc->sc_dev.dv_xname);
   2601  1.25        pk 		goto reset;
   2602   1.1   thorpej 	}
   2603  1.25        pk 
   2604  1.25        pk out:
   2605  1.25        pk 	return (1);
   2606   1.1   thorpej 
   2607   1.1   thorpej reset:
   2608   1.1   thorpej 	ncr53c9x_init(sc, 1);
   2609  1.25        pk 	goto out;
   2610   1.1   thorpej 
   2611   1.1   thorpej finish:
   2612   1.1   thorpej 	ncr53c9x_done(sc, ecb);
   2613   1.1   thorpej 	goto out;
   2614   1.1   thorpej 
   2615   1.1   thorpej sched:
   2616   1.1   thorpej 	sc->sc_state = NCR_IDLE;
   2617   1.1   thorpej 	ncr53c9x_sched(sc);
   2618   1.1   thorpej 	goto out;
   2619   1.1   thorpej 
   2620  1.25        pk shortcut:
   2621  1.25        pk 	/*
   2622  1.25        pk 	 * The idea is that many of the SCSI operations take very little
   2623  1.25        pk 	 * time, and going away and getting interrupted is too high an
   2624  1.25        pk 	 * overhead to pay. For example, selecting, sending a message
   2625  1.25        pk 	 * and command and then doing some work can be done in one "pass".
   2626  1.25        pk 	 *
   2627  1.25        pk 	 * The delay is a heuristic. It is 2 when at 20Mhz, 2 at 25Mhz and 1
   2628  1.25        pk 	 * at 40Mhz. This needs testing.
   2629  1.25        pk 	 */
   2630  1.68       eeh 	{
   2631  1.68       eeh 		struct timeval wait, cur;
   2632  1.68       eeh 
   2633  1.68       eeh 		microtime(&wait);
   2634  1.68       eeh 		wait.tv_usec += 50/sc->sc_freq;
   2635  1.68       eeh 		if (wait.tv_usec > 1000000) {
   2636  1.68       eeh 			wait.tv_sec++;
   2637  1.68       eeh 			wait.tv_usec -= 1000000;
   2638  1.68       eeh 		}
   2639  1.68       eeh 		do {
   2640  1.68       eeh 			if (NCRDMA_ISINTR(sc))
   2641  1.68       eeh 				goto again;
   2642  1.68       eeh 			microtime(&cur);
   2643  1.68       eeh 		} while (cur.tv_sec <= wait.tv_sec &&
   2644  1.68       eeh 			 cur.tv_usec <= wait.tv_usec);
   2645  1.68       eeh 	}
   2646  1.25        pk 	goto out;
   2647   1.1   thorpej }
   2648   1.1   thorpej 
   2649   1.1   thorpej void
   2650   1.1   thorpej ncr53c9x_abort(sc, ecb)
   2651   1.1   thorpej 	struct ncr53c9x_softc *sc;
   2652   1.1   thorpej 	struct ncr53c9x_ecb *ecb;
   2653   1.1   thorpej {
   2654   1.1   thorpej 
   2655   1.1   thorpej 	/* 2 secs for the abort */
   2656   1.1   thorpej 	ecb->timeout = NCR_ABORT_TIMEOUT;
   2657   1.1   thorpej 	ecb->flags |= ECB_ABORT;
   2658   1.1   thorpej 
   2659   1.1   thorpej 	if (ecb == sc->sc_nexus) {
   2660  1.52  nisimura 		int timeout;
   2661  1.52  nisimura 
   2662   1.1   thorpej 		/*
   2663   1.1   thorpej 		 * If we're still selecting, the message will be scheduled
   2664   1.1   thorpej 		 * after selection is complete.
   2665   1.1   thorpej 		 */
   2666   1.1   thorpej 		if (sc->sc_state == NCR_CONNECTED)
   2667   1.1   thorpej 			ncr53c9x_sched_msgout(SEND_ABORT);
   2668   1.1   thorpej 
   2669   1.1   thorpej 		/*
   2670  1.48   thorpej 		 * Reschedule timeout.
   2671   1.1   thorpej 		 */
   2672  1.52  nisimura 		timeout = ecb->timeout;
   2673  1.52  nisimura 		if (hz > 100 && timeout > 1000)
   2674  1.52  nisimura 			timeout = (timeout / 1000) * hz;
   2675  1.52  nisimura 		else
   2676  1.52  nisimura 			timeout = (timeout * hz) / 1000;
   2677  1.52  nisimura 		callout_reset(&ecb->xs->xs_callout, timeout,
   2678  1.48   thorpej 		    ncr53c9x_timeout, ecb);
   2679   1.1   thorpej 	} else {
   2680  1.23        pk 		/*
   2681  1.54       eeh 		 * Just leave the command where it is.
   2682  1.23        pk 		 * XXX - what choice do we have but to reset the SCSI
   2683  1.23        pk 		 *	 eventually?
   2684  1.23        pk 		 */
   2685   1.1   thorpej 		if (sc->sc_state == NCR_IDLE)
   2686   1.1   thorpej 			ncr53c9x_sched(sc);
   2687   1.1   thorpej 	}
   2688   1.1   thorpej }
   2689   1.1   thorpej 
   2690   1.1   thorpej void
   2691   1.1   thorpej ncr53c9x_timeout(arg)
   2692   1.1   thorpej 	void *arg;
   2693   1.1   thorpej {
   2694   1.1   thorpej 	struct ncr53c9x_ecb *ecb = arg;
   2695  1.18    bouyer 	struct scsipi_xfer *xs = ecb->xs;
   2696  1.18    bouyer 	struct scsipi_link *sc_link = xs->sc_link;
   2697   1.1   thorpej 	struct ncr53c9x_softc *sc = sc_link->adapter_softc;
   2698  1.18    bouyer 	struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
   2699   1.1   thorpej 	int s;
   2700   1.1   thorpej 
   2701  1.18    bouyer 	scsi_print_addr(sc_link);
   2702   1.1   thorpej 	printf("%s: timed out [ecb %p (flags 0x%x, dleft %x, stat %x)], "
   2703  1.23        pk 	       "<state %d, nexus %p, phase(l %x, c %x, p %x), resid %lx, "
   2704   1.1   thorpej 	       "msg(q %x,o %x) %s>",
   2705   1.1   thorpej 		sc->sc_dev.dv_xname,
   2706   1.1   thorpej 		ecb, ecb->flags, ecb->dleft, ecb->stat,
   2707  1.23        pk 		sc->sc_state, sc->sc_nexus,
   2708  1.23        pk 		NCR_READ_REG(sc, NCR_STAT),
   2709  1.23        pk 		sc->sc_phase, sc->sc_prevphase,
   2710   1.1   thorpej 		(long)sc->sc_dleft, sc->sc_msgpriq, sc->sc_msgout,
   2711   1.1   thorpej 		NCRDMA_ISACTIVE(sc) ? "DMA active" : "");
   2712   1.7       gwr #if NCR53C9X_DEBUG > 1
   2713   1.1   thorpej 	printf("TRACE: %s.", ecb->trace);
   2714   1.1   thorpej #endif
   2715   1.1   thorpej 
   2716   1.1   thorpej 	s = splbio();
   2717   1.1   thorpej 
   2718   1.1   thorpej 	if (ecb->flags & ECB_ABORT) {
   2719   1.1   thorpej 		/* abort timed out */
   2720   1.1   thorpej 		printf(" AGAIN\n");
   2721  1.16        pk 
   2722   1.1   thorpej 		ncr53c9x_init(sc, 1);
   2723   1.1   thorpej 	} else {
   2724   1.1   thorpej 		/* abort the operation that has timed out */
   2725   1.1   thorpej 		printf("\n");
   2726   1.1   thorpej 		xs->error = XS_TIMEOUT;
   2727   1.1   thorpej 		ncr53c9x_abort(sc, ecb);
   2728  1.16        pk 
   2729  1.16        pk 		/* Disable sync mode if stuck in a data phase */
   2730  1.16        pk 		if (ecb == sc->sc_nexus &&
   2731  1.16        pk 		    (ti->flags & T_SYNCMODE) != 0 &&
   2732  1.16        pk 		    (sc->sc_phase & (MSGI|CDI)) == 0) {
   2733  1.18    bouyer 			scsi_print_addr(sc_link);
   2734  1.16        pk 			printf("sync negotiation disabled\n");
   2735  1.18    bouyer 			sc->sc_cfflags |= (1<<(sc_link->scsipi_scsi.target+8));
   2736  1.16        pk 		}
   2737   1.1   thorpej 	}
   2738   1.1   thorpej 
   2739   1.1   thorpej 	splx(s);
   2740   1.1   thorpej }
   2741  1.54       eeh 
   2742  1.54       eeh void
   2743  1.54       eeh ncr53c9x_watch(arg)
   2744  1.54       eeh 	void *arg;
   2745  1.54       eeh {
   2746  1.54       eeh 	struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
   2747  1.54       eeh 	struct ncr53c9x_tinfo *ti;
   2748  1.54       eeh 	struct ncr53c9x_linfo *li;
   2749  1.54       eeh 	int t, s;
   2750  1.54       eeh 	/* Delete any structures that have not been used in 10min. */
   2751  1.54       eeh 	time_t old = time.tv_sec - (10*60);
   2752  1.54       eeh 
   2753  1.54       eeh 	s = splbio();
   2754  1.54       eeh 	for (t=0; t<NCR_NTARG; t++) {
   2755  1.54       eeh 		ti = &sc->sc_tinfo[t];
   2756  1.57        pk 		li = LIST_FIRST(&ti->luns);
   2757  1.54       eeh 		while (li) {
   2758  1.57        pk 			if (li->last_used < old && li->untagged == NULL &&
   2759  1.57        pk 			    li->used == 0) {
   2760  1.54       eeh 				if (li->lun < NCR_NLUN)
   2761  1.54       eeh 					ti->lun[li->lun] = NULL;
   2762  1.54       eeh 				LIST_REMOVE(li, link);
   2763  1.54       eeh 				free(li, M_DEVBUF);
   2764  1.54       eeh 				/* Restart the search at the beginning */
   2765  1.57        pk 				li = LIST_FIRST(&ti->luns);
   2766  1.54       eeh 				continue;
   2767  1.54       eeh 			}
   2768  1.57        pk 			li = LIST_NEXT(li, link);
   2769  1.54       eeh 		}
   2770  1.54       eeh 	}
   2771  1.54       eeh 	splx(s);
   2772  1.54       eeh 	callout_reset(&sc->sc_watchdog, 60*hz, ncr53c9x_watch, sc);
   2773  1.54       eeh }
   2774  1.61       eeh 
   2775