Home | History | Annotate | Line # | Download | only in dev
siop2.c revision 1.14.2.1
      1  1.14.2.1   bouyer /*	$NetBSD: siop2.c,v 1.14.2.1 2000/11/20 19:58:43 bouyer Exp $	*/
      2       1.1       is 
      3       1.1       is /*
      4       1.1       is  * Copyright (c) 1994,1998 Michael L. Hitch
      5       1.1       is  * Copyright (c) 1990 The Regents of the University of California.
      6       1.1       is  * All rights reserved.
      7       1.1       is  *
      8       1.1       is  * This code is derived from software contributed to Berkeley by
      9       1.1       is  * Van Jacobson of Lawrence Berkeley Laboratory.
     10       1.1       is  *
     11       1.1       is  * Redistribution and use in source and binary forms, with or without
     12       1.1       is  * modification, are permitted provided that the following conditions
     13       1.1       is  * are met:
     14       1.1       is  * 1. Redistributions of source code must retain the above copyright
     15       1.1       is  *    notice, this list of conditions and the following disclaimer.
     16       1.1       is  * 2. Redistributions in binary form must reproduce the above copyright
     17       1.1       is  *    notice, this list of conditions and the following disclaimer in the
     18       1.1       is  *    documentation and/or other materials provided with the distribution.
     19       1.1       is  * 3. All advertising materials mentioning features or use of this software
     20       1.1       is  *    must display the following acknowledgement:
     21       1.1       is  *	This product includes software developed by the University of
     22       1.1       is  *	California, Berkeley and its contributors.
     23       1.1       is  * 4. Neither the name of the University nor the names of its contributors
     24       1.1       is  *    may be used to endorse or promote products derived from this software
     25       1.1       is  *    without specific prior written permission.
     26       1.1       is  *
     27       1.1       is  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     28       1.1       is  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     29       1.1       is  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     30       1.1       is  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     31       1.1       is  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     32       1.1       is  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     33       1.1       is  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     34       1.1       is  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     35       1.1       is  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     36       1.1       is  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     37       1.1       is  * SUCH DAMAGE.
     38       1.1       is  *
     39       1.1       is  *	@(#)siop.c	7.5 (Berkeley) 5/4/91
     40       1.1       is  */
     41       1.1       is 
     42       1.1       is /*
     43       1.1       is  * AMIGA 53C720/770 scsi adaptor driver
     44       1.1       is  */
     45       1.1       is 
     46       1.1       is #include "opt_ddb.h"
     47       1.1       is 
     48       1.1       is #include <sys/param.h>
     49       1.1       is #include <sys/systm.h>
     50       1.1       is #include <sys/device.h>
     51       1.1       is #include <sys/disklabel.h>
     52       1.1       is #include <sys/dkstat.h>
     53       1.1       is #include <sys/buf.h>
     54       1.1       is #include <sys/malloc.h>
     55       1.1       is #include <dev/scsipi/scsi_all.h>
     56       1.1       is #include <dev/scsipi/scsipi_all.h>
     57       1.1       is #include <dev/scsipi/scsiconf.h>
     58       1.1       is #include <machine/cpu.h>
     59      1.13       is #ifdef __m68k__
     60      1.13       is #include <m68k/include/cacheops.h>
     61      1.13       is #endif
     62       1.1       is #include <amiga/amiga/custom.h>
     63       1.1       is #include <amiga/amiga/isr.h>
     64       1.1       is 
     65       1.1       is #define ARCH_720
     66       1.1       is 
     67       1.1       is #include <amiga/dev/siopreg.h>
     68       1.1       is #include <amiga/dev/siopvar.h>
     69       1.1       is 
     70       1.1       is /*
     71       1.1       is  * SCSI delays
     72       1.1       is  * In u-seconds, primarily for state changes on the SPC.
     73       1.1       is  */
     74       1.1       is #define	SCSI_CMD_WAIT	500000	/* wait per step of 'immediate' cmds */
     75       1.1       is #define	SCSI_DATA_WAIT	500000	/* wait per data in/out step */
     76       1.1       is #define	SCSI_INIT_WAIT	500000	/* wait per step (both) during init */
     77       1.1       is 
     78       1.1       is void siopng_select __P((struct siop_softc *));
     79       1.1       is void siopngabort __P((struct siop_softc *, siop_regmap_p, char *));
     80       1.1       is void siopngerror __P((struct siop_softc *, siop_regmap_p, u_char));
     81       1.1       is void siopngstart __P((struct siop_softc *));
     82       1.1       is int  siopng_checkintr __P((struct siop_softc *, u_char, u_char, u_short, int *));
     83       1.1       is void siopngreset __P((struct siop_softc *));
     84       1.1       is void siopngsetdelay __P((int));
     85       1.1       is void siopng_scsidone __P((struct siop_acb *, int));
     86       1.1       is void siopng_sched __P((struct siop_softc *));
     87       1.1       is int  siopng_poll __P((struct siop_softc *, struct siop_acb *));
     88       1.1       is void siopngintr __P((struct siop_softc *));
     89       1.1       is void scsi_period_to_siopng __P((struct siop_softc *, int));
     90       1.1       is void siopng_start __P((struct siop_softc *, int, int, u_char *, int, u_char *, int));
     91       1.1       is void siopng_dump_acb __P((struct siop_acb *));
     92       1.1       is 
     93       1.1       is /* 53C720/770 script */
     94       1.1       is const
     95       1.1       is #include <amiga/dev/siop2_script.out>
     96       1.1       is 
     97       1.1       is /* default to not inhibit sync negotiation on any drive */
     98       1.7       is u_char siopng_inhibit_sync[16] = {
     99       1.7       is 	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0
    100       1.7       is }; /* initialize, so patchable */
    101       1.7       is 
    102       1.7       is u_char siopng_inhibit_wide[16] = {
    103       1.7       is 	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0
    104       1.7       is }; /* initialize, so patchable */
    105       1.7       is 
    106       1.7       is u_char siopng_allow_disc[16] = {
    107       1.7       is 	3, 3, 3, 3,	3, 3, 3, 3,	3, 3, 3, 3,	3, 3, 3, 3
    108       1.7       is };
    109       1.7       is 
    110       1.1       is int siopng_no_dma = 0;
    111       1.1       is 
    112       1.1       is int siopng_reset_delay = 250;	/* delay after reset, in milleseconds */
    113       1.1       is 
    114       1.1       is int siopng_cmd_wait = SCSI_CMD_WAIT;
    115       1.1       is int siopng_data_wait = SCSI_DATA_WAIT;
    116       1.1       is int siopng_init_wait = SCSI_INIT_WAIT;
    117       1.1       is 
    118       1.1       is #define DEBUG_SYNC
    119       1.1       is 
    120       1.1       is #ifdef DEBUG
    121       1.1       is /*
    122       1.1       is  *	0x01 - full debug
    123       1.1       is  *	0x02 - DMA chaining
    124       1.1       is  *	0x04 - siopngintr
    125       1.1       is  *	0x08 - phase mismatch
    126       1.1       is  *	0x10 - <not used>
    127       1.1       is  *	0x20 - panic on unhandled exceptions
    128       1.1       is  *	0x100 - disconnect/reselect
    129       1.1       is  */
    130       1.1       is int	siopng_debug = 0;
    131       1.1       is int	siopngsync_debug = 0;
    132       1.1       is int	siopngdma_hits = 0;
    133       1.1       is int	siopngdma_misses = 0;
    134       1.1       is int	siopngchain_ints = 0;
    135       1.1       is int	siopngstarts = 0;
    136       1.1       is int	siopngints = 0;
    137       1.1       is int	siopngphmm = 0;
    138       1.1       is #define SIOP_TRACE_SIZE	128
    139       1.1       is #define SIOP_TRACE(a,b,c,d) \
    140       1.1       is 	siopng_trbuf[siopng_trix] = (a); \
    141       1.1       is 	siopng_trbuf[siopng_trix+1] = (b); \
    142       1.1       is 	siopng_trbuf[siopng_trix+2] = (c); \
    143       1.1       is 	siopng_trbuf[siopng_trix+3] = (d); \
    144       1.1       is 	siopng_trix = (siopng_trix + 4) & (SIOP_TRACE_SIZE - 1);
    145       1.1       is u_char	siopng_trbuf[SIOP_TRACE_SIZE];
    146       1.1       is int	siopng_trix;
    147       1.1       is void siopng_dump __P((struct siop_softc *));
    148       1.1       is void siopng_dump_trace __P((void));
    149       1.1       is #else
    150       1.1       is #define SIOP_TRACE(a,b,c,d)
    151       1.1       is #endif
    152       1.1       is 
    153       1.1       is 
    154       1.4       is static char *siopng_chips[] = {
    155       1.4       is 	"720", "720SE", "770", "0x3",
    156       1.8       is 	"810A", "0x5", "0x6", "0x7",
    157       1.4       is 	"0x8", "0x9", "0xA", "0xB",
    158       1.4       is 	"0xC", "0xD", "0xE", "0xF",
    159       1.4       is };
    160       1.4       is 
    161       1.1       is /*
    162       1.1       is  * default minphys routine for siopng based controllers
    163       1.1       is  */
    164       1.1       is void
    165       1.1       is siopng_minphys(bp)
    166       1.1       is 	struct buf *bp;
    167       1.1       is {
    168       1.1       is 
    169       1.1       is 	/*
    170       1.1       is 	 * No max transfer at this level.
    171       1.1       is 	 */
    172       1.1       is 	minphys(bp);
    173       1.1       is }
    174       1.1       is 
    175       1.1       is /*
    176       1.1       is  * used by specific siopng controller
    177       1.1       is  *
    178       1.1       is  */
    179  1.14.2.1   bouyer void
    180  1.14.2.1   bouyer siopng_scsipi_request(chan, req, arg)
    181  1.14.2.1   bouyer 	struct scsipi_channel *chan;
    182  1.14.2.1   bouyer 	scsipi_adapter_req_t req;
    183  1.14.2.1   bouyer 	void *arg;
    184       1.1       is {
    185  1.14.2.1   bouyer 	struct scsipi_xfer *xs;
    186  1.14.2.1   bouyer 	struct scsipi_periph *periph;
    187       1.1       is 	struct siop_acb *acb;
    188  1.14.2.1   bouyer 	struct siop_softc *sc = (void *)chan->chan_adapter->adapt_dev;
    189       1.1       is 	int flags, s;
    190       1.1       is 
    191  1.14.2.1   bouyer 	switch (req) {
    192  1.14.2.1   bouyer 	case ADAPTER_REQ_RUN_XFER:
    193  1.14.2.1   bouyer 		xs = arg;
    194  1.14.2.1   bouyer 		periph = xs->xs_periph;
    195  1.14.2.1   bouyer 		flags = xs->xs_control;
    196  1.14.2.1   bouyer 
    197  1.14.2.1   bouyer 		/* XXXX ?? */
    198  1.14.2.1   bouyer 		if (flags & XS_CTL_DATA_UIO)
    199  1.14.2.1   bouyer 			panic("siopng: scsi data uio requested");
    200  1.14.2.1   bouyer 
    201  1.14.2.1   bouyer 		/* XXXX ?? */
    202  1.14.2.1   bouyer 		if (sc->sc_nexus && flags & XS_CTL_POLL)
    203  1.14.2.1   bouyer /*			panic("siopng_scsicmd: busy");*/
    204  1.14.2.1   bouyer 			printf("siopng_scsicmd: busy\n");
    205  1.14.2.1   bouyer 
    206  1.14.2.1   bouyer 		s = splbio();
    207  1.14.2.1   bouyer 		acb = sc->free_list.tqh_first;
    208  1.14.2.1   bouyer 		if (acb) {
    209  1.14.2.1   bouyer 			TAILQ_REMOVE(&sc->free_list, acb, chain);
    210  1.14.2.1   bouyer 		}
    211  1.14.2.1   bouyer 		splx(s);
    212       1.1       is 
    213  1.14.2.1   bouyer #ifdef DIAGNOSTIC
    214  1.14.2.1   bouyer 		/*
    215  1.14.2.1   bouyer 		 * This should never happen as we track the resources
    216  1.14.2.1   bouyer 		 * in the mid-layer.
    217  1.14.2.1   bouyer 		 */
    218  1.14.2.1   bouyer 		if (acb == NULL) {
    219  1.14.2.1   bouyer 			scsipi_printaddr(periph);
    220  1.14.2.1   bouyer 			printf("unable to allocate acb\n");
    221  1.14.2.1   bouyer 			panic("sea_scsipi_request");
    222  1.14.2.1   bouyer 		}
    223  1.14.2.1   bouyer #endif
    224  1.14.2.1   bouyer 		acb->flags = ACB_ACTIVE;
    225  1.14.2.1   bouyer 		acb->xs = xs;
    226  1.14.2.1   bouyer 		bcopy(xs->cmd, &acb->cmd, xs->cmdlen);
    227  1.14.2.1   bouyer 		acb->clen = xs->cmdlen;
    228  1.14.2.1   bouyer 		acb->daddr = xs->data;
    229  1.14.2.1   bouyer 		acb->dleft = xs->datalen;
    230       1.1       is 
    231  1.14.2.1   bouyer 		s = splbio();
    232  1.14.2.1   bouyer 		TAILQ_INSERT_TAIL(&sc->ready_list, acb, chain);
    233       1.1       is 
    234  1.14.2.1   bouyer 		if (sc->sc_nexus == NULL)
    235  1.14.2.1   bouyer 			siopng_sched(sc);
    236       1.1       is 
    237  1.14.2.1   bouyer 		splx(s);
    238       1.1       is 
    239  1.14.2.1   bouyer 		if (flags & XS_CTL_POLL || siopng_no_dma)
    240  1.14.2.1   bouyer 			siopng_poll(sc, acb);
    241  1.14.2.1   bouyer 		return;
    242       1.1       is 
    243  1.14.2.1   bouyer 	case ADAPTER_REQ_GROW_RESOURCES:
    244  1.14.2.1   bouyer 		return;
    245       1.1       is 
    246  1.14.2.1   bouyer 	case ADAPTER_REQ_SET_XFER_MODE:
    247  1.14.2.1   bouyer 		return;
    248  1.14.2.1   bouyer 	}
    249       1.1       is }
    250       1.1       is 
    251       1.1       is int
    252       1.1       is siopng_poll(sc, acb)
    253       1.1       is 	struct siop_softc *sc;
    254       1.1       is 	struct siop_acb *acb;
    255       1.1       is {
    256       1.1       is 	siop_regmap_p rp = sc->sc_siopp;
    257       1.1       is 	struct scsipi_xfer *xs = acb->xs;
    258       1.1       is 	int i;
    259       1.1       is 	int status;
    260       1.1       is 	u_char istat;
    261       1.1       is 	u_char dstat;
    262       1.1       is 	u_short sist;
    263       1.1       is 	int s;
    264       1.1       is 	int to;
    265       1.1       is 
    266       1.1       is 	s = splbio();
    267       1.1       is 	to = xs->timeout / 1000;
    268       1.1       is 	if (sc->nexus_list.tqh_first)
    269       1.1       is 		printf("%s: siopng_poll called with disconnected device\n",
    270       1.1       is 		    sc->sc_dev.dv_xname);
    271       1.1       is 	for (;;) {
    272       1.1       is 		/* use cmd_wait values? */
    273       1.1       is 		i = 50000;
    274       1.1       is 		/* XXX spl0(); */
    275       1.1       is 		while (((istat = rp->siop_istat) &
    276       1.1       is 		    (SIOP_ISTAT_SIP | SIOP_ISTAT_DIP)) == 0) {
    277       1.1       is 			if (--i <= 0) {
    278       1.1       is #ifdef DEBUG
    279       1.1       is 				printf ("waiting: tgt %d cmd %02x sbcl %02x istat %02x sbdl %04x\n         dsp %lx (+%lx) dcmd %lx ds %p timeout %d\n",
    280  1.14.2.1   bouyer 				    xs->xs_periph->periph_target, acb->cmd.opcode,
    281       1.1       is 				    rp->siop_sbcl, istat, rp->siop_sbdl, rp->siop_dsp,
    282       1.1       is 				    rp->siop_dsp - sc->sc_scriptspa,
    283       1.1       is 				    *((long *)&rp->siop_dcmd), &acb->ds, acb->xs->timeout);
    284       1.1       is #endif
    285       1.1       is 				i = 50000;
    286       1.1       is 				--to;
    287       1.1       is 				if (to <= 0) {
    288       1.1       is 					siopngreset(sc);
    289       1.1       is 					return(COMPLETE);
    290       1.1       is 				}
    291       1.1       is 			}
    292       1.1       is 			delay(20);
    293       1.1       is 		}
    294       1.1       is 		sist = rp->siop_sist;
    295       1.1       is 		dstat = rp->siop_dstat;
    296       1.1       is 		if (siopng_checkintr(sc, istat, dstat, sist, &status)) {
    297       1.1       is 			if (acb != sc->sc_nexus)
    298       1.1       is 				printf("%s: siopng_poll disconnected device completed\n",
    299       1.1       is 				    sc->sc_dev.dv_xname);
    300       1.1       is 			else if ((sc->sc_flags & SIOP_INTDEFER) == 0) {
    301       1.1       is 				sc->sc_flags &= ~SIOP_INTSOFF;
    302       1.1       is 				rp->siop_sien = sc->sc_sien;
    303       1.1       is 				rp->siop_dien = sc->sc_dien;
    304       1.1       is 			}
    305       1.1       is 			siopng_scsidone(sc->sc_nexus, status);
    306       1.1       is 		}
    307      1.14  thorpej 		if (xs->xs_status & XS_STS_DONE)
    308       1.1       is 			break;
    309       1.1       is 	}
    310       1.1       is 	splx(s);
    311       1.1       is 	return (COMPLETE);
    312       1.1       is }
    313       1.1       is 
    314       1.1       is /*
    315       1.1       is  * start next command that's ready
    316       1.1       is  */
    317       1.1       is void
    318       1.1       is siopng_sched(sc)
    319       1.1       is 	struct siop_softc *sc;
    320       1.1       is {
    321  1.14.2.1   bouyer 	struct scsipi_periph *periph;
    322       1.1       is 	struct siop_acb *acb;
    323       1.1       is 	int i;
    324       1.1       is 
    325       1.1       is #ifdef DEBUG
    326       1.1       is 	if (sc->sc_nexus) {
    327       1.1       is 		printf("%s: siopng_sched- nexus %p/%d ready %p/%d\n",
    328       1.1       is 		    sc->sc_dev.dv_xname, sc->sc_nexus,
    329  1.14.2.1   bouyer 		    sc->sc_nexus->xs->xs_periph->periph_target,
    330       1.1       is 		    sc->ready_list.tqh_first,
    331  1.14.2.1   bouyer 		    sc->ready_list.tqh_first->xs->xs_periph->periph_target);
    332       1.1       is 		return;
    333       1.1       is 	}
    334       1.1       is #endif
    335       1.1       is 	for (acb = sc->ready_list.tqh_first; acb; acb = acb->chain.tqe_next) {
    336  1.14.2.1   bouyer 		periph = acb->xs->xs_periph;
    337  1.14.2.1   bouyer 		i = periph->periph_target;
    338  1.14.2.1   bouyer 		if(!(sc->sc_tinfo[i].lubusy & (1 << periph->periph_lun))) {
    339       1.1       is 			struct siop_tinfo *ti = &sc->sc_tinfo[i];
    340       1.1       is 
    341       1.1       is 			TAILQ_REMOVE(&sc->ready_list, acb, chain);
    342       1.1       is 			sc->sc_nexus = acb;
    343  1.14.2.1   bouyer 			periph = acb->xs->xs_periph;
    344  1.14.2.1   bouyer 			ti = &sc->sc_tinfo[periph->periph_target];
    345  1.14.2.1   bouyer 			ti->lubusy |= (1 << periph->periph_lun);
    346       1.1       is 			break;
    347       1.1       is 		}
    348       1.1       is 	}
    349       1.1       is 
    350       1.1       is 	if (acb == NULL) {
    351       1.1       is #ifdef DEBUGXXX
    352       1.1       is 		printf("%s: siopng_sched didn't find ready command\n",
    353       1.1       is 		    sc->sc_dev.dv_xname);
    354       1.1       is #endif
    355       1.1       is 		return;
    356       1.1       is 	}
    357       1.1       is 
    358      1.14  thorpej 	if (acb->xs->xs_control & XS_CTL_RESET)
    359       1.1       is 		siopngreset(sc);
    360       1.1       is 
    361       1.1       is #if 0
    362  1.14.2.1   bouyer 	acb->cmd.bytes[0] |= periph->periph_lun << 5;	/* XXXX */
    363       1.1       is #endif
    364       1.1       is 	++sc->sc_active;
    365       1.1       is 	siopng_select(sc);
    366       1.1       is }
    367       1.1       is 
    368       1.1       is void
    369       1.1       is siopng_scsidone(acb, stat)
    370       1.1       is 	struct siop_acb *acb;
    371       1.1       is 	int stat;
    372       1.1       is {
    373       1.1       is 	struct scsipi_xfer *xs;
    374  1.14.2.1   bouyer 	struct scsipi_periph *periph;
    375       1.1       is 	struct siop_softc *sc;
    376       1.1       is 	int dosched = 0;
    377       1.1       is 
    378       1.1       is 	if (acb == NULL || (xs = acb->xs) == NULL) {
    379       1.1       is #ifdef DIAGNOSTIC
    380       1.1       is 		printf("siopng_scsidone: NULL acb or scsipi_xfer\n");
    381       1.1       is #if defined(DEBUG) && defined(DDB)
    382       1.1       is 		Debugger();
    383       1.1       is #endif
    384       1.1       is #endif
    385       1.1       is 		return;
    386       1.1       is 	}
    387  1.14.2.1   bouyer 	periph = xs->xs_periph;
    388  1.14.2.1   bouyer 	sc = (void *)periph->periph_chan->chan_adapter->adapt_dev;
    389       1.1       is 	/*
    390       1.1       is 	 * is this right?
    391       1.1       is 	 */
    392       1.1       is 	xs->status = stat;
    393       1.1       is 
    394       1.1       is 	if (xs->error == XS_NOERROR && !(acb->flags & ACB_CHKSENSE)) {
    395       1.1       is 		if (stat == SCSI_CHECK) {
    396       1.1       is 			struct scsipi_sense *ss = (void *)&acb->cmd;
    397       1.1       is 			bzero(ss, sizeof(*ss));
    398       1.1       is 			ss->opcode = REQUEST_SENSE;
    399  1.14.2.1   bouyer 			ss->byte2 = periph->periph_lun << 5;
    400       1.1       is 			ss->length = sizeof(struct scsipi_sense_data);
    401       1.1       is 			acb->clen = sizeof(*ss);
    402       1.1       is 			acb->daddr = (char *)&xs->sense.scsi_sense;
    403       1.1       is 			acb->dleft = sizeof(struct scsipi_sense_data);
    404       1.1       is 			acb->flags = ACB_ACTIVE | ACB_CHKSENSE;
    405       1.1       is 			TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
    406       1.1       is 			--sc->sc_active;
    407  1.14.2.1   bouyer 			sc->sc_tinfo[periph->periph_target].lubusy &=
    408  1.14.2.1   bouyer 			    ~(1 << periph->periph_lun);
    409  1.14.2.1   bouyer 			sc->sc_tinfo[periph->periph_target].senses++;
    410       1.1       is 			if (sc->sc_nexus == acb) {
    411       1.1       is 				sc->sc_nexus = NULL;
    412       1.1       is 				siopng_sched(sc);
    413       1.1       is 			}
    414       1.1       is 			SIOP_TRACE('d','s',0,0)
    415       1.1       is 			return;
    416       1.1       is 		}
    417       1.1       is 	}
    418       1.1       is 	if (xs->error == XS_NOERROR && (acb->flags & ACB_CHKSENSE)) {
    419       1.1       is 		xs->error = XS_SENSE;
    420       1.1       is 	} else {
    421       1.1       is 		xs->resid = 0;		/* XXXX */
    422       1.1       is 	}
    423       1.1       is #if whataboutthisone
    424       1.1       is 		case SCSI_BUSY:
    425       1.1       is 			xs->error = XS_BUSY;
    426       1.1       is 			break;
    427       1.1       is #endif
    428      1.14  thorpej 	xs->xs_status |= XS_STS_DONE;
    429       1.1       is 
    430       1.1       is 	/*
    431       1.1       is 	 * Remove the ACB from whatever queue it's on.  We have to do a bit of
    432       1.1       is 	 * a hack to figure out which queue it's on.  Note that it is *not*
    433       1.1       is 	 * necessary to cdr down the ready queue, but we must cdr down the
    434       1.1       is 	 * nexus queue and see if it's there, so we can mark the unit as no
    435       1.1       is 	 * longer busy.  This code is sickening, but it works.
    436       1.1       is 	 */
    437       1.1       is 	if (acb == sc->sc_nexus) {
    438       1.1       is 		sc->sc_nexus = NULL;
    439  1.14.2.1   bouyer 		sc->sc_tinfo[periph->periph_target].lubusy &=
    440  1.14.2.1   bouyer 			~(1<<periph->periph_lun);
    441       1.1       is 		if (sc->ready_list.tqh_first)
    442       1.1       is 			dosched = 1;	/* start next command */
    443       1.1       is 		--sc->sc_active;
    444       1.1       is 		SIOP_TRACE('d','a',stat,0)
    445       1.1       is 	} else if (sc->ready_list.tqh_last == &acb->chain.tqe_next) {
    446       1.1       is 		TAILQ_REMOVE(&sc->ready_list, acb, chain);
    447       1.1       is 		SIOP_TRACE('d','r',stat,0)
    448       1.1       is 	} else {
    449       1.1       is 		register struct siop_acb *acb2;
    450       1.1       is 		for (acb2 = sc->nexus_list.tqh_first; acb2;
    451       1.1       is 		    acb2 = acb2->chain.tqe_next)
    452       1.1       is 			if (acb2 == acb) {
    453       1.1       is 				TAILQ_REMOVE(&sc->nexus_list, acb, chain);
    454  1.14.2.1   bouyer 				sc->sc_tinfo[periph->periph_target].lubusy
    455  1.14.2.1   bouyer 					&= ~(1<<periph->periph_lun);
    456       1.1       is 				--sc->sc_active;
    457       1.1       is 				break;
    458       1.1       is 			}
    459       1.1       is 		if (acb2)
    460       1.1       is 			;
    461       1.1       is 		else if (acb->chain.tqe_next) {
    462       1.1       is 			TAILQ_REMOVE(&sc->ready_list, acb, chain);
    463       1.1       is 			--sc->sc_active;
    464       1.1       is 		} else {
    465       1.1       is 			printf("%s: can't find matching acb\n",
    466       1.1       is 			    sc->sc_dev.dv_xname);
    467       1.1       is #ifdef DDB
    468       1.1       is /*			Debugger(); */
    469       1.1       is #endif
    470       1.1       is 		}
    471       1.1       is 		SIOP_TRACE('d','n',stat,0);
    472       1.1       is 	}
    473       1.1       is 	/* Put it on the free list. */
    474       1.1       is 	acb->flags = ACB_FREE;
    475       1.1       is 	TAILQ_INSERT_HEAD(&sc->free_list, acb, chain);
    476       1.1       is 
    477  1.14.2.1   bouyer 	sc->sc_tinfo[periph->periph_target].cmds++;
    478       1.1       is 
    479       1.1       is 	scsipi_done(xs);
    480       1.1       is 
    481       1.1       is 	if (dosched && sc->sc_nexus == NULL)
    482       1.1       is 		siopng_sched(sc);
    483       1.1       is }
    484       1.1       is 
    485       1.1       is void
    486       1.1       is siopngabort(sc, rp, where)
    487       1.1       is 	register struct siop_softc *sc;
    488       1.1       is 	siop_regmap_p rp;
    489       1.1       is 	char *where;
    490       1.1       is {
    491       1.1       is #ifdef fix_this
    492       1.1       is 	int i;
    493       1.1       is #endif
    494       1.1       is 
    495       1.1       is 	printf ("%s: abort %s: dstat %02x, istat %02x sist %04x sien %04x sbcl %02x\n",
    496       1.1       is 	    sc->sc_dev.dv_xname,
    497       1.1       is 	    where, rp->siop_dstat, rp->siop_istat, rp->siop_sist,
    498       1.1       is 	    rp->siop_sien, rp->siop_sbcl);
    499       1.1       is 	siopng_dump_registers(sc);
    500       1.1       is 
    501       1.1       is 	if (sc->sc_active > 0) {
    502       1.1       is #ifdef TODO
    503       1.1       is       SET_SBIC_cmd (rp, SBIC_CMD_ABORT);
    504       1.1       is       WAIT_CIP (rp);
    505       1.1       is 
    506       1.1       is       GET_SBIC_asr (rp, asr);
    507       1.1       is       if (asr & (SBIC_ASR_BSY|SBIC_ASR_LCI))
    508       1.1       is         {
    509       1.1       is           /* ok, get more drastic.. */
    510       1.1       is 
    511       1.1       is 	  SET_SBIC_cmd (rp, SBIC_CMD_RESET);
    512       1.1       is 	  delay(25);
    513       1.1       is 	  SBIC_WAIT(rp, SBIC_ASR_INT, 0);
    514       1.1       is 	  GET_SBIC_csr (rp, csr);       /* clears interrupt also */
    515       1.1       is 
    516       1.1       is           return;
    517       1.1       is         }
    518       1.1       is 
    519       1.1       is       do
    520       1.1       is         {
    521       1.1       is           SBIC_WAIT (rp, SBIC_ASR_INT, 0);
    522       1.1       is           GET_SBIC_csr (rp, csr);
    523       1.1       is         }
    524       1.1       is       while ((csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1)
    525       1.1       is 	      && (csr != SBIC_CSR_CMD_INVALID));
    526       1.1       is #endif
    527       1.1       is 
    528       1.1       is 		/* lets just hope it worked.. */
    529       1.1       is #ifdef fix_this
    530       1.1       is 		for (i = 0; i < 2; ++i) {
    531       1.1       is 			if (sc->sc_iob[i].sc_xs && &sc->sc_iob[i] !=
    532       1.1       is 			    sc->sc_cur) {
    533       1.1       is 				printf ("siopngabort: cleanup!\n");
    534       1.1       is 				sc->sc_iob[i].sc_xs = NULL;
    535       1.1       is 			}
    536       1.1       is 		}
    537       1.1       is #endif	/* fix_this */
    538       1.1       is /*		sc->sc_active = 0; */
    539       1.1       is 	}
    540       1.1       is }
    541       1.1       is 
    542       1.1       is void
    543       1.1       is siopnginitialize(sc)
    544       1.1       is 	struct siop_softc *sc;
    545       1.1       is {
    546       1.1       is 	int i;
    547       1.1       is 	u_int inhibit_sync;
    548       1.1       is 	extern u_long scsi_nosync;
    549       1.1       is 	extern int shift_nosync;
    550       1.1       is 
    551       1.1       is 	/*
    552       1.1       is 	 * Need to check that scripts is on a long word boundary
    553       1.1       is 	 * Also should verify that dev doesn't span non-contiguous
    554       1.1       is 	 * physical pages.
    555       1.1       is 	 */
    556       1.1       is 	sc->sc_scriptspa = kvtop((caddr_t)siopng_scripts);
    557       1.1       is 
    558       1.1       is 	/*
    559       1.1       is 	 * malloc sc_acb to ensure that DS is on a long word boundary.
    560       1.1       is 	 */
    561       1.1       is 
    562       1.1       is 	MALLOC(sc->sc_acb, struct siop_acb *,
    563       1.1       is 		sizeof(struct siop_acb) * SIOP_NACB, M_DEVBUF, M_NOWAIT);
    564       1.1       is 	if (sc->sc_acb == NULL)
    565       1.1       is 		panic("siopnginitialize: ACB malloc failed!");
    566       1.1       is 
    567       1.1       is 	sc->sc_tcp[1] = 1000 / sc->sc_clock_freq;
    568       1.1       is 	sc->sc_tcp[2] = 1500 / sc->sc_clock_freq;
    569       1.1       is 	sc->sc_tcp[3] = 2000 / sc->sc_clock_freq;
    570       1.1       is 	sc->sc_minsync = sc->sc_tcp[1];		/* in 4ns units */
    571       1.1       is 	if (sc->sc_minsync < 25)
    572       1.1       is 		sc->sc_minsync = 25;
    573       1.6   mhitch 	sc->sc_minsync >>= 1;			/* Using clock doubler, allow Ultra */
    574       1.1       is 	if (sc->sc_clock_freq <= 25) {
    575       1.1       is 		sc->sc_dcntl |= 0x80;		/* SCLK/1 */
    576       1.1       is 		sc->sc_tcp[0] = sc->sc_tcp[1];
    577       1.1       is 	} else if (sc->sc_clock_freq <= 37) {
    578       1.1       is 		sc->sc_dcntl |= 0x40;		/* SCLK/1.5 */
    579       1.1       is 		sc->sc_tcp[0] = sc->sc_tcp[2];
    580       1.1       is 	} else if (sc->sc_clock_freq <= 50) {
    581       1.1       is 		sc->sc_dcntl |= 0x00;		/* SCLK/2 */
    582       1.1       is 		sc->sc_tcp[0] = sc->sc_tcp[3];
    583       1.1       is 	} else {
    584       1.1       is 		sc->sc_dcntl |= 0xc0;		/* SCLK/3 */
    585       1.1       is 		sc->sc_tcp[0] = 3000 / sc->sc_clock_freq;
    586       1.1       is 	}
    587       1.1       is 
    588       1.1       is 	if (scsi_nosync) {
    589       1.6   mhitch 		inhibit_sync = (scsi_nosync >> shift_nosync) & 0xffff;
    590       1.6   mhitch 		shift_nosync += 16;		/* XXX maxtarget */
    591       1.1       is #ifdef DEBUG
    592       1.1       is 		if (inhibit_sync)
    593       1.1       is 			printf("%s: Inhibiting synchronous transfer %02x\n",
    594       1.1       is 				sc->sc_dev.dv_xname, inhibit_sync);
    595       1.1       is #endif
    596       1.6   mhitch 		for (i = 0; i < 16; ++i)		/* XXX maxtarget */
    597       1.1       is 			if (inhibit_sync & (1 << i))
    598       1.1       is 				siopng_inhibit_sync[i] = 1;
    599       1.1       is 	}
    600       1.1       is 
    601       1.1       is 	siopngreset (sc);
    602       1.1       is }
    603       1.1       is 
    604       1.1       is void
    605       1.1       is siopngreset(sc)
    606       1.1       is 	struct siop_softc *sc;
    607       1.1       is {
    608       1.1       is 	siop_regmap_p rp;
    609       1.1       is 	u_int i, s;
    610       1.1       is 	u_short  dummy;
    611       1.1       is 	struct siop_acb *acb;
    612       1.1       is 
    613       1.1       is 	rp = sc->sc_siopp;
    614       1.1       is 
    615       1.1       is 	if (sc->sc_flags & SIOP_ALIVE)
    616       1.1       is 		siopngabort(sc, rp, "reset");
    617       1.1       is 
    618       1.1       is 	printf("%s: ", sc->sc_dev.dv_xname);		/* XXXX */
    619       1.1       is 
    620       1.1       is 	s = splbio();
    621       1.1       is 
    622       1.1       is 	/*
    623       1.1       is 	 * Reset the chip
    624       1.1       is 	 * XXX - is this really needed?
    625       1.1       is 	 */
    626       1.1       is 	rp->siop_istat |= SIOP_ISTAT_ABRT;	/* abort current script */
    627       1.1       is 	rp->siop_istat |= SIOP_ISTAT_RST;		/* reset chip */
    628       1.1       is 	rp->siop_istat &= ~SIOP_ISTAT_RST;
    629       1.1       is 	/*
    630       1.1       is 	 * Reset SCSI bus (do we really want this?)
    631       1.1       is 	 */
    632       1.1       is 	rp->siop_sien = 0;
    633       1.1       is 	rp->siop_scntl1 |= SIOP_SCNTL1_RST;
    634       1.1       is 	delay(1);
    635       1.1       is 	rp->siop_scntl1 &= ~SIOP_SCNTL1_RST;
    636       1.1       is 
    637       1.1       is 	/*
    638       1.1       is 	 * Set up various chip parameters
    639       1.1       is 	 */
    640       1.6   mhitch 	rp->siop_stest1 |= SIOP_STEST1_DBLEN;	/* SCLK doubler enable */
    641       1.1       is 	delay(20);
    642       1.6   mhitch 	rp->siop_stest3 |= SIOP_STEST3_HSC;	/* Halt SCSI clock */
    643       1.6   mhitch 	rp->siop_scntl3 = 0x15;			/* SCF/CCF*/
    644       1.6   mhitch 	rp->siop_stest1 |= SIOP_STEST1_DBLSEL;	/* SCLK doubler select */
    645       1.6   mhitch 	rp->siop_stest3 &= ~SIOP_STEST3_HSC;	/* Clear Halt SCSI clock */
    646       1.1       is 	rp->siop_scntl0 = SIOP_ARB_FULL | /*SIOP_SCNTL0_EPC |*/ SIOP_SCNTL0_EPG;
    647       1.1       is 	rp->siop_dcntl = sc->sc_dcntl;
    648       1.1       is 	rp->siop_dmode = 0xc0;		/* XXX burst length */
    649       1.1       is 	rp->siop_sien = 0x00;	/* don't enable interrupts yet */
    650       1.1       is 	rp->siop_dien = 0x00;	/* don't enable interrupts yet */
    651  1.14.2.1   bouyer 	rp->siop_scid = sc->sc_channel->chan_id |
    652       1.6   mhitch 	    SIOP_SCID_RRE | SIOP_SCID_SRE;
    653  1.14.2.1   bouyer 	rp->siop_respid = 1 << sc->channel->chan_id;
    654       1.1       is 	rp->siop_dwt = 0x00;
    655       1.1       is 	rp->siop_stime0 = 0x0c;		/* XXXXX check */
    656       1.1       is 
    657       1.1       is 	/* will need to re-negotiate sync xfers */
    658       1.1       is 	bzero(&sc->sc_sync, sizeof (sc->sc_sync));
    659       1.1       is 
    660       1.1       is 	i = rp->siop_istat;
    661       1.1       is 	if (i & SIOP_ISTAT_SIP)
    662       1.1       is 		dummy = rp->siop_sist;
    663       1.1       is 	if (i & SIOP_ISTAT_DIP)
    664       1.1       is 		dummy = rp->siop_dstat;
    665       1.1       is 
    666       1.1       is 	splx (s);
    667       1.1       is 
    668       1.1       is 	delay (siopng_reset_delay * 1000);
    669      1.12       is 
    670      1.12       is 	/*
    671      1.12       is 	 * is lower half unterminated?
    672      1.12       is 	 */
    673      1.12       is 	if ((rp->siop_sbdl & 0x00ff) == 0x00ff) {
    674      1.12       is 		printf(" no SCSI termination, host adapter deactivated.\n");
    675  1.14.2.1   bouyer 		sc->sc_channel->chan_ntargets = 0;	/* XXX */
    676      1.12       is 		sc->sc_flags &= ~(SIOP_ALIVE|SIOP_INTDEFER|SIOP_INTSOFF);
    677      1.12       is 		/* disable SCSI and DMA interrupts */
    678      1.12       is 		sc->sc_sien = 0;
    679      1.12       is 		sc->sc_dien = 0;
    680      1.12       is 		rp->siop_sien = sc->sc_sien;
    681      1.12       is 		rp->siop_dien = sc->sc_dien;
    682      1.12       is 
    683      1.12       is 		return;
    684      1.12       is 	}
    685      1.12       is 
    686       1.1       is 	/*
    687       1.1       is 	 * Check if upper half of SCSI bus is unterminated, and disallow
    688       1.1       is 	 * disconnections if it appears to be unterminated.
    689       1.1       is 	 */
    690       1.1       is 	if ((rp->siop_sbdl & 0xff00) == 0xff00) {
    691       1.1       is 		printf(" NO WIDE TERM");
    692       1.6   mhitch 		/* XXX need to restrict maximum target ID as well? */
    693  1.14.2.1   bouyer 		sc->sc_channel->chan_ntargets = 8;
    694       1.6   mhitch 		for (i = 0; i < 16; ++i) {
    695       1.1       is 			siopng_allow_disc[i] = 0;
    696       1.6   mhitch 			siopng_inhibit_wide[i] |= 0x80;
    697       1.6   mhitch 		}
    698       1.1       is 	}
    699       1.4       is 
    700       1.4       is 	printf("siopng type %s id %d reset V%d\n",
    701       1.4       is 	    siopng_chips[rp->siop_macntl>>4],
    702  1.14.2.1   bouyer 	    sc->sc_channel->chan_ntargets,
    703       1.1       is 	    rp->siop_ctest3 >> 4);
    704       1.1       is 
    705       1.1       is 	if ((sc->sc_flags & SIOP_ALIVE) == 0) {
    706       1.1       is 		TAILQ_INIT(&sc->ready_list);
    707       1.1       is 		TAILQ_INIT(&sc->nexus_list);
    708       1.1       is 		TAILQ_INIT(&sc->free_list);
    709       1.1       is 		sc->sc_nexus = NULL;
    710       1.1       is 		acb = sc->sc_acb;
    711       1.1       is 		bzero(acb, sizeof(struct siop_acb) * SIOP_NACB);
    712       1.1       is 		for (i = 0; i < SIOP_NACB; i++) {
    713       1.1       is 			TAILQ_INSERT_TAIL(&sc->free_list, acb, chain);
    714       1.1       is 			acb++;
    715       1.1       is 		}
    716       1.1       is 		bzero(sc->sc_tinfo, sizeof(sc->sc_tinfo));
    717       1.1       is 	} else {
    718       1.1       is 		if (sc->sc_nexus != NULL) {
    719  1.14.2.1   bouyer 			sc->sc_nexus->xs->error = XS_RESET;
    720       1.1       is 			siopng_scsidone(sc->sc_nexus, sc->sc_nexus->stat[0]);
    721       1.1       is 		}
    722       1.1       is 		while ((acb = sc->nexus_list.tqh_first) > 0) {
    723  1.14.2.1   bouyer 			acb->xs->error = XS_RESET;
    724       1.1       is 			siopng_scsidone(acb, acb->stat[0]);
    725       1.1       is 		}
    726       1.1       is 	}
    727       1.1       is 
    728       1.1       is 	sc->sc_flags |= SIOP_ALIVE;
    729       1.1       is 	sc->sc_flags &= ~(SIOP_INTDEFER|SIOP_INTSOFF);
    730       1.1       is 	/* enable SCSI and DMA interrupts */
    731       1.1       is 	sc->sc_sien = SIOP_SIEN_MA | SIOP_SIEN_STO | /*SIOP_SIEN_GEN |*/
    732       1.1       is 	    /*SIOP_SIEN_SEL |*/ SIOP_SIEN_SGE | SIOP_SIEN_UDC |
    733       1.1       is 	     SIOP_SIEN_RST | SIOP_SIEN_PAR;
    734       1.1       is 	sc->sc_dien = SIOP_DIEN_BF | SIOP_DIEN_ABRT | SIOP_DIEN_SIR |
    735       1.1       is 	    /*SIOP_DIEN_WTD |*/ SIOP_DIEN_IID;
    736       1.1       is 	rp->siop_sien = sc->sc_sien;
    737       1.1       is 	rp->siop_dien = sc->sc_dien;
    738      1.10       is 	/*siopng_dump_registers(sc);*/
    739       1.1       is }
    740       1.1       is 
    741       1.1       is /*
    742       1.1       is  * Setup Data Storage for 53C720/770 and start SCRIPTS processing
    743       1.1       is  */
    744       1.1       is 
    745       1.1       is void
    746       1.1       is siopng_start (sc, target, lun, cbuf, clen, buf, len)
    747       1.1       is 	struct siop_softc *sc;
    748       1.1       is 	int target;
    749       1.1       is 	int lun;
    750       1.1       is 	u_char *cbuf;
    751       1.1       is 	int clen;
    752       1.1       is 	u_char *buf;
    753       1.1       is 	int len;
    754       1.1       is {
    755       1.1       is 	siop_regmap_p rp = sc->sc_siopp;
    756       1.1       is 	int nchain;
    757       1.1       is 	int count, tcount;
    758       1.1       is 	char *addr, *dmaend;
    759       1.1       is 	struct siop_acb *acb = sc->sc_nexus;
    760       1.1       is #ifdef DEBUG
    761       1.1       is 	int i;
    762       1.1       is #endif
    763       1.1       is 
    764       1.1       is #ifdef DEBUG
    765       1.1       is 	if (siopng_debug & 0x100 && rp->siop_sbcl & SIOP_BSY) {
    766       1.1       is 		printf ("ACK! siopng was busy: rp %p script %p dsa %p active %ld\n",
    767       1.2       is 		    rp, &siopng_scripts, &acb->ds, sc->sc_active);
    768       1.1       is 		printf ("istat %02x sfbr %02x respid %02x sien %04x dien %02x\n",
    769       1.1       is 		    rp->siop_istat, rp->siop_sfbr, rp->siop_respid,
    770       1.1       is 		    rp->siop_sien, rp->siop_dien);
    771       1.1       is #ifdef DDB
    772       1.1       is 		/*Debugger();*/
    773       1.1       is #endif
    774       1.1       is 	}
    775       1.1       is #endif
    776       1.1       is 	acb->msgout[0] = MSG_IDENTIFY | lun;
    777       1.1       is 	if (siopng_allow_disc[target] & 2 ||
    778       1.1       is 	    (siopng_allow_disc[target] && len == 0))
    779       1.1       is 		acb->msgout[0] = MSG_IDENTIFY_DR | lun;
    780       1.1       is 	acb->status = 0;
    781       1.1       is 	acb->stat[0] = -1;
    782       1.1       is 	acb->msg[0] = -1;
    783       1.1       is 	acb->ds.scsi_addr = (target << 16) | (sc->sc_sync[target].sxfer << 8) |
    784       1.6   mhitch 	    (sc->sc_sync[target].scntl3 << 24);
    785       1.1       is 	acb->ds.idlen = 1;
    786       1.1       is 	acb->ds.idbuf = (char *) kvtop(&acb->msgout[0]);
    787       1.1       is 	acb->ds.cmdlen = clen;
    788       1.1       is 	acb->ds.cmdbuf = (char *) kvtop(cbuf);
    789       1.1       is 	acb->ds.stslen = 1;
    790       1.1       is 	acb->ds.stsbuf = (char *) kvtop(&acb->stat[0]);
    791       1.1       is 	acb->ds.msglen = 1;
    792       1.1       is 	acb->ds.msgbuf = (char *) kvtop(&acb->msg[0]);
    793       1.1       is 	acb->msg[1] = -1;
    794       1.1       is 	acb->ds.msginlen = 1;
    795       1.1       is 	acb->ds.extmsglen = 1;
    796       1.1       is 	acb->ds.synmsglen = 3;
    797       1.6   mhitch 	acb->ds.msginbuf = acb->ds.msgbuf + 1;
    798       1.6   mhitch 	acb->ds.extmsgbuf = acb->ds.msginbuf + 1;
    799       1.6   mhitch 	acb->ds.synmsgbuf = acb->ds.extmsgbuf + 1;
    800       1.1       is 	bzero(&acb->ds.chain, sizeof (acb->ds.chain));
    801       1.1       is 
    802       1.6   mhitch 	if (sc->sc_sync[target].state == NEG_WIDE) {
    803       1.6   mhitch 		if (siopng_inhibit_wide[target]) {
    804       1.6   mhitch 			sc->sc_sync[target].state = NEG_SYNC;
    805       1.6   mhitch 			sc->sc_sync[target].scntl3 &= ~SIOP_SCNTL3_EWS;
    806       1.6   mhitch #ifdef DEBUG
    807       1.6   mhitch 			if (siopngsync_debug)
    808       1.6   mhitch 				printf ("Forcing target %d narrow\n", target);
    809       1.6   mhitch #endif
    810       1.6   mhitch 		}
    811       1.6   mhitch 		else {
    812       1.6   mhitch 			sc->sc_sync[target].scntl3 = 0x15 |	/* XXX */
    813       1.6   mhitch 			    (sc->sc_sync[target].scntl3 & 0x88);	/* XXX */
    814       1.6   mhitch 			acb->msg[2] = -1;
    815       1.6   mhitch 			acb->msgout[1] = MSG_EXT_MESSAGE;
    816       1.6   mhitch 			acb->msgout[2] = 2;
    817       1.6   mhitch 			acb->msgout[3] = MSG_WIDE_REQ;
    818       1.6   mhitch 			acb->msgout[4] = 1;
    819       1.6   mhitch 			acb->ds.idlen = 5;
    820       1.6   mhitch 			acb->ds.synmsglen = 2;
    821       1.6   mhitch 			sc->sc_sync[target].state = NEG_WAITW;
    822       1.6   mhitch #ifdef DEBUG
    823       1.6   mhitch 			if (siopngsync_debug)
    824       1.6   mhitch 				printf("Sending wide request to target %d\n", target);
    825       1.6   mhitch #endif
    826       1.6   mhitch 		}
    827       1.6   mhitch 	}
    828       1.6   mhitch 	if (sc->sc_sync[target].state == NEG_SYNC) {
    829       1.1       is 		if (siopng_inhibit_sync[target]) {
    830       1.6   mhitch 			sc->sc_sync[target].state = NEG_DONE;
    831       1.6   mhitch 			sc->sc_sync[target].scntl3 = 5 |		/* XXX */
    832       1.6   mhitch 			    (sc->sc_sync[target].scntl3 & 0x88);	/* XXX */
    833       1.1       is 			sc->sc_sync[target].sxfer = 0;
    834       1.1       is #ifdef DEBUG
    835       1.1       is 			if (siopngsync_debug)
    836       1.1       is 				printf ("Forcing target %d asynchronous\n", target);
    837       1.1       is #endif
    838       1.1       is 		}
    839       1.1       is 		else {
    840       1.6   mhitch 			sc->sc_sync[target].scntl3 = 0x15 |	/* XXX */
    841       1.6   mhitch 			    (sc->sc_sync[target].scntl3 & 0x88);	/* XXX */
    842       1.1       is 			acb->msg[2] = -1;
    843       1.1       is 			acb->msgout[1] = MSG_EXT_MESSAGE;
    844       1.1       is 			acb->msgout[2] = 3;
    845       1.1       is 			acb->msgout[3] = MSG_SYNC_REQ;
    846       1.1       is #ifdef MAXTOR_SYNC_KLUDGE
    847       1.1       is 			acb->msgout[4] = 50 / 4;	/* ask for ridiculous period */
    848       1.1       is #else
    849       1.1       is 			acb->msgout[4] = sc->sc_minsync;
    850       1.1       is #endif
    851       1.1       is 			acb->msgout[5] = SIOP_MAX_OFFSET;
    852       1.1       is 			acb->ds.idlen = 6;
    853       1.6   mhitch 			sc->sc_sync[target].state = NEG_WAITS;
    854       1.1       is #ifdef DEBUG
    855       1.1       is 			if (siopngsync_debug)
    856       1.1       is 				printf ("Sending sync request to target %d\n", target);
    857       1.1       is #endif
    858       1.1       is 		}
    859       1.1       is 	}
    860       1.1       is 
    861       1.1       is /*
    862       1.1       is  * Build physical DMA addresses for scatter/gather I/O
    863       1.1       is  */
    864       1.1       is 	acb->iob_buf = buf;
    865       1.1       is 	acb->iob_len = len;
    866       1.1       is 	acb->iob_curbuf = acb->iob_curlen = 0;
    867       1.1       is 	nchain = 0;
    868       1.1       is 	count = len;
    869       1.1       is 	addr = buf;
    870       1.1       is 	dmaend = NULL;
    871       1.1       is 	while (count > 0) {
    872       1.1       is 		acb->ds.chain[nchain].databuf = (char *) kvtop (addr);
    873       1.1       is 		if (count < (tcount = NBPG - ((int) addr & PGOFSET)))
    874       1.1       is 			tcount = count;
    875       1.3       is 
    876       1.3       is #if DEBUG_ONLY_IF_DESPERATE
    877       1.3       is 		printf("chain[%d]: count %d tcount %d vaddr %p paddr %p\n",
    878       1.3       is 			nchain, count, tcount, addr,
    879       1.3       is 			acb->ds.chain[nchain].databuf);
    880       1.3       is #endif
    881       1.1       is 		acb->ds.chain[nchain].datalen = tcount;
    882       1.1       is 		addr += tcount;
    883       1.1       is 		count -= tcount;
    884       1.1       is 		if (acb->ds.chain[nchain].databuf == dmaend) {
    885       1.1       is 			dmaend += acb->ds.chain[nchain].datalen;
    886       1.1       is 			acb->ds.chain[nchain].datalen = 0;
    887       1.1       is 			acb->ds.chain[--nchain].datalen += tcount;
    888       1.1       is #ifdef DEBUG
    889       1.1       is 			++siopngdma_hits;
    890       1.1       is #endif
    891       1.1       is 		}
    892       1.1       is 		else {
    893       1.1       is 			dmaend = acb->ds.chain[nchain].databuf +
    894       1.1       is 			    acb->ds.chain[nchain].datalen;
    895       1.1       is 			acb->ds.chain[nchain].datalen = tcount;
    896       1.1       is #ifdef DEBUG
    897       1.1       is 			if (nchain)	/* Don't count miss on first one */
    898       1.1       is 				++siopngdma_misses;
    899       1.1       is #endif
    900       1.1       is 		}
    901       1.1       is 		++nchain;
    902       1.1       is 	}
    903       1.1       is #ifdef DEBUG
    904       1.1       is 	if (nchain != 1 && len != 0 && siopng_debug & 3) {
    905       1.1       is 		printf ("DMA chaining set: %d\n", nchain);
    906       1.1       is 		for (i = 0; i < nchain; ++i) {
    907       1.1       is 			printf ("  [%d] %8p %lx\n", i, acb->ds.chain[i].databuf,
    908       1.1       is 			    acb->ds.chain[i].datalen);
    909       1.1       is 		}
    910       1.1       is 	}
    911       1.1       is #endif
    912       1.1       is 
    913       1.1       is 	/* push data cache for all data the 53c720/770 needs to access */
    914       1.1       is 	dma_cachectl ((caddr_t)acb, sizeof (struct siop_acb));
    915       1.1       is 	dma_cachectl (cbuf, clen);
    916       1.1       is 	if (buf != NULL && len != 0)
    917       1.1       is 		dma_cachectl (buf, len);
    918       1.1       is #ifdef DEBUG
    919       1.1       is 	if (siopng_debug & 0x100 && rp->siop_sbcl & SIOP_BSY) {
    920       1.1       is 		printf ("ACK! siopng was busy at start: rp %p script %p dsa %p active %ld\n",
    921       1.2       is 		    rp, &siopng_scripts, &acb->ds, sc->sc_active);
    922       1.1       is #ifdef DDB
    923       1.1       is 		/*Debugger();*/
    924       1.1       is #endif
    925       1.1       is 	}
    926       1.1       is #endif
    927       1.1       is 	if (sc->nexus_list.tqh_first == NULL) {
    928       1.1       is 		if (rp->siop_istat & SIOP_ISTAT_CON)
    929       1.1       is 			printf("%s: siopng_select while connected?\n",
    930       1.1       is 			    sc->sc_dev.dv_xname);
    931       1.1       is 		rp->siop_temp = 0;
    932       1.1       is #ifndef FIXME
    933       1.6   mhitch 		rp->siop_scntl3 = sc->sc_sync[target].scntl3;
    934       1.1       is #endif
    935       1.1       is 		rp->siop_dsa = kvtop((caddr_t)&acb->ds);
    936       1.1       is 		rp->siop_dsp = sc->sc_scriptspa;
    937       1.1       is 		SIOP_TRACE('s',1,0,0)
    938       1.1       is 	} else {
    939       1.1       is 		if ((rp->siop_istat & SIOP_ISTAT_CON) == 0) {
    940       1.1       is 			rp->siop_istat = SIOP_ISTAT_SIGP;
    941       1.1       is 			SIOP_TRACE('s',2,0,0);
    942       1.1       is 		}
    943       1.1       is 		else {
    944       1.1       is 			SIOP_TRACE('s',3,rp->siop_istat,0);
    945       1.1       is 		}
    946       1.1       is 	}
    947       1.1       is #ifdef DEBUG
    948       1.1       is 	++siopngstarts;
    949       1.1       is #endif
    950       1.1       is }
    951       1.1       is 
    952       1.1       is /*
    953       1.1       is  * Process a DMA or SCSI interrupt from the 53C720/770 SIOP
    954       1.1       is  */
    955       1.1       is 
    956       1.1       is int
    957       1.1       is siopng_checkintr(sc, istat, dstat, sist, status)
    958       1.1       is 	struct	siop_softc *sc;
    959       1.1       is 	u_char	istat;
    960       1.1       is 	u_char	dstat;
    961       1.1       is 	u_short	sist;
    962       1.1       is 	int	*status;
    963       1.1       is {
    964       1.1       is 	siop_regmap_p rp = sc->sc_siopp;
    965       1.1       is 	struct siop_acb *acb = sc->sc_nexus;
    966       1.1       is 	int	target = 0;
    967       1.3       is 	int	dfifo, dbc, sstat0, sstat1, sstat2;
    968       1.1       is 
    969       1.1       is 	dfifo = rp->siop_dfifo;
    970       1.1       is 	dbc = rp->siop_dbc0;
    971       1.3       is 	sstat0 = rp->siop_sstat0;
    972       1.1       is 	sstat1 = rp->siop_sstat1;
    973       1.3       is 	sstat2 = rp->siop_sstat2;
    974       1.1       is 	rp->siop_ctest3 |= SIOP_CTEST8_CLF;
    975       1.1       is 	while ((rp->siop_ctest1 & SIOP_CTEST1_FMT) != SIOP_CTEST1_FMT)
    976       1.1       is 		;
    977       1.1       is 	rp->siop_ctest3 &= ~SIOP_CTEST8_CLF;
    978       1.1       is #ifdef DEBUG
    979       1.1       is 	++siopngints;
    980       1.1       is #if 0
    981       1.1       is 	if (siopng_debug & 0x100) {
    982       1.1       is 		DCIAS(&acb->stat[0]);	/* XXX */
    983       1.1       is 		printf ("siopngchkintr: istat %x dstat %x sist %x dsps %x sbcl %x sts %x msg %x\n",
    984       1.1       is 		    istat, dstat, sist, rp->siop_dsps, rp->siop_sbcl, acb->stat[0], acb->msg[0]);
    985       1.1       is 		printf ("sync msg in: %02x %02x %02x %02x %02x %02x\n",
    986       1.1       is 		    acb->msg[0], acb->msg[1], acb->msg[2],
    987       1.1       is 		    acb->msg[3], acb->msg[4], acb->msg[5]);
    988       1.1       is 	}
    989       1.1       is #endif
    990       1.1       is 	if (rp->siop_dsp && (rp->siop_dsp < sc->sc_scriptspa ||
    991       1.2       is 	    rp->siop_dsp >= sc->sc_scriptspa + sizeof(siopng_scripts))) {
    992       1.1       is 		printf ("%s: dsp not within script dsp %lx scripts %lx:%lx",
    993       1.1       is 		    sc->sc_dev.dv_xname, rp->siop_dsp, sc->sc_scriptspa,
    994       1.2       is 		    sc->sc_scriptspa + sizeof(siopng_scripts));
    995       1.1       is 		printf(" istat %x dstat %x sist %x\n",
    996       1.1       is 		    istat, dstat, sist);
    997       1.1       is #ifdef DDB
    998       1.1       is 		Debugger();
    999       1.1       is #endif
   1000       1.1       is 	}
   1001       1.1       is #endif
   1002       1.1       is 	SIOP_TRACE('i',dstat,istat,(istat&SIOP_ISTAT_DIP)?rp->siop_dsps&0xff:sist);
   1003       1.1       is 	if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff00) {
   1004       1.1       is 		/* Normal completion status, or check condition */
   1005       1.1       is #ifdef DEBUG
   1006       1.1       is 		if (rp->siop_dsa != kvtop((caddr_t)&acb->ds)) {
   1007       1.1       is 			printf ("siopng: invalid dsa: %lx %x\n", rp->siop_dsa,
   1008       1.1       is 			    kvtop((caddr_t)&acb->ds));
   1009       1.1       is 			panic("*** siopng DSA invalid ***");
   1010       1.1       is 		}
   1011       1.1       is #endif
   1012  1.14.2.1   bouyer 		target = acb->xs->xs_periph->periph_target;
   1013       1.6   mhitch 		if (sc->sc_sync[target].state == NEG_WAITW) {
   1014       1.6   mhitch 			if (acb->msg[1] == 0xff)
   1015       1.6   mhitch 				printf ("%s: target %d ignored wide request\n",
   1016       1.6   mhitch 				    sc->sc_dev.dv_xname, target);
   1017       1.6   mhitch 			else if (acb->msg[1] == MSG_REJECT)
   1018       1.6   mhitch 				printf ("%s: target %d rejected wide request\n",
   1019       1.6   mhitch 				    sc->sc_dev.dv_xname, target);
   1020       1.6   mhitch 			else {
   1021       1.6   mhitch 				printf("%s: target %d (wide) %02x %02x %02x %02x\n",
   1022       1.6   mhitch 				    sc->sc_dev.dv_xname, target, acb->msg[1],
   1023       1.6   mhitch 				    acb->msg[2], acb->msg[3], acb->msg[4]);
   1024       1.6   mhitch 				if (acb->msg[1] == MSG_EXT_MESSAGE &&
   1025       1.6   mhitch 				    acb->msg[2] == 2 &&
   1026       1.6   mhitch 				    acb->msg[3] == MSG_WIDE_REQ)
   1027       1.6   mhitch 					sc->sc_sync[target].scntl3 = acb->msg[4] ?
   1028       1.6   mhitch 					    sc->sc_sync[target].scntl3 | SIOP_SCNTL3_EWS :
   1029       1.6   mhitch 					    sc->sc_sync[target].scntl3 & ~SIOP_SCNTL3_EWS;
   1030       1.6   mhitch 			}
   1031       1.6   mhitch 			sc->sc_sync[target].state = NEG_SYNC;
   1032       1.6   mhitch 		}
   1033       1.6   mhitch 		if (sc->sc_sync[target].state == NEG_WAITS) {
   1034       1.6   mhitch 			if (acb->msg[1] == 0xff)
   1035       1.6   mhitch 				printf ("%s: target %d ignored sync request\n",
   1036       1.6   mhitch 				    sc->sc_dev.dv_xname, target);
   1037       1.6   mhitch 			else if (acb->msg[1] == MSG_REJECT)
   1038       1.6   mhitch 				printf ("%s: target %d rejected sync request\n",
   1039       1.6   mhitch 				    sc->sc_dev.dv_xname, target);
   1040       1.6   mhitch 			else
   1041       1.6   mhitch /* XXX - need to set sync transfer parameters */
   1042       1.6   mhitch 				printf("%s: target %d (sync) %02x %02x %02x\n",
   1043       1.6   mhitch 				    sc->sc_dev.dv_xname, target, acb->msg[1],
   1044       1.6   mhitch 				    acb->msg[2], acb->msg[3]);
   1045       1.6   mhitch 			sc->sc_sync[target].state = NEG_DONE;
   1046       1.6   mhitch 		}
   1047       1.6   mhitch 		dma_cachectl(&acb->stat[0], 1);
   1048       1.6   mhitch 		*status = acb->stat[0];
   1049       1.6   mhitch #ifdef DEBUG
   1050       1.6   mhitch 		if (rp->siop_sbcl & SIOP_BSY) {
   1051       1.6   mhitch 			/*printf ("ACK! siop was busy at end: rp %x script %x dsa %x\n",
   1052       1.6   mhitch 			    rp, &siopng_scripts, &acb->ds);*/
   1053       1.6   mhitch #ifdef DDB
   1054       1.6   mhitch 			/*Debugger();*/
   1055       1.6   mhitch #endif
   1056       1.6   mhitch 		}
   1057       1.6   mhitch 		if (acb->msg[0] != 0x00)
   1058       1.6   mhitch 			printf("%s: message was not COMMAND COMPLETE: %x\n",
   1059       1.6   mhitch 			    sc->sc_dev.dv_xname, acb->msg[0]);
   1060       1.6   mhitch #endif
   1061       1.6   mhitch 		if (sc->nexus_list.tqh_first)
   1062       1.6   mhitch 			rp->siop_dcntl |= SIOP_DCNTL_STD;
   1063       1.6   mhitch 		return 1;
   1064       1.6   mhitch 	}
   1065       1.6   mhitch 	if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff0b) {
   1066  1.14.2.1   bouyer 		target = acb->xs->xs_periph->periph_target;
   1067       1.6   mhitch 		if (acb->msg[1] == MSG_EXT_MESSAGE && acb->msg[2] == 2 &&
   1068       1.6   mhitch 		    acb->msg[3] == MSG_WIDE_REQ) {
   1069       1.6   mhitch #ifdef DEBUG
   1070       1.6   mhitch 			if (siopngsync_debug)
   1071       1.6   mhitch 				printf ("wide msg in: %02x %02x %02x %02x %02x %02x\n",
   1072       1.6   mhitch 				    acb->msg[0], acb->msg[1], acb->msg[2],
   1073       1.6   mhitch 				    acb->msg[3], acb->msg[4], acb->msg[5]);
   1074       1.6   mhitch #endif
   1075       1.6   mhitch 			sc->sc_sync[target].scntl3 &= ~(SIOP_SCNTL3_EWS);
   1076       1.6   mhitch 			if (acb->msg[2] == 2 &&
   1077       1.6   mhitch 			    acb->msg[3] == MSG_WIDE_REQ &&
   1078       1.6   mhitch 			    acb->msg[4] != 0) {
   1079       1.6   mhitch 				sc->sc_sync[target].scntl3 |= SIOP_SCNTL3_EWS;
   1080       1.6   mhitch 				printf ("%s: target %d now wide %d\n",
   1081       1.6   mhitch 				    sc->sc_dev.dv_xname, target,
   1082       1.6   mhitch 				    acb->msg[4]);
   1083       1.6   mhitch 			}
   1084       1.6   mhitch 			rp->siop_scntl3 = sc->sc_sync[target].scntl3;
   1085       1.6   mhitch 			if (sc->sc_sync[target].state == NEG_WAITW) {
   1086       1.6   mhitch 				sc->sc_sync[target].state = NEG_SYNC;
   1087       1.6   mhitch 				rp->siop_dsp = sc->sc_scriptspa + Ent_clear_ack;
   1088       1.6   mhitch 				return(0);
   1089       1.6   mhitch 			}
   1090       1.6   mhitch 			rp->siop_dcntl |= SIOP_DCNTL_STD;
   1091       1.6   mhitch 			sc->sc_sync[target].state = NEG_SYNC;
   1092       1.6   mhitch 			return (0);
   1093       1.6   mhitch 		}
   1094       1.6   mhitch 		if (acb->msg[1] == MSG_EXT_MESSAGE && acb->msg[2] == 3 &&
   1095       1.6   mhitch 		    acb->msg[3] == MSG_SYNC_REQ) {
   1096       1.1       is #ifdef DEBUG
   1097       1.1       is 			if (siopngsync_debug)
   1098       1.1       is 				printf ("sync msg in: %02x %02x %02x %02x %02x %02x\n",
   1099       1.1       is 				    acb->msg[0], acb->msg[1], acb->msg[2],
   1100       1.1       is 				    acb->msg[3], acb->msg[4], acb->msg[5]);
   1101       1.1       is #endif
   1102       1.1       is 			sc->sc_sync[target].sxfer = 0;
   1103       1.6   mhitch 			sc->sc_sync[target].scntl3 = 5 |		/* XXX */
   1104       1.6   mhitch 			    (sc->sc_sync[target].scntl3 & 0x88);	/* XXX */
   1105       1.1       is 			if (acb->msg[2] == 3 &&
   1106       1.1       is 			    acb->msg[3] == MSG_SYNC_REQ &&
   1107       1.1       is 			    acb->msg[5] != 0) {
   1108       1.1       is #ifdef MAXTOR_KLUDGE
   1109       1.1       is 				/*
   1110       1.1       is 				 * Kludge for my Maxtor XT8580S
   1111       1.1       is 				 * It accepts whatever we request, even
   1112       1.1       is 				 * though it won't work.  So we ask for
   1113       1.1       is 				 * a short period than we can handle.  If
   1114       1.1       is 				 * the device says it can do it, use 208ns.
   1115       1.1       is 				 * If the device says it can do less than
   1116       1.1       is 				 * 100ns, then we limit it to 100ns.
   1117       1.1       is 				 */
   1118       1.1       is 				if (acb->msg[4] && acb->msg[4] < 100 / 4) {
   1119       1.1       is #ifdef DEBUG
   1120       1.1       is 					printf ("%d: target %d wanted %dns period\n",
   1121       1.1       is 					    sc->sc_dev.dv_xname, target,
   1122       1.1       is 					    acb->msg[4] * 4);
   1123       1.1       is #endif
   1124       1.1       is 					if (acb->msg[4] == 50 / 4)
   1125       1.1       is 						acb->msg[4] = 208 / 4;
   1126       1.1       is 					else
   1127       1.1       is 						acb->msg[4] = 100 / 4;
   1128       1.1       is 				}
   1129       1.1       is #endif /* MAXTOR_KLUDGE */
   1130       1.1       is 				printf ("%s: target %d now synchronous, period=%dns, offset=%d\n",
   1131       1.1       is 				    sc->sc_dev.dv_xname, target,
   1132      1.11   mhitch 				    (acb->msg[4] == 12) ? 50 : acb->msg[4] * 4,
   1133      1.11   mhitch 				    acb->msg[5]);
   1134       1.1       is 				scsi_period_to_siopng (sc, target);
   1135       1.1       is 			}
   1136       1.6   mhitch 			rp->siop_sxfer = sc->sc_sync[target].sxfer;
   1137       1.6   mhitch 			rp->siop_scntl3 = sc->sc_sync[target].scntl3;
   1138       1.6   mhitch 			if (sc->sc_sync[target].state == NEG_WAITS) {
   1139       1.6   mhitch 				sc->sc_sync[target].state = NEG_DONE;
   1140       1.6   mhitch 				rp->siop_dsp = sc->sc_scriptspa + Ent_clear_ack;
   1141       1.6   mhitch 				return(0);
   1142       1.6   mhitch 			}
   1143       1.6   mhitch 			rp->siop_dcntl |= SIOP_DCNTL_STD;
   1144       1.6   mhitch 			sc->sc_sync[target].state = NEG_DONE;
   1145       1.6   mhitch 			return (0);
   1146       1.1       is 		}
   1147       1.6   mhitch 		/* XXX - not SDTR message */
   1148       1.1       is 	}
   1149       1.1       is 	if (sist & SIOP_SIST_MA) {		/* Phase mismatch */
   1150       1.1       is #ifdef DEBUG
   1151       1.1       is 		++siopngphmm;
   1152       1.1       is 		if (acb == NULL)
   1153       1.1       is 			printf("%s: Phase mismatch with no active command?\n",
   1154       1.1       is 			    sc->sc_dev.dv_xname);
   1155       1.1       is #endif
   1156       1.1       is 		if (acb->iob_len) {
   1157       1.1       is 			int adjust;
   1158       1.1       is 			adjust = ((dfifo - (dbc & 0x7f)) & 0x7f);
   1159       1.6   mhitch 			if (sstat0 & SIOP_SSTAT0_OLF)	/* sstat0 SODL lsb */
   1160       1.3       is 				++adjust;
   1161       1.9   mhitch 			if (sstat0 & SIOP_SSTAT0_ORF)	/* sstat0 SODR lsb */
   1162       1.3       is 				++adjust;
   1163       1.6   mhitch 			if (sstat2 & SIOP_SSTAT2_OLF1)	/* sstat2 SODL msb */
   1164       1.1       is 				++adjust;
   1165       1.9   mhitch 			if (sstat2 & SIOP_SSTAT2_ORF1)	/* sstat2 SODR msb */
   1166       1.1       is 				++adjust;
   1167       1.1       is 			acb->iob_curlen = *((long *)&rp->siop_dcmd) & 0xffffff;
   1168       1.1       is 			acb->iob_curlen += adjust;
   1169       1.1       is 			acb->iob_curbuf = *((long *)&rp->siop_dnad) - adjust;
   1170       1.1       is #ifdef DEBUG
   1171       1.1       is 			if (siopng_debug & 0x100) {
   1172       1.1       is 				int i;
   1173       1.1       is 				printf ("Phase mismatch: curbuf %lx curlen %lx dfifo %x dbc %x sstat1 %x adjust %x sbcl %x starts %d acb %p\n",
   1174       1.1       is 				    acb->iob_curbuf, acb->iob_curlen, dfifo,
   1175       1.1       is 				    dbc, sstat1, adjust, rp->siop_sbcl, siopngstarts, acb);
   1176       1.1       is 				if (acb->ds.chain[1].datalen) {
   1177       1.1       is 					for (i = 0; acb->ds.chain[i].datalen; ++i)
   1178       1.1       is 						printf("chain[%d] addr %p len %lx\n",
   1179       1.1       is 						    i, acb->ds.chain[i].databuf,
   1180       1.1       is 						    acb->ds.chain[i].datalen);
   1181       1.1       is 				}
   1182       1.1       is 			}
   1183       1.1       is #endif
   1184       1.1       is 			dma_cachectl ((caddr_t)acb, sizeof(*acb));
   1185       1.1       is 		}
   1186       1.1       is #ifdef DEBUG
   1187       1.1       is 		SIOP_TRACE('m',rp->siop_sbcl,(rp->siop_dsp>>8),rp->siop_dsp);
   1188       1.1       is 		if (siopng_debug & 9)
   1189       1.1       is 			printf ("Phase mismatch: %x dsp +%lx dcmd %lx\n",
   1190       1.1       is 			    rp->siop_sbcl,
   1191       1.1       is 			    rp->siop_dsp - sc->sc_scriptspa,
   1192       1.1       is 			    *((long *)&rp->siop_dcmd));
   1193       1.1       is #endif
   1194       1.1       is 		if ((rp->siop_sbcl & SIOP_REQ) == 0) {
   1195       1.1       is 			printf ("Phase mismatch: REQ not asserted! %02x dsp %lx\n",
   1196       1.1       is 			    rp->siop_sbcl, rp->siop_dsp);
   1197       1.1       is #if defined(DEBUG) && defined(DDB)
   1198       1.1       is 			Debugger();
   1199       1.1       is #endif
   1200       1.1       is 		}
   1201       1.1       is 		switch (rp->siop_sbcl & 7) {
   1202       1.1       is 		case 0:		/* data out */
   1203       1.1       is 		case 1:		/* data in */
   1204       1.1       is 		case 2:		/* status */
   1205       1.1       is 		case 3:		/* command */
   1206       1.1       is 		case 6:		/* message in */
   1207       1.1       is 		case 7:		/* message out */
   1208       1.1       is 			rp->siop_dsp = sc->sc_scriptspa + Ent_switch;
   1209       1.1       is 			break;
   1210       1.1       is 		default:
   1211       1.1       is 			goto bad_phase;
   1212       1.1       is 		}
   1213       1.1       is 		return 0;
   1214       1.1       is 	}
   1215       1.1       is 	if (sist & SIOP_SIST_STO) {		/* Select timed out */
   1216       1.1       is #ifdef DEBUG
   1217       1.1       is 		if (acb == NULL)
   1218       1.1       is 			printf("%s: Select timeout with no active command?\n",
   1219       1.1       is 			    sc->sc_dev.dv_xname);
   1220       1.1       is 		if (rp->siop_sbcl & SIOP_BSY) {
   1221       1.1       is 			printf ("ACK! siop was busy at timeout: rp %p script %p dsa %p\n",
   1222       1.2       is 			    rp, &siopng_scripts, &acb->ds);
   1223       1.1       is 			printf(" sbcl %x sdid %x istat %x dstat %x sist %x\n",
   1224       1.1       is 			    rp->siop_sbcl, rp->siop_sdid, istat, dstat, sist);
   1225       1.1       is 			if (!(rp->siop_sbcl & SIOP_BSY)) {
   1226       1.1       is 				printf ("Yikes, it's not busy now!\n");
   1227       1.1       is #if 0
   1228       1.1       is 				*status = -1;
   1229       1.1       is 				if (sc->nexus_list.tqh_first)
   1230       1.1       is 					rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect;
   1231       1.1       is 				return 1;
   1232       1.1       is #endif
   1233       1.1       is 			}
   1234       1.1       is /*			rp->siop_dcntl |= SIOP_DCNTL_STD;*/
   1235       1.1       is 			return (0);
   1236       1.1       is #ifdef DDB
   1237       1.1       is 			Debugger();
   1238       1.1       is #endif
   1239       1.1       is 		}
   1240       1.1       is #endif
   1241       1.1       is 		*status = -1;
   1242       1.1       is 		acb->xs->error = XS_SELTIMEOUT;
   1243       1.1       is 		if (sc->nexus_list.tqh_first)
   1244       1.1       is 			rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect;
   1245       1.1       is 		return 1;
   1246       1.1       is 	}
   1247       1.1       is 	if (acb)
   1248  1.14.2.1   bouyer 		target = acb->xs->xs_periph->periph_target;
   1249       1.1       is 	else
   1250       1.1       is 		target = 7;
   1251       1.1       is 	if (sist & SIOP_SIST_UDC) {
   1252       1.1       is #ifdef DEBUG
   1253       1.1       is 		if (acb == NULL)
   1254       1.1       is 			printf("%s: Unexpected disconnect with no active command?\n",
   1255       1.1       is 			    sc->sc_dev.dv_xname);
   1256       1.1       is 		printf ("%s: target %d disconnected unexpectedly\n",
   1257       1.1       is 		   sc->sc_dev.dv_xname, target);
   1258       1.1       is siopng_dump_registers(sc);
   1259       1.1       is siopng_dump(sc);
   1260       1.1       is #endif
   1261       1.1       is #if 0
   1262       1.1       is 		siopngabort (sc, rp, "siopngchkintr");
   1263       1.1       is #endif
   1264       1.1       is 		*status = STS_BUSY;
   1265       1.1       is 		if (sc->nexus_list.tqh_first)
   1266       1.1       is 			rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect;
   1267       1.1       is 		return (acb != NULL);
   1268       1.1       is 	}
   1269       1.1       is 	if (dstat & SIOP_DSTAT_SIR && (rp->siop_dsps == 0xff01 ||
   1270       1.1       is 	    rp->siop_dsps == 0xff02)) {
   1271       1.1       is #ifdef DEBUG
   1272       1.1       is 		if (siopng_debug & 0x100)
   1273       1.1       is 			printf ("%s: ID %02x disconnected TEMP %lx (+%lx) curbuf %lx curlen %lx buf %p len %lx dfifo %x dbc %x sstat1 %x starts %d acb %p\n",
   1274       1.1       is 			    sc->sc_dev.dv_xname, 1 << target, rp->siop_temp,
   1275       1.1       is 			    rp->siop_temp ? rp->siop_temp - sc->sc_scriptspa : 0,
   1276       1.1       is 			    acb->iob_curbuf, acb->iob_curlen,
   1277       1.1       is 			    acb->ds.chain[0].databuf, acb->ds.chain[0].datalen, dfifo, dbc, sstat1, siopngstarts, acb);
   1278       1.1       is #endif
   1279       1.1       is 		if (acb == NULL) {
   1280       1.1       is 			printf("%s: Disconnect with no active command?\n",
   1281       1.1       is 			    sc->sc_dev.dv_xname);
   1282       1.1       is 			return (0);
   1283       1.1       is 		}
   1284       1.1       is 		/*
   1285       1.1       is 		 * XXXX need to update iob_curbuf/iob_curlen to reflect
   1286       1.1       is 		 * current data transferred.  If device disconnected in
   1287       1.1       is 		 * the middle of a DMA block, they should already be set
   1288       1.1       is 		 * by the phase change interrupt.  If the disconnect
   1289       1.1       is 		 * occurs on a DMA block boundary, we have to figure out
   1290       1.1       is 		 * which DMA block it was.
   1291       1.1       is 		 */
   1292       1.1       is 		if (acb->iob_len && rp->siop_temp) {
   1293       1.1       is 			int n = rp->siop_temp - sc->sc_scriptspa;
   1294       1.1       is 
   1295       1.1       is 			if (acb->iob_curlen && acb->iob_curlen != acb->ds.chain[0].datalen)
   1296       1.1       is 				printf("%s: iob_curbuf/len already set? n %x iob %lx/%lx chain[0] %p/%lx\n",
   1297       1.1       is 				    sc->sc_dev.dv_xname, n, acb->iob_curbuf, acb->iob_curlen,
   1298       1.1       is 				    acb->ds.chain[0].databuf, acb->ds.chain[0].datalen);
   1299       1.1       is 			if (n < Ent_datain)
   1300       1.1       is 				n = (n - Ent_dataout) / 16;
   1301       1.1       is 			else
   1302       1.1       is 				n = (n - Ent_datain) / 16;
   1303       1.1       is 			if (n <= 0 && n > DMAMAXIO)
   1304       1.1       is 				printf("TEMP invalid %d\n", n);
   1305       1.1       is 			else {
   1306       1.1       is 				acb->iob_curbuf = (u_long)acb->ds.chain[n].databuf;
   1307       1.1       is 				acb->iob_curlen = acb->ds.chain[n].datalen;
   1308       1.1       is 			}
   1309       1.1       is #ifdef DEBUG
   1310       1.1       is 			if (siopng_debug & 0x100) {
   1311       1.1       is 				printf("%s: TEMP offset %d", sc->sc_dev.dv_xname, n);
   1312       1.1       is 				printf(" curbuf %lx curlen %lx\n", acb->iob_curbuf,
   1313       1.1       is 				    acb->iob_curlen);
   1314       1.1       is 			}
   1315       1.1       is #endif
   1316       1.1       is 		}
   1317       1.1       is 		/*
   1318       1.1       is 		 * If data transfer was interrupted by disconnect, iob_curbuf
   1319       1.1       is 		 * and iob_curlen should reflect the point of interruption.
   1320       1.1       is 		 * Adjust the DMA chain so that the data transfer begins
   1321       1.1       is 		 * at the appropriate place upon reselection.
   1322       1.1       is 		 * XXX This should only be done on save data pointer message?
   1323       1.1       is 		 */
   1324       1.1       is 		if (acb->iob_curlen) {
   1325       1.1       is 			int i, j;
   1326       1.1       is 
   1327       1.1       is #ifdef DEBUG
   1328       1.1       is 			if (siopng_debug & 0x100)
   1329       1.1       is 				printf ("%s: adjusting DMA chain\n",
   1330       1.1       is 				    sc->sc_dev.dv_xname);
   1331       1.1       is 			if (rp->siop_dsps == 0xff02)
   1332       1.1       is 				printf ("%s: ID %02x disconnected without Save Data Pointers\n",
   1333       1.1       is 				    sc->sc_dev.dv_xname, 1 << target);
   1334       1.1       is #endif
   1335       1.1       is 			for (i = 0; i < DMAMAXIO; ++i) {
   1336       1.1       is 				if (acb->ds.chain[i].datalen == 0)
   1337       1.1       is 					break;
   1338       1.1       is 				if (acb->iob_curbuf >= (long)acb->ds.chain[i].databuf &&
   1339       1.1       is 				    acb->iob_curbuf < (long)(acb->ds.chain[i].databuf +
   1340       1.1       is 				    acb->ds.chain[i].datalen))
   1341       1.1       is 					break;
   1342       1.1       is 			}
   1343       1.1       is 			if (i >= DMAMAXIO || acb->ds.chain[i].datalen == 0) {
   1344       1.1       is 				printf("couldn't find saved data pointer: ");
   1345       1.1       is 				printf("curbuf %lx curlen %lx i %d\n",
   1346       1.1       is 				    acb->iob_curbuf, acb->iob_curlen, i);
   1347       1.1       is #ifdef DDB
   1348       1.1       is 				Debugger();
   1349       1.1       is #endif
   1350       1.1       is 			}
   1351       1.1       is #ifdef DEBUG
   1352       1.1       is 			if (siopng_debug & 0x100)
   1353       1.1       is 				printf("  chain[0]: %p/%lx -> %lx/%lx\n",
   1354       1.1       is 				    acb->ds.chain[0].databuf,
   1355       1.1       is 				    acb->ds.chain[0].datalen,
   1356       1.1       is 				    acb->iob_curbuf,
   1357       1.1       is 				    acb->iob_curlen);
   1358       1.1       is #endif
   1359       1.1       is 			acb->ds.chain[0].databuf = (char *)acb->iob_curbuf;
   1360       1.1       is 			acb->ds.chain[0].datalen = acb->iob_curlen;
   1361       1.1       is 			for (j = 1, ++i; i < DMAMAXIO && acb->ds.chain[i].datalen; ++i, ++j) {
   1362       1.1       is #ifdef DEBUG
   1363       1.1       is 			if (siopng_debug & 0x100)
   1364       1.1       is 				printf("  chain[%d]: %p/%lx -> %p/%lx\n", j,
   1365       1.1       is 				    acb->ds.chain[j].databuf,
   1366       1.1       is 				    acb->ds.chain[j].datalen,
   1367       1.1       is 				    acb->ds.chain[i].databuf,
   1368       1.1       is 				    acb->ds.chain[i].datalen);
   1369       1.1       is #endif
   1370       1.1       is 				acb->ds.chain[j].databuf = acb->ds.chain[i].databuf;
   1371       1.1       is 				acb->ds.chain[j].datalen = acb->ds.chain[i].datalen;
   1372       1.1       is 			}
   1373       1.1       is 			if (j < DMAMAXIO)
   1374       1.1       is 				acb->ds.chain[j].datalen = 0;
   1375       1.1       is 			DCIAS(kvtop((caddr_t)&acb->ds.chain));
   1376       1.1       is 		}
   1377       1.1       is 		++sc->sc_tinfo[target].dconns;
   1378       1.1       is 		/*
   1379       1.1       is 		 * add nexus to waiting list
   1380       1.1       is 		 * clear nexus
   1381       1.1       is 		 * try to start another command for another target/lun
   1382       1.1       is 		 */
   1383       1.1       is 		acb->status = sc->sc_flags & SIOP_INTSOFF;
   1384       1.1       is 		TAILQ_INSERT_HEAD(&sc->nexus_list, acb, chain);
   1385       1.1       is 		sc->sc_nexus = NULL;		/* no current device */
   1386       1.1       is 		/* start script to wait for reselect */
   1387       1.1       is 		if (sc->sc_nexus == NULL)
   1388       1.1       is 			rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect;
   1389       1.1       is /* XXXX start another command ? */
   1390       1.1       is 		if (sc->ready_list.tqh_first)
   1391       1.1       is 			siopng_sched(sc);
   1392       1.1       is #if 0
   1393       1.1       is 		else
   1394       1.1       is 			rp->siop_dcntl |= SIOP_DCNTL_STD;
   1395       1.1       is #endif
   1396       1.1       is 		return (0);
   1397       1.1       is 	}
   1398       1.1       is 	if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff03) {
   1399       1.1       is 		int reselid = rp->siop_scratcha & 0x7f;
   1400       1.1       is 		int reselun = rp->siop_sfbr & 0x07;
   1401       1.1       is 
   1402       1.1       is 		sc->sc_sstat1 = rp->siop_sbcl;	/* XXXX save current SBCL */
   1403       1.1       is #ifdef DEBUG
   1404       1.1       is 		if (siopng_debug & 0x100)
   1405       1.1       is 			printf ("%s: target ID %02x reselected dsps %lx\n",
   1406       1.1       is 			     sc->sc_dev.dv_xname, reselid,
   1407       1.1       is 			     rp->siop_dsps);
   1408       1.1       is 		if ((rp->siop_sfbr & 0x80) == 0)
   1409       1.1       is 			printf("%s: Reselect message in was not identify: %x\n",
   1410       1.1       is 			    sc->sc_dev.dv_xname, rp->siop_sfbr);
   1411       1.1       is #endif
   1412       1.1       is 		if (sc->sc_nexus) {
   1413       1.1       is #ifdef DEBUG
   1414       1.1       is 			if (siopng_debug & 0x100)
   1415       1.1       is 				printf ("%s: reselect ID %02x w/active\n",
   1416       1.1       is 				    sc->sc_dev.dv_xname, reselid);
   1417       1.1       is #endif
   1418       1.1       is 			TAILQ_INSERT_HEAD(&sc->ready_list, sc->sc_nexus, chain);
   1419  1.14.2.1   bouyer 			sc->sc_tinfo[sc->sc_nexus->xs->xs_periph->periph_target].lubusy
   1420  1.14.2.1   bouyer 			    &= ~(1 << sc->sc_nexus->xs->xs_periph->periph_lun);
   1421       1.1       is 			--sc->sc_active;
   1422       1.1       is 		}
   1423       1.1       is 		/*
   1424       1.1       is 		 * locate acb of reselecting device
   1425       1.1       is 		 * set sc->sc_nexus to acb
   1426       1.1       is 		 */
   1427       1.1       is 		for (acb = sc->nexus_list.tqh_first; acb;
   1428       1.1       is 		    acb = acb->chain.tqe_next) {
   1429       1.1       is 			if (reselid != ((acb->ds.scsi_addr >> 16) & 0xff) ||
   1430       1.1       is 			    reselun != (acb->msgout[0] & 0x07))
   1431       1.1       is 				continue;
   1432       1.1       is 			TAILQ_REMOVE(&sc->nexus_list, acb, chain);
   1433       1.1       is 			sc->sc_nexus = acb;
   1434       1.1       is 			sc->sc_flags |= acb->status;
   1435       1.1       is 			acb->status = 0;
   1436       1.1       is 			DCIAS(kvtop(&acb->stat[0]));
   1437       1.1       is 			rp->siop_dsa = kvtop((caddr_t)&acb->ds);
   1438       1.1       is 			rp->siop_sxfer =
   1439  1.14.2.1   bouyer 				sc->sc_sync[acb->xs->xs_periph->periph_target].sxfer;
   1440       1.1       is #ifndef FIXME
   1441       1.1       is 			rp->siop_scntl3 =
   1442  1.14.2.1   bouyer 				sc->sc_sync[acb->xs->xs_periph->periph_target].scntl3;
   1443       1.1       is #endif
   1444       1.1       is 			break;
   1445       1.1       is 		}
   1446       1.1       is 		if (acb == NULL) {
   1447       1.1       is 			printf("%s: target ID %02x reselect nexus_list %p\n",
   1448       1.1       is 			    sc->sc_dev.dv_xname, reselid,
   1449       1.1       is 			    sc->nexus_list.tqh_first);
   1450       1.1       is 			panic("unable to find reselecting device");
   1451       1.1       is 		}
   1452       1.1       is 		dma_cachectl ((caddr_t)acb, sizeof(*acb));
   1453       1.1       is 		rp->siop_temp = 0;
   1454       1.1       is 		rp->siop_dcntl |= SIOP_DCNTL_STD;
   1455       1.1       is 		return (0);
   1456       1.1       is 	}
   1457       1.1       is 	if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff04) {
   1458       1.1       is #ifdef DEBUG
   1459       1.1       is 		u_short ctest2 = rp->siop_ctest2;
   1460       1.1       is 
   1461       1.1       is 		/* reselect was interrupted (by Sig_P or select) */
   1462       1.1       is 		if (siopng_debug & 0x100 ||
   1463       1.1       is 		    (ctest2 & SIOP_CTEST2_SIGP) == 0)
   1464       1.1       is 			printf ("%s: reselect interrupted (Sig_P?) scntl1 %x ctest2 %x sfbr %x istat %x/%x\n",
   1465       1.1       is 			    sc->sc_dev.dv_xname, rp->siop_scntl1,
   1466       1.1       is 			    ctest2, rp->siop_sfbr, istat, rp->siop_istat);
   1467       1.1       is #endif
   1468       1.1       is 		/* XXX assumes it was not select */
   1469       1.1       is 		if (sc->sc_nexus == NULL) {
   1470       1.1       is #ifdef DEBUG
   1471       1.1       is 			printf("%s: reselect interrupted, sc_nexus == NULL\n",
   1472       1.1       is 			    sc->sc_dev.dv_xname);
   1473       1.1       is #if 0
   1474       1.1       is 			siopng_dump(sc);
   1475       1.1       is #ifdef DDB
   1476       1.1       is 			Debugger();
   1477       1.1       is #endif
   1478       1.1       is #endif
   1479       1.1       is #endif
   1480       1.1       is 			rp->siop_dcntl |= SIOP_DCNTL_STD;
   1481       1.1       is 			return(0);
   1482       1.1       is 		}
   1483  1.14.2.1   bouyer 		target = sc->sc_nexus->xs->xs_periph->periph_target;
   1484       1.1       is 		rp->siop_temp = 0;
   1485       1.1       is 		rp->siop_dsa = kvtop((caddr_t)&sc->sc_nexus->ds);
   1486       1.1       is 		rp->siop_sxfer = sc->sc_sync[target].sxfer;
   1487       1.1       is #ifndef FIXME
   1488       1.6   mhitch 		rp->siop_scntl3 = sc->sc_sync[target].scntl3;
   1489       1.1       is #endif
   1490       1.1       is 		rp->siop_dsp = sc->sc_scriptspa;
   1491       1.1       is 		return (0);
   1492       1.1       is 	}
   1493       1.1       is 	if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff06) {
   1494       1.1       is 		if (acb == NULL)
   1495       1.1       is 			printf("%s: Bad message-in with no active command?\n",
   1496       1.1       is 			    sc->sc_dev.dv_xname);
   1497       1.1       is 		/* Unrecognized message in byte */
   1498       1.1       is 		dma_cachectl (&acb->msg[1],1);
   1499       1.1       is 		printf ("%s: Unrecognized message in data sfbr %x msg %x sbcl %x\n",
   1500       1.1       is 			sc->sc_dev.dv_xname, rp->siop_sfbr, acb->msg[1], rp->siop_sbcl);
   1501       1.1       is 		/* what should be done here? */
   1502       1.1       is 		DCIAS(kvtop(&acb->msg[1]));
   1503       1.1       is 		rp->siop_dsp = sc->sc_scriptspa + Ent_switch;
   1504       1.1       is 		return (0);
   1505       1.1       is 	}
   1506       1.1       is 	if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff0a) {
   1507       1.1       is 		/* Status phase wasn't followed by message in phase? */
   1508       1.1       is 		printf ("%s: Status phase not followed by message in phase? sbcl %x sbdl %x\n",
   1509       1.1       is 			sc->sc_dev.dv_xname, rp->siop_sbcl, rp->siop_sbdl);
   1510       1.1       is 		if (rp->siop_sbcl == 0xa7) {
   1511       1.1       is 			/* It is now, just continue the script? */
   1512       1.1       is 			rp->siop_dcntl |= SIOP_DCNTL_STD;
   1513       1.1       is 			return (0);
   1514       1.1       is 		}
   1515       1.1       is 	}
   1516       1.1       is 	if (sist == 0 && dstat & SIOP_DSTAT_SIR) {
   1517       1.1       is 		dma_cachectl (&acb->stat[0], 1);
   1518       1.1       is 		dma_cachectl (&acb->msg[0], 1);
   1519       1.1       is 		printf ("SIOP interrupt: %lx sts %x msg %x %x sbcl %x\n",
   1520       1.1       is 		    rp->siop_dsps, acb->stat[0], acb->msg[0], acb->msg[1],
   1521       1.1       is 		    rp->siop_sbcl);
   1522       1.1       is 		siopngreset (sc);
   1523       1.1       is 		*status = -1;
   1524       1.1       is 		return 0;	/* siopngreset has cleaned up */
   1525       1.1       is 	}
   1526       1.1       is 	if (sist & SIOP_SIST_SGE)
   1527       1.1       is 		printf ("SIOP: SCSI Gross Error\n");
   1528       1.1       is 	if (sist & SIOP_SIST_PAR)
   1529       1.1       is 		printf ("SIOP: Parity Error\n");
   1530       1.1       is 	if (dstat & SIOP_DSTAT_IID)
   1531       1.1       is 		printf ("SIOP: Invalid instruction detected\n");
   1532       1.1       is bad_phase:
   1533       1.1       is 	/*
   1534       1.1       is 	 * temporary panic for unhandled conditions
   1535       1.1       is 	 * displays various things about the 53C720/770 status and registers
   1536       1.1       is 	 * then panics.
   1537       1.1       is 	 * XXXX need to clean this up to print out the info, reset, and continue
   1538       1.1       is 	 */
   1539       1.1       is 	printf ("siopngchkintr: target %x ds %p\n", target, &acb->ds);
   1540       1.1       is 	printf ("scripts %lx ds %x rp %x dsp %lx dcmd %lx\n", sc->sc_scriptspa,
   1541       1.1       is 	    kvtop((caddr_t)&acb->ds), kvtop((caddr_t)rp), rp->siop_dsp,
   1542       1.1       is 	    *((long *)&rp->siop_dcmd));
   1543       1.1       is 	printf ("siopngchkintr: istat %x dstat %x sist %x dsps %lx dsa %lx sbcl %x sts %x msg %x %x sfbr %x\n",
   1544       1.1       is 	    istat, dstat, sist, rp->siop_dsps, rp->siop_dsa,
   1545       1.1       is 	     rp->siop_sbcl, acb->stat[0], acb->msg[0], acb->msg[1], rp->siop_sfbr);
   1546       1.1       is #ifdef DEBUG
   1547       1.1       is 	if (siopng_debug & 0x20)
   1548       1.1       is 		panic("siopngchkintr: **** temp ****");
   1549       1.1       is #endif
   1550       1.1       is #ifdef DDB
   1551       1.1       is 	Debugger ();
   1552       1.1       is #endif
   1553       1.1       is 	siopngreset (sc);		/* hard reset */
   1554       1.1       is 	*status = -1;
   1555       1.1       is 	return 0;		/* siopngreset cleaned up */
   1556       1.1       is }
   1557       1.1       is 
   1558       1.1       is void
   1559       1.1       is siopng_select(sc)
   1560       1.1       is 	struct siop_softc *sc;
   1561       1.1       is {
   1562       1.1       is 	siop_regmap_p rp;
   1563       1.1       is 	struct siop_acb *acb = sc->sc_nexus;
   1564       1.1       is 
   1565       1.1       is #ifdef DEBUG
   1566       1.1       is 	if (siopng_debug & 1)
   1567       1.1       is 		printf ("%s: select ", sc->sc_dev.dv_xname);
   1568       1.1       is #endif
   1569       1.1       is 
   1570       1.1       is 	rp = sc->sc_siopp;
   1571      1.14  thorpej 	if (acb->xs->xs_control & XS_CTL_POLL || siopng_no_dma) {
   1572       1.1       is 		sc->sc_flags |= SIOP_INTSOFF;
   1573       1.1       is 		sc->sc_flags &= ~SIOP_INTDEFER;
   1574       1.1       is 		if ((rp->siop_istat & 0x08) == 0) {
   1575       1.1       is 			rp->siop_sien = 0;
   1576       1.1       is 			rp->siop_dien = 0;
   1577       1.1       is 		}
   1578       1.1       is #if 0
   1579       1.1       is 	} else if ((sc->sc_flags & SIOP_INTDEFER) == 0) {
   1580       1.1       is 		sc->sc_flags &= ~SIOP_INTSOFF;
   1581       1.1       is 		if ((rp->siop_istat & 0x08) == 0) {
   1582       1.1       is 			rp->siop_sien = sc->sc_sien;
   1583       1.1       is 			rp->siop_dien = sc->sc_dien;
   1584       1.1       is 		}
   1585       1.1       is #endif
   1586       1.1       is 	}
   1587       1.1       is #ifdef DEBUG
   1588       1.1       is 	if (siopng_debug & 1)
   1589       1.1       is 		printf ("siopng_select: target %x cmd %02x ds %p\n",
   1590  1.14.2.1   bouyer 		    acb->xs->xs_periph->periph_target, acb->cmd.opcode,
   1591       1.1       is 		    &sc->sc_nexus->ds);
   1592       1.1       is #endif
   1593       1.1       is 
   1594  1.14.2.1   bouyer 	siopng_start(sc, acb->xs->xs_periph->periph_target,
   1595  1.14.2.1   bouyer 		acb->xs->xs_periph->periph_lun,
   1596       1.1       is 	    (u_char *)&acb->cmd, acb->clen, acb->daddr, acb->dleft);
   1597       1.1       is 
   1598       1.1       is 	return;
   1599       1.1       is }
   1600       1.1       is 
   1601       1.1       is /*
   1602       1.1       is  * 53C720/770 interrupt handler
   1603       1.1       is  */
   1604       1.1       is 
   1605       1.1       is void
   1606       1.1       is siopngintr (sc)
   1607       1.1       is 	register struct siop_softc *sc;
   1608       1.1       is {
   1609       1.1       is 	siop_regmap_p rp;
   1610       1.1       is 	u_char istat, dstat;
   1611       1.1       is 	u_short sist;
   1612       1.1       is 	int status;
   1613       1.1       is 	int s = splbio();
   1614       1.1       is 
   1615       1.1       is 	istat = sc->sc_istat;
   1616       1.1       is 	if ((istat & (SIOP_ISTAT_SIP | SIOP_ISTAT_DIP)) == 0) {
   1617       1.1       is 		splx(s);
   1618       1.1       is 		return;
   1619       1.1       is 	}
   1620       1.1       is 
   1621       1.1       is 	/* Got a valid interrupt on this device */
   1622       1.1       is 	rp = sc->sc_siopp;
   1623       1.1       is 	dstat = sc->sc_dstat;
   1624       1.1       is 	sist = sc->sc_sist;
   1625       1.1       is 	if (dstat & SIOP_DSTAT_SIR)
   1626       1.1       is 		sc->sc_intcode = rp->siop_dsps;
   1627       1.1       is 	sc->sc_istat = 0;
   1628       1.1       is #ifdef DEBUG
   1629       1.1       is 	if (siopng_debug & 1)
   1630       1.1       is 		printf ("%s: intr istat %x dstat %x sist %x\n",
   1631       1.1       is 		    sc->sc_dev.dv_xname, istat, dstat, sist);
   1632       1.1       is 	if (!sc->sc_active) {
   1633       1.1       is 		printf ("%s: spurious interrupt? istat %x dstat %x sist %x nexus %p status %x\n",
   1634       1.1       is 		    sc->sc_dev.dv_xname, istat, dstat, sist,
   1635       1.1       is 		    sc->sc_nexus, sc->sc_nexus ? sc->sc_nexus->stat[0] : 0);
   1636       1.1       is 	}
   1637       1.1       is #endif
   1638       1.1       is 
   1639       1.1       is #ifdef DEBUG
   1640       1.1       is 	if (siopng_debug & 5) {
   1641       1.1       is 		DCIAS(kvtop(&sc->sc_nexus->stat[0]));
   1642       1.1       is 		printf ("%s: intr istat %x dstat %x sist %x dsps %lx sbcl %x sts %x msg %x\n",
   1643       1.1       is 		    sc->sc_dev.dv_xname, istat, dstat, sist,
   1644       1.1       is 		    rp->siop_dsps,  rp->siop_sbcl,
   1645       1.1       is 		    sc->sc_nexus->stat[0], sc->sc_nexus->msg[0]);
   1646       1.1       is 	}
   1647       1.1       is #endif
   1648       1.1       is 	if (sc->sc_flags & SIOP_INTDEFER) {
   1649       1.1       is 		sc->sc_flags &= ~(SIOP_INTDEFER | SIOP_INTSOFF);
   1650       1.1       is 		rp->siop_sien = sc->sc_sien;
   1651       1.1       is 		rp->siop_dien = sc->sc_dien;
   1652       1.1       is 	}
   1653       1.1       is 	if (siopng_checkintr (sc, istat, dstat, sist, &status)) {
   1654       1.1       is #if 1
   1655       1.1       is 		if (status == 0xff)
   1656       1.1       is 			printf ("siopngintr: status == 0xff\n");
   1657       1.1       is #endif
   1658       1.1       is 		if ((sc->sc_flags & (SIOP_INTSOFF | SIOP_INTDEFER)) != SIOP_INTSOFF) {
   1659       1.1       is #if 0
   1660       1.1       is 			if (rp->siop_sbcl & SIOP_BSY) {
   1661       1.1       is 				printf ("%s: SCSI bus busy at completion",
   1662       1.1       is 					sc->sc_dev.dv_xname);
   1663       1.1       is 				printf(" targ %d sbcl %02x sfbr %x respid %02x dsp +%x\n",
   1664  1.14.2.1   bouyer 				    sc->sc_nexus->xs->xs_periph->periph_target,
   1665       1.1       is 				    rp->siop_sbcl, rp->siop_sfbr, rp->siop_respid,
   1666       1.1       is 				    rp->siop_dsp - sc->sc_scriptspa);
   1667       1.1       is 			}
   1668       1.1       is #endif
   1669       1.1       is 			siopng_scsidone(sc->sc_nexus, sc->sc_nexus ?
   1670       1.1       is 			    sc->sc_nexus->stat[0] : -1);
   1671       1.1       is 		}
   1672       1.1       is 	}
   1673       1.1       is 	splx(s);
   1674       1.1       is }
   1675       1.1       is 
   1676       1.1       is /*
   1677       1.1       is  * This is based on the Progressive Peripherals 33Mhz Zeus driver and will
   1678       1.1       is  * not be correct for other 53c710 boards.
   1679       1.1       is  *
   1680       1.1       is  */
   1681       1.1       is void
   1682       1.1       is scsi_period_to_siopng (sc, target)
   1683       1.1       is 	struct siop_softc *sc;
   1684       1.1       is 	int target;
   1685       1.1       is {
   1686       1.1       is 	int period, offset, sxfer, scntl3 = 0;
   1687       1.1       is 
   1688       1.1       is 	period = sc->sc_nexus->msg[4];
   1689       1.1       is 	offset = sc->sc_nexus->msg[5];
   1690       1.1       is #ifdef FIXME
   1691       1.1       is 	for (scntl3 = 1; scntl3 < 4; ++scntl3) {
   1692       1.1       is 		sxfer = (period * 4 - 1) / sc->sc_tcp[scntl3] - 3;
   1693       1.1       is 		if (sxfer >= 0 && sxfer <= 7)
   1694       1.1       is 			break;
   1695       1.1       is 	}
   1696       1.1       is 	if (scntl3 > 3) {
   1697       1.1       is 		printf("siopng sync: unable to compute sync params for period %dns\n",
   1698       1.1       is 		    period * 4);
   1699       1.1       is 		/*
   1700       1.1       is 		 * XXX need to pick a value we can do and renegotiate
   1701       1.1       is 		 */
   1702       1.1       is 		sxfer = scntl3 = 0;
   1703       1.1       is 	} else {
   1704       1.1       is 		sxfer = (sxfer << 4) | ((offset <= SIOP_MAX_OFFSET) ?
   1705       1.1       is 		    offset : SIOP_MAX_OFFSET);
   1706       1.1       is #ifdef DEBUG_SYNC
   1707       1.1       is 		printf("siopng sync: params for period %dns: sxfer %x scntl3 %x",
   1708       1.1       is 		    period * 4, sxfer, scntl3);
   1709       1.1       is 		printf(" actual period %dns\n",
   1710       1.1       is 		    sc->sc_tcp[scntl3] * ((sxfer >> 4) + 4));
   1711       1.1       is #endif /* DEBUG_SYNC */
   1712       1.1       is 	}
   1713       1.1       is #else /* FIXME */
   1714       1.1       is 	sxfer = offset <= SIOP_MAX_OFFSET ? offset : SIOP_MAX_OFFSET;
   1715       1.6   mhitch 	sxfer |= 0x20;		/* XXX XFERP: 5 */
   1716       1.1       is #ifndef FIXME
   1717       1.6   mhitch 	if (period <= (50 / 4))	/* XXX */
   1718       1.6   mhitch 		scntl3 = 0x95;	/* Ultra, SCF: /1, CCF: /4 */
   1719       1.6   mhitch 	else if (period <= (100 / 4))
   1720       1.6   mhitch 		scntl3 = 0x35;	/* SCF: /2, CCF: /4 */
   1721       1.6   mhitch 	else if (period <= (200 / 4))
   1722       1.6   mhitch 		scntl3 = 0x55;	/* SCF: /4, CCF: /4 */
   1723       1.6   mhitch 	else
   1724       1.6   mhitch 		scntl3 = 0xff;	/* XXX ??? */
   1725       1.1       is #else
   1726       1.1       is 	scntl3 = 5;
   1727       1.1       is #endif
   1728       1.1       is #endif
   1729       1.1       is 	sc->sc_sync[target].sxfer = sxfer;
   1730       1.6   mhitch 	sc->sc_sync[target].scntl3 = scntl3 |
   1731       1.6   mhitch 	    (sc->sc_sync[target].scntl3 & SIOP_SCNTL3_EWS);
   1732       1.1       is #ifdef DEBUG_SYNC
   1733       1.1       is 	printf ("siopng sync: siop_sxfr %02x, siop_scntl3 %02x\n", sxfer, scntl3);
   1734       1.1       is #endif
   1735       1.1       is }
   1736       1.1       is 
   1737       1.1       is void
   1738       1.1       is siopng_dump_registers(sc)
   1739       1.1       is 	struct siop_softc *sc;
   1740       1.1       is {
   1741       1.1       is 	siop_regmap_p rp = sc->sc_siopp;
   1742       1.1       is 
   1743       1.1       is 	printf("  scntl0   %02x scntl1 %02x scntl2 %02x scntl3 %02x\n",
   1744       1.1       is 	    rp->siop_scntl0, rp->siop_scntl1, rp->siop_scntl2, rp->siop_scntl3);
   1745       1.1       is 	printf("  scid     %02x sxfer  %02x sdid   %02x gpreg  %02x\n",
   1746       1.1       is 	    rp->siop_scid, rp->siop_sxfer, rp->siop_sdid, rp->siop_gpreg);
   1747       1.1       is 	printf("  sfbr     %02x socl   %02x ssid   %02x sbcl   %02x\n",
   1748       1.1       is 	    rp->siop_sfbr, rp->siop_socl, rp->siop_ssid, rp->siop_sbcl);
   1749       1.1       is 	printf("  dstat    %02x sstat0 %02x sstat1 %02x sstat2 %02x\n",
   1750       1.1       is 	    rp->siop_dstat, rp->siop_sstat0, rp->siop_sstat1, rp->siop_sstat2);
   1751       1.1       is 	printf("  ctest0   %02x ctest1 %02x ctest2 %02x ctest3 %02x\n",
   1752       1.1       is 	    rp->siop_ctest0, rp->siop_ctest1, rp->siop_ctest2, rp->siop_ctest3);
   1753       1.1       is 	printf("  dfifo    %02x ctest4 %02x ctest5 %02x ctest6 %02x\n",
   1754       1.1       is 	    0, rp->siop_ctest4, rp->siop_ctest5, rp->siop_ctest6);
   1755       1.1       is 	printf("  dcmd     %02x dbc2   %02x dbc1   %02x dbc0   %02x\n",
   1756       1.1       is 	    rp->siop_dcmd, rp->siop_dbc2, rp->siop_dbc1, rp->siop_dbc0);
   1757       1.1       is 	printf("  dmode    %02x dien   %02x dwt    %02x dcntl  %02x\n",
   1758       1.1       is 	    rp->siop_dmode, rp->siop_dien, rp->siop_dwt, rp->siop_dcntl);
   1759       1.1       is 	printf("  stest0   %02x stest1 %02x stest2 %02x stest3 %02x\n",
   1760       1.1       is 	    rp->siop_stest0, rp->siop_stest1, rp->siop_stest2, rp->siop_stest3);
   1761       1.1       is 	printf("  istat    %02x sien %04x sist %04x respid %04x\n",
   1762       1.1       is 	    rp->siop_istat, rp->siop_sien, rp->siop_sist, rp->siop_respid);
   1763       1.1       is 	printf("  sidl   %04x sodl %04x sbdl %04x\n",
   1764       1.1       is 	    rp->siop_sidl, rp->siop_sodl, rp->siop_sbdl);
   1765       1.1       is 	printf("  dsps     %08lx dsp      %08lx (+%lx)\n",
   1766       1.1       is 	    rp->siop_dsps, rp->siop_dsp, rp->siop_dsp > sc->sc_scriptspa ?
   1767       1.1       is 	    rp->siop_dsp - sc->sc_scriptspa : 0);
   1768       1.1       is 	printf("  dsa      %08lx temp     %08lx dnad     %08lx\n",
   1769       1.1       is 	    rp->siop_dsa, rp->siop_temp, rp->siop_dnad);
   1770       1.1       is 	printf("  scratcha %08lx scratchb %08lx adder     %08lx\n",
   1771       1.1       is 	    rp->siop_scratcha, rp->siop_scratchb, rp->siop_adder);
   1772       1.1       is }
   1773       1.1       is 
   1774       1.1       is #ifdef DEBUG
   1775       1.1       is 
   1776       1.1       is #if SIOP_TRACE_SIZE
   1777       1.1       is void
   1778       1.1       is siopng_dump_trace()
   1779       1.1       is {
   1780       1.1       is 	int i;
   1781       1.1       is 
   1782       1.1       is 	printf("siopng trace: next index %d\n", siopng_trix);
   1783       1.1       is 	i = siopng_trix;
   1784       1.1       is 	do {
   1785       1.1       is 		printf("%3d: '%c' %02x %02x %02x\n", i, siopng_trbuf[i],
   1786       1.1       is 		    siopng_trbuf[i + 1], siopng_trbuf[i + 2], siopng_trbuf[i + 3]);
   1787       1.1       is 		i = (i + 4) & (SIOP_TRACE_SIZE - 1);
   1788       1.1       is 	} while (i != siopng_trix);
   1789       1.1       is }
   1790       1.1       is #endif
   1791       1.1       is 
   1792       1.1       is void
   1793       1.1       is siopng_dump_acb(acb)
   1794       1.1       is 	struct siop_acb *acb;
   1795       1.1       is {
   1796       1.1       is 	u_char *b = (u_char *) &acb->cmd;
   1797       1.1       is 	int i;
   1798       1.1       is 
   1799       1.1       is 	printf("acb@%p ", acb);
   1800       1.1       is 	if (acb->xs == NULL) {
   1801       1.1       is 		printf("<unused>\n");
   1802       1.1       is 		return;
   1803       1.1       is 	}
   1804       1.1       is 	printf("(%d:%d) flags %2x clen %2d cmd ",
   1805  1.14.2.1   bouyer 		acb->xs->xs_periph->periph_target,
   1806  1.14.2.1   bouyer 	    acb->xs->xs_periph->periph_lun, acb->flags, acb->clen);
   1807       1.1       is 	for (i = acb->clen; i; --i)
   1808       1.1       is 		printf(" %02x", *b++);
   1809       1.1       is 	printf("\n");
   1810       1.1       is 	printf("  xs: %p data %p:%04x ", acb->xs, acb->xs->data,
   1811       1.1       is 	    acb->xs->datalen);
   1812       1.1       is 	printf("va %p:%lx ", acb->iob_buf, acb->iob_len);
   1813       1.1       is 	printf("cur %lx:%lx\n", acb->iob_curbuf, acb->iob_curlen);
   1814       1.1       is }
   1815       1.1       is 
   1816       1.1       is void
   1817       1.1       is siopng_dump(sc)
   1818       1.1       is 	struct siop_softc *sc;
   1819       1.1       is {
   1820       1.1       is 	struct siop_acb *acb;
   1821       1.1       is 	siop_regmap_p rp = sc->sc_siopp;
   1822       1.1       is 	int s;
   1823       1.1       is 	int i;
   1824       1.1       is 
   1825       1.1       is 	s = splbio();
   1826       1.1       is #if SIOP_TRACE_SIZE
   1827       1.1       is 	siopng_dump_trace();
   1828       1.1       is #endif
   1829       1.1       is 	printf("%s@%p regs %p istat %x\n",
   1830       1.1       is 	    sc->sc_dev.dv_xname, sc, rp, rp->siop_istat);
   1831       1.1       is 	if ((acb = sc->free_list.tqh_first) > 0) {
   1832       1.1       is 		printf("Free list:\n");
   1833       1.1       is 		while (acb) {
   1834       1.1       is 			siopng_dump_acb(acb);
   1835       1.1       is 			acb = acb->chain.tqe_next;
   1836       1.1       is 		}
   1837       1.1       is 	}
   1838       1.1       is 	if ((acb = sc->ready_list.tqh_first) > 0) {
   1839       1.1       is 		printf("Ready list:\n");
   1840       1.1       is 		while (acb) {
   1841       1.1       is 			siopng_dump_acb(acb);
   1842       1.1       is 			acb = acb->chain.tqe_next;
   1843       1.1       is 		}
   1844       1.1       is 	}
   1845       1.1       is 	if ((acb = sc->nexus_list.tqh_first) > 0) {
   1846       1.1       is 		printf("Nexus list:\n");
   1847       1.1       is 		while (acb) {
   1848       1.1       is 			siopng_dump_acb(acb);
   1849       1.1       is 			acb = acb->chain.tqe_next;
   1850       1.1       is 		}
   1851       1.1       is 	}
   1852       1.1       is 	if (sc->sc_nexus) {
   1853       1.1       is 		printf("Nexus:\n");
   1854       1.1       is 		siopng_dump_acb(sc->sc_nexus);
   1855       1.1       is 	}
   1856       1.1       is 	for (i = 0; i < 8; ++i) {
   1857       1.1       is 		if (sc->sc_tinfo[i].cmds > 2) {
   1858       1.1       is 			printf("tgt %d: cmds %d disc %d senses %d lubusy %x\n",
   1859       1.1       is 			    i, sc->sc_tinfo[i].cmds,
   1860       1.1       is 			    sc->sc_tinfo[i].dconns,
   1861       1.1       is 			    sc->sc_tinfo[i].senses,
   1862       1.1       is 			    sc->sc_tinfo[i].lubusy);
   1863       1.1       is 		}
   1864       1.1       is 	}
   1865       1.1       is 	splx(s);
   1866       1.1       is }
   1867       1.1       is #endif
   1868