The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/ninjascsi32.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: ninjascsi32.c,v 1.2.2.3 2004/08/30 09:54:17 tron Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2004 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by ITOH Yasufumi.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: ninjascsi32.c,v 1.2.2.3 2004/08/30 09:54:17 tron Exp $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/callout.h>
   45 #include <sys/device.h>
   46 #include <sys/kernel.h>
   47 #include <sys/buf.h>
   48 #include <sys/scsiio.h>
   49 
   50 #include <machine/bus.h>
   51 #include <machine/intr.h>
   52 
   53 #include <uvm/uvm_extern.h>
   54 
   55 #include <dev/scsipi/scsi_all.h>
   56 #include <dev/scsipi/scsipi_all.h>
   57 #include <dev/scsipi/scsiconf.h>
   58 #include <dev/scsipi/scsi_message.h>
   59 
   60 /*
   61  * DualEdge transfer support
   62  */
   63 /* #define NJSC32_DUALEDGE */   /* XXX untested */
   64 
   65 /*
   66  * Auto param loading does not work properly (it partially works (works on
   67  * start, doesn't on restart) on rev 0x54, it doesn't work at all on rev 0x51),
   68  * and it doesn't improve the performance so much,
   69  * forget about it.
   70  */
   71 #undef NJSC32_AUTOPARAM
   72 
   73 #include <dev/ic/ninjascsi32reg.h>
   74 #include <dev/ic/ninjascsi32var.h>
   75 
   76 /* #define NJSC32_DEBUG */
   77 /* #define NJSC32_TRACE */
   78 
   79 #ifdef NJSC32_DEBUG
   80 #define DPRINTF(x)      printf x
   81 #define DPRINTC(cmd, x) PRINTC(cmd, x)
   82 #else
   83 #define DPRINTF(x)
   84 #define DPRINTC(cmd, x)
   85 #endif
   86 #ifdef NJSC32_TRACE
   87 #define TPRINTF(x)      printf x
   88 #define TPRINTC(cmd, x) PRINTC(cmd, x)
   89 #else
   90 #define TPRINTF(x)
   91 #define TPRINTC(cmd, x)
   92 #endif
   93 
   94 #define PRINTC(cmd, x)  do {                                    \
   95                 scsi_print_addr((cmd)->c_xs->xs_periph);        \
   96                 printf x;                                       \
   97         } while (/* CONSTCOND */ 0)
   98 
   99 static void     njsc32_scsipi_request(struct scsipi_channel *,
  100                     scsipi_adapter_req_t, void *);
  101 static void     njsc32_scsipi_minphys(struct buf *buf);
  102 static int      njsc32_scsipi_ioctl(struct scsipi_channel *, u_long, caddr_t,
  103                     int, struct proc *);
  104 
  105 static void     njsc32_init(struct njsc32_softc *, int nosleep);
  106 static int      njsc32_init_cmds(struct njsc32_softc *);
  107 static void     njsc32_target_async(struct njsc32_softc *,
  108                     struct njsc32_target *);
  109 static void     njsc32_init_targets(struct njsc32_softc *);
  110 static void     njsc32_add_msgout(struct njsc32_softc *, int);
  111 static u_int32_t njsc32_get_auto_msgout(struct njsc32_softc *);
  112 #ifdef NJSC32_DUALEDGE
  113 static void     njsc32_msgout_wdtr(struct njsc32_softc *, int);
  114 #endif
  115 static void     njsc32_msgout_sdtr(struct njsc32_softc *, int period,
  116                     int offset);
  117 static void     njsc32_negotiate_xfer(struct njsc32_softc *,
  118                     struct njsc32_target *);
  119 static void     njsc32_arbitration_failed(struct njsc32_softc *);
  120 static void     njsc32_start(struct njsc32_softc *);
  121 static void     njsc32_run_xfer(struct njsc32_softc *, struct scsipi_xfer *);
  122 static void     njsc32_end_cmd(struct njsc32_softc *, struct njsc32_cmd *,
  123                     scsipi_xfer_result_t);
  124 static void     njsc32_reset_bus(struct njsc32_softc *);
  125 static void     njsc32_clear_cmds(struct njsc32_softc *,
  126                     scsipi_xfer_result_t);
  127 static void     njsc32_reset_detected(struct njsc32_softc *);
  128 static void     njsc32_set_ptr(struct njsc32_softc *, struct njsc32_cmd *,
  129                     u_int32_t);
  130 static void     njsc32_assert_ack(struct njsc32_softc *);
  131 static void     njsc32_negate_ack(struct njsc32_softc *);
  132 static void     njsc32_wait_req_negate(struct njsc32_softc *);
  133 static void     njsc32_reconnect(struct njsc32_softc *, struct njsc32_cmd *);
  134 enum njsc32_reselstat {
  135         NJSC32_RESEL_ERROR,             /* to be rejected */
  136         NJSC32_RESEL_COMPLETE,          /* reselection is just complete */
  137         NJSC32_RESEL_THROUGH            /* this message is OK (no reply) */
  138 };
  139 static enum njsc32_reselstat njsc32_resel_identify(struct njsc32_softc *,
  140                     int lun, struct njsc32_cmd **);
  141 static enum njsc32_reselstat njsc32_resel_tag(struct njsc32_softc *,
  142                     int tag, struct njsc32_cmd **);
  143 static void     njsc32_cmd_reload(struct njsc32_softc *, struct njsc32_cmd *,
  144                     int);
  145 static void     njsc32_update_xfer_mode(struct njsc32_softc *,
  146                     struct njsc32_target *);
  147 static void     njsc32_msgin(struct njsc32_softc *);
  148 static void     njsc32_msgout(struct njsc32_softc *);
  149 static void     njsc32_cmdtimeout(void *);
  150 static void     njsc32_reseltimeout(void *);
  151 
  152 static __inline unsigned
  153 njsc32_read_1(struct njsc32_softc *sc, int no)
  154 {
  155 
  156         return bus_space_read_1(sc->sc_regt, sc->sc_regh, no);
  157 }
  158 
  159 static __inline unsigned
  160 njsc32_read_2(struct njsc32_softc *sc, int no)
  161 {
  162 
  163         return bus_space_read_2(sc->sc_regt, sc->sc_regh, no);
  164 }
  165 
  166 static __inline u_int32_t
  167 njsc32_read_4(struct njsc32_softc *sc, int no)
  168 {
  169 
  170         return bus_space_read_4(sc->sc_regt, sc->sc_regh, no);
  171 }
  172 
  173 static __inline void
  174 njsc32_write_1(struct njsc32_softc *sc, int no, int val)
  175 {
  176 
  177         bus_space_write_1(sc->sc_regt, sc->sc_regh, no, val);
  178 }
  179 
  180 static __inline void
  181 njsc32_write_2(struct njsc32_softc *sc, int no, int val)
  182 {
  183 
  184         bus_space_write_2(sc->sc_regt, sc->sc_regh, no, val);
  185 }
  186 
  187 static __inline void
  188 njsc32_write_4(struct njsc32_softc *sc, int no, u_int32_t val)
  189 {
  190 
  191         bus_space_write_4(sc->sc_regt, sc->sc_regh, no, val);
  192 }
  193 
  194 static __inline unsigned
  195 njsc32_ireg_read_1(struct njsc32_softc *sc, int no)
  196 {
  197 
  198         bus_space_write_1(sc->sc_regt, sc->sc_regh, NJSC32_REG_INDEX, no);
  199         return bus_space_read_1(sc->sc_regt, sc->sc_regh, NJSC32_REG_DATA_LOW);
  200 }
  201 
  202 static __inline unsigned
  203 njsc32_ireg_read_2(struct njsc32_softc *sc, int no)
  204 {
  205 
  206         bus_space_write_1(sc->sc_regt, sc->sc_regh, NJSC32_REG_INDEX, no);
  207         return bus_space_read_2(sc->sc_regt, sc->sc_regh, NJSC32_REG_DATA_LOW);
  208 }
  209 
  210 static __inline u_int32_t
  211 njsc32_ireg_read_4(struct njsc32_softc *sc, int no)
  212 {
  213         u_int32_t val;
  214 
  215         bus_space_write_1(sc->sc_regt, sc->sc_regh, NJSC32_REG_INDEX, no);
  216         val = (u_int16_t)bus_space_read_2(sc->sc_regt, sc->sc_regh,
  217             NJSC32_REG_DATA_LOW);
  218         return val | (bus_space_read_2(sc->sc_regt, sc->sc_regh,
  219             NJSC32_REG_DATA_HIGH) << 16);
  220 }
  221 
  222 static __inline void
  223 njsc32_ireg_write_1(struct njsc32_softc *sc, int no, int val)
  224 {
  225 
  226         bus_space_write_1(sc->sc_regt, sc->sc_regh, NJSC32_REG_INDEX, no);
  227         bus_space_write_1(sc->sc_regt, sc->sc_regh, NJSC32_REG_DATA_LOW, val);
  228 }
  229 
  230 static __inline void
  231 njsc32_ireg_write_2(struct njsc32_softc *sc, int no, int val)
  232 {
  233 
  234         bus_space_write_1(sc->sc_regt, sc->sc_regh, NJSC32_REG_INDEX, no);
  235         bus_space_write_2(sc->sc_regt, sc->sc_regh, NJSC32_REG_DATA_LOW, val);
  236 }
  237 
  238 static __inline void
  239 njsc32_ireg_write_4(struct njsc32_softc *sc, int no, u_int32_t val)
  240 {
  241 
  242         bus_space_write_1(sc->sc_regt, sc->sc_regh, NJSC32_REG_INDEX, no);
  243         bus_space_write_2(sc->sc_regt, sc->sc_regh, NJSC32_REG_DATA_LOW, val);
  244         bus_space_write_2(sc->sc_regt, sc->sc_regh, NJSC32_REG_DATA_HIGH,
  245             val >> 16);
  246 }
  247 
  248 #define NS(ns)  ((ns) / 4)      /* nanosecond (>= 50) -> sync value */
  249 #ifdef __STDC__
  250 # define ACKW(n)        NJSC32_ACK_WIDTH_ ## n ## CLK
  251 # define SMPL(n)        (NJSC32_SREQ_SAMPLING_ ## n ## CLK |    \
  252                          NJSC32_SREQ_SAMPLING_ENABLE)
  253 #else
  254 # define ACKW(n)        NJSC32_ACK_WIDTH_/**/n/**/CLK
  255 # define SMPL(n)        (NJSC32_SREQ_SAMPLING_/**/n/**/CLK |    \
  256                          NJSC32_SREQ_SAMPLING_ENABLE)
  257 #endif
  258 
  259 #define NJSC32_NSYNCT_MAXSYNC   1
  260 #define NJSC32_NSYNCT           16
  261 
  262 /* 40MHz (25ns) */
  263 static const struct njsc32_sync_param njsc32_synct_40M[NJSC32_NSYNCT] = {
  264         { 0, 0, 0 },                    /* dummy for async */
  265         { NS( 50), ACKW(1), 0       },  /* 20.0 :  50ns,  25ns */
  266         { NS( 75), ACKW(1), SMPL(1) },  /* 13.3 :  75ns,  25ns */
  267         { NS(100), ACKW(2), SMPL(1) },  /* 10.0 : 100ns,  50ns */
  268         { NS(125), ACKW(2), SMPL(2) },  /*  8.0 : 125ns,  50ns */
  269         { NS(150), ACKW(3), SMPL(2) },  /*  6.7 : 150ns,  75ns */
  270         { NS(175), ACKW(3), SMPL(2) },  /*  5.7 : 175ns,  75ns */
  271         { NS(200), ACKW(4), SMPL(2) },  /*  5.0 : 200ns, 100ns */
  272         { NS(225), ACKW(4), SMPL(4) },  /*  4.4 : 225ns, 100ns */
  273         { NS(250), ACKW(4), SMPL(4) },  /*  4.0 : 250ns, 100ns */
  274         { NS(275), ACKW(4), SMPL(4) },  /*  3.64: 275ns, 100ns */
  275         { NS(300), ACKW(4), SMPL(4) },  /*  3.33: 300ns, 100ns */
  276         { NS(325), ACKW(4), SMPL(4) },  /*  3.01: 325ns, 100ns */
  277         { NS(350), ACKW(4), SMPL(4) },  /*  2.86: 350ns, 100ns */
  278         { NS(375), ACKW(4), SMPL(4) },  /*  2.67: 375ns, 100ns */
  279         { NS(400), ACKW(4), SMPL(4) }   /*  2.50: 400ns, 100ns */
  280 };
  281 
  282 #ifdef NJSC32_SUPPORT_OTHER_CLOCKS
  283 /* 20MHz (50ns) */
  284 static const struct njsc32_sync_param njsc32_synct_20M[NJSC32_NSYNCT] = {
  285         { 0, 0, 0 },                    /* dummy for async */
  286         { NS(100), ACKW(1), 0       },  /* 10.0 : 100ns,  50ns */
  287         { NS(150), ACKW(1), SMPL(2) },  /*  6.7 : 150ns,  50ns */
  288         { NS(200), ACKW(2), SMPL(2) },  /*  5.0 : 200ns, 100ns */
  289         { NS(250), ACKW(2), SMPL(4) },  /*  4.0 : 250ns, 100ns */
  290         { NS(300), ACKW(3), SMPL(4) },  /*  3.3 : 300ns, 150ns */
  291         { NS(350), ACKW(3), SMPL(4) },  /*  2.8 : 350ns, 150ns */
  292         { NS(400), ACKW(4), SMPL(4) },  /*  2.5 : 400ns, 200ns */
  293         { NS(450), ACKW(4), SMPL(4) },  /*  2.2 : 450ns, 200ns */
  294         { NS(500), ACKW(4), SMPL(4) },  /*  2.0 : 500ns, 200ns */
  295         { NS(550), ACKW(4), SMPL(4) },  /*  1.82: 550ns, 200ns */
  296         { NS(600), ACKW(4), SMPL(4) },  /*  1.67: 600ns, 200ns */
  297         { NS(650), ACKW(4), SMPL(4) },  /*  1.54: 650ns, 200ns */
  298         { NS(700), ACKW(4), SMPL(4) },  /*  1.43: 700ns, 200ns */
  299         { NS(750), ACKW(4), SMPL(4) },  /*  1.33: 750ns, 200ns */
  300         { NS(800), ACKW(4), SMPL(4) }   /*  1.25: 800ns, 200ns */
  301 };
  302 
  303 /* 33.3MHz (30ns) */
  304 static const struct njsc32_sync_param njsc32_synct_pci[NJSC32_NSYNCT] = {
  305         { 0, 0, 0 },                    /* dummy for async */
  306         { NS( 60), ACKW(1), 0       },  /* 16.6 :  60ns,  30ns */
  307         { NS( 90), ACKW(1), SMPL(1) },  /* 11.1 :  90ns,  30ns */
  308         { NS(120), ACKW(2), SMPL(2) },  /*  8.3 : 120ns,  60ns */
  309         { NS(150), ACKW(2), SMPL(2) },  /*  6.7 : 150ns,  60ns */
  310         { NS(180), ACKW(3), SMPL(2) },  /*  5.6 : 180ns,  90ns */
  311         { NS(210), ACKW(3), SMPL(4) },  /*  4.8 : 210ns,  90ns */
  312         { NS(240), ACKW(4), SMPL(4) },  /*  4.2 : 240ns, 120ns */
  313         { NS(270), ACKW(4), SMPL(4) },  /*  3.7 : 270ns, 120ns */
  314         { NS(300), ACKW(4), SMPL(4) },  /*  3.3 : 300ns, 120ns */
  315         { NS(330), ACKW(4), SMPL(4) },  /*  3.0 : 330ns, 120ns */
  316         { NS(360), ACKW(4), SMPL(4) },  /*  2.8 : 360ns, 120ns */
  317         { NS(390), ACKW(4), SMPL(4) },  /*  2.6 : 390ns, 120ns */
  318         { NS(420), ACKW(4), SMPL(4) },  /*  2.4 : 420ns, 120ns */
  319         { NS(450), ACKW(4), SMPL(4) },  /*  2.2 : 450ns, 120ns */
  320         { NS(480), ACKW(4), SMPL(4) }   /*  2.1 : 480ns, 120ns */
  321 };
  322 #endif  /* NJSC32_SUPPORT_OTHER_CLOCKS */
  323 
  324 #undef NS
  325 #undef ACKW
  326 #undef SMPL
  327 
  328 /* initialize device */
  329 static void
  330 njsc32_init(struct njsc32_softc *sc, int nosleep)
  331 {
  332         u_int16_t intstat;
  333 
  334         /* block all interrupts */
  335         njsc32_write_2(sc, NJSC32_REG_IRQ, NJSC32_IRQ_MASK_ALL);
  336 
  337         /* clear transfer */
  338         njsc32_write_2(sc, NJSC32_REG_TRANSFER, 0);
  339         njsc32_write_4(sc, NJSC32_REG_BM_CNT, 0);
  340 
  341         /* make sure interrupts are cleared */
  342         /* XXX loop forever? */
  343         while ((intstat = njsc32_read_2(sc, NJSC32_REG_IRQ)) &
  344             NJSC32_IRQ_INTR_PENDING) {
  345                 DPRINTF(("%s: njsc32_init: intr pending: %#x\n",
  346                     sc->sc_dev.dv_xname, intstat));
  347         }
  348 
  349         /* FIFO threshold */
  350         njsc32_ireg_write_1(sc, NJSC32_IREG_FIFO_THRESHOLD_FULL,
  351             NJSC32_FIFO_FULL_BUSMASTER);
  352         njsc32_ireg_write_1(sc, NJSC32_IREG_FIFO_THRESHOLD_EMPTY,
  353             NJSC32_FIFO_EMPTY_BUSMASTER);
  354 
  355         /* clock source */
  356         njsc32_ireg_write_1(sc, NJSC32_IREG_CLOCK, sc->sc_clk);
  357 
  358         /* memory read multiple */
  359         njsc32_ireg_write_1(sc, NJSC32_IREG_BM,
  360             NJSC32_BM_MEMRD_CMD1 | NJSC32_BM_SGT_AUTO_PARA_MEMRD_CMD);
  361 
  362         /* clear parity error and enable parity detection */
  363         njsc32_write_1(sc, NJSC32_REG_PARITY_CONTROL,
  364             NJSC32_PARITYCTL_CHECK_ENABLE | NJSC32_PARITYCTL_CLEAR_ERROR);
  365 
  366         /* misc configuration */
  367         njsc32_ireg_write_2(sc, NJSC32_IREG_MISC,
  368             NJSC32_MISC_SCSI_DIRECTION_DETECTOR_SELECT |
  369             NJSC32_MISC_DELAYED_BMSTART |
  370             NJSC32_MISC_MASTER_TERMINATION_SELECT |
  371             NJSC32_MISC_BMREQ_NEGATE_TIMING_SEL |
  372             NJSC32_MISC_AUTOSEL_TIMING_SEL |
  373             NJSC32_MISC_BMSTOP_CHANGE2_NONDATA_PHASE);
  374 
  375         /*
  376          * Check for termination power (32Bi only?).
  377          */
  378         if (!nosleep || cold) {
  379                 DPRINTF(("%s: njsc32_init: checking TERMPWR\n",
  380                     sc->sc_dev.dv_xname));
  381 
  382                 /* First, turn termination power off */
  383                 njsc32_ireg_write_1(sc, NJSC32_IREG_TERM_PWR, 0);
  384 
  385                 /* give 0.5s to settle */
  386                 if (nosleep)
  387                         delay(500000);
  388                 else
  389                         tsleep(sc, PWAIT, "njs_t1", hz / 2);
  390         }
  391 
  392         /* supply termination power if not supplied by other devices */
  393         if ((njsc32_ireg_read_1(sc, NJSC32_IREG_TERM_PWR) &
  394             NJSC32_TERMPWR_SENSE) == 0) {
  395                 /* termination power is not present on the bus */
  396                 if (sc->sc_flags & NJSC32_CANNOT_SUPPLY_TERMPWR) {
  397                         /*
  398                          * CardBus device must not supply termination power
  399                          * to avoid excessive power consumption.
  400                          */
  401                         printf("%s: no termination power present\n",
  402                             sc->sc_dev.dv_xname);
  403                 } else {
  404                         /* supply termination power */
  405                         njsc32_ireg_write_1(sc, NJSC32_IREG_TERM_PWR,
  406                             NJSC32_TERMPWR_BPWR);
  407 
  408                         DPRINTF(("%s: supplying termination power\n",
  409                             sc->sc_dev.dv_xname));
  410 
  411                         /* give 0.5s to settle */
  412                         if (!nosleep)
  413                                 tsleep(sc, PWAIT, "njs_t2", hz / 2);
  414                 }
  415         }
  416 
  417         /* stop timer */
  418         njsc32_write_2(sc, NJSC32_REG_TIMER, NJSC32_TIMER_STOP);
  419         njsc32_write_2(sc, NJSC32_REG_TIMER, NJSC32_TIMER_STOP);
  420 
  421         /* default transfer parameter */
  422         njsc32_write_1(sc, NJSC32_REG_SYNC, 0);
  423         njsc32_write_1(sc, NJSC32_REG_ACK_WIDTH, NJSC32_ACK_WIDTH_1CLK);
  424         njsc32_write_2(sc, NJSC32_REG_SEL_TIMEOUT,
  425             NJSC32_SEL_TIMEOUT_TIME);
  426 
  427         /* select interrupt source */
  428         njsc32_ireg_write_2(sc, NJSC32_IREG_IRQ_SELECT,
  429             NJSC32_IRQSEL_RESELECT |
  430             NJSC32_IRQSEL_PHASE_CHANGE |
  431             NJSC32_IRQSEL_SCSIRESET |
  432             NJSC32_IRQSEL_TIMER |
  433             NJSC32_IRQSEL_FIFO_THRESHOLD |
  434             NJSC32_IRQSEL_TARGET_ABORT |
  435             NJSC32_IRQSEL_MASTER_ABORT |
  436         /* XXX not yet
  437             NJSC32_IRQSEL_SERR |
  438             NJSC32_IRQSEL_PERR |
  439             NJSC32_IRQSEL_BMCNTERR |
  440         */
  441             NJSC32_IRQSEL_AUTO_SCSI_SEQ);
  442 
  443         /* unblock interrupts */
  444         njsc32_write_2(sc, NJSC32_REG_IRQ, 0);
  445 
  446         /* turn LED off */
  447         njsc32_ireg_write_1(sc, NJSC32_IREG_EXT_PORT_DDR,
  448             NJSC32_EXTPORT_LED_OFF);
  449         njsc32_ireg_write_1(sc, NJSC32_IREG_EXT_PORT,
  450             NJSC32_EXTPORT_LED_OFF);
  451 
  452         /* reset SCSI bus so the targets become known state */
  453         njsc32_reset_bus(sc);
  454 }
  455 
  456 static int
  457 njsc32_init_cmds(struct njsc32_softc *sc)
  458 {
  459         struct njsc32_cmd *cmd;
  460         bus_addr_t dmaaddr;
  461         int i, error;
  462 
  463         /*
  464          * allocate DMA area for command
  465          */
  466         if ((error = bus_dmamem_alloc(sc->sc_dmat,
  467             sizeof(struct njsc32_dma_page), PAGE_SIZE, 0,
  468             &sc->sc_cmdpg_seg, 1, &sc->sc_cmdpg_nsegs, BUS_DMA_NOWAIT)) != 0) {
  469                 printf("%s: unable to allocate cmd page, error = %d\n",
  470                     sc->sc_dev.dv_xname, error);
  471                 return 0;
  472         }
  473         if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cmdpg_seg,
  474             sc->sc_cmdpg_nsegs, sizeof(struct njsc32_dma_page),
  475             (caddr_t *)&sc->sc_cmdpg,
  476             BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
  477                 printf("%s: unable to map cmd page, error = %d\n",
  478                     sc->sc_dev.dv_xname, error);
  479                 goto fail1;
  480         }
  481         if ((error = bus_dmamap_create(sc->sc_dmat,
  482             sizeof(struct njsc32_dma_page), 1,
  483             sizeof(struct njsc32_dma_page), 0, BUS_DMA_NOWAIT,
  484             &sc->sc_dmamap_cmdpg)) != 0) {
  485                 printf("%s: unable to create cmd DMA map, error = %d\n",
  486                     sc->sc_dev.dv_xname, error);
  487                 goto fail2;
  488         }
  489         if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_cmdpg,
  490             sc->sc_cmdpg, sizeof(struct njsc32_dma_page),
  491             NULL, BUS_DMA_NOWAIT)) != 0) {
  492                 printf("%s: unable to load cmd DMA map, error = %d\n",
  493                     sc->sc_dev.dv_xname, error);
  494                 goto fail3;
  495         }
  496 
  497         memset(sc->sc_cmdpg, 0, sizeof(struct njsc32_dma_page));
  498         dmaaddr = sc->sc_dmamap_cmdpg->dm_segs[0].ds_addr;
  499 
  500 #ifdef NJSC32_AUTOPARAM
  501         sc->sc_ap_dma = dmaaddr + offsetof(struct njsc32_dma_page, dp_ap);
  502 #endif
  503 
  504         for (i = 0; i < NJSC32_NUM_CMD; i++) {
  505                 cmd = &sc->sc_cmds[i];
  506                 cmd->c_sc = sc;
  507                 cmd->c_sgt = sc->sc_cmdpg->dp_sg[i];
  508                 cmd->c_sgt_dma = dmaaddr +
  509                     offsetof(struct njsc32_dma_page, dp_sg[i]);
  510                 cmd->c_flags = 0;
  511 
  512                 error = bus_dmamap_create(sc->sc_dmat,
  513                     NJSC32_MAX_XFER,            /* max total map size */
  514                     NJSC32_NUM_SG,              /* max number of segments */
  515                     NJSC32_SGT_MAXSEGLEN,       /* max size of a segment */
  516                     0,                          /* boundary */
  517                     BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &cmd->c_dmamap_xfer);
  518                 if (error) {
  519                         printf("%s: only %d cmd descs available (error = %d)\n",
  520                             sc->sc_dev.dv_xname, i, error);
  521                         break;
  522                 }
  523                 TAILQ_INSERT_TAIL(&sc->sc_freecmd, cmd, c_q);
  524         }
  525 
  526         if (i > 0)
  527                 return i;
  528 
  529 fail3:  bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap_cmdpg);
  530 fail2:  bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_cmdpg,
  531             sizeof(struct njsc32_dma_page));
  532 fail1:  bus_dmamem_free(sc->sc_dmat, &sc->sc_cmdpg_seg, sc->sc_cmdpg_nsegs);
  533 
  534         return 0;
  535 }
  536 
  537 static void
  538 njsc32_target_async(struct njsc32_softc *sc, struct njsc32_target *target)
  539 {
  540 
  541         target->t_sync =
  542             NJSC32_SYNC_VAL(sc->sc_sync_max, NJSC32_SYNCOFFSET_ASYNC);
  543         target->t_ackwidth = NJSC32_ACK_WIDTH_1CLK;
  544         target->t_sample = 0;           /* disable */
  545         target->t_syncoffset = NJSC32_SYNCOFFSET_ASYNC;
  546         target->t_syncperiod = NJSC32_SYNCPERIOD_ASYNC;
  547 }
  548 
  549 static void
  550 njsc32_init_targets(struct njsc32_softc *sc)
  551 {
  552         int id, lun;
  553         struct njsc32_lu *lu;
  554 
  555         for (id = 0; id <= NJSC32_MAX_TARGET_ID; id++) {
  556                 /* cancel negotiation status */
  557                 sc->sc_targets[id].t_state = NJSC32_TARST_INIT;
  558 
  559                 /* default to async mode */
  560                 njsc32_target_async(sc, &sc->sc_targets[id]);
  561 
  562 #ifdef NJSC32_DUALEDGE
  563                 sc->sc_targets[id].t_xferctl = 0;
  564 #endif
  565 
  566                 sc->sc_targets[id].t_targetid =
  567                     (1 << id) | (1 << NJSC32_INITIATOR_ID);
  568 
  569                 /* init logical units */
  570                 for (lun = 0; lun < NJSC32_NLU; lun++) {
  571                         lu = &sc->sc_targets[id].t_lus[lun];
  572                         lu->lu_cmd = NULL;
  573                         TAILQ_INIT(&lu->lu_q);
  574                 }
  575         }
  576 }
  577 
  578 void
  579 njsc32_attach(struct njsc32_softc *sc)
  580 {
  581         const char *str;
  582 #if 1   /* test */
  583         int reg;
  584         njsc32_model_t detected_model;
  585 #endif
  586 
  587         /* init */
  588         TAILQ_INIT(&sc->sc_freecmd);
  589         TAILQ_INIT(&sc->sc_reqcmd);
  590 
  591 #if 1   /* test */
  592         /*
  593          * try to distinguish 32Bi and 32UDE
  594          */
  595         /* try to set DualEdge bit (exists on 32UDE only) and read it back */
  596         njsc32_write_2(sc, NJSC32_REG_TRANSFER, NJSC32_XFR_DUALEDGE_ENABLE);
  597         if ((reg = njsc32_read_2(sc, NJSC32_REG_TRANSFER)) == 0xffff) {
  598                 /* device was removed? */
  599                 aprint_error("%s: attach failed\n", sc->sc_dev.dv_xname);
  600                 return;
  601         } else if (reg & NJSC32_XFR_DUALEDGE_ENABLE) {
  602                 detected_model = NJSC32_MODEL_32UDE | NJSC32_FLAG_DUALEDGE;
  603         } else {
  604                 detected_model = NJSC32_MODEL_32BI;
  605         }
  606         njsc32_write_2(sc, NJSC32_REG_TRANSFER, 0);     /* restore */
  607 
  608 #if 1/*def DIAGNOSTIC*/
  609         /* compare what is configured with what is detected */
  610         if ((sc->sc_model & NJSC32_MODEL_MASK) !=
  611             (detected_model & NJSC32_MODEL_MASK)) {
  612                 /*
  613                  * Please report this error if it happens.
  614                  */
  615                 aprint_error("%s: model mismatch: %#x vs %#x\n",
  616                     sc->sc_dev.dv_xname, sc->sc_model, detected_model);
  617                 return;
  618         }
  619 #endif
  620 #endif
  621 
  622         /* check model */
  623         switch (sc->sc_model & NJSC32_MODEL_MASK) {
  624         case NJSC32_MODEL_32BI:
  625                 str = "Bi";
  626                 /* 32Bi doesn't support DualEdge transfer */
  627                 KASSERT((sc->sc_model & NJSC32_FLAG_DUALEDGE) == 0);
  628                 break;
  629         case NJSC32_MODEL_32UDE:
  630                 str = "UDE";
  631                 break;
  632         default:
  633                 aprint_error("%s: unknown model!\n", sc->sc_dev.dv_xname);
  634                 return;
  635         }
  636         aprint_normal("%s: NJSC-32%s", sc->sc_dev.dv_xname, str);
  637 
  638         switch (sc->sc_clk) {
  639         default:
  640 #ifdef DIAGNOSTIC
  641                 panic("njsc32_attach: unknown clk %d", sc->sc_clk);
  642 #endif
  643         case NJSC32_CLOCK_DIV_4:
  644                 sc->sc_synct = njsc32_synct_40M;
  645                 str = "40MHz";
  646                 break;
  647 #ifdef NJSC32_SUPPORT_OTHER_CLOCKS
  648         case NJSC32_CLOCK_DIV_2:
  649                 sc->sc_synct = njsc32_synct_20M;
  650                 str = "20MHz";
  651                 break;
  652         case NJSC32_CLOCK_PCICLK:
  653                 sc->sc_synct = njsc32_synct_pci;
  654                 str = "PCI";
  655                 break;
  656 #endif
  657         }
  658         aprint_normal(", G/A rev %#x, clk %s%s\n",
  659             NJSC32_INDEX_GAREV(njsc32_read_2(sc, NJSC32_REG_INDEX)), str,
  660             (sc->sc_model & NJSC32_FLAG_DUALEDGE) ?
  661 #ifdef NJSC32_DUALEDGE
  662                 ", DualEdge"
  663 #else
  664                 ", DualEdge (no driver support)"
  665 #endif
  666             : "");
  667 
  668         /* allocate DMA resource */
  669         if ((sc->sc_ncmd = njsc32_init_cmds(sc)) == 0) {
  670                 printf("%s: no usable DMA map\n", sc->sc_dev.dv_xname);
  671                 return;
  672         }
  673         sc->sc_flags |= NJSC32_CMDPG_MAPPED;
  674 
  675         sc->sc_curcmd = NULL;
  676         sc->sc_nusedcmds = 0;
  677         sc->sc_stat = NJSC32_STAT_IDLE;
  678 
  679         sc->sc_sync_max = 1;    /* XXX look up EEPROM configuration? */
  680 
  681         /* initialize target structure */
  682         njsc32_init_targets(sc);
  683 
  684         /* initialize hardware */
  685         njsc32_init(sc, cold);
  686 
  687         /* setup adapter */
  688         sc->sc_adapter.adapt_dev = &sc->sc_dev;
  689         sc->sc_adapter.adapt_nchannels = 1;
  690         sc->sc_adapter.adapt_request = njsc32_scsipi_request;
  691         sc->sc_adapter.adapt_minphys = njsc32_scsipi_minphys;
  692         sc->sc_adapter.adapt_ioctl = njsc32_scsipi_ioctl;
  693 
  694         sc->sc_adapter.adapt_max_periph = sc->sc_adapter.adapt_openings =
  695             sc->sc_ncmd;
  696 
  697         /* setup channel */
  698         sc->sc_channel.chan_adapter = &sc->sc_adapter;
  699         sc->sc_channel.chan_bustype = &scsi_bustype;
  700         sc->sc_channel.chan_channel = 0;
  701         sc->sc_channel.chan_ntargets = NJSC32_NTARGET;
  702         sc->sc_channel.chan_nluns = NJSC32_NLU;
  703         sc->sc_channel.chan_id = NJSC32_INITIATOR_ID;
  704 
  705         sc->sc_scsi = config_found(&sc->sc_dev, &sc->sc_channel, scsiprint);
  706 }
  707 
  708 int
  709 njsc32_detach(struct njsc32_softc *sc, int flags)
  710 {
  711         int rv = 0;
  712         int i, s;
  713         struct njsc32_cmd *cmd;
  714 
  715         s = splbio();
  716 
  717         /* clear running/disconnected commands */
  718         njsc32_clear_cmds(sc, XS_DRIVER_STUFFUP);
  719 
  720         sc->sc_stat = NJSC32_STAT_DETACH;
  721 
  722         /* clear pending commands */
  723         while ((cmd = TAILQ_FIRST(&sc->sc_reqcmd)) != NULL) {
  724                 TAILQ_REMOVE(&sc->sc_reqcmd, cmd, c_q);
  725                 njsc32_end_cmd(sc, cmd, XS_RESET);
  726         }
  727 
  728         if (sc->sc_scsi != NULL)
  729                 rv = config_detach(sc->sc_scsi, flags);
  730 
  731         splx(s);
  732 
  733         /* free DMA resource */
  734         if (sc->sc_flags & NJSC32_CMDPG_MAPPED) {
  735                 for (i = 0; i < sc->sc_ncmd; i++) {
  736                         cmd = &sc->sc_cmds[i];
  737                         if (cmd->c_flags & NJSC32_CMD_DMA_MAPPED)
  738                                 bus_dmamap_unload(sc->sc_dmat,
  739                                     cmd->c_dmamap_xfer);
  740                         bus_dmamap_destroy(sc->sc_dmat, cmd->c_dmamap_xfer);
  741                 }
  742 
  743                 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap_cmdpg);
  744                 bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap_cmdpg);
  745                 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_cmdpg,
  746                     sizeof(struct njsc32_dma_page));
  747                 bus_dmamem_free(sc->sc_dmat, &sc->sc_cmdpg_seg,
  748                     sc->sc_cmdpg_nsegs);
  749         }
  750 
  751         return 0;
  752 }
  753 
  754 static __inline void
  755 njsc32_cmd_init(struct njsc32_cmd *cmd)
  756 {
  757 
  758         cmd->c_flags = 0;
  759 
  760         /* scatter/gather table */
  761         cmd->c_sgtdmaaddr = NJSC32_CMD_DMAADDR_SGT(cmd, 0);
  762         cmd->c_sgoffset = 0;
  763         cmd->c_sgfixcnt = 0;
  764 
  765         /* data pointer */
  766         cmd->c_dp_cur = cmd->c_dp_saved = cmd->c_dp_max = 0;
  767 }
  768 
  769 static __inline void
  770 njsc32_init_msgout(struct njsc32_softc *sc)
  771 {
  772 
  773         sc->sc_msgoutlen = 0;
  774         sc->sc_msgoutidx = 0;
  775 }
  776 
  777 static void
  778 njsc32_add_msgout(struct njsc32_softc *sc, int byte)
  779 {
  780 
  781         if (sc->sc_msgoutlen >= NJSC32_MSGOUT_LEN) {
  782                 printf("njsc32_add_msgout: too many\n");
  783                 return;
  784         }
  785         sc->sc_msgout[sc->sc_msgoutlen++] = byte;
  786 }
  787 
  788 static u_int32_t
  789 njsc32_get_auto_msgout(struct njsc32_softc *sc)
  790 {
  791         u_int32_t val;
  792         u_int8_t *p;
  793 
  794         val = 0;
  795         p = sc->sc_msgout;
  796         switch (sc->sc_msgoutlen) {
  797                 /* 31-24 23-16 15-8 7 ... 1 0 */
  798         case 3: /* MSG3  MSG2  MSG1 V --- cnt */
  799                 val |= *p++ << NJSC32_MSGOUT_MSG1_SHIFT;
  800                 /* FALLTHROUGH */
  801 
  802         case 2: /* MSG2  MSG1  ---  V --- cnt */
  803                 val |= *p++ << NJSC32_MSGOUT_MSG2_SHIFT;
  804                 /* FALLTHROUGH */
  805 
  806         case 1: /* MSG1  ---   ---  V --- cnt */
  807                 val |= *p++ << NJSC32_MSGOUT_MSG3_SHIFT;
  808                 val |= NJSC32_MSGOUT_VALID | sc->sc_msgoutlen;
  809                 break;
  810 
  811         default:
  812                 break;
  813         }
  814         return val;
  815 }
  816 
  817 #ifdef NJSC32_DUALEDGE
  818 /* add Wide Data Transfer Request to the next Message Out */
  819 static void
  820 njsc32_msgout_wdtr(struct njsc32_softc *sc, int width)
  821 {
  822 
  823         njsc32_add_msgout(sc, MSG_EXTENDED);
  824         njsc32_add_msgout(sc, MSG_EXT_WDTR_LEN);
  825         njsc32_add_msgout(sc, MSG_EXT_WDTR);
  826         njsc32_add_msgout(sc, width);
  827 }
  828 #endif
  829 
  830 /* add Synchronous Data Transfer Request to the next Message Out */
  831 static void
  832 njsc32_msgout_sdtr(struct njsc32_softc *sc, int period, int offset)
  833 {
  834 
  835         njsc32_add_msgout(sc, MSG_EXTENDED);
  836         njsc32_add_msgout(sc, MSG_EXT_SDTR_LEN);
  837         njsc32_add_msgout(sc, MSG_EXT_SDTR);
  838         njsc32_add_msgout(sc, period);
  839         njsc32_add_msgout(sc, offset);
  840 }
  841 
  842 static void
  843 njsc32_negotiate_xfer(struct njsc32_softc *sc, struct njsc32_target *target)
  844 {
  845 
  846         /* initial negotiation state */
  847         if (target->t_state == NJSC32_TARST_INIT) {
  848 #ifdef NJSC32_DUALEDGE
  849                 if (target->t_flags & NJSC32_TARF_DE)
  850                         target->t_state = NJSC32_TARST_DE;
  851                 else
  852 #endif
  853                 if (target->t_flags & NJSC32_TARF_SYNC)
  854                         target->t_state = NJSC32_TARST_SDTR;
  855                 else
  856                         target->t_state = NJSC32_TARST_DONE;
  857         }
  858 
  859         switch (target->t_state) {
  860         default:
  861         case NJSC32_TARST_INIT:
  862 #ifdef DIAGNOSTIC
  863                 panic("njsc32_negotiate_xfer");
  864                 /* NOTREACHED */
  865 #endif
  866                 /* FALLTHROUGH */
  867         case NJSC32_TARST_DONE:
  868                 /* no more work */
  869                 break;
  870 
  871 #ifdef NJSC32_DUALEDGE
  872         case NJSC32_TARST_DE:
  873                 njsc32_msgout_wdtr(sc, 0xde /* XXX? */);
  874                 break;
  875 
  876         case NJSC32_TARST_WDTR:
  877                 njsc32_msgout_wdtr(sc, MSG_EXT_WDTR_BUS_8_BIT);
  878                 break;
  879 #endif
  880 
  881         case NJSC32_TARST_SDTR:
  882                 njsc32_msgout_sdtr(sc, sc->sc_synct[sc->sc_sync_max].sp_period,
  883                     NJSC32_SYNCOFFSET_MAX);
  884                 break;
  885 
  886         case NJSC32_TARST_ASYNC:
  887                 njsc32_msgout_sdtr(sc, NJSC32_SYNCPERIOD_ASYNC,
  888                     NJSC32_SYNCOFFSET_ASYNC);
  889                 break;
  890         }
  891 }
  892 
  893 /* turn LED on */
  894 static __inline void
  895 njsc32_led_on(struct njsc32_softc *sc)
  896 {
  897 
  898         njsc32_ireg_write_1(sc, NJSC32_IREG_EXT_PORT, NJSC32_EXTPORT_LED_ON);
  899 }
  900 
  901 /* turn LED off */
  902 static __inline void
  903 njsc32_led_off(struct njsc32_softc *sc)
  904 {
  905 
  906         njsc32_ireg_write_1(sc, NJSC32_IREG_EXT_PORT, NJSC32_EXTPORT_LED_OFF);
  907 }
  908 
  909 static void
  910 njsc32_arbitration_failed(struct njsc32_softc *sc)
  911 {
  912         struct njsc32_cmd *cmd;
  913 
  914         if ((cmd = sc->sc_curcmd) == NULL || sc->sc_stat != NJSC32_STAT_ARBIT)
  915                 return;
  916 
  917         if ((cmd->c_xs->xs_control & XS_CTL_POLL) == 0)
  918                 callout_stop(&cmd->c_xs->xs_callout);
  919 
  920         sc->sc_stat = NJSC32_STAT_IDLE;
  921         sc->sc_curcmd = NULL;
  922 
  923         /* the command is no longer active */
  924         if (--sc->sc_nusedcmds == 0)
  925                 njsc32_led_off(sc);
  926 }
  927 
  928 static __inline void
  929 njsc32_cmd_load(struct njsc32_softc *sc, struct njsc32_cmd *cmd)
  930 {
  931         struct njsc32_target *target;
  932         struct scsipi_xfer *xs;
  933         int i, control, lun;
  934         u_int32_t msgoutreg;
  935 #ifdef NJSC32_AUTOPARAM
  936         struct njsc32_autoparam *ap;
  937 #endif
  938 
  939         xs = cmd->c_xs;
  940 #ifdef NJSC32_AUTOPARAM
  941         ap = &sc->sc_cmdpg->dp_ap;
  942 #else
  943         /* reset CDB pointer */
  944         njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL, NJSC32_CMD_CLEAR_CDB_FIFO_PTR);
  945 #endif
  946 
  947         /* CDB */
  948         TPRINTC(cmd, ("njsc32_cmd_load: CDB"));
  949         for (i = 0; i < xs->cmdlen; i++) {
  950 #ifdef NJSC32_AUTOPARAM
  951                 ap->ap_cdb[i].cdb_data = ((u_int8_t *)xs->cmd)[i];
  952 #else
  953                 njsc32_write_1(sc, NJSC32_REG_COMMAND_DATA,
  954                     ((u_int8_t *)xs->cmd)[i]);
  955 #endif
  956                 TPRINTF((" %02x", ((u_int8_t *)cmd->c_xs->cmd)[i]));
  957         }
  958 #ifdef NJSC32_AUTOPARAM /* XXX needed? */
  959         for ( ; i < NJSC32_AUTOPARAM_CDBLEN; i++)
  960                 ap->ap_cdb[i].cdb_data = 0;
  961 #endif
  962 
  963         control = xs->xs_control;
  964 
  965         /*
  966          * Message Out
  967          */
  968         njsc32_init_msgout(sc);
  969 
  970         /* Identify */
  971         lun = xs->xs_periph->periph_lun;
  972         njsc32_add_msgout(sc, (control & XS_CTL_REQSENSE) ?
  973             MSG_IDENTIFY(lun, 0) : MSG_IDENTIFY(lun, 1));
  974 
  975         /* tagged queueing */
  976         if (control & XS_CTL_TAGMASK) {
  977                 njsc32_add_msgout(sc, xs->xs_tag_type);
  978                 njsc32_add_msgout(sc, xs->xs_tag_id);
  979                 TPRINTF((" (tag %#x %#x)\n", xs->xs_tag_type, xs->xs_tag_id));
  980         }
  981         TPRINTF(("\n"));
  982 
  983         target = cmd->c_target;
  984 
  985         /* transfer negotiation */
  986         if (control & XS_CTL_REQSENSE)
  987                 target->t_state = NJSC32_TARST_INIT;
  988         njsc32_negotiate_xfer(sc, target);
  989 
  990         msgoutreg = njsc32_get_auto_msgout(sc);
  991 
  992 #ifdef NJSC32_AUTOPARAM
  993         ap->ap_msgout = htole32(msgoutreg);
  994 
  995         ap->ap_sync     = target->t_sync;
  996         ap->ap_ackwidth = target->t_ackwidth;
  997         ap->ap_targetid = target->t_targetid;
  998         ap->ap_sample   = target->t_sample;
  999 
 1000         ap->ap_cmdctl = htole16(NJSC32_CMD_CLEAR_CDB_FIFO_PTR |
 1001             NJSC32_CMD_AUTO_COMMAND_PHASE |
 1002             NJSC32_CMD_AUTO_SCSI_START | NJSC32_CMD_AUTO_ATN |
 1003             NJSC32_CMD_AUTO_MSGIN_00_04 | NJSC32_CMD_AUTO_MSGIN_02);
 1004 #ifdef NJSC32_DUALEDGE
 1005         ap->ap_xferctl = htole16(cmd->c_xferctl | target->t_xferctl);
 1006 #else
 1007         ap->ap_xferctl = htole16(cmd->c_xferctl);
 1008 #endif
 1009         ap->ap_sgtdmaaddr = htole32(cmd->c_sgtdmaaddr);
 1010 
 1011         /* sync njsc32_autoparam */
 1012         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_cmdpg,
 1013             offsetof(struct njsc32_dma_page, dp_ap),    /* offset */
 1014             sizeof(struct njsc32_autoparam),
 1015             BUS_DMASYNC_PREWRITE);
 1016 
 1017         /* autoparam DMA address */
 1018         njsc32_write_4(sc, NJSC32_REG_SGT_ADR, sc->sc_ap_dma);
 1019 
 1020         /* start command (autoparam) */
 1021         njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL,
 1022             NJSC32_CMD_CLEAR_CDB_FIFO_PTR | NJSC32_CMD_AUTO_PARAMETER);
 1023 
 1024 #else   /* not NJSC32_AUTOPARAM */
 1025 
 1026         njsc32_write_4(sc, NJSC32_REG_SCSI_MSG_OUT, msgoutreg);
 1027 
 1028         /* load parameters */
 1029         njsc32_write_1(sc, NJSC32_REG_TARGET_ID, target->t_targetid);
 1030         njsc32_write_1(sc, NJSC32_REG_SYNC, target->t_sync);
 1031         njsc32_write_1(sc, NJSC32_REG_ACK_WIDTH, target->t_ackwidth);
 1032         njsc32_write_1(sc, NJSC32_REG_SREQ_SAMPLING, target->t_sample);
 1033         njsc32_write_4(sc, NJSC32_REG_SGT_ADR, cmd->c_sgtdmaaddr);
 1034 #ifdef NJSC32_DUALEDGE
 1035         njsc32_write_2(sc, NJSC32_REG_TRANSFER,
 1036             cmd->c_xferctl | target->t_xferctl);
 1037 #else
 1038         njsc32_write_2(sc, NJSC32_REG_TRANSFER, cmd->c_xferctl);
 1039 #endif
 1040         /* start AutoSCSI */
 1041         njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL,
 1042             NJSC32_CMD_CLEAR_CDB_FIFO_PTR | NJSC32_CMD_AUTO_COMMAND_PHASE |
 1043             NJSC32_CMD_AUTO_SCSI_START | NJSC32_CMD_AUTO_ATN |
 1044             NJSC32_CMD_AUTO_MSGIN_00_04 | NJSC32_CMD_AUTO_MSGIN_02);
 1045 #endif  /* not NJSC32_AUTOPARAM */
 1046 }
 1047 
 1048 /* Note: must be called at splbio() */
 1049 static void
 1050 njsc32_start(struct njsc32_softc *sc)
 1051 {
 1052         struct njsc32_cmd *cmd;
 1053 
 1054         /* get a command to issue */
 1055         TAILQ_FOREACH(cmd, &sc->sc_reqcmd, c_q) {
 1056                 if (cmd->c_lu->lu_cmd == NULL &&
 1057                     ((cmd->c_flags & NJSC32_CMD_TAGGED) ||
 1058                      TAILQ_EMPTY(&cmd->c_lu->lu_q)))
 1059                         break;  /* OK, the logical unit is free */
 1060         }
 1061         if (!cmd)
 1062                 goto out;       /* no work to do */
 1063 
 1064         /* request will always fail if not in bus free phase */
 1065         if (njsc32_read_1(sc, NJSC32_REG_SCSI_BUS_MONITOR) !=
 1066             NJSC32_BUSMON_BUSFREE)
 1067                 goto busy;
 1068 
 1069         /* clear parity error and enable parity detection */
 1070         njsc32_write_1(sc, NJSC32_REG_PARITY_CONTROL,
 1071             NJSC32_PARITYCTL_CHECK_ENABLE | NJSC32_PARITYCTL_CLEAR_ERROR);
 1072 
 1073         njsc32_cmd_load(sc, cmd);
 1074 
 1075         if (sc->sc_nusedcmds++ == 0)
 1076                 njsc32_led_on(sc);
 1077 
 1078         sc->sc_curcmd = cmd;
 1079         sc->sc_stat = NJSC32_STAT_ARBIT;
 1080 
 1081         if ((cmd->c_xs->xs_control & XS_CTL_POLL) == 0) {
 1082                 callout_reset(&cmd->c_xs->xs_callout,
 1083                     mstohz(cmd->c_xs->timeout),
 1084                     njsc32_cmdtimeout, cmd);
 1085         }
 1086 
 1087         return;
 1088 
 1089 busy:   /* XXX retry counter */
 1090         TPRINTF(("%s: njsc32_start: busy\n", sc->sc_dev.dv_xname));
 1091         njsc32_write_2(sc, NJSC32_REG_TIMER, NJSC32_ARBITRATION_RETRY_TIME);
 1092 out:    njsc32_write_2(sc, NJSC32_REG_TRANSFER, 0);
 1093 }
 1094 
 1095 static void
 1096 njsc32_run_xfer(struct njsc32_softc *sc, struct scsipi_xfer *xs)
 1097 {
 1098         struct scsipi_periph *periph;
 1099         int control;
 1100         int lun;
 1101         struct njsc32_cmd *cmd;
 1102         int s, i, error;
 1103 
 1104         periph = xs->xs_periph;
 1105         KASSERT((unsigned)periph->periph_target <= NJSC32_MAX_TARGET_ID);
 1106 
 1107         control = xs->xs_control;
 1108         lun = periph->periph_lun;
 1109 
 1110         /*
 1111          * get a free cmd
 1112          * (scsipi layer knows the number of cmds, so this shall never fail)
 1113          */
 1114         s = splbio();
 1115         cmd = TAILQ_FIRST(&sc->sc_freecmd);
 1116         KASSERT(cmd);
 1117         TAILQ_REMOVE(&sc->sc_freecmd, cmd, c_q);
 1118         splx(s);
 1119 
 1120         /*
 1121          * build a request
 1122          */
 1123         njsc32_cmd_init(cmd);
 1124         cmd->c_xs = xs;
 1125         cmd->c_target = &sc->sc_targets[periph->periph_target];
 1126         cmd->c_lu = &cmd->c_target->t_lus[lun];
 1127 
 1128         /* tagged queueing */
 1129         if (control & XS_CTL_TAGMASK) {
 1130                 cmd->c_flags |= NJSC32_CMD_TAGGED;
 1131                 if (control & XS_CTL_HEAD_TAG)
 1132                         cmd->c_flags |= NJSC32_CMD_TAGGED_HEAD;
 1133         }
 1134 
 1135         /* map DMA buffer */
 1136         cmd->c_datacnt = xs->datalen;
 1137         if (xs->datalen) {
 1138                 /* Is XS_CTL_DATA_UIO ever used anywhere? */
 1139                 KASSERT((control & XS_CTL_DATA_UIO) == 0);
 1140 
 1141                 error = bus_dmamap_load(sc->sc_dmat, cmd->c_dmamap_xfer,
 1142                     xs->data, xs->datalen, NULL,
 1143                     ((control & XS_CTL_NOSLEEP) ?
 1144                         BUS_DMA_NOWAIT : BUS_DMA_WAITOK) |
 1145                     BUS_DMA_STREAMING |
 1146                     ((control & XS_CTL_DATA_IN) ?
 1147                         BUS_DMA_READ : BUS_DMA_WRITE));
 1148 
 1149                 switch (error) {
 1150                 case 0:
 1151                         break;
 1152                 case ENOMEM:
 1153                 case EAGAIN:
 1154                         xs->error = XS_RESOURCE_SHORTAGE;
 1155                         goto map_failed;
 1156                 default:
 1157                         xs->error = XS_DRIVER_STUFFUP;
 1158                 map_failed:
 1159                         printf("%s: njsc32_run_xfer: map failed, error %d\n",
 1160                             sc->sc_dev.dv_xname, error);
 1161                         /* put it back to free command list */
 1162                         s = splbio();
 1163                         TAILQ_INSERT_HEAD(&sc->sc_freecmd, cmd, c_q);
 1164                         splx(s);
 1165                         /* abort this transfer */
 1166                         scsipi_done(xs);
 1167                         return;
 1168                 }
 1169 
 1170                 bus_dmamap_sync(sc->sc_dmat, cmd->c_dmamap_xfer,
 1171                     0, cmd->c_dmamap_xfer->dm_mapsize,
 1172                     (control & XS_CTL_DATA_IN) ?
 1173                         BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
 1174 
 1175                 for (i = 0; i < cmd->c_dmamap_xfer->dm_nsegs; i++) {
 1176                         cmd->c_sgt[i].sg_addr =
 1177                             htole32(cmd->c_dmamap_xfer->dm_segs[i].ds_addr);
 1178                         cmd->c_sgt[i].sg_len =
 1179                             htole32(cmd->c_dmamap_xfer->dm_segs[i].ds_len);
 1180                 }
 1181                 /* end mark */
 1182                 cmd->c_sgt[i - 1].sg_len |= htole32(NJSC32_SGT_ENDMARK);
 1183 
 1184                 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_cmdpg,
 1185                     (char *)cmd->c_sgt - (char *)sc->sc_cmdpg, /* offset */
 1186                     NJSC32_SIZE_SGT,
 1187                     BUS_DMASYNC_PREWRITE);
 1188 
 1189                 cmd->c_flags |= NJSC32_CMD_DMA_MAPPED;
 1190 
 1191                 /* enable transfer */
 1192                 cmd->c_xferctl =
 1193                     NJSC32_XFR_TRANSFER_GO | NJSC32_XFR_BM_START |
 1194                     NJSC32_XFR_ALL_COUNT_CLR;
 1195 
 1196                 /* XXX How can we specify the DMA direction? */
 1197 
 1198 #if 0   /* faster write mode? (doesn't work) */
 1199                 if ((control & XS_CTL_DATA_IN) == 0)
 1200                         cmd->c_xferctl |= NJSC32_XFR_ADVANCED_BM_WRITE;
 1201 #endif
 1202         } else {
 1203                 /* no data transfer */
 1204                 cmd->c_xferctl = 0;
 1205         }
 1206 
 1207         /* queue request */
 1208         s = splbio();
 1209         TAILQ_INSERT_TAIL(&sc->sc_reqcmd, cmd, c_q);
 1210 
 1211         /* start the controller if idle */
 1212         if (sc->sc_stat == NJSC32_STAT_IDLE)
 1213                 njsc32_start(sc);
 1214 
 1215         splx(s);
 1216 
 1217         if (control & XS_CTL_POLL) {
 1218                 /* wait for completion */
 1219                 /* XXX should handle timeout? */
 1220                 while ((xs->xs_status & XS_STS_DONE) == 0) {
 1221                         delay(1000);
 1222                         njsc32_intr(sc);
 1223                 }
 1224         }
 1225 }
 1226 
 1227 static void
 1228 njsc32_end_cmd(struct njsc32_softc *sc, struct njsc32_cmd *cmd,
 1229     scsipi_xfer_result_t result)
 1230 {
 1231         struct scsipi_xfer *xs;
 1232         int s;
 1233 #ifdef DIAGNOSTIC
 1234         struct njsc32_cmd *c;
 1235 #endif
 1236 
 1237         KASSERT(cmd);
 1238 
 1239 #ifdef DIAGNOSTIC
 1240         s = splbio();
 1241         TAILQ_FOREACH(c, &sc->sc_freecmd, c_q) {
 1242                 if (cmd == c)
 1243                         panic("njsc32_end_cmd: already in free list");
 1244         }
 1245         splx(s);
 1246 #endif
 1247         xs = cmd->c_xs;
 1248 
 1249         if (cmd->c_flags & NJSC32_CMD_DMA_MAPPED) {
 1250                 if (cmd->c_datacnt) {
 1251                         bus_dmamap_sync(sc->sc_dmat, cmd->c_dmamap_xfer,
 1252                             0, cmd->c_dmamap_xfer->dm_mapsize,
 1253                             (xs->xs_control & XS_CTL_DATA_IN) ?
 1254                                 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
 1255 
 1256                         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_cmdpg,
 1257                             (char *)cmd->c_sgt - (char *)sc->sc_cmdpg,
 1258                             NJSC32_SIZE_SGT, BUS_DMASYNC_POSTWRITE);
 1259                 }
 1260 
 1261                 bus_dmamap_unload(sc->sc_dmat, cmd->c_dmamap_xfer);
 1262                 cmd->c_flags &= ~NJSC32_CMD_DMA_MAPPED;
 1263         }
 1264 
 1265         s = splbio();
 1266         if ((xs->xs_control & XS_CTL_POLL) == 0)
 1267                 callout_stop(&xs->xs_callout);
 1268 
 1269         TAILQ_INSERT_HEAD(&sc->sc_freecmd, cmd, c_q);
 1270         splx(s);
 1271 
 1272         xs->error = result;
 1273         scsipi_done(xs);
 1274 
 1275         if (--sc->sc_nusedcmds == 0)
 1276                 njsc32_led_off(sc);
 1277 }
 1278 
 1279 /*
 1280  * request from scsipi layer
 1281  */
 1282 static void
 1283 njsc32_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
 1284     void *arg)
 1285 {
 1286         struct njsc32_softc *sc;
 1287         struct scsipi_xfer_mode *xm;
 1288         struct njsc32_target *target;
 1289 
 1290         sc = (void *)chan->chan_adapter->adapt_dev;
 1291 
 1292         switch (req) {
 1293         case ADAPTER_REQ_RUN_XFER:
 1294                 njsc32_run_xfer(sc, arg);
 1295                 break;
 1296 
 1297         case ADAPTER_REQ_GROW_RESOURCES:
 1298                 /* not supported */
 1299                 break;
 1300 
 1301         case ADAPTER_REQ_SET_XFER_MODE:
 1302                 xm = arg;
 1303                 target = &sc->sc_targets[xm->xm_target];
 1304 
 1305                 target->t_flags = 0;
 1306                 if (xm->xm_mode & PERIPH_CAP_TQING)
 1307                         target->t_flags |= NJSC32_TARF_TAG;
 1308                 if (xm->xm_mode & PERIPH_CAP_SYNC) {
 1309                         target->t_flags |= NJSC32_TARF_SYNC;
 1310 #ifdef NJSC32_DUALEDGE
 1311                         if (sc->sc_model & NJSC32_FLAG_DUALEDGE)
 1312                                 target->t_flags |= NJSC32_TARF_DE;
 1313 #endif
 1314                 }
 1315 #ifdef NJSC32_DUALEDGE
 1316                 target->t_xferctl = 0;
 1317 #endif
 1318                 target->t_state = NJSC32_TARST_INIT;
 1319                 njsc32_target_async(sc, target);
 1320 
 1321                 break;
 1322         default:
 1323                 break;
 1324         }
 1325 }
 1326 
 1327 static void
 1328 njsc32_scsipi_minphys(struct buf *bp)
 1329 {
 1330 
 1331         if (bp->b_bcount > NJSC32_MAX_XFER)
 1332                 bp->b_bcount = NJSC32_MAX_XFER;
 1333         minphys(bp);
 1334 }
 1335 
 1336 static void
 1337 njsc32_reset_bus(struct njsc32_softc *sc)
 1338 {
 1339         int s;
 1340 
 1341         DPRINTF(("%s: njsc32_reset_bus:\n", sc->sc_dev.dv_xname));
 1342 
 1343         /* SCSI bus reset */
 1344         njsc32_write_1(sc, NJSC32_REG_SCSI_BUS_CONTROL, NJSC32_SBCTL_RST);
 1345         delay(NJSC32_RESET_HOLD_TIME);
 1346         njsc32_write_1(sc, NJSC32_REG_SCSI_BUS_CONTROL, 0);
 1347 
 1348         /* clear transfer */
 1349         s = splbio();
 1350         njsc32_reset_detected(sc);
 1351         splx(s);
 1352 }
 1353 
 1354 /*
 1355  * clear running/disconnected commands
 1356  */
 1357 static void
 1358 njsc32_clear_cmds(struct njsc32_softc *sc, scsipi_xfer_result_t cmdresult)
 1359 {
 1360         struct njsc32_cmd *cmd;
 1361         int id, lun;
 1362         struct njsc32_lu *lu;
 1363 
 1364         njsc32_arbitration_failed(sc);
 1365 
 1366         /* clear current transfer */
 1367         if ((cmd = sc->sc_curcmd) != NULL) {
 1368                 sc->sc_curcmd = NULL;
 1369                 njsc32_end_cmd(sc, cmd, cmdresult);
 1370         }
 1371 
 1372         /* clear disconnected transfers */
 1373         for (id = 0; id <= NJSC32_MAX_TARGET_ID; id++) {
 1374                 for (lun = 0; lun < NJSC32_NLU; lun++) {
 1375                         lu = &sc->sc_targets[id].t_lus[lun];
 1376 
 1377                         if ((cmd = lu->lu_cmd) != NULL) {
 1378                                 lu->lu_cmd = NULL;
 1379                                 njsc32_end_cmd(sc, cmd, cmdresult);
 1380                         }
 1381                         while ((cmd = TAILQ_FIRST(&lu->lu_q)) != NULL) {
 1382                                 TAILQ_REMOVE(&lu->lu_q, cmd, c_q);
 1383                                 njsc32_end_cmd(sc, cmd, cmdresult);
 1384                         }
 1385                 }
 1386         }
 1387 }
 1388 
 1389 static void
 1390 njsc32_reset_detected(struct njsc32_softc *sc)
 1391 {
 1392 
 1393         njsc32_clear_cmds(sc, XS_RESET);
 1394         njsc32_init_targets(sc);
 1395         sc->sc_stat = NJSC32_STAT_IDLE;
 1396         KASSERT(sc->sc_nusedcmds == 0);
 1397         scsipi_async_event(&sc->sc_channel, ASYNC_EVENT_RESET, NULL);
 1398 }
 1399 
 1400 static int
 1401 njsc32_scsipi_ioctl(struct scsipi_channel *chan, u_long cmd, caddr_t addr,
 1402     int flag, struct proc *p)
 1403 {
 1404         struct njsc32_softc *sc = (void *)chan->chan_adapter->adapt_dev;
 1405 
 1406         switch (cmd) {
 1407         case SCBUSIORESET:
 1408                 njsc32_init(sc, 0);
 1409                 return 0;
 1410         default:
 1411                 break;
 1412         }
 1413 
 1414         return ENOTTY;
 1415 }
 1416 
 1417 /*
 1418  * set current data pointer
 1419  */
 1420 static __inline void
 1421 njsc32_set_cur_ptr(struct njsc32_cmd *cmd, u_int32_t pos)
 1422 {
 1423 
 1424         /* new current data pointer */
 1425         cmd->c_dp_cur = pos;
 1426 
 1427         /* update number of bytes transferred */
 1428         if (pos > cmd->c_dp_max)
 1429                 cmd->c_dp_max = pos;
 1430 }
 1431 
 1432 /*
 1433  * set data pointer for the next transfer
 1434  */
 1435 static void
 1436 njsc32_set_ptr(struct njsc32_softc *sc, struct njsc32_cmd *cmd, u_int32_t pos)
 1437 {
 1438         struct njsc32_sgtable *sg;
 1439         unsigned sgte;
 1440         u_int32_t len;
 1441 
 1442         /* set current pointer */
 1443         njsc32_set_cur_ptr(cmd, pos);
 1444 
 1445         /* undo previous fix if any */
 1446         if (cmd->c_sgfixcnt != 0) {
 1447                 sg = &cmd->c_sgt[cmd->c_sgoffset];
 1448                 sg->sg_addr = htole32(le32toh(sg->sg_addr) - cmd->c_sgfixcnt);
 1449                 sg->sg_len = htole32(le32toh(sg->sg_len) + cmd->c_sgfixcnt);
 1450                 cmd->c_sgfixcnt = 0;
 1451         }
 1452 
 1453         if (pos >= cmd->c_datacnt) {
 1454                 /* transfer done */
 1455 #if 1 /*def DIAGNOSTIC*/
 1456                 if (pos > cmd->c_datacnt)
 1457                         printf("%s: pos %u too large\n",
 1458                             sc->sc_dev.dv_xname, pos - cmd->c_datacnt);
 1459 #endif
 1460                 cmd->c_xferctl = 0;     /* XXX correct? */
 1461 
 1462                 return;
 1463         }
 1464 
 1465         for (sgte = 0, sg = cmd->c_sgt;
 1466             sgte < NJSC32_NUM_SG && pos > 0; sgte++, sg++) {
 1467                 len = le32toh(sg->sg_len) & ~NJSC32_SGT_ENDMARK;
 1468                 if (pos < len) {
 1469                         sg->sg_addr = htole32(le32toh(sg->sg_addr) + pos);
 1470                         sg->sg_len = htole32(le32toh(sg->sg_len) - pos);
 1471                         cmd->c_sgfixcnt = pos;
 1472                         break;
 1473                 }
 1474                 pos -= len;
 1475 #ifdef DIAGNOSTIC
 1476                 if (sg->sg_len & htole32(NJSC32_SGT_ENDMARK)) {
 1477                         panic("njsc32_set_ptr: bad pos");
 1478                 }
 1479 #endif
 1480         }
 1481 #ifdef DIAGNOSTIC
 1482         if (sgte >= NJSC32_NUM_SG)
 1483                 panic("njsc32_set_ptr: bad sg");
 1484 #endif
 1485         if (cmd->c_sgoffset != sgte) {
 1486                 cmd->c_sgoffset = sgte;
 1487                 cmd->c_sgtdmaaddr = NJSC32_CMD_DMAADDR_SGT(cmd, sgte);
 1488         }
 1489 
 1490         /* XXX overkill */
 1491         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_cmdpg,
 1492             (char *)cmd->c_sgt - (char *)sc->sc_cmdpg,  /* offset */
 1493             NJSC32_SIZE_SGT,
 1494             BUS_DMASYNC_PREWRITE);
 1495 }
 1496 
 1497 /*
 1498  * save data pointer
 1499  */
 1500 static __inline void
 1501 njsc32_save_ptr(struct njsc32_cmd *cmd)
 1502 {
 1503 
 1504         cmd->c_dp_saved = cmd->c_dp_cur;
 1505 }
 1506 
 1507 static void
 1508 njsc32_assert_ack(struct njsc32_softc *sc)
 1509 {
 1510         u_int8_t reg;
 1511 
 1512         reg = njsc32_read_1(sc, NJSC32_REG_SCSI_BUS_CONTROL);
 1513         reg |= NJSC32_SBCTL_ACK | NJSC32_SBCTL_ACK_ENABLE;
 1514 #if 0   /* needed? */
 1515         reg |= NJSC32_SBCTL_AUTODIRECTION;
 1516 #endif
 1517         njsc32_write_1(sc, NJSC32_REG_SCSI_BUS_CONTROL, reg);
 1518 }
 1519 
 1520 static void
 1521 njsc32_negate_ack(struct njsc32_softc *sc)
 1522 {
 1523         u_int8_t reg;
 1524 
 1525         reg = njsc32_read_1(sc, NJSC32_REG_SCSI_BUS_CONTROL);
 1526 #if 0   /* needed? */
 1527         reg |= NJSC32_SBCTL_ACK_ENABLE;
 1528         reg |= NJSC32_SBCTL_AUTODIRECTION;
 1529 #endif
 1530         reg &= ~NJSC32_SBCTL_ACK;
 1531         njsc32_write_1(sc, NJSC32_REG_SCSI_BUS_CONTROL, reg);
 1532 }
 1533 
 1534 static void
 1535 njsc32_wait_req_negate(struct njsc32_softc *sc)
 1536 {
 1537         int cnt;
 1538 
 1539         for (cnt = 0; cnt < NJSC32_REQ_TIMEOUT; cnt++) {
 1540                 if ((njsc32_read_1(sc, NJSC32_REG_SCSI_BUS_MONITOR) &
 1541                     NJSC32_BUSMON_REQ) == 0)
 1542                         return;
 1543                 delay(1);
 1544         }
 1545         printf("%s: njsc32_wait_req_negate: timed out\n", sc->sc_dev.dv_xname);
 1546 }
 1547 
 1548 static void
 1549 njsc32_reconnect(struct njsc32_softc *sc, struct njsc32_cmd *cmd)
 1550 {
 1551         struct scsipi_xfer *xs;
 1552 
 1553         xs = cmd->c_xs;
 1554         if ((xs->xs_control & XS_CTL_POLL) == 0) {
 1555                 callout_stop(&xs->xs_callout);
 1556                 callout_reset(&xs->xs_callout,
 1557                     mstohz(xs->timeout),
 1558                     njsc32_cmdtimeout, cmd);
 1559         }
 1560 
 1561         /* Reconnection implies Restore Pointers */
 1562         njsc32_set_ptr(sc, cmd, cmd->c_dp_saved);
 1563 }
 1564 
 1565 static enum njsc32_reselstat
 1566 njsc32_resel_identify(struct njsc32_softc *sc, int lun,
 1567     struct njsc32_cmd **pcmd)
 1568 {
 1569         int targetid;
 1570         struct njsc32_lu *plu;
 1571         struct njsc32_cmd *cmd;
 1572 
 1573         switch (sc->sc_stat) {
 1574         case NJSC32_STAT_RESEL:
 1575                 break;  /* OK */
 1576 
 1577         case NJSC32_STAT_RESEL_LUN:
 1578         case NJSC32_STAT_RECONNECT:
 1579                 /*
 1580                  * accept and ignore if the LUN is the same as the current one,
 1581                  * reject otherwise.
 1582                  */
 1583                 return sc->sc_resellun == lun ?
 1584                     NJSC32_RESEL_THROUGH : NJSC32_RESEL_ERROR;
 1585 
 1586         default:
 1587                 printf("%s: njsc32_resel_identify: not in reselection\n",
 1588                     sc->sc_dev.dv_xname);
 1589                 return NJSC32_RESEL_ERROR;
 1590         }
 1591 
 1592         targetid = sc->sc_reselid;
 1593         TPRINTF(("%s: njsc32_resel_identify: reselection lun %d\n",
 1594             sc->sc_dev.dv_xname, lun));
 1595 
 1596         if (targetid > NJSC32_MAX_TARGET_ID || lun >= NJSC32_NLU)
 1597                 return NJSC32_RESEL_ERROR;
 1598 
 1599         sc->sc_resellun = lun;
 1600         plu = &sc->sc_targets[targetid].t_lus[lun];
 1601 
 1602         if ((cmd = plu->lu_cmd) != NULL) {
 1603                 sc->sc_stat = NJSC32_STAT_RECONNECT;
 1604                 plu->lu_cmd = NULL;
 1605                 *pcmd = cmd;
 1606                 TPRINTC(cmd, ("njsc32_resel_identify: I_T_L nexus\n"));
 1607                 njsc32_reconnect(sc, cmd);
 1608                 return NJSC32_RESEL_COMPLETE;
 1609         } else if (!TAILQ_EMPTY(&plu->lu_q)) {
 1610                 /* wait for tag */
 1611                 sc->sc_stat = NJSC32_STAT_RESEL_LUN;
 1612                 return NJSC32_RESEL_THROUGH;
 1613         }
 1614 
 1615         /* no disconnected commands */
 1616         return NJSC32_RESEL_ERROR;
 1617 }
 1618 
 1619 static enum njsc32_reselstat
 1620 njsc32_resel_tag(struct njsc32_softc *sc, int tag, struct njsc32_cmd **pcmd)
 1621 {
 1622         struct njsc32_cmd_head *head;
 1623         struct njsc32_cmd *cmd;
 1624 
 1625         TPRINTF(("%s: njsc32_resel_tag: reselection tag %d\n",
 1626             sc->sc_dev.dv_xname, tag));
 1627         if (sc->sc_stat != NJSC32_STAT_RESEL_LUN)
 1628                 return NJSC32_RESEL_ERROR;
 1629 
 1630         head = &sc->sc_targets[sc->sc_reselid].t_lus[sc->sc_resellun].lu_q;
 1631 
 1632         /* XXX slow? */
 1633         /* search for the command of the tag */
 1634         TAILQ_FOREACH(cmd, head, c_q) {
 1635                 if (cmd->c_xs->xs_tag_id == tag) {
 1636                         sc->sc_stat = NJSC32_STAT_RECONNECT;
 1637                         TAILQ_REMOVE(head, cmd, c_q);
 1638                         *pcmd = cmd;
 1639                         TPRINTC(cmd, ("njsc32_resel_tag: I_T_L_Q nexus\n"));
 1640                         njsc32_reconnect(sc, cmd);
 1641                         return NJSC32_RESEL_COMPLETE;
 1642                 }
 1643         }
 1644 
 1645         /* no disconnected commands */
 1646         return NJSC32_RESEL_ERROR;
 1647 }
 1648 
 1649 /*
 1650  * Reload parameters and restart AutoSCSI.
 1651  *
 1652  * XXX autoparam doesn't work as expected and we can't use it here.
 1653  */
 1654 static void
 1655 njsc32_cmd_reload(struct njsc32_softc *sc, struct njsc32_cmd *cmd, int cctl)
 1656 {
 1657         struct njsc32_target *target;
 1658 
 1659         target = cmd->c_target;
 1660 
 1661         /* clear parity error and enable parity detection */
 1662         njsc32_write_1(sc, NJSC32_REG_PARITY_CONTROL,
 1663             NJSC32_PARITYCTL_CHECK_ENABLE | NJSC32_PARITYCTL_CLEAR_ERROR);
 1664 
 1665         /* load parameters */
 1666         njsc32_write_1(sc, NJSC32_REG_SYNC, target->t_sync);
 1667         njsc32_write_1(sc, NJSC32_REG_ACK_WIDTH, target->t_ackwidth);
 1668         njsc32_write_1(sc, NJSC32_REG_SREQ_SAMPLING, target->t_sample);
 1669         njsc32_write_4(sc, NJSC32_REG_SGT_ADR, cmd->c_sgtdmaaddr);
 1670 #ifdef NJSC32_DUALEDGE
 1671         njsc32_write_2(sc, NJSC32_REG_TRANSFER,
 1672             cmd->c_xferctl | target->t_xferctl);
 1673 #else
 1674         njsc32_write_2(sc, NJSC32_REG_TRANSFER, cmd->c_xferctl);
 1675 #endif
 1676         /* start AutoSCSI */
 1677         njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL, cctl);
 1678 
 1679         sc->sc_curcmd = cmd;
 1680 }
 1681 
 1682 static void
 1683 njsc32_update_xfer_mode(struct njsc32_softc *sc, struct njsc32_target *target)
 1684 {
 1685         struct scsipi_xfer_mode xm;
 1686 
 1687         xm.xm_target = target - sc->sc_targets; /* target ID */
 1688         xm.xm_mode = 0;
 1689         xm.xm_period = target->t_syncperiod;
 1690         xm.xm_offset = target->t_syncoffset;
 1691         if (xm.xm_offset != 0)
 1692                 xm.xm_mode |= PERIPH_CAP_SYNC;
 1693         if (target->t_flags & NJSC32_TARF_TAG)
 1694                 xm.xm_mode |= PERIPH_CAP_TQING;
 1695 
 1696         scsipi_async_event(&sc->sc_channel, ASYNC_EVENT_XFER_MODE, &xm);
 1697 }
 1698 
 1699 static void
 1700 njsc32_msgin(struct njsc32_softc *sc)
 1701 {
 1702         u_int8_t msg0, msg;
 1703         int msgcnt;
 1704         struct njsc32_cmd *cmd;
 1705         enum njsc32_reselstat rstat;
 1706         int cctl = 0;
 1707         u_int32_t ptr;  /* unsigned type ensures 2-complement calculation */
 1708         u_int32_t msgout = 0;
 1709         boolean_t reload_params = FALSE;
 1710         struct njsc32_target *target;
 1711         int idx, period, offset;
 1712 
 1713         /*
 1714          * we are in Message In, so the previous Message Out should have
 1715          * been done.
 1716          */
 1717         njsc32_init_msgout(sc);
 1718 
 1719         /* get a byte of Message In */
 1720         msg = njsc32_read_1(sc, NJSC32_REG_DATA_IN);
 1721         TPRINTF(("%s: njsc32_msgin: got %#x\n", sc->sc_dev.dv_xname, msg));
 1722         if ((msgcnt = sc->sc_msgincnt) < NJSC32_MSGIN_LEN)
 1723                 sc->sc_msginbuf[sc->sc_msgincnt] = msg;
 1724 
 1725         njsc32_assert_ack(sc);
 1726 
 1727         msg0 = sc->sc_msginbuf[0];
 1728         cmd = sc->sc_curcmd;
 1729 
 1730         /* check for parity error */
 1731         if (njsc32_read_1(sc, NJSC32_REG_PARITY_STATUS) &
 1732             NJSC32_PARITYSTATUS_ERROR_LSB) {
 1733 
 1734                 printf("%s: msgin: parity error\n", sc->sc_dev.dv_xname);
 1735 
 1736                 /* clear parity error */
 1737                 njsc32_write_1(sc, NJSC32_REG_PARITY_CONTROL,
 1738                     NJSC32_PARITYCTL_CHECK_ENABLE |
 1739                     NJSC32_PARITYCTL_CLEAR_ERROR);
 1740 
 1741                 /* respond as Message Parity Error */
 1742                 njsc32_add_msgout(sc, MSG_PARITY_ERROR);
 1743 
 1744                 /* clear Message In */
 1745                 sc->sc_msgincnt = 0;
 1746                 goto reply;
 1747         }
 1748 
 1749 #define WAITNEXTMSG     do { sc->sc_msgincnt++; goto restart; } while (0)
 1750 #define MSGCOMPLETE     do { sc->sc_msgincnt = 0; goto restart; } while (0)
 1751         if (MSG_ISIDENTIFY(msg0)) {
 1752                 /*
 1753                  * Got Identify message from target.
 1754                  */
 1755                 if ((msg0 & ~MSG_IDENTIFY_LUNMASK) != MSG_IDENTIFYFLAG ||
 1756                     (rstat = njsc32_resel_identify(sc, msg0 &
 1757                         MSG_IDENTIFY_LUNMASK, &cmd)) == NJSC32_RESEL_ERROR) {
 1758                         /*
 1759                          * invalid Identify -> Reject
 1760                          */
 1761                         goto reject;
 1762                 }
 1763                 if (rstat == NJSC32_RESEL_COMPLETE)
 1764                         reload_params = TRUE;
 1765                 MSGCOMPLETE;
 1766         }
 1767 
 1768         if (msg0 == MSG_SIMPLE_Q_TAG) {
 1769                 if (msgcnt == 0)
 1770                         WAITNEXTMSG;
 1771 
 1772                 /* got whole message */
 1773                 sc->sc_msgincnt = 0;
 1774 
 1775                 if ((rstat = njsc32_resel_tag(sc, sc->sc_msginbuf[1], &cmd))
 1776                     == NJSC32_RESEL_ERROR) {
 1777                         /*
 1778                          * invalid Simple Queue Tag -> Abort Tag
 1779                          */
 1780                         printf("%s: msgin: invalid tag\n", sc->sc_dev.dv_xname);
 1781                         njsc32_add_msgout(sc, MSG_ABORT_TAG);
 1782                         goto reply;
 1783                 }
 1784                 if (rstat == NJSC32_RESEL_COMPLETE)
 1785                         reload_params = TRUE;
 1786                 MSGCOMPLETE;
 1787         }
 1788 
 1789         /* I_T_L or I_T_L_Q nexus should be established now */
 1790         if (cmd == NULL) {
 1791                 printf("%s: msgin %#x without nexus -- sending abort\n",
 1792                     sc->sc_dev.dv_xname, msg0);
 1793                 njsc32_add_msgout(sc, MSG_ABORT);
 1794                 goto reply;
 1795         }
 1796 
 1797         /*
 1798          * extended message
 1799          * 0x01 <length (0 stands for 256)> <length bytes>
 1800          *                                 (<code> [<parameter> ...])
 1801          */
 1802 #define EXTLENOFF       1
 1803 #define EXTCODEOFF      2
 1804         if (msg0 == MSG_EXTENDED) {
 1805                 if (msgcnt < EXTLENOFF ||
 1806                     msgcnt < EXTLENOFF + 1 +
 1807                     (u_int8_t)(sc->sc_msginbuf[EXTLENOFF] - 1))
 1808                         WAITNEXTMSG;
 1809 
 1810                 /* got whole message */
 1811                 sc->sc_msgincnt = 0;
 1812 
 1813                 switch (sc->sc_msginbuf[EXTCODEOFF]) {
 1814                 case 0: /* Modify Data Pointer */
 1815                         if (msgcnt != 5 + EXTCODEOFF - 1)
 1816                                 break;
 1817                         /*
 1818                          * parameter is 32bit big-endian signed (2-complement)
 1819                          * value
 1820                          */
 1821                         ptr = (sc->sc_msginbuf[EXTCODEOFF + 1] << 24) |
 1822                               (sc->sc_msginbuf[EXTCODEOFF + 2] << 16) |
 1823                               (sc->sc_msginbuf[EXTCODEOFF + 3] << 8) |
 1824                               sc->sc_msginbuf[EXTCODEOFF + 4];
 1825 
 1826                         /* new pointer */
 1827                         ptr += cmd->c_dp_cur;   /* ignore overflow */
 1828 
 1829                         /* reject if ptr is not in data buffer */
 1830                         if (ptr > cmd->c_datacnt)
 1831                                 break;
 1832 
 1833                         njsc32_set_ptr(sc, cmd, ptr);
 1834                         goto restart;
 1835 
 1836                 case MSG_EXT_SDTR:      /* Synchronous Data Transfer Request */
 1837                         DPRINTC(cmd, ("SDTR %#x %#x\n",
 1838                             sc->sc_msginbuf[EXTCODEOFF + 1],
 1839                             sc->sc_msginbuf[EXTCODEOFF + 2]));
 1840                         if (msgcnt != MSG_EXT_SDTR_LEN + EXTCODEOFF-1)
 1841                                 break;  /* reject */
 1842 
 1843                         target = cmd->c_target;
 1844 
 1845                         /* lookup sync period parameters */
 1846                         period = sc->sc_msginbuf[EXTCODEOFF + 1];
 1847                         for (idx = sc->sc_sync_max; idx < NJSC32_NSYNCT; idx++)
 1848                                 if (sc->sc_synct[idx].sp_period >= period) {
 1849                                         period = sc->sc_synct[idx].sp_period;
 1850                                         break;
 1851                                 }
 1852                         if (idx >= NJSC32_NSYNCT) {
 1853                                 /*
 1854                                  * We can't meet the timing condition that
 1855                                  * the target requests -- use async.
 1856                                  */
 1857                                 njsc32_target_async(sc, target);
 1858                                 njsc32_update_xfer_mode(sc, target);
 1859                                 if (target->t_state == NJSC32_TARST_SDTR) {
 1860                                         /*
 1861                                          * We started SDTR exchange -- start
 1862                                          * negotiation again and request async.
 1863                                          */
 1864                                         target->t_state = NJSC32_TARST_ASYNC;
 1865                                         njsc32_negotiate_xfer(sc, target);
 1866                                         goto reply;
 1867                                 } else {
 1868                                         /*
 1869                                          * The target started SDTR exchange
 1870                                          * -- just reject and fallback
 1871                                          * to async.
 1872                                          */
 1873                                         goto reject;
 1874                                 }
 1875                         }
 1876 
 1877                         /* check sync offset */
 1878                         offset = sc->sc_msginbuf[EXTCODEOFF + 2];
 1879                         if (offset > NJSC32_SYNCOFFSET_MAX) {
 1880                                 if (target->t_state == NJSC32_TARST_SDTR) {
 1881                                         printf("%s: wrong sync offset: %d\n",
 1882                                             cmd->c_xs->xs_periph->periph_dev->dv_xname,
 1883                                             offset);
 1884                                         /* XXX what to do? */
 1885                                 }
 1886                                 offset = NJSC32_SYNCOFFSET_MAX;
 1887                         }
 1888 
 1889                         target->t_ackwidth = sc->sc_synct[idx].sp_ackw;
 1890                         target->t_sample   = sc->sc_synct[idx].sp_sample;
 1891                         target->t_syncperiod = period;
 1892                         target->t_syncoffset = offset;
 1893                         target->t_sync = NJSC32_SYNC_VAL(idx, offset);
 1894                         njsc32_update_xfer_mode(sc, target);
 1895 
 1896                         if (target->t_state == NJSC32_TARST_SDTR) {
 1897                                 target->t_state = NJSC32_TARST_DONE;
 1898                         } else {
 1899                                 njsc32_msgout_sdtr(sc, period, offset);
 1900                                 goto reply;
 1901                         }
 1902                         goto restart;
 1903 
 1904                 case MSG_EXT_WDTR:      /* Wide Data Transfer Request */
 1905                         DPRINTC(cmd,
 1906                             ("WDTR %#x\n", sc->sc_msginbuf[EXTCODEOFF + 1]));
 1907 #ifdef NJSC32_DUALEDGE
 1908                         if (msgcnt != MSG_EXT_WDTR_LEN + EXTCODEOFF-1)
 1909                                 break;  /* reject */
 1910 
 1911                         /*
 1912                          * T->I of this message is not used for
 1913                          * DualEdge negotiation, so the device
 1914                          * must not be a DualEdge device.
 1915                          *
 1916                          * XXX correct?
 1917                          */
 1918                         target = cmd->c_target;
 1919                         target->t_xferctl = 0;
 1920 
 1921                         switch (target->t_state) {
 1922                         case NJSC32_TARST_DE:
 1923                                 if (sc->sc_msginbuf[EXTCODEOFF + 1] !=
 1924                                     MSG_EXT_WDTR_BUS_8_BIT) {
 1925                                         /*
 1926                                          * Oops, we got unexpected WDTR.
 1927                                          * Negotiate for 8bit.
 1928                                          */
 1929                                         target->t_state = NJSC32_TARST_WDTR;
 1930                                 } else {
 1931                                         target->t_state = NJSC32_TARST_SDTR;
 1932                                 }
 1933                                 njsc32_negotiate_xfer(sc, target);
 1934                                 goto reply;
 1935 
 1936                         case NJSC32_TARST_WDTR:
 1937                                 if (sc->sc_msginbuf[EXTCODEOFF + 1] !=
 1938                                     MSG_EXT_WDTR_BUS_8_BIT) {
 1939                                         printf("%s: unexpected transfer width: %#x\n",
 1940                                             cmd->c_xs->xs_periph->periph_dev->dv_xname,
 1941                                             sc->sc_msginbuf[EXTCODEOFF + 1]);
 1942                                         /* XXX what to do? */
 1943                                 }
 1944                                 target->t_state = NJSC32_TARST_SDTR;
 1945                                 njsc32_negotiate_xfer(sc, target);
 1946                                 goto reply;
 1947 
 1948                         default:
 1949                                 /* the target started WDTR exchange */
 1950                                 DPRINTC(cmd, ("WDTR from target\n"));
 1951 
 1952                                 target->t_state = NJSC32_TARST_SDTR;
 1953                                 njsc32_target_async(sc, target);
 1954 
 1955                                 break;  /* reject the WDTR (8bit transfer) */
 1956                         }
 1957 #endif  /* NJSC32_DUALEDGE */
 1958                         break;  /* reject */
 1959                 }
 1960                 DPRINTC(cmd, ("njsc32_msgin: reject ext msg %#x msgincnt %d\n",
 1961                     sc->sc_msginbuf[EXTCODEOFF], msgcnt));
 1962                 goto reject;
 1963         }
 1964 
 1965         /* 2byte messages */
 1966         if (MSG_IS2BYTE(msg0)) {
 1967                 if (msgcnt == 0)
 1968                         WAITNEXTMSG;
 1969 
 1970                 /* got whole message */
 1971                 sc->sc_msgincnt = 0;
 1972         }
 1973 
 1974         switch (msg0) {
 1975         case MSG_CMDCOMPLETE:           /* 0x00 */
 1976         case MSG_SAVEDATAPOINTER:       /* 0x02 */
 1977         case MSG_DISCONNECT:            /* 0x04 */
 1978                 /* handled by AutoSCSI */
 1979                 PRINTC(cmd, ("msgin: unexpected msg: %#x\n", msg0));
 1980                 break;
 1981 
 1982         case MSG_RESTOREPOINTERS:       /* 0x03 */
 1983                 /* restore data pointer to what was saved */
 1984                 DPRINTC(cmd, ("njsc32_msgin: Restore Pointers\n"));
 1985                 njsc32_set_ptr(sc, cmd, cmd->c_dp_saved);
 1986                 reload_params = TRUE;
 1987                 MSGCOMPLETE;
 1988                 /* NOTREACHED */
 1989                 break;
 1990 
 1991 #if 0   /* handled above */
 1992         case MSG_EXTENDED:              /* 0x01 */
 1993 #endif
 1994         case MSG_MESSAGE_REJECT:        /* 0x07 */
 1995                 target = cmd->c_target;
 1996                 DPRINTC(cmd, ("Reject tarst %d\n", target->t_state));
 1997                 switch (target->t_state) {
 1998 #ifdef NJSC32_DUALEDGE
 1999                 case NJSC32_TARST_WDTR:
 2000                 case NJSC32_TARST_DE:
 2001                         target->t_xferctl = 0;
 2002                         target->t_state = NJSC32_TARST_SDTR;
 2003                         njsc32_negotiate_xfer(sc, target);
 2004                         goto reply;
 2005 #endif
 2006                 case NJSC32_TARST_SDTR:
 2007                 case NJSC32_TARST_ASYNC:
 2008                         njsc32_target_async(sc, target);
 2009                         target->t_state = NJSC32_TARST_DONE;
 2010                         njsc32_update_xfer_mode(sc, target);
 2011                         break;
 2012                 default:
 2013                         break;
 2014                 }
 2015                 goto restart;
 2016 
 2017         case MSG_NOOP:                  /* 0x08 */
 2018 #ifdef NJSC32_DUALEDGE
 2019                 target = cmd->c_target;
 2020                 if (target->t_state == NJSC32_TARST_DE) {
 2021                         aprint_normal("%s: DualEdge transfer\n",
 2022                             cmd->c_xs->xs_periph->periph_dev->dv_xname);
 2023                         target->t_xferctl = NJSC32_XFR_DUALEDGE_ENABLE;
 2024                         /* go to next negotiation */
 2025                         target->t_state = NJSC32_TARST_SDTR;
 2026                         njsc32_negotiate_xfer(sc, target);
 2027                         goto reply;
 2028                 }
 2029 #endif
 2030                 goto restart;
 2031 
 2032         case MSG_INITIATOR_DET_ERR:     /* 0x05 I->T only */
 2033         case MSG_ABORT:                 /* 0x06 I->T only */
 2034         case MSG_PARITY_ERROR:          /* 0x09 I->T only */
 2035         case MSG_LINK_CMD_COMPLETE:     /* 0x0a */
 2036         case MSG_LINK_CMD_COMPLETEF:    /* 0x0b */
 2037         case MSG_BUS_DEV_RESET:         /* 0x0c I->T only */
 2038         case MSG_ABORT_TAG:             /* 0x0d I->T only */
 2039         case MSG_CLEAR_QUEUE:           /* 0x0e I->T only */
 2040 
 2041 #if 0   /* handled above */
 2042         case MSG_SIMPLE_Q_TAG:          /* 0x20 */
 2043 #endif
 2044         case MSG_HEAD_OF_Q_TAG:         /* 0x21 I->T only */
 2045         case MSG_ORDERED_Q_TAG:         /* 0x22 I->T only */
 2046         case MSG_IGN_WIDE_RESIDUE:      /* 0x23 */
 2047 
 2048         default:
 2049 #ifdef NJSC32_DEBUG
 2050                 PRINTC(cmd, ("msgin: unsupported msg: %#x", msg0));
 2051                 if (MSG_IS2BYTE(msg0))
 2052                         printf(" %#x", msg);
 2053                 printf("\n");
 2054 #endif
 2055                 break;
 2056         }
 2057 
 2058 reject:
 2059         njsc32_add_msgout(sc, MSG_MESSAGE_REJECT);
 2060 
 2061 reply:
 2062         msgout = njsc32_get_auto_msgout(sc);
 2063 
 2064 restart:
 2065         cctl = NJSC32_CMD_CLEAR_CDB_FIFO_PTR |
 2066             NJSC32_CMD_AUTO_COMMAND_PHASE |
 2067             NJSC32_CMD_AUTO_SCSI_RESTART;
 2068 
 2069         /*
 2070          * Be careful the second and latter bytes of Message In
 2071          * shall not be absorbed by AutoSCSI.
 2072          */
 2073         if (sc->sc_msgincnt == 0)
 2074                 cctl |= NJSC32_CMD_AUTO_MSGIN_00_04 | NJSC32_CMD_AUTO_MSGIN_02;
 2075 
 2076         if (sc->sc_msgoutlen != 0)
 2077                 cctl |= NJSC32_CMD_AUTO_ATN;
 2078 
 2079         njsc32_write_4(sc, NJSC32_REG_SCSI_MSG_OUT, msgout);
 2080 
 2081         /* (re)start AutoSCSI (may assert ATN) */
 2082         if (reload_params) {
 2083                 njsc32_cmd_reload(sc, cmd, cctl);
 2084         } else {
 2085                 njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL, cctl);
 2086         }
 2087 
 2088         /* +ATN -> -REQ: need 90ns delay? */
 2089 
 2090         njsc32_wait_req_negate(sc);     /* wait for REQ negation */
 2091 
 2092         njsc32_negate_ack(sc);
 2093 
 2094         return;
 2095 }
 2096 
 2097 static void
 2098 njsc32_msgout(struct njsc32_softc *sc)
 2099 {
 2100         int cctl;
 2101         u_int8_t bus;
 2102         unsigned n;
 2103 
 2104         if (sc->sc_msgoutlen == 0) {
 2105                 /* target entered to Message Out on unexpected timing */
 2106                 njsc32_add_msgout(sc, MSG_NOOP);
 2107         }
 2108 
 2109         cctl = NJSC32_CMD_CLEAR_CDB_FIFO_PTR |
 2110             NJSC32_CMD_AUTO_COMMAND_PHASE | NJSC32_CMD_AUTO_SCSI_RESTART |
 2111             NJSC32_CMD_AUTO_MSGIN_00_04 | NJSC32_CMD_AUTO_MSGIN_02;
 2112 
 2113         /* make sure target is in Message Out phase */
 2114         bus = njsc32_read_1(sc, NJSC32_REG_SCSI_BUS_MONITOR);
 2115         if ((bus & NJSC32_BUSMON_PHASE_MASK) != NJSC32_PHASE_MESSAGE_OUT) {
 2116                 /*
 2117                  * Message Out is aborted by target.
 2118                  */
 2119                 printf("%s: njsc32_msgout: phase change %#x\n",
 2120                     sc->sc_dev.dv_xname, bus);
 2121 
 2122                 /* XXX what to do? */
 2123 
 2124                 /* restart AutoSCSI (negate ATN) */
 2125                 njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL, cctl);
 2126 
 2127                 sc->sc_msgoutidx = 0;
 2128                 return;
 2129         }
 2130 
 2131         n = sc->sc_msgoutidx;
 2132         if (n == sc->sc_msgoutlen - 1) {
 2133                 /*
 2134                  * negate ATN before sending ACK
 2135                  */
 2136                 njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL, 0);
 2137 
 2138                 sc->sc_msgoutidx = 0;   /* target may retry Message Out */
 2139         } else {
 2140                 cctl |= NJSC32_CMD_AUTO_ATN;
 2141                 sc->sc_msgoutidx++;
 2142         }
 2143 
 2144         /* Send Message Out */
 2145         njsc32_write_1(sc, NJSC32_REG_SCSI_OUT_LATCH, sc->sc_msgout[n]);
 2146 
 2147         /* DBn -> +ACK: need 55ns delay? */
 2148 
 2149         njsc32_assert_ack(sc);
 2150         njsc32_wait_req_negate(sc);     /* wait for REQ negation */
 2151 
 2152         /* restart AutoSCSI */
 2153         njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL, cctl);
 2154 
 2155         njsc32_negate_ack(sc);
 2156 
 2157         /*
 2158          * do not reset sc->sc_msgoutlen so the target
 2159          * can retry Message Out phase
 2160          */
 2161 }
 2162 
 2163 static void
 2164 njsc32_cmdtimeout(void *arg)
 2165 {
 2166         struct njsc32_cmd *cmd = arg;
 2167         struct njsc32_softc *sc;
 2168         int s;
 2169 
 2170         PRINTC(cmd, ("command timeout\n"));
 2171 
 2172         sc = cmd->c_sc;
 2173 
 2174         s = splbio();
 2175 
 2176         if (sc->sc_stat == NJSC32_STAT_ARBIT)
 2177                 njsc32_arbitration_failed(sc);
 2178         else {
 2179                 sc->sc_curcmd = NULL;
 2180                 sc->sc_stat = NJSC32_STAT_IDLE;
 2181                 njsc32_end_cmd(sc, cmd, XS_TIMEOUT);
 2182         }
 2183 
 2184         /* XXX? */
 2185         njsc32_init(sc, 1);     /* bus reset */
 2186 
 2187         splx(s);
 2188 }
 2189 
 2190 static void
 2191 njsc32_reseltimeout(void *arg)
 2192 {
 2193         struct njsc32_cmd *cmd = arg;
 2194         struct njsc32_softc *sc;
 2195         int s;
 2196 
 2197         PRINTC(cmd, ("reselection timeout\n"));
 2198 
 2199         sc = cmd->c_sc;
 2200 
 2201         s = splbio();
 2202 
 2203         /* remove from disconnected list */
 2204         if (cmd->c_flags & NJSC32_CMD_TAGGED) {
 2205                 /* I_T_L_Q */
 2206                 KASSERT(cmd->c_lu->lu_cmd == NULL);
 2207                 TAILQ_REMOVE(&cmd->c_lu->lu_q, cmd, c_q);
 2208         } else {
 2209                 /* I_T_L */
 2210                 KASSERT(cmd->c_lu->lu_cmd == cmd);
 2211                 cmd->c_lu->lu_cmd = NULL;
 2212         }
 2213 
 2214         njsc32_end_cmd(sc, cmd, XS_TIMEOUT);
 2215 
 2216         /* XXX? */
 2217         njsc32_init(sc, 1);     /* bus reset */
 2218 
 2219         splx(s);
 2220 }
 2221 
 2222 static __inline void
 2223 njsc32_end_auto(struct njsc32_softc *sc, struct njsc32_cmd *cmd, int auto_phase)
 2224 {
 2225         struct scsipi_xfer *xs;
 2226 
 2227         if (auto_phase & NJSC32_XPHASE_MSGIN_02) {
 2228                 /* Message In: 0x02 Save Data Pointer */
 2229 
 2230                 /*
 2231                  * Adjust saved data pointer
 2232                  * if the command is not completed yet.
 2233                  */
 2234                 if ((auto_phase & NJSC32_XPHASE_MSGIN_00) == 0 &&
 2235                     (auto_phase &
 2236                      (NJSC32_XPHASE_DATA_IN | NJSC32_XPHASE_DATA_OUT)) != 0) {
 2237                         njsc32_save_ptr(cmd);
 2238                 }
 2239                 TPRINTF(("BM %u, SGT %u, SACK %u, SAVED_ACK %u\n",
 2240                     njsc32_read_4(sc, NJSC32_REG_BM_CNT),
 2241                     njsc32_read_4(sc, NJSC32_REG_SGT_ADR),
 2242                     njsc32_read_4(sc, NJSC32_REG_SACK_CNT),
 2243                     njsc32_read_4(sc, NJSC32_REG_SAVED_ACK_CNT)));
 2244         }
 2245 
 2246         xs = cmd->c_xs;
 2247 
 2248         if (auto_phase & NJSC32_XPHASE_MSGIN_00) {
 2249                 /* Command Complete */
 2250                 TPRINTC(cmd, ("njsc32_intr: Command Complete\n"));
 2251                 switch (xs->status) {
 2252                 case SCSI_CHECK: case SCSI_QUEUE_FULL: case SCSI_BUSY:
 2253                         /*
 2254                          * scsipi layer will automatically handle the error
 2255                          */
 2256                         njsc32_end_cmd(sc, cmd, XS_BUSY);
 2257                         break;
 2258                 default:
 2259                         xs->resid -= cmd->c_dp_max;
 2260                         njsc32_end_cmd(sc, cmd, XS_NOERROR);
 2261                         break;
 2262                 }
 2263         } else if (auto_phase & NJSC32_XPHASE_MSGIN_04) {
 2264                 /* Disconnect */
 2265                 TPRINTC(cmd, ("njsc32_intr: Disconnect\n"));
 2266 
 2267                 /* for ill-designed devices */
 2268                 if ((xs->xs_periph->periph_quirks & PQUIRK_AUTOSAVE) != 0)
 2269                         njsc32_save_ptr(cmd);
 2270 
 2271                 /*
 2272                  * move current cmd to disconnected list
 2273                  */
 2274                 if (cmd->c_flags & NJSC32_CMD_TAGGED) {
 2275                         /* I_T_L_Q */
 2276                         if (cmd->c_flags & NJSC32_CMD_TAGGED_HEAD)
 2277                                 TAILQ_INSERT_HEAD(&cmd->c_lu->lu_q, cmd, c_q);
 2278                         else
 2279                                 TAILQ_INSERT_TAIL(&cmd->c_lu->lu_q, cmd, c_q);
 2280                 } else {
 2281                         /* I_T_L */
 2282                         cmd->c_lu->lu_cmd = cmd;
 2283                 }
 2284 
 2285                 /*
 2286                  * schedule timeout -- avoid being
 2287                  * disconnected forever
 2288                  */
 2289                 if ((xs->xs_control & XS_CTL_POLL) == 0) {
 2290                         callout_stop(&xs->xs_callout);
 2291                         callout_reset(&xs->xs_callout, mstohz(xs->timeout),
 2292                             njsc32_reseltimeout, cmd);
 2293                 }
 2294 
 2295         } else {
 2296                 /*
 2297                  * target has come to Bus Free phase
 2298                  * probably to notify an error
 2299                  */
 2300                 PRINTC(cmd, ("njsc32_intr: unexpected bus free\n"));
 2301                 /* try Request Sense */
 2302                 xs->status = SCSI_CHECK;
 2303                 njsc32_end_cmd(sc, cmd, XS_BUSY);
 2304         }
 2305 }
 2306 
 2307 int
 2308 njsc32_intr(void *arg)
 2309 {
 2310         struct njsc32_softc *sc = arg;
 2311         u_int16_t intr;
 2312         u_int8_t arbstat, bus_phase;
 2313         int auto_phase;
 2314         int idbit;
 2315         struct njsc32_cmd *cmd;
 2316 
 2317         intr = njsc32_read_2(sc, NJSC32_REG_IRQ);
 2318         if ((intr & NJSC32_IRQ_INTR_PENDING) == 0)
 2319                 return 0;       /* not mine */
 2320 
 2321         TPRINTF(("%s: njsc32_intr: %#x\n", sc->sc_dev.dv_xname, intr));
 2322 
 2323 #if 0   /* I don't think this is required */
 2324         /* mask interrupts */
 2325         njsc32_write_2(sc, NJSC32_REG_IRQ, NJSC32_IRQ_MASK_ALL);
 2326 #endif
 2327 
 2328         /* we got an interrupt, so stop the timer */
 2329         njsc32_write_2(sc, NJSC32_REG_TIMER, NJSC32_TIMER_STOP);
 2330 
 2331         if (intr & NJSC32_IRQ_SCSIRESET) {
 2332                 printf("%s: detected bus reset\n", sc->sc_dev.dv_xname);
 2333                 /* clear current request */
 2334                 njsc32_reset_detected(sc);
 2335                 goto out;
 2336         }
 2337 
 2338         if (sc->sc_stat == NJSC32_STAT_ARBIT) {
 2339                 cmd = sc->sc_curcmd;
 2340                 KASSERT(cmd);
 2341                 arbstat = njsc32_read_1(sc, NJSC32_REG_ARBITRATION_STAT);
 2342                 if (arbstat & (NJSC32_ARBSTAT_WIN | NJSC32_ARBSTAT_FAIL)) {
 2343                         /*
 2344                          * arbitration done
 2345                          */
 2346                         /* clear arbitration status */
 2347                         njsc32_write_1(sc, NJSC32_REG_SET_ARBITRATION,
 2348                             NJSC32_SETARB_CLEAR);
 2349 
 2350                         if (arbstat & NJSC32_ARBSTAT_WIN) {
 2351                                 TPRINTC(cmd,
 2352                                     ("njsc32_intr: arbitration won\n"));
 2353 
 2354                                 TAILQ_REMOVE(&sc->sc_reqcmd, cmd, c_q);
 2355 
 2356                                 sc->sc_stat = NJSC32_STAT_CONNECT;
 2357                         } else {
 2358                                 TPRINTC(cmd,
 2359                                     ("njsc32_intr: arbitration failed\n"));
 2360 
 2361                                 njsc32_arbitration_failed(sc);
 2362 
 2363                                 /* XXX delay */
 2364                                 /* XXX retry counter */
 2365                         }
 2366                 }
 2367         }
 2368 
 2369         if (intr & NJSC32_IRQ_TIMER) {
 2370                 TPRINTF(("%s: njsc32_intr: timer interrupt\n",
 2371                     sc->sc_dev.dv_xname));
 2372         }
 2373 
 2374         if (intr & NJSC32_IRQ_RESELECT) {
 2375                 /* Reselection from a target */
 2376                 njsc32_arbitration_failed(sc);  /* just in case */
 2377                 if ((cmd = sc->sc_curcmd) != NULL) {
 2378                         /* ? */
 2379                         printf("%s: unexpected reselection\n",
 2380                             sc->sc_dev.dv_xname);
 2381                         sc->sc_curcmd = NULL;
 2382                         sc->sc_stat = NJSC32_STAT_IDLE;
 2383                         njsc32_end_cmd(sc, cmd, XS_DRIVER_STUFFUP);
 2384                 }
 2385 
 2386                 idbit = njsc32_read_1(sc, NJSC32_REG_RESELECT_ID);
 2387                 if ((idbit & (1 << NJSC32_INITIATOR_ID)) == 0 ||
 2388                     (sc->sc_reselid = ffs(idbit & ~NJSC32_INITIATOR_ID) -1)
 2389                     < 0) {
 2390                         printf("%s: invalid reselection (id: %#x)\n",
 2391                             sc->sc_dev.dv_xname, idbit);
 2392                         sc->sc_stat = NJSC32_STAT_IDLE; /* XXX ? */
 2393                 } else {
 2394                         sc->sc_stat = NJSC32_STAT_RESEL;
 2395                         TPRINTF(("%s: njsc32_intr: reselection from %d\n",
 2396                             sc->sc_dev.dv_xname, sc->sc_reselid));
 2397                 }
 2398         }
 2399 
 2400         if (intr & NJSC32_IRQ_PHASE_CHANGE) {
 2401 #if 1   /* XXX probably not needed */
 2402                 if (sc->sc_stat == NJSC32_STAT_ARBIT)
 2403                         PRINTC(sc->sc_curcmd,
 2404                             ("njsc32_intr: cancel arbitration phase\n"));
 2405                 njsc32_arbitration_failed(sc);
 2406 #endif
 2407                 /* current bus phase */
 2408                 bus_phase = njsc32_read_1(sc, NJSC32_REG_SCSI_BUS_MONITOR) &
 2409                     NJSC32_BUSMON_PHASE_MASK;
 2410 
 2411                 switch (bus_phase) {
 2412                 case NJSC32_PHASE_MESSAGE_IN:
 2413                         njsc32_msgin(sc);
 2414                         break;
 2415 
 2416                 /*
 2417                  * target may suddenly become Status / Bus Free phase
 2418                  * to notify an error condition
 2419                  */
 2420                 case NJSC32_PHASE_STATUS:
 2421                         printf("%s: unexpected bus phase: Status\n",
 2422                             sc->sc_dev.dv_xname);
 2423                         if ((cmd = sc->sc_curcmd) != NULL) {
 2424                                 cmd->c_xs->status =
 2425                                     njsc32_read_1(sc, NJSC32_REG_SCSI_CSB_IN);
 2426                                 TPRINTC(cmd, ("njsc32_intr: Status %d\n",
 2427                                     cmd->c_xs->status));
 2428                         }
 2429                         break;
 2430                 case NJSC32_PHASE_BUSFREE:
 2431                         printf("%s: unexpected bus phase: Bus Free\n",
 2432                             sc->sc_dev.dv_xname);
 2433                         if ((cmd = sc->sc_curcmd) != NULL) {
 2434                                 sc->sc_curcmd = NULL;
 2435                                 sc->sc_stat = NJSC32_STAT_IDLE;
 2436                                 if (cmd->c_xs->status != SCSI_QUEUE_FULL &&
 2437                                     cmd->c_xs->status != SCSI_BUSY)
 2438                                         cmd->c_xs->status = SCSI_CHECK;/* XXX */
 2439                                 njsc32_end_cmd(sc, cmd, XS_BUSY);
 2440                         }
 2441                         goto out;
 2442                 default:
 2443 #ifdef NJSC32_DEBUG
 2444                         printf("%s: unexpected bus phase: ",
 2445                             sc->sc_dev.dv_xname);
 2446                         switch (bus_phase) {
 2447                         case NJSC32_PHASE_COMMAND:
 2448                                 printf("Command\n");    break;
 2449                         case NJSC32_PHASE_MESSAGE_OUT:
 2450                                 printf("Message Out\n");break;
 2451                         case NJSC32_PHASE_DATA_IN:
 2452                                 printf("Data In\n");    break;
 2453                         case NJSC32_PHASE_DATA_OUT:
 2454                                 printf("Data Out\n");   break;
 2455                         case NJSC32_PHASE_RESELECT:
 2456                                 printf("Reselect\n");break;
 2457                         default: printf("%#x\n", bus_phase);    break;
 2458                         }
 2459 #else
 2460                         printf("%s: unexpected bus phase: %#x",
 2461                             sc->sc_dev.dv_xname, bus_phase);
 2462 #endif
 2463                         break;
 2464                 }
 2465         }
 2466 
 2467         if (intr & NJSC32_IRQ_AUTOSCSI) {
 2468                 /*
 2469                  * AutoSCSI interrupt
 2470                  */
 2471                 auto_phase = njsc32_read_2(sc, NJSC32_REG_EXECUTE_PHASE);
 2472                 TPRINTF(("%s: njsc32_intr: AutoSCSI: %#x\n",
 2473                     sc->sc_dev.dv_xname, auto_phase));
 2474                 njsc32_write_2(sc, NJSC32_REG_EXECUTE_PHASE, 0);
 2475 
 2476                 if (auto_phase & NJSC32_XPHASE_SEL_TIMEOUT) {
 2477                         cmd = sc->sc_curcmd;
 2478                         if (cmd == NULL) {
 2479                                 printf("%s: sel no cmd\n",
 2480                                     sc->sc_dev.dv_xname);
 2481                                 goto out;
 2482                         }
 2483                         DPRINTC(cmd, ("njsc32_intr: selection timeout\n"));
 2484 
 2485                         sc->sc_curcmd = NULL;
 2486                         sc->sc_stat = NJSC32_STAT_IDLE;
 2487                         njsc32_end_cmd(sc, cmd, XS_SELTIMEOUT);
 2488 
 2489                         goto out;
 2490                 }
 2491 
 2492 #ifdef NJSC32_TRACE
 2493                 if (auto_phase & NJSC32_XPHASE_COMMAND) {
 2494                         /* Command phase has been automatically processed */
 2495                         TPRINTF(("%s: njsc32_intr: Command\n",
 2496                             sc->sc_dev.dv_xname));
 2497                 }
 2498 #endif
 2499 #ifdef NJSC32_DEBUG
 2500                 if (auto_phase & NJSC32_XPHASE_ILLEGAL) {
 2501                         printf("%s: njsc32_intr: Illegal phase\n",
 2502                             sc->sc_dev.dv_xname);
 2503                 }
 2504 #endif
 2505 
 2506                 if (auto_phase & NJSC32_XPHASE_PAUSED_MSG_IN) {
 2507                         TPRINTF(("%s: njsc32_intr: Process Message In\n",
 2508                             sc->sc_dev.dv_xname));
 2509                         njsc32_msgin(sc);
 2510                 }
 2511 
 2512                 if (auto_phase & NJSC32_XPHASE_PAUSED_MSG_OUT) {
 2513                         TPRINTF(("%s: njsc32_intr: Process Message Out\n",
 2514                             sc->sc_dev.dv_xname));
 2515                         njsc32_msgout(sc);
 2516                 }
 2517 
 2518                 cmd = sc->sc_curcmd;
 2519                 if (cmd == NULL) {
 2520                         TPRINTF(("%s: njsc32_intr: no cmd\n",
 2521                             sc->sc_dev.dv_xname));
 2522                         goto out;
 2523                 }
 2524 
 2525                 if (auto_phase &
 2526                     (NJSC32_XPHASE_DATA_IN | NJSC32_XPHASE_DATA_OUT)) {
 2527 #ifdef NJSC32_TRACE
 2528                         if (auto_phase & NJSC32_XPHASE_DATA_IN)
 2529                                 PRINTC(cmd, ("njsc32_intr: data in done\n"));
 2530                         if (auto_phase & NJSC32_XPHASE_DATA_OUT)
 2531                                 PRINTC(cmd, ("njsc32_intr: data out done\n"));
 2532                         printf("BM %u, SGT %u, SACK %u, SAVED_ACK %u\n",
 2533                                 njsc32_read_4(sc, NJSC32_REG_BM_CNT),
 2534                                 njsc32_read_4(sc, NJSC32_REG_SGT_ADR),
 2535                                 njsc32_read_4(sc, NJSC32_REG_SACK_CNT),
 2536                                 njsc32_read_4(sc, NJSC32_REG_SAVED_ACK_CNT));
 2537 #endif
 2538 
 2539                         /*
 2540                          * detected parity error on data transfer?
 2541                          */
 2542                         if (njsc32_read_1(sc, NJSC32_REG_PARITY_STATUS) &
 2543                             (NJSC32_PARITYSTATUS_ERROR_LSB|
 2544                              NJSC32_PARITYSTATUS_ERROR_MSB)) {
 2545 
 2546                                 PRINTC(cmd, ("datain: parity error\n"));
 2547 
 2548                                 /* clear parity error */
 2549                                 njsc32_write_1(sc, NJSC32_REG_PARITY_CONTROL,
 2550                                     NJSC32_PARITYCTL_CHECK_ENABLE |
 2551                                     NJSC32_PARITYCTL_CLEAR_ERROR);
 2552 
 2553                                 if (auto_phase & NJSC32_XPHASE_BUS_FREE) {
 2554                                         /*
 2555                                          * XXX command has already finished
 2556                                          * -- what can we do?
 2557                                          *
 2558                                          * It is not clear current command
 2559                                          * caused the error -- reset everything.
 2560                                          */
 2561                                         njsc32_init(sc, 1);     /* XXX */
 2562                                 } else {
 2563                                         /* XXX does this case occur? */
 2564 #if 1
 2565                                         printf("%s: datain: parity error\n",
 2566                                             sc->sc_dev.dv_xname);
 2567 #endif
 2568                                         /*
 2569                                          * Make attention condition and try
 2570                                          * to send Initiator Detected Error
 2571                                          * message.
 2572                                          */
 2573                                         njsc32_init_msgout(sc);
 2574                                         njsc32_add_msgout(sc,
 2575                                             MSG_INITIATOR_DET_ERR);
 2576                                         njsc32_write_4(sc,
 2577                                             NJSC32_REG_SCSI_MSG_OUT,
 2578                                             njsc32_get_auto_msgout(sc));
 2579                                         /* restart autoscsi with ATN */
 2580                                         njsc32_write_2(sc,
 2581                                             NJSC32_REG_COMMAND_CONTROL,
 2582                                             NJSC32_CMD_CLEAR_CDB_FIFO_PTR |
 2583                                             NJSC32_CMD_AUTO_COMMAND_PHASE |
 2584                                             NJSC32_CMD_AUTO_SCSI_RESTART |
 2585                                             NJSC32_CMD_AUTO_MSGIN_00_04 |
 2586                                             NJSC32_CMD_AUTO_MSGIN_02 |
 2587                                             NJSC32_CMD_AUTO_ATN);
 2588                                 }
 2589                                 goto out;
 2590                         }
 2591 
 2592                         /*
 2593                          * data has been transferred, and current pointer
 2594                          * is changed
 2595                          */
 2596                         njsc32_set_cur_ptr(cmd, cmd->c_dp_cur +
 2597                             njsc32_read_4(sc, NJSC32_REG_SACK_CNT));
 2598                 }
 2599 
 2600                 if (auto_phase & NJSC32_XPHASE_MSGOUT) {
 2601                         /* Message Out phase has been automatically processed */
 2602                         TPRINTC(cmd, ("njsc32_intr: Message Out\n"));
 2603                         if ((auto_phase & NJSC32_XPHASE_PAUSED_MSG_IN) == 0 &&
 2604                             sc->sc_msgoutlen <= NJSC32_MSGOUT_MAX_AUTO) {
 2605                                 njsc32_init_msgout(sc);
 2606                         }
 2607                 }
 2608 
 2609                 if (auto_phase & NJSC32_XPHASE_STATUS) {
 2610                         /* Status phase has been automatically processed */
 2611                         cmd->c_xs->status =
 2612                             njsc32_read_1(sc, NJSC32_REG_SCSI_CSB_IN);
 2613                         TPRINTC(cmd, ("njsc32_intr: Status %#x\n",
 2614                             cmd->c_xs->status));
 2615                 }
 2616 
 2617                 if (auto_phase & NJSC32_XPHASE_BUS_FREE) {
 2618                         /* AutoSCSI is finished */
 2619 
 2620                         TPRINTC(cmd, ("njsc32_intr: Bus Free\n"));
 2621 
 2622                         sc->sc_stat = NJSC32_STAT_IDLE;
 2623                         sc->sc_curcmd = NULL;
 2624 
 2625                         njsc32_end_auto(sc, cmd, auto_phase);
 2626                 }
 2627                 goto out;
 2628         }
 2629 
 2630         if (intr & NJSC32_IRQ_FIFO_THRESHOLD) {
 2631                 /* XXX We use DMA, and this shouldn't happen */
 2632                 printf("%s: njsc32_intr: FIFO\n", sc->sc_dev.dv_xname);
 2633                 njsc32_init(sc, 1);
 2634                 goto out;
 2635         }
 2636         if (intr & NJSC32_IRQ_PCI) {
 2637                 /* XXX? */
 2638                 printf("%s: njsc32_intr: PCI\n", sc->sc_dev.dv_xname);
 2639         }
 2640         if (intr & NJSC32_IRQ_BMCNTERR) {
 2641                 /* XXX? */
 2642                 printf("%s: njsc32_intr: BM\n", sc->sc_dev.dv_xname);
 2643         }
 2644 
 2645 out:
 2646         /* go next command if controller is idle */
 2647         if (sc->sc_stat == NJSC32_STAT_IDLE)
 2648                 njsc32_start(sc);
 2649 
 2650 #if 0
 2651         /* enable interrupts */
 2652         njsc32_write_2(sc, NJSC32_REG_IRQ, 0);
 2653 #endif
 2654 
 2655         return 1;       /* processed */
 2656 }

Cache object: e2cdea4657b499199b40cbaae53928e0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.