LCOV - code coverage report
Current view: top level - dev/ic - ncr53c9x.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1301 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 29 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13