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