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/ncr5380sbc.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: ncr5380sbc.c,v 1.63 2008/04/04 16:00:58 tsutsui Exp $  */
    2 
    3 /*
    4  * Copyright (c) 1995 David Jones, Gordon W. Ross
    5  * Copyright (c) 1994 Jarle Greipsland
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. The name of the authors may not be used to endorse or promote products
   17  *    derived from this software without specific prior written permission.
   18  * 4. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by
   21  *      David Jones and Gordon Ross
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
   24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   26  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33  */
   34 
   35 /*
   36  * This is a machine-independent driver for the NCR5380
   37  * SCSI Bus Controller (SBC), also known as the Am5380.
   38  *
   39  * This code should work with any memory-mapped 5380,
   40  * and can be shared by multiple adapters that address
   41  * the 5380 with different register offset spacings.
   42  * (This can happen on the atari, for example.)
   43  * For porting/design info. see: ncr5380.doc
   44  *
   45  * Credits, history:
   46  *
   47  * David Jones is the author of most of the code that now
   48  * appears in this file, and was the architect of the
   49  * current overall structure (MI/MD code separation, etc.)
   50  *
   51  * Gordon Ross integrated the message phase code, added lots of
   52  * comments about what happens when and why (re. SCSI spec.),
   53  * debugged some reentrance problems, and added several new
   54  * "hooks" needed for the Sun3 "si" adapters.
   55  *
   56  * The message in/out code was taken nearly verbatim from
   57  * the aic6360 driver by Jarle Greipsland.
   58  *
   59  * Several other NCR5380 drivers were used for reference
   60  * while developing this driver, including work by:
   61  *   The Alice Group (mac68k port) namely:
   62  *       Allen K. Briggs, Chris P. Caputo, Michael L. Finch,
   63  *       Bradley A. Grantham, and Lawrence A. Kesteloot
   64  *   Michael L. Hitch (amiga drivers: sci.c)
   65  *   Leo Weppelman (atari driver: ncr5380.c)
   66  * There are others too.  Thanks, everyone.
   67  *
   68  * Transliteration to bus_space() performed 9/17/98 by
   69  * John Ruschmeyer (jruschme@exit109.com) for i386 'nca' driver.
   70  * Thank you all.
   71  */
   72 
   73 #include <sys/cdefs.h>
   74 __KERNEL_RCSID(0, "$NetBSD: ncr5380sbc.c,v 1.63 2008/04/04 16:00:58 tsutsui Exp $");
   75 
   76 #include "opt_ddb.h"
   77 
   78 #include <sys/param.h>
   79 #include <sys/systm.h>
   80 #include <sys/kernel.h>
   81 #include <sys/errno.h>
   82 #include <sys/device.h>
   83 #include <sys/buf.h>
   84 #include <sys/proc.h>
   85 #include <sys/user.h>
   86 
   87 #include <dev/scsipi/scsi_all.h>
   88 #include <dev/scsipi/scsipi_all.h>
   89 #include <dev/scsipi/scsipi_debug.h>
   90 #include <dev/scsipi/scsi_message.h>
   91 #include <dev/scsipi/scsiconf.h>
   92 
   93 #ifdef DDB
   94 #include <ddb/db_output.h>
   95 #endif
   96 
   97 #include <dev/ic/ncr5380reg.h>
   98 #include <dev/ic/ncr5380var.h>
   99 #include <dev/ic/ncr53c400reg.h>
  100 
  101 static void     ncr5380_reset_scsibus(struct ncr5380_softc *);
  102 static void     ncr5380_sched(struct ncr5380_softc *);
  103 static void     ncr5380_done(struct ncr5380_softc *);
  104 
  105 static int      ncr5380_select(struct ncr5380_softc *, struct sci_req *);
  106 static void     ncr5380_reselect(struct ncr5380_softc *);
  107 
  108 static int      ncr5380_msg_in(struct ncr5380_softc *);
  109 static int      ncr5380_msg_out(struct ncr5380_softc *);
  110 static int      ncr5380_data_xfer(struct ncr5380_softc *, int);
  111 static int      ncr5380_command(struct ncr5380_softc *);
  112 static int      ncr5380_status(struct ncr5380_softc *);
  113 static void     ncr5380_machine(struct ncr5380_softc *);
  114 
  115 void    ncr5380_abort(struct ncr5380_softc *);
  116 void    ncr5380_cmd_timeout(void *);
  117 /*
  118  * Action flags returned by the info_transfer functions:
  119  * (These determine what happens next.)
  120  */
  121 #define ACT_CONTINUE    0x00    /* No flags: expect another phase */
  122 #define ACT_DISCONNECT  0x01    /* Target is disconnecting */
  123 #define ACT_CMD_DONE    0x02    /* Need to call scsipi_done() */
  124 #define ACT_RESET_BUS   0x04    /* Need bus reset (cmd timeout) */
  125 #define ACT_WAIT_DMA    0x10    /* Wait for DMA to complete */
  126 
  127 /*****************************************************************
  128  * Debugging stuff
  129  *****************************************************************/
  130 
  131 #ifndef DDB
  132 /* This is used only in recoverable places. */
  133 #ifndef Debugger
  134 #define Debugger() printf("Debug: ncr5380.c:%d\n", __LINE__)
  135 #endif
  136 #endif
  137 
  138 #ifdef  NCR5380_DEBUG
  139 
  140 #define NCR_DBG_BREAK   1
  141 #define NCR_DBG_CMDS    2
  142 int ncr5380_debug = 0;
  143 #define NCR_BREAK() \
  144         do { if (ncr5380_debug & NCR_DBG_BREAK) Debugger(); } while (0)
  145 static void ncr5380_show_scsi_cmd(struct scsipi_xfer *);
  146 #ifdef DDB
  147 void    ncr5380_clear_trace(void);
  148 void    ncr5380_show_trace(void);
  149 void    ncr5380_show_req(struct sci_req *);
  150 void    ncr5380_show_state(void);
  151 #endif  /* DDB */
  152 #else   /* NCR5380_DEBUG */
  153 
  154 #define NCR_BREAK()             /* nada */
  155 #define ncr5380_show_scsi_cmd(xs) /* nada */
  156 
  157 #endif  /* NCR5380_DEBUG */
  158 
  159 static const char *
  160 phase_names[8] = {
  161         "DATA_OUT",
  162         "DATA_IN",
  163         "COMMAND",
  164         "STATUS",
  165         "UNSPEC1",
  166         "UNSPEC2",
  167         "MSG_OUT",
  168         "MSG_IN",
  169 };
  170 
  171 /*****************************************************************
  172  * Actual chip control
  173  *****************************************************************/
  174 
  175 /*
  176  * XXX: These timeouts might need to be tuned...
  177  */
  178 
  179 /* This one is used when waiting for a phase change. (X100uS.) */
  180 int ncr5380_wait_phase_timo = 1000 * 10 * 300;  /* 5 min. */
  181 
  182 /* These are used in the following inline functions. */
  183 int ncr5380_wait_req_timo = 1000 * 50;  /* X2 = 100 mS. */
  184 int ncr5380_wait_nrq_timo = 1000 * 25;  /* X2 =  50 mS. */
  185 
  186 static inline int ncr5380_wait_req(struct ncr5380_softc *);
  187 static inline int ncr5380_wait_not_req(struct ncr5380_softc *);
  188 static inline void ncr_sched_msgout(struct ncr5380_softc *, int);
  189 
  190 /* Return zero on success. */
  191 static inline int
  192 ncr5380_wait_req(struct ncr5380_softc *sc)
  193 {
  194         int timo = ncr5380_wait_req_timo;
  195 
  196         for (;;) {
  197                 if (NCR5380_READ(sc, sci_bus_csr) & SCI_BUS_REQ) {
  198                         timo = 0;       /* return 0 */
  199                         break;
  200                 }
  201                 if (--timo < 0)
  202                         break;  /* return -1 */
  203                 delay(2);
  204         }
  205         return timo;
  206 }
  207 
  208 /* Return zero on success. */
  209 static inline int
  210 ncr5380_wait_not_req(struct ncr5380_softc *sc)
  211 {
  212         int timo = ncr5380_wait_nrq_timo;
  213 
  214         for (;;) {
  215                 if ((NCR5380_READ(sc, sci_bus_csr) & SCI_BUS_REQ) == 0) {
  216                         timo = 0;       /* return 0 */
  217                         break;
  218                 }
  219                 if (--timo < 0)
  220                         break;  /* return -1 */
  221                 delay(2);
  222         }
  223         return timo;
  224 }
  225 
  226 /* Ask the target for a MSG_OUT phase. */
  227 static inline void
  228 ncr_sched_msgout(struct ncr5380_softc *sc, int msg_code)
  229 {
  230 
  231         /* First time, raise ATN line. */
  232         if (sc->sc_msgpriq == 0) {
  233                 uint8_t icmd;
  234                 icmd = NCR5380_READ(sc, sci_icmd) & SCI_ICMD_RMASK;
  235                 NCR5380_WRITE(sc, sci_icmd, (icmd | SCI_ICMD_ATN));
  236                 delay(2);
  237         }
  238         sc->sc_msgpriq |= msg_code;
  239 }
  240 
  241 
  242 int
  243 ncr5380_pio_out(struct ncr5380_softc *sc, int phase, int count, uint8_t *data)
  244 {
  245         uint8_t icmd;
  246         int resid;
  247         int error;
  248 
  249         icmd = NCR5380_READ(sc, sci_icmd) & SCI_ICMD_RMASK;
  250 
  251         icmd |= SCI_ICMD_DATA;
  252         NCR5380_WRITE(sc, sci_icmd, icmd);
  253 
  254         resid = count;
  255         while (resid > 0) {
  256                 if (!SCI_BUSY(sc)) {
  257                         NCR_TRACE("pio_out: lost BSY, resid=%d\n", resid);
  258                         break;
  259                 }
  260                 if (ncr5380_wait_req(sc)) {
  261                         NCR_TRACE("pio_out: no REQ, resid=%d\n", resid);
  262                         break;
  263                 }
  264                 if (SCI_BUS_PHASE(NCR5380_READ(sc, sci_bus_csr)) != phase)
  265                         break;
  266 
  267                 /* Put the data on the bus. */
  268                 if (data)
  269                         NCR5380_WRITE(sc, sci_odata, *data++);
  270                 else
  271                         NCR5380_WRITE(sc, sci_odata, 0);
  272 
  273                 /* Tell the target it's there. */
  274                 icmd |= SCI_ICMD_ACK;
  275                 NCR5380_WRITE(sc, sci_icmd, icmd);
  276 
  277                 /* Wait for target to get it. */
  278                 error = ncr5380_wait_not_req(sc);
  279 
  280                 /* OK, it's got it (or we gave up waiting). */
  281                 icmd &= ~SCI_ICMD_ACK;
  282                 NCR5380_WRITE(sc, sci_icmd, icmd);
  283 
  284                 if (error) {
  285                         NCR_TRACE("pio_out: stuck REQ, resid=%d\n", resid);
  286                         break;
  287                 }
  288 
  289                 --resid;
  290         }
  291 
  292         /* Stop driving the data bus. */
  293         icmd &= ~SCI_ICMD_DATA;
  294         NCR5380_WRITE(sc, sci_icmd, icmd);
  295 
  296         return count - resid;
  297 }
  298 
  299 
  300 int
  301 ncr5380_pio_in(struct ncr5380_softc *sc, int phase, int count, uint8_t *data)
  302 {
  303         uint8_t icmd;
  304         int resid;
  305         int error;
  306 
  307         icmd = NCR5380_READ(sc, sci_icmd) & SCI_ICMD_RMASK;
  308 
  309         resid = count;
  310         while (resid > 0) {
  311                 if (!SCI_BUSY(sc)) {
  312                         NCR_TRACE("pio_in: lost BSY, resid=%d\n", resid);
  313                         break;
  314                 }
  315                 if (ncr5380_wait_req(sc)) {
  316                         NCR_TRACE("pio_in: no REQ, resid=%d\n", resid);
  317                         break;
  318                 }
  319                 /* A phase change is not valid until AFTER REQ rises! */
  320                 if (SCI_BUS_PHASE(NCR5380_READ(sc, sci_bus_csr)) != phase)
  321                         break;
  322 
  323                 /* Read the data bus. */
  324                 if (data)
  325                         *data++ = NCR5380_READ(sc, sci_data);
  326                 else
  327                         (void) NCR5380_READ(sc, sci_data);
  328 
  329                 /* Tell target we got it. */
  330                 icmd |= SCI_ICMD_ACK;
  331                 NCR5380_WRITE(sc, sci_icmd, icmd);
  332 
  333                 /* Wait for target to drop REQ... */
  334                 error = ncr5380_wait_not_req(sc);
  335 
  336                 /* OK, we can drop ACK. */
  337                 icmd &= ~SCI_ICMD_ACK;
  338                 NCR5380_WRITE(sc, sci_icmd, icmd);
  339 
  340                 if (error) {
  341                         NCR_TRACE("pio_in: stuck REQ, resid=%d\n", resid);
  342                         break;
  343                 }
  344 
  345                 --resid;
  346         }
  347 
  348         return count - resid;
  349 }
  350 
  351 
  352 void
  353 ncr5380_init(struct ncr5380_softc *sc)
  354 {
  355         int i, j;
  356 
  357 #ifdef  NCR5380_DEBUG
  358         ncr5380_debug_sc = sc;
  359 #endif
  360 
  361         for (i = 0; i < SCI_OPENINGS; i++)
  362                 sc->sc_ring[i].sr_xs = NULL;
  363         for (i = 0; i < 8; i++)
  364                 for (j = 0; j < 8; j++)
  365                         sc->sc_matrix[i][j] = NULL;
  366 
  367         sc->sc_prevphase = PHASE_INVALID;
  368         sc->sc_state = NCR_IDLE;
  369 
  370 #ifdef NCR5380_USE_BUS_SPACE
  371         if (sc->sc_rev == NCR_VARIANT_NCR53C400)
  372                 bus_space_write_1(sc->sc_regt, sc->sc_regh, C400_CSR,
  373                     C400_CSR_5380_ENABLE);
  374 #endif
  375 
  376         NCR5380_WRITE(sc, sci_tcmd, PHASE_INVALID);
  377         NCR5380_WRITE(sc, sci_icmd, 0);
  378         NCR5380_WRITE(sc, sci_mode, 0);
  379         NCR5380_WRITE(sc, sci_sel_enb, 0);
  380         SCI_CLR_INTR(sc);
  381 
  382         /* XXX: Enable reselect interrupts... */
  383         NCR5380_WRITE(sc, sci_sel_enb, 0x80);
  384 
  385         /* Another hack (Er.. hook!) for the sun3 si: */
  386         if (sc->sc_intr_on) {
  387                 NCR_TRACE("init: intr ON\n", 0);
  388                 sc->sc_intr_on(sc);
  389         }
  390 }
  391 
  392 
  393 static void
  394 ncr5380_reset_scsibus(struct ncr5380_softc *sc)
  395 {
  396 
  397         NCR_TRACE("reset_scsibus, cur=0x%x\n",
  398                           (long) sc->sc_current);
  399 
  400         NCR5380_WRITE(sc, sci_icmd, SCI_ICMD_RST);
  401         delay(500);
  402         NCR5380_WRITE(sc, sci_icmd, 0);
  403 
  404         NCR5380_WRITE(sc, sci_mode, 0);
  405         NCR5380_WRITE(sc, sci_tcmd, PHASE_INVALID);
  406 
  407         SCI_CLR_INTR(sc);
  408         /* XXX - Need long delay here! */
  409         delay(100000);
  410 
  411         /* XXX - Need to cancel disconnected requests. */
  412 }
  413 
  414 
  415 /*
  416  * Interrupt handler for the SCSI Bus Controller (SBC)
  417  * This may also called for a DMA timeout (at splbio).
  418  */
  419 int
  420 ncr5380_intr(void *arg)
  421 {
  422         struct ncr5380_softc *sc = arg;
  423         int claimed = 0;
  424 
  425         /*
  426          * Do not touch SBC regs here unless sc_current == NULL
  427          * or it will complain about "register conflict" errors.
  428          * Instead, just let ncr5380_machine() deal with it.
  429          */
  430         NCR_TRACE("intr: top, state=%d\n", sc->sc_state);
  431 
  432         if (sc->sc_state == NCR_IDLE) {
  433                 /*
  434                  * Might be reselect.  ncr5380_reselect() will check,
  435                  * and set up the connection if so.  This will verify
  436                  * that sc_current == NULL at the beginning...
  437                  */
  438 
  439                 /* Another hack (Er.. hook!) for the sun3 si: */
  440                 if (sc->sc_intr_off) {
  441                         NCR_TRACE("intr: for reselect, intr off\n", 0);
  442                     sc->sc_intr_off(sc);
  443                 }
  444 
  445                 ncr5380_reselect(sc);
  446         }
  447 
  448         /*
  449          * The remaining documented interrupt causes are phase mismatch and
  450          * disconnect.  In addition, the sunsi controller may produce a state
  451          * where SCI_CSR_DONE is false, yet DMA is complete.
  452          *
  453          * The procedure in all these cases is to let ncr5380_machine()
  454          * figure out what to do next.
  455          */
  456         if (sc->sc_state & NCR_WORKING) {
  457                 NCR_TRACE("intr: call machine, cur=0x%x\n",
  458                                   (long) sc->sc_current);
  459                 /* This will usually free-up the nexus. */
  460                 ncr5380_machine(sc);
  461                 NCR_TRACE("intr: machine done, cur=0x%x\n",
  462                                   (long) sc->sc_current);
  463                 claimed = 1;
  464         }
  465 
  466         /* Maybe we can run some commands now... */
  467         if (sc->sc_state == NCR_IDLE) {
  468                 NCR_TRACE("intr: call sched, cur=0x%x\n",
  469                                   (long) sc->sc_current);
  470                 ncr5380_sched(sc);
  471                 NCR_TRACE("intr: sched done, cur=0x%x\n",
  472                                   (long) sc->sc_current);
  473         }
  474 
  475         return claimed;
  476 }
  477 
  478 
  479 /*
  480  * Abort the current command (i.e. due to timeout)
  481  */
  482 void
  483 ncr5380_abort(struct ncr5380_softc *sc)
  484 {
  485 
  486         /*
  487          * Finish it now.  If DMA is in progress, we
  488          * can not call ncr_sched_msgout() because
  489          * that hits the SBC (avoid DMA conflict).
  490          */
  491 
  492         /* Another hack (Er.. hook!) for the sun3 si: */
  493         if (sc->sc_intr_off) {
  494                 NCR_TRACE("abort: intr off\n", 0);
  495                 sc->sc_intr_off(sc);
  496         }
  497 
  498         sc->sc_state |= NCR_ABORTING;
  499         if ((sc->sc_state & NCR_DOINGDMA) == 0) {
  500                 ncr_sched_msgout(sc, SEND_ABORT);
  501         }
  502         NCR_TRACE("abort: call machine, cur=0x%x\n",
  503                           (long) sc->sc_current);
  504         ncr5380_machine(sc);
  505         NCR_TRACE("abort: machine done, cur=0x%x\n",
  506                           (long) sc->sc_current);
  507 
  508         /* Another hack (Er.. hook!) for the sun3 si: */
  509         if (sc->sc_intr_on) {
  510                 NCR_TRACE("abort: intr ON\n", 0);
  511                 sc->sc_intr_on(sc);
  512         }
  513 }
  514 
  515 /*
  516  * Timeout handler, scheduled for each SCSI command.
  517  */
  518 void
  519 ncr5380_cmd_timeout(void *arg)
  520 {
  521         struct sci_req *sr = arg;
  522         struct scsipi_xfer *xs;
  523         struct scsipi_periph *periph;
  524         struct ncr5380_softc *sc;
  525         int s;
  526 
  527         s = splbio();
  528 
  529         /* Get all our variables... */
  530         xs = sr->sr_xs;
  531         if (xs == NULL) {
  532                 printf("ncr5380_cmd_timeout: no scsipi_xfer\n");
  533                 goto out;
  534         }
  535         periph = xs->xs_periph;
  536         sc = device_private(periph->periph_channel->chan_adapter->adapt_dev);
  537 
  538         printf("%s: cmd timeout, targ=%d, lun=%d\n",
  539             device_xname(sc->sc_dev),
  540             sr->sr_target, sr->sr_lun);
  541 
  542         /*
  543          * Mark the overdue job as failed, and arrange for
  544          * ncr5380_machine to terminate it.  If the victim
  545          * is the current job, call ncr5380_machine() now.
  546          * Otherwise arrange for ncr5380_sched() to do it.
  547          */
  548         sr->sr_flags |= SR_OVERDUE;
  549         if (sc->sc_current == sr) {
  550                 NCR_TRACE("cmd_tmo: call abort, sr=0x%x\n", (long) sr);
  551                 ncr5380_abort(sc);
  552         } else {
  553                 /*
  554                  * The driver may be idle, or busy with another job.
  555                  * Arrange for ncr5380_sched() to do the deed.
  556                  */
  557                 NCR_TRACE("cmd_tmo: clear matrix, t/l=0x%02x\n",
  558                                   (sr->sr_target << 4) | sr->sr_lun);
  559                 sc->sc_matrix[sr->sr_target][sr->sr_lun] = NULL;
  560         }
  561 
  562         /*
  563          * We may have aborted the current job, or may have
  564          * already been idle. In either case, we should now
  565          * be idle, so try to start another job.
  566          */
  567         if (sc->sc_state == NCR_IDLE) {
  568                 NCR_TRACE("cmd_tmo: call sched, cur=0x%x\n",
  569                                   (long) sc->sc_current);
  570                 ncr5380_sched(sc);
  571                 NCR_TRACE("cmd_tmo: sched done, cur=0x%x\n",
  572                     (int)sc->sc_current);
  573         }
  574 
  575 out:
  576         splx(s);
  577 }
  578 
  579 
  580 /*****************************************************************
  581  * Interface to higher level
  582  *****************************************************************/
  583 
  584 
  585 /*
  586  * Enter a new SCSI command into the "issue" queue, and
  587  * if there is work to do, start it going.
  588  *
  589  * WARNING:  This can be called recursively!
  590  * (see comment in ncr5380_done)
  591  */
  592 
  593 void
  594 ncr5380_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
  595     void *arg)
  596 {
  597         struct scsipi_xfer *xs;
  598         struct scsipi_periph *periph;
  599         struct ncr5380_softc *sc;
  600         struct sci_req  *sr;
  601         int s, i, flags;
  602 
  603         sc = device_private(chan->chan_adapter->adapt_dev);
  604 
  605         switch (req) {
  606         case ADAPTER_REQ_RUN_XFER:
  607                 xs = arg;
  608                 periph = xs->xs_periph;
  609                 flags = xs->xs_control;
  610 
  611                 if (flags & XS_CTL_DATA_UIO)
  612                         panic("%s: scsi data uio requested", __func__);
  613 
  614                 s = splbio();
  615 
  616                 if (flags & XS_CTL_POLL) {
  617                         /* Terminate any current command. */
  618                         sr = sc->sc_current;
  619                         if (sr) {
  620                                 printf("%s: polled request aborting %d/%d\n",
  621                                     device_xname(sc->sc_dev),
  622                                     sr->sr_target, sr->sr_lun);
  623                                 ncr5380_abort(sc);
  624                         }
  625                         if (sc->sc_state != NCR_IDLE) {
  626                                 panic("%s: polled request, abort failed",
  627                                     __func__);
  628                         }
  629                 }
  630 
  631                 /*
  632                  * Find lowest empty slot in ring buffer.
  633                  * XXX: What about "fairness" and cmd order?
  634                  */
  635                 for (i = 0; i < SCI_OPENINGS; i++)
  636                         if (sc->sc_ring[i].sr_xs == NULL)
  637                                 goto new;
  638 
  639                 /*
  640                  * This should never happen as we track the resources
  641                  * in the mid-layer.
  642                  */
  643                 scsipi_printaddr(periph);
  644                 printf("unable to allocate ring slot\n");
  645                 panic("%s", __func__);
  646 
  647 new:
  648                 /* Create queue entry */
  649                 sr = &sc->sc_ring[i];
  650                 sr->sr_xs = xs;
  651                 sr->sr_target = periph->periph_target;
  652                 sr->sr_lun = periph->periph_lun;
  653                 sr->sr_dma_hand = NULL;
  654                 sr->sr_dataptr = xs->data;
  655                 sr->sr_datalen = xs->datalen;
  656                 sr->sr_flags = (flags & XS_CTL_POLL) ? SR_IMMED : 0;
  657                 if (xs->xs_control & XS_CTL_REQSENSE)
  658                         sr->sr_flags |= SR_IMMED; /* no disconnect */
  659                 sr->sr_status = -1;     /* no value */
  660                 sc->sc_ncmds++;
  661 
  662                 NCR_TRACE("scsipi_cmd: new sr=0x0\n", (long)sr);
  663 
  664                 if (flags & XS_CTL_POLL) {
  665                         /* Force this new command to be next. */
  666                         sc->sc_rr = i;
  667                 }
  668 
  669                 /*
  670                  * If we were idle, run some commands...
  671                  */
  672                 if (sc->sc_state == NCR_IDLE) {
  673                         NCR_TRACE("scsipi_cmd: call sched, cur=0x%x\n",
  674                                           (long) sc->sc_current);
  675                         ncr5380_sched(sc);
  676                         NCR_TRACE("scsipi_cmd: sched done, cur=0x%x\n",
  677                                           (long) sc->sc_current);
  678                 }
  679 
  680                 if (flags & XS_CTL_POLL) {
  681                         /* Make sure ncr5380_sched() finished it. */
  682                         if ((xs->xs_status & XS_STS_DONE) == 0)
  683                                 panic("%s: poll didn't finish", __func__);
  684                 }
  685                 splx(s);
  686                 return;
  687 
  688         case ADAPTER_REQ_GROW_RESOURCES:
  689                 /* XXX Not supported. */
  690                 return;
  691 
  692         case ADAPTER_REQ_SET_XFER_MODE:
  693             {
  694                 /*
  695                  * We don't support Sync, Wide, or Tagged Queueing.
  696                  * Just callback now, to report this.
  697                  */
  698                 struct scsipi_xfer_mode *xm = arg;
  699 
  700                 xm->xm_mode = 0;
  701                 xm->xm_period = 0;
  702                 xm->xm_offset = 0;
  703                 scsipi_async_event(chan, ASYNC_EVENT_XFER_MODE, xm);
  704                 return;
  705             }
  706         }
  707 }
  708 
  709 /*
  710  * POST PROCESSING OF SCSI_CMD (usually current)
  711  * Called by ncr5380_sched(), ncr5380_machine()
  712  */
  713 static void
  714 ncr5380_done(struct ncr5380_softc *sc)
  715 {
  716         struct  sci_req *sr;
  717         struct  scsipi_xfer *xs;
  718 
  719 #ifdef  DIAGNOSTIC
  720         if (sc->sc_state == NCR_IDLE)
  721                 panic("%s: state=idle", __func__);
  722         if (sc->sc_current == NULL)
  723                 panic("%s: current=0", __func__);
  724 #endif
  725 
  726         sr = sc->sc_current;
  727         xs = sr->sr_xs;
  728 
  729         NCR_TRACE("done: top, cur=0x%x\n", (long) sc->sc_current);
  730 
  731         /*
  732          * Clean up DMA resources for this command.
  733          */
  734         if (sr->sr_dma_hand) {
  735                 NCR_TRACE("done: dma_free, dh=0x%x\n",
  736                                   (long) sr->sr_dma_hand);
  737                 (*sc->sc_dma_free)(sc);
  738         }
  739 #ifdef  DIAGNOSTIC
  740         if (sr->sr_dma_hand)
  741                 panic("%s: DMA free did not", __func__);
  742 #endif
  743 
  744         if (sc->sc_state & NCR_ABORTING) {
  745                 NCR_TRACE("done: aborting, error=%d\n", xs->error);
  746                 if (xs->error == XS_NOERROR)
  747                         xs->error = XS_TIMEOUT;
  748         }
  749 
  750         NCR_TRACE("done: check error=%d\n", (long) xs->error);
  751 
  752         /* If error is already set, ignore sr_status value. */
  753         if (xs->error != XS_NOERROR)
  754                 goto finish;
  755 
  756         NCR_TRACE("done: check status=%d\n", sr->sr_status);
  757 
  758         xs->status = sr->sr_status;
  759         switch (sr->sr_status) {
  760         case SCSI_OK:   /* 0 */
  761                 xs->error = XS_NOERROR;
  762                 break;
  763 
  764         case SCSI_CHECK:
  765         case SCSI_BUSY:
  766                 xs->error = XS_BUSY;
  767                 break;
  768 
  769         case -1:
  770                 /* This is our "impossible" initial value. */
  771                 /* fallthrough */
  772         default:
  773                 printf("%s: target %d, bad status=%d\n",
  774                     device_xname(sc->sc_dev), sr->sr_target, sr->sr_status);
  775                 xs->error = XS_DRIVER_STUFFUP;
  776                 break;
  777         }
  778 
  779 finish:
  780 
  781         NCR_TRACE("done: finish, error=%d\n", xs->error);
  782 
  783         /*
  784          * Dequeue the finished command, but don't clear sc_state until
  785          * after the call to scsipi_done(), because that may call back to
  786          * ncr5380_scsi_cmd() - unwanted recursion!
  787          *
  788          * Keeping sc->sc_state != idle terminates the recursion.
  789          */
  790 #ifdef  DIAGNOSTIC
  791         if ((sc->sc_state & NCR_WORKING) == 0)
  792                 panic("%s: bad state", __func__);
  793 #endif
  794 
  795         /* Clear our pointers to the request. */
  796         sc->sc_current = NULL;
  797         sc->sc_matrix[sr->sr_target][sr->sr_lun] = NULL;
  798         callout_stop(&sr->sr_xs->xs_callout);
  799 
  800         /* Make the request free. */
  801         sr->sr_xs = NULL;
  802         sc->sc_ncmds--;
  803 
  804         /* Tell common SCSI code it is done. */
  805         scsipi_done(xs);
  806 
  807         sc->sc_state = NCR_IDLE;
  808         /* Now ncr5380_sched() may be called again. */
  809 }
  810 
  811 
  812 /*
  813  * Schedule a SCSI operation.  This routine should return
  814  * only after it achieves one of the following conditions:
  815  *      Busy (sc->sc_state != NCR_IDLE)
  816  *      No more work can be started.
  817  */
  818 static void
  819 ncr5380_sched(struct ncr5380_softc *sc)
  820 {
  821         struct sci_req  *sr;
  822         struct scsipi_xfer *xs;
  823         int target = 0, lun = 0;
  824         int error, i;
  825 
  826         /* Another hack (Er.. hook!) for the sun3 si: */
  827         if (sc->sc_intr_off) {
  828                 NCR_TRACE("sched: top, intr off\n", 0);
  829                 sc->sc_intr_off(sc);
  830         }
  831 
  832 next_job:
  833         /*
  834          * Grab the next job from queue.  Must be idle.
  835          */
  836 #ifdef  DIAGNOSTIC
  837         if (sc->sc_state != NCR_IDLE)
  838                 panic("%s: not idle", __func__);
  839         if (sc->sc_current)
  840                 panic("%s: current set", __func__);
  841 #endif
  842 
  843         /*
  844          * Always start the search where we last looked.
  845          * The REQUEST_SENSE logic depends on this to
  846          * choose the same job as was last picked, so it
  847          * can just clear sc_current and reschedule.
  848          * (Avoids loss of "contingent allegiance".)
  849          */
  850         i = sc->sc_rr;
  851         sr = NULL;
  852         do {
  853                 if (sc->sc_ring[i].sr_xs) {
  854                         target = sc->sc_ring[i].sr_target;
  855                         lun = sc->sc_ring[i].sr_lun;
  856                         if (sc->sc_matrix[target][lun] == NULL) {
  857                                 /*
  858                                  * Do not mark the  target/LUN busy yet,
  859                                  * because reselect may cause some other
  860                                  * job to become the current one, so we
  861                                  * might not actually start this job.
  862                                  * Instead, set sc_matrix later on.
  863                                  */
  864                                 sc->sc_rr = i;
  865                                 sr = &sc->sc_ring[i];
  866                                 break;
  867                         }
  868                 }
  869                 i++;
  870                 if (i == SCI_OPENINGS)
  871                         i = 0;
  872         } while (i != sc->sc_rr);
  873 
  874         if (sr == NULL) {
  875                 NCR_TRACE("sched: no work, cur=0x%x\n",
  876                                   (long) sc->sc_current);
  877 
  878                 /* Another hack (Er.. hook!) for the sun3 si: */
  879                 if (sc->sc_intr_on) {
  880                         NCR_TRACE("sched: ret, intr ON\n", 0);
  881                         sc->sc_intr_on(sc);
  882                 }
  883 
  884                 return;         /* No more work to do. */
  885         }
  886 
  887         NCR_TRACE("sched: select for t/l=0x%02x\n",
  888                           (sr->sr_target << 4) | sr->sr_lun);
  889 
  890         sc->sc_state = NCR_WORKING;
  891         error = ncr5380_select(sc, sr);
  892         if (sc->sc_current) {
  893                 /* Lost the race!  reselected out from under us! */
  894                 /* Work with the reselected job. */
  895                 if (sr->sr_flags & SR_IMMED) {
  896                         printf("%s: reselected while polling (abort)\n",
  897                             device_xname(sc->sc_dev));
  898                         /* Abort the reselected job. */
  899                         sc->sc_state |= NCR_ABORTING;
  900                         sc->sc_msgpriq |= SEND_ABORT;
  901                 }
  902                 sr = sc->sc_current;
  903                 xs = sr->sr_xs;
  904                 NCR_TRACE("sched: reselect, new sr=0x%x\n", (long)sr);
  905                 goto have_nexus;
  906         }
  907 
  908         /* Normal selection result.  Target/LUN is now busy. */
  909         sc->sc_matrix[target][lun] = sr;
  910         sc->sc_current = sr;    /* connected */
  911         xs = sr->sr_xs;
  912 
  913         /*
  914          * Initialize pointers, etc. for this job
  915          */
  916         sc->sc_dataptr  = sr->sr_dataptr;
  917         sc->sc_datalen  = sr->sr_datalen;
  918         sc->sc_prevphase = PHASE_INVALID;
  919         sc->sc_msgpriq = SEND_IDENTIFY;
  920         sc->sc_msgoutq = 0;
  921         sc->sc_msgout  = 0;
  922 
  923         NCR_TRACE("sched: select rv=%d\n", error);
  924 
  925         switch (error) {
  926         case XS_NOERROR:
  927                 break;
  928 
  929         case XS_BUSY:
  930                 /* XXX - Reset and try again. */
  931                 printf("%s: select found SCSI bus busy, resetting...\n",
  932                     device_xname(sc->sc_dev));
  933                 ncr5380_reset_scsibus(sc);
  934                 /* fallthrough */
  935         case XS_SELTIMEOUT:
  936         default:
  937                 xs->error = error;      /* from select */
  938                 NCR_TRACE("sched: call done, sr=0x%x\n", (long)sr);
  939                 ncr5380_done(sc);
  940 
  941                 /* Paranoia: clear everything. */
  942                 sc->sc_dataptr = NULL;
  943                 sc->sc_datalen = 0;
  944                 sc->sc_prevphase = PHASE_INVALID;
  945                 sc->sc_msgpriq = 0;
  946                 sc->sc_msgoutq = 0;
  947                 sc->sc_msgout  = 0;
  948 
  949                 goto next_job;
  950         }
  951 
  952         /*
  953          * Selection was successful.  Normally, this means
  954          * we are starting a new command.  However, this
  955          * might be the termination of an overdue job.
  956          */
  957         if (sr->sr_flags & SR_OVERDUE) {
  958                 NCR_TRACE("sched: overdue, sr=0x%x\n", (long)sr);
  959                 sc->sc_state |= NCR_ABORTING;
  960                 sc->sc_msgpriq |= SEND_ABORT;
  961                 goto have_nexus;
  962         }
  963 
  964         /*
  965          * OK, we are starting a new command.
  966          * Initialize and allocate resources for the new command.
  967          * Device reset is special (only uses MSG_OUT phase).
  968          * Normal commands start in MSG_OUT phase where we will
  969          * send and IDENDIFY message, and then expect CMD phase.
  970          */
  971 #ifdef  NCR5380_DEBUG
  972         if (ncr5380_debug & NCR_DBG_CMDS) {
  973                 printf("ncr5380_sched: begin, target=%d, LUN=%d\n",
  974                     xs->xs_periph->periph_target, xs->xs_periph->periph_lun);
  975                 ncr5380_show_scsi_cmd(xs);
  976         }
  977 #endif
  978         if (xs->xs_control & XS_CTL_RESET) {
  979                 NCR_TRACE("sched: cmd=reset, sr=0x%x\n", (long)sr);
  980                 /* Not an error, so do not set NCR_ABORTING */
  981                 sc->sc_msgpriq |= SEND_DEV_RESET;
  982                 goto have_nexus;
  983         }
  984 
  985 #ifdef  DIAGNOSTIC
  986         if ((xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) == 0) {
  987                 if (sc->sc_dataptr) {
  988                         printf("%s: ptr but no data in/out flags?\n",
  989                             device_xname(sc->sc_dev));
  990                         NCR_BREAK();
  991                         sc->sc_dataptr = NULL;
  992                 }
  993         }
  994 #endif
  995 
  996         /* Allocate DMA space (maybe) */
  997         if (sc->sc_dataptr && sc->sc_dma_alloc &&
  998                 (sc->sc_datalen >= sc->sc_min_dma_len))
  999         {
 1000                 NCR_TRACE("sched: dma_alloc, len=%d\n", sc->sc_datalen);
 1001                 (*sc->sc_dma_alloc)(sc);
 1002         }
 1003 
 1004         /*
 1005          * Initialization hook called just after select,
 1006          * at the beginning of COMMAND phase.
 1007          * (but AFTER the DMA allocation is done)
 1008          *
 1009          * The evil Sun "si" adapter (OBIO variant) needs some
 1010          * setup done to the DMA engine BEFORE the target puts
 1011          * the SCSI bus into any DATA phase.
 1012          */
 1013         if (sr->sr_dma_hand && sc->sc_dma_setup) {
 1014                 NCR_TRACE("sched: dma_setup, dh=0x%x\n",
 1015                                   (long) sr->sr_dma_hand);
 1016                 sc->sc_dma_setup(sc);
 1017         }
 1018 
 1019         /*
 1020          * Schedule a timeout for the job we are starting.
 1021          */
 1022         if ((sr->sr_flags & SR_IMMED) == 0) {
 1023                 i = mstohz(xs->timeout);
 1024                 NCR_TRACE("sched: set timeout=%d\n", i);
 1025                 callout_reset(&sr->sr_xs->xs_callout, i,
 1026                     ncr5380_cmd_timeout, sr);
 1027         }
 1028 
 1029 have_nexus:
 1030         NCR_TRACE("sched: call machine, cur=0x%x\n",
 1031                           (long) sc->sc_current);
 1032         ncr5380_machine(sc);
 1033         NCR_TRACE("sched: machine done, cur=0x%x\n",
 1034                           (long) sc->sc_current);
 1035 
 1036         /*
 1037          * What state did ncr5380_machine() leave us in?
 1038          * Hopefully it sometimes completes a job...
 1039          */
 1040         if (sc->sc_state == NCR_IDLE)
 1041                 goto next_job;
 1042 
 1043         return;         /* Have work in progress. */
 1044 }
 1045 
 1046 
 1047 /*
 1048  *  Reselect handler: checks for reselection, and if we are being
 1049  *      reselected, it sets up sc->sc_current.
 1050  *
 1051  *  We are reselected when:
 1052  *      SEL is TRUE
 1053  *      IO  is TRUE
 1054  *      BSY is FALSE
 1055  */
 1056 void
 1057 ncr5380_reselect(struct ncr5380_softc *sc)
 1058 {
 1059         struct sci_req *sr;
 1060         int target, lun, phase, timo;
 1061         int target_mask = 0;    /* XXX gcc (on ns32k) */
 1062         uint8_t bus, data, icmd, mode, msg;
 1063 
 1064 #ifdef  DIAGNOSTIC
 1065         /*
 1066          * Note: sc_state will be "idle" when ncr5380_intr()
 1067          * calls, or "working" when ncr5380_select() calls.
 1068          * (So don't test that in this DIAGNOSTIC)
 1069          */
 1070         if (sc->sc_current)
 1071                 panic("%s: current set", __func__);
 1072 #endif
 1073 
 1074         /*
 1075          * First, check the select line.
 1076          * (That has to be set first.)
 1077          */
 1078         bus = NCR5380_READ(sc, sci_bus_csr);
 1079         if ((bus & SCI_BUS_SEL) == 0) {
 1080                 /* Not a selection or reselection. */
 1081                 return;
 1082         }
 1083 
 1084         /*
 1085          * The target will assert BSY first (for bus arbitration),
 1086          * then raise SEL, and finally drop BSY.  Only then is the
 1087          * data bus required to have valid selection ID bits set.
 1088          * Wait for: SEL==1, BSY==0 before reading the data bus.
 1089          * While this theoretically can happen, we are apparently
 1090          * never fast enough to get here before BSY drops.
 1091          */
 1092         timo = ncr5380_wait_nrq_timo;
 1093         for (;;) {
 1094                 if ((bus & SCI_BUS_BSY) == 0)
 1095                         break;
 1096                 /* Probably never get here... */
 1097                 if (--timo <= 0) {
 1098                         printf("%s: reselect, BSY stuck, bus=0x%x\n",
 1099                             device_xname(sc->sc_dev), bus);
 1100                         /* Not much we can do. Reset the bus. */
 1101                         ncr5380_reset_scsibus(sc);
 1102                         return;
 1103                 }
 1104                 delay(2);
 1105                 bus = NCR5380_READ(sc, sci_bus_csr);
 1106                 /* If SEL went away, forget it. */
 1107                 if ((bus & SCI_BUS_SEL) == 0)
 1108                         return;
 1109                 /* Still have SEL, check BSY. */
 1110         }
 1111         NCR_TRACE("reselect, valid data after %d loops\n",
 1112                           ncr5380_wait_nrq_timo - timo);
 1113 
 1114         /*
 1115          * Good.  We have SEL=1 and BSY=0.  Now wait for a
 1116          * "bus settle delay" before we sample the data bus
 1117          */
 1118         delay(2);
 1119         data = NCR5380_READ(sc, sci_data) & 0xFF;
 1120         /* Parity check is implicit in data validation below. */
 1121 
 1122         /*
 1123          * Is this a reselect (I/O == 1) or have we been
 1124          * selected as a target? (I/O == 0)
 1125          */
 1126         if ((bus & SCI_BUS_IO) == 0) {
 1127                 printf("%s: selected as target, data=0x%x\n",
 1128                     device_xname(sc->sc_dev), data);
 1129                 /* Not much we can do. Reset the bus. */
 1130                 /* XXX: send some sort of message? */
 1131                 ncr5380_reset_scsibus(sc);
 1132                 return;
 1133         }
 1134 
 1135         /*
 1136          * OK, this is a reselection.
 1137          */
 1138         for (target = 0; target < 7; target++) {
 1139                 target_mask = (1 << target);
 1140                 if (data & target_mask)
 1141                         break;
 1142         }
 1143         if ((data & 0x7F) != target_mask) {
 1144                 /* No selecting ID? or >2 IDs on bus? */
 1145                 printf("%s: bad reselect, data=0x%x\n",
 1146                     device_xname(sc->sc_dev), data);
 1147                 return;
 1148         }
 1149 
 1150         NCR_TRACE("reselect: target=0x%x\n", target);
 1151 
 1152         /* Raise BSY to acknowledge target reselection. */
 1153         NCR5380_WRITE(sc, sci_icmd, SCI_ICMD_BSY);
 1154 
 1155         /* Wait for target to drop SEL. */
 1156         timo = ncr5380_wait_nrq_timo;
 1157         for (;;) {
 1158                 bus = NCR5380_READ(sc, sci_bus_csr);
 1159                 if ((bus & SCI_BUS_SEL) == 0)
 1160                         break;  /* success */
 1161                 if (--timo <= 0) {
 1162                         printf("%s: reselect, SEL stuck, bus=0x%x\n",
 1163                             device_xname(sc->sc_dev), bus);
 1164                         NCR_BREAK();
 1165                         /* assume connected (fail later if not) */
 1166                         break;
 1167                 }
 1168                 delay(2);
 1169         }
 1170 
 1171         /* Now we drop BSY, and we are connected. */
 1172         NCR5380_WRITE(sc, sci_icmd, 0);
 1173         NCR5380_WRITE(sc, sci_sel_enb, 0);
 1174         SCI_CLR_INTR(sc);
 1175 
 1176         /*
 1177          * At this point the target should send an IDENTIFY message,
 1178          * which will permit us to determine the reselecting LUN.
 1179          * If not, we assume LUN 0.
 1180          */
 1181         lun = 0;
 1182         /* Wait for REQ before reading bus phase. */
 1183         if (ncr5380_wait_req(sc)) {
 1184                 printf("%s: reselect, no REQ\n",
 1185                     device_xname(sc->sc_dev));
 1186                 /* Try to send an ABORT message. */
 1187                 goto abort;
 1188         }
 1189         phase = SCI_BUS_PHASE(NCR5380_READ(sc, sci_bus_csr));
 1190         if (phase != PHASE_MSG_IN) {
 1191                 printf("%s: reselect, phase=%d\n",
 1192                     device_xname(sc->sc_dev), phase);
 1193                 goto abort;
 1194         }
 1195 
 1196         /* Ack. the change to PHASE_MSG_IN */
 1197         NCR5380_WRITE(sc, sci_tcmd, PHASE_MSG_IN);
 1198 
 1199         /* Peek at the message byte without consuming it! */
 1200         msg = NCR5380_READ(sc, sci_data);
 1201         if ((msg & 0x80) == 0) {
 1202                 printf("%s: reselect, not identify, msg=%d\n",
 1203                     device_xname(sc->sc_dev), msg);
 1204                 goto abort;
 1205         }
 1206         lun = msg & 7;
 1207 
 1208         /* We now know target/LUN.  Do we have the request? */
 1209         sr = sc->sc_matrix[target][lun];
 1210         if (sr) {
 1211                 /* We now have a nexus. */
 1212                 sc->sc_state |= NCR_WORKING;
 1213                 sc->sc_current = sr;
 1214                 NCR_TRACE("reselect: resume sr=0x%x\n", (long)sr);
 1215 
 1216                 /* Implicit restore pointers message */
 1217                 sc->sc_dataptr = sr->sr_dataptr;
 1218                 sc->sc_datalen = sr->sr_datalen;
 1219 
 1220                 sc->sc_prevphase = PHASE_INVALID;
 1221                 sc->sc_msgpriq = 0;
 1222                 sc->sc_msgoutq = 0;
 1223                 sc->sc_msgout  = 0;
 1224 
 1225                 /* XXX: Restore the normal mode register. */
 1226                 /* If this target's bit is set, do NOT check parity. */
 1227                 if (sc->sc_parity_disable & target_mask)
 1228                         mode = SCI_MODE_MONBSY;
 1229                 else
 1230                         mode = SCI_MODE_MONBSY | SCI_MODE_PAR_CHK;
 1231                 /* XXX CXD1180 asserts MONBSY before disconnect */
 1232                 if (sc->sc_rev == NCR_VARIANT_CXD1180)
 1233                         mode &= ~SCI_MODE_MONBSY;
 1234 
 1235                 NCR5380_WRITE(sc, sci_mode, mode);
 1236 
 1237                 /*
 1238                  * Another hack for the Sun3 "si", which needs
 1239                  * some setup done to its DMA engine before the
 1240                  * target puts the SCSI bus into any DATA phase.
 1241                  */
 1242                 if (sr->sr_dma_hand && sc->sc_dma_setup) {
 1243                         NCR_TRACE("reselect: call DMA setup, dh=0x%x\n",
 1244                                           (long) sr->sr_dma_hand);
 1245                     sc->sc_dma_setup(sc);
 1246                 }
 1247 
 1248                 /* Now consume the IDENTIFY message. */
 1249                 ncr5380_pio_in(sc, PHASE_MSG_IN, 1, &msg);
 1250                 return;
 1251         }
 1252 
 1253         printf("%s: phantom reselect: target=%d, LUN=%d\n",
 1254             device_xname(sc->sc_dev), target, lun);
 1255 abort:
 1256         /*
 1257          * Try to send an ABORT message.  This makes us
 1258          * temporarily busy, but no current command...
 1259          */
 1260         sc->sc_state |= NCR_ABORTING;
 1261 
 1262         /* Raise ATN, delay, raise ACK... */
 1263         icmd = SCI_ICMD_ATN;
 1264         NCR5380_WRITE(sc, sci_icmd, icmd);
 1265         delay(2);
 1266 
 1267         /* Now consume the IDENTIFY message. */
 1268         ncr5380_pio_in(sc, PHASE_MSG_IN, 1, &msg);
 1269 
 1270         /* Finally try to send the ABORT. */
 1271         sc->sc_prevphase = PHASE_INVALID;
 1272         sc->sc_msgpriq = SEND_ABORT;
 1273         ncr5380_msg_out(sc);
 1274 
 1275         NCR5380_WRITE(sc, sci_tcmd, PHASE_INVALID);
 1276         NCR5380_WRITE(sc, sci_sel_enb, 0);
 1277         SCI_CLR_INTR(sc);
 1278         NCR5380_WRITE(sc, sci_sel_enb, 0x80);
 1279 
 1280         sc->sc_state &= ~NCR_ABORTING;
 1281 }
 1282 
 1283 
 1284 /*
 1285  *  Select target: xs is the transfer that we are selecting for.
 1286  *  sc->sc_current should be NULL.
 1287  *
 1288  *  Returns:
 1289  *      sc->sc_current != NULL  ==> we were reselected (race!)
 1290  *      XS_NOERROR              ==> selection worked
 1291  *      XS_BUSY                 ==> lost arbitration
 1292  *      XS_SELTIMEOUT           ==> no response to selection
 1293  */
 1294 static int
 1295 ncr5380_select(struct ncr5380_softc *sc, struct sci_req *sr)
 1296 {
 1297         int timo, s, target_mask;
 1298         uint8_t data, icmd, mode;
 1299 
 1300         /* Check for reselect */
 1301         ncr5380_reselect(sc);
 1302         if (sc->sc_current) {
 1303                 NCR_TRACE("select: reselect, cur=0x%x\n",
 1304                                   (long) sc->sc_current);
 1305                 return XS_BUSY; /* reselected */
 1306         }
 1307 
 1308         /*
 1309          * Set phase bits to 0, otherwise the 5380 won't drive the bus during
 1310          * selection.
 1311          */
 1312         NCR5380_WRITE(sc, sci_tcmd, PHASE_DATA_OUT);
 1313         NCR5380_WRITE(sc, sci_icmd, 0);
 1314         icmd = 0;
 1315         NCR5380_WRITE(sc, sci_mode, 0);
 1316 
 1317         /*
 1318          * Arbitrate for the bus.  The 5380 takes care of the
 1319          * time-critical bus interactions.  We set our ID bit
 1320          * in the output data register and set MODE_ARB.  The
 1321          * 5380 watches for the required "bus free" period.
 1322          * If and when the "bus free" period is detected, the
 1323          * 5380 drives BSY, drives the data bus, and sets the
 1324          * "arbitration in progress" (AIP) bit to let us know
 1325          * arbitration has started (and that it asserts BSY).
 1326          * We then wait for one arbitration delay (2.2uS) and
 1327          * check the ICMD_LST bit, which will be set if some
 1328          * other target drives SEL during arbitration.
 1329          *
 1330          * There is a time-critical section during the period
 1331          * after we enter arbitration up until we assert SEL.
 1332          * Avoid long interrupts during this period.
 1333          */
 1334         s = splvm();    /* XXX: Begin time-critical section */
 1335 
 1336         NCR5380_WRITE(sc, sci_odata, 0x80);     /* OUR_ID */
 1337         NCR5380_WRITE(sc, sci_mode, SCI_MODE_ARB);
 1338 
 1339 #define WAIT_AIP_USEC   20      /* pleanty of time */
 1340         /* Wait for the AIP bit to turn on. */
 1341         timo = WAIT_AIP_USEC;
 1342         for (;;) {
 1343                 if (NCR5380_READ(sc, sci_icmd) & SCI_ICMD_AIP)
 1344                         break;
 1345                 if (timo <= 0) {
 1346                         /*
 1347                          * Did not see any "bus free" period.
 1348                          * The usual reason is a reselection,
 1349                          * so treat this as arbitration loss.
 1350                          */
 1351                         NCR_TRACE("select: bus busy, rc=%d\n", XS_BUSY);
 1352                         goto lost_arb;
 1353                 }
 1354                 timo -= 2;
 1355                 delay(2);
 1356         }
 1357         NCR_TRACE("select: have AIP after %d uSec.\n",
 1358                           WAIT_AIP_USEC - timo);
 1359 
 1360         /* Got AIP.  Wait one arbitration delay (2.2 uS.) */
 1361         delay(3);
 1362 
 1363         /* Check for ICMD_LST */
 1364         if (NCR5380_READ(sc, sci_icmd) & SCI_ICMD_LST) {
 1365                 /* Some other target asserted SEL. */
 1366                 NCR_TRACE("select: lost one, rc=%d\n", XS_BUSY);
 1367                 goto lost_arb;
 1368         }
 1369 
 1370         /*
 1371          * No other device has declared itself the winner.
 1372          * The spec. says to check for higher IDs, but we
 1373          * are always the highest (ID=7) so don't bother.
 1374          * We can now declare victory by asserting SEL.
 1375          *
 1376          * Note that the 5380 is asserting BSY because we
 1377          * have entered arbitration mode.  We will now hold
 1378          * BSY directly so we can turn off ARB mode.
 1379          */
 1380         icmd = (SCI_ICMD_BSY | SCI_ICMD_SEL);
 1381         NCR5380_WRITE(sc, sci_icmd, icmd);
 1382 
 1383         /*
 1384          * "The SCSI device that wins arbitration shall wait
 1385          *  at least a bus clear delay plus a bus settle delay
 1386          *  after asserting the SEL signal before changing
 1387          *  any [other] signal."  (1.2uS. total)
 1388          */
 1389         delay(2);
 1390 
 1391         /*
 1392          * Check one last time to see if we really did
 1393          * win arbitration.  This might only happen if
 1394          * there can be a higher selection ID than ours.
 1395          * Keep this code for reference anyway...
 1396          */
 1397         /* XXX CXD1180 asserts LST here */
 1398         if ((sc->sc_rev != NCR_VARIANT_CXD1180) &&
 1399             (NCR5380_READ(sc, sci_icmd) & SCI_ICMD_LST)) {
 1400                 /* Some other target asserted SEL. */
 1401                 NCR_TRACE("select: lost two, rc=%d\n", XS_BUSY);
 1402 
 1403         lost_arb:
 1404                 NCR5380_WRITE(sc, sci_icmd, 0);
 1405                 NCR5380_WRITE(sc, sci_mode, 0);
 1406 
 1407                 splx(s);        /* XXX: End of time-critical section. */
 1408 
 1409                 /*
 1410                  * When we lose arbitration, it usually means
 1411                  * there is a target trying to reselect us.
 1412                  */
 1413                 ncr5380_reselect(sc);
 1414                 return XS_BUSY;
 1415         }
 1416 
 1417         /* Leave ARB mode Now that we drive BSY+SEL */
 1418         NCR5380_WRITE(sc, sci_mode, 0);
 1419         NCR5380_WRITE(sc, sci_sel_enb, 0);
 1420 
 1421         splx(s);        /* XXX: End of time-critical section. */
 1422 
 1423         /*
 1424          * Arbitration is complete.  Now do selection:
 1425          * Drive the data bus with the ID bits for both
 1426          * the host and target.  Also set ATN now, to
 1427          * ask the target for a message out phase.
 1428          */
 1429         target_mask = (1 << sr->sr_target);
 1430         data = 0x80 | target_mask;
 1431         NCR5380_WRITE(sc, sci_odata, data);
 1432         icmd |= (SCI_ICMD_DATA | SCI_ICMD_ATN);
 1433         NCR5380_WRITE(sc, sci_icmd, icmd);
 1434         delay(2);       /* two deskew delays. */
 1435 
 1436         /* De-assert BSY (targets sample the data now). */
 1437         icmd &= ~SCI_ICMD_BSY;
 1438         NCR5380_WRITE(sc, sci_icmd, icmd);
 1439         delay(3);       /* Bus settle delay. */
 1440 
 1441         /*
 1442          * Wait for the target to assert BSY.
 1443          * SCSI spec. says wait for 250 mS.
 1444          */
 1445         for (timo = 25000;;) {
 1446                 if (NCR5380_READ(sc, sci_bus_csr) & SCI_BUS_BSY)
 1447                         goto success;
 1448                 if (--timo <= 0)
 1449                         break;
 1450                 delay(10);
 1451         }
 1452 
 1453         /*
 1454          * There is no reaction from the target.  Start the selection
 1455          * timeout procedure. We release the databus but keep SEL+ATN
 1456          * asserted. After that we wait a 'selection abort time' (200
 1457          * usecs) and 2 deskew delays (90 ns) and check BSY again.
 1458          * When BSY is asserted, we assume the selection succeeded,
 1459          * otherwise we release the bus.
 1460          */
 1461         icmd &= ~SCI_ICMD_DATA;
 1462         NCR5380_WRITE(sc, sci_icmd, icmd);
 1463         delay(201);
 1464         if ((NCR5380_READ(sc, sci_bus_csr) & SCI_BUS_BSY) == 0) {
 1465                 /* Really no device on bus */
 1466                 NCR5380_WRITE(sc, sci_tcmd, PHASE_INVALID);
 1467                 NCR5380_WRITE(sc, sci_icmd, 0);
 1468                 NCR5380_WRITE(sc, sci_mode, 0);
 1469                 NCR5380_WRITE(sc, sci_sel_enb, 0);
 1470                 SCI_CLR_INTR(sc);
 1471                 NCR5380_WRITE(sc, sci_sel_enb, 0x80);
 1472                 NCR_TRACE("select: device down, rc=%d\n", XS_SELTIMEOUT);
 1473                 return XS_SELTIMEOUT;
 1474         }
 1475 
 1476 success:
 1477         /*
 1478          * The target is now driving BSY, so we can stop
 1479          * driving SEL and the data bus (keep ATN true).
 1480          * Configure the ncr5380 to monitor BSY, parity.
 1481          */
 1482         icmd &= ~(SCI_ICMD_DATA | SCI_ICMD_SEL);
 1483         NCR5380_WRITE(sc, sci_icmd, icmd);
 1484 
 1485         /* If this target's bit is set, do NOT check parity. */
 1486         if (sc->sc_parity_disable & target_mask)
 1487                 mode = SCI_MODE_MONBSY;
 1488         else
 1489                 mode = SCI_MODE_MONBSY | SCI_MODE_PAR_CHK;
 1490         /* XXX CXD1180 asserts MONBSY before disconnect */
 1491         if (sc->sc_rev == NCR_VARIANT_CXD1180)
 1492                 mode &= ~SCI_MODE_MONBSY;
 1493 
 1494         NCR5380_WRITE(sc, sci_mode, mode);
 1495 
 1496         return XS_NOERROR;
 1497 }
 1498 
 1499 
 1500 /*****************************************************************
 1501  * Functions to handle each info. transfer phase:
 1502  *****************************************************************/
 1503 
 1504 /*
 1505  * The message system:
 1506  *
 1507  * This is a revamped message system that now should easier accommodate
 1508  * new messages, if necessary.
 1509  *
 1510  * Currently we accept these messages:
 1511  * IDENTIFY (when reselecting)
 1512  * COMMAND COMPLETE # (expect bus free after messages marked #)
 1513  * NOOP
 1514  * MESSAGE REJECT
 1515  * SYNCHRONOUS DATA TRANSFER REQUEST
 1516  * SAVE DATA POINTER
 1517  * RESTORE POINTERS
 1518  * DISCONNECT #
 1519  *
 1520  * We may send these messages in prioritized order:
 1521  * BUS DEVICE RESET #           if XS_CTL_RESET & xs->xs_control (or in
 1522  *                              weird sits.)
 1523  * MESSAGE PARITY ERROR         par. err. during MSGI
 1524  * MESSAGE REJECT               If we get a message we don't know how to handle
 1525  * ABORT #                      send on errors
 1526  * INITIATOR DETECTED ERROR     also on errors (SCSI2) (during info xfer)
 1527  * IDENTIFY                     At the start of each transfer
 1528  * SYNCHRONOUS DATA TRANSFER REQUEST    if appropriate
 1529  * NOOP                         if nothing else fits the bill ...
 1530  */
 1531 
 1532 /*
 1533  * Precondition:
 1534  * The SCSI bus is already in the MSGI phase and there is a message byte
 1535  * on the bus, along with an asserted REQ signal.
 1536  *
 1537  * Our return value determines whether our caller, ncr5380_machine()
 1538  * will expect to see another REQ (and possibly phase change).
 1539  */
 1540 static int
 1541 ncr5380_msg_in(struct ncr5380_softc *sc)
 1542 {
 1543         struct sci_req *sr = sc->sc_current;
 1544         struct scsipi_xfer *xs = sr->sr_xs;
 1545         int n, phase;
 1546         int act_flags;
 1547         uint8_t icmd;
 1548 
 1549         /* acknowledge phase change */
 1550         NCR5380_WRITE(sc, sci_tcmd, PHASE_MSG_IN);
 1551 
 1552         act_flags = ACT_CONTINUE;
 1553         icmd = NCR5380_READ(sc, sci_icmd) & SCI_ICMD_RMASK;
 1554 
 1555         if (sc->sc_prevphase == PHASE_MSG_IN) {
 1556                 /* This is a continuation of the previous message. */
 1557                 n = sc->sc_imp - sc->sc_imess;
 1558                 NCR_TRACE("msg_in: continuation, n=%d\n", n);
 1559                 goto nextbyte;
 1560         }
 1561 
 1562         /* This is a new MESSAGE IN phase.  Clean up our state. */
 1563         sc->sc_state &= ~NCR_DROP_MSGIN;
 1564 
 1565 nextmsg:
 1566         n = 0;
 1567         sc->sc_imp = &sc->sc_imess[n];
 1568 
 1569 nextbyte:
 1570         /*
 1571          * Read a whole message, but don't ack the last byte.  If we reject the
 1572          * message, we have to assert ATN during the message transfer phase
 1573          * itself.
 1574          */
 1575         for (;;) {
 1576                 /*
 1577                  * Read a message byte.
 1578                  * First, check BSY, REQ, phase...
 1579                  */
 1580                 if (!SCI_BUSY(sc)) {
 1581                         NCR_TRACE("msg_in: lost BSY, n=%d\n", n);
 1582                         /* XXX - Assume the command completed? */
 1583                         act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
 1584                         return act_flags;
 1585                 }
 1586                 if (ncr5380_wait_req(sc)) {
 1587                         NCR_TRACE("msg_in: BSY but no REQ, n=%d\n", n);
 1588                         /* Just let ncr5380_machine() handle it... */
 1589                         return act_flags;
 1590                 }
 1591                 phase = SCI_BUS_PHASE(NCR5380_READ(sc, sci_bus_csr));
 1592                 if (phase != PHASE_MSG_IN) {
 1593                         /*
 1594                          * Target left MESSAGE IN, probably because it
 1595                          * a) noticed our ATN signal, or
 1596                          * b) ran out of messages.
 1597                          */
 1598                         return act_flags;
 1599                 }
 1600                 /* Still in MESSAGE IN phase, and REQ is asserted. */
 1601                 if (NCR5380_READ(sc, sci_csr) & SCI_CSR_PERR) {
 1602                         ncr_sched_msgout(sc, SEND_PARITY_ERROR);
 1603                         sc->sc_state |= NCR_DROP_MSGIN;
 1604                 }
 1605 
 1606                 /* Gather incoming message bytes if needed. */
 1607                 if ((sc->sc_state & NCR_DROP_MSGIN) == 0) {
 1608                         if (n >= NCR_MAX_MSG_LEN) {
 1609                                 ncr_sched_msgout(sc, SEND_REJECT);
 1610                                 sc->sc_state |= NCR_DROP_MSGIN;
 1611                         } else {
 1612                                 *sc->sc_imp++ = NCR5380_READ(sc, sci_data);
 1613                                 n++;
 1614                                 /*
 1615                                  * This testing is suboptimal, but most
 1616                                  * messages will be of the one byte variety, so
 1617                                  * it should not affect performance
 1618                                  * significantly.
 1619                                  */
 1620                                 if (n == 1 && MSG_IS1BYTE(sc->sc_imess[0]))
 1621                                         goto have_msg;
 1622                                 if (n == 2 && MSG_IS2BYTE(sc->sc_imess[0]))
 1623                                         goto have_msg;
 1624                                 if (n >= 3 && MSG_ISEXTENDED(sc->sc_imess[0]) &&
 1625                                         n == sc->sc_imess[1] + 2)
 1626                                         goto have_msg;
 1627                         }
 1628                 }
 1629 
 1630                 /*
 1631                  * If we reach this spot we're either:
 1632                  * a) in the middle of a multi-byte message, or
 1633                  * b) dropping bytes.
 1634                  */
 1635 
 1636                 /* Ack the last byte read. */
 1637                 icmd |= SCI_ICMD_ACK;
 1638                 NCR5380_WRITE(sc, sci_icmd, icmd);
 1639 
 1640                 if (ncr5380_wait_not_req(sc)) {
 1641                         NCR_TRACE("msg_in: drop, stuck REQ, n=%d\n", n);
 1642                         act_flags |= ACT_RESET_BUS;
 1643                 }
 1644 
 1645                 icmd &= ~SCI_ICMD_ACK;
 1646                 NCR5380_WRITE(sc, sci_icmd, icmd);
 1647 
 1648                 if (act_flags != ACT_CONTINUE)
 1649                         return act_flags;
 1650 
 1651                 /* back to nextbyte */
 1652         }
 1653 
 1654 have_msg:
 1655         /* We now have a complete message.  Parse it. */
 1656 
 1657         switch (sc->sc_imess[0]) {
 1658         case MSG_CMDCOMPLETE:
 1659                 NCR_TRACE("msg_in: CMDCOMPLETE\n", 0);
 1660                 /* Target is about to disconnect. */
 1661                 act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
 1662                 break;
 1663 
 1664         case MSG_PARITY_ERROR:
 1665                 NCR_TRACE("msg_in: PARITY_ERROR\n", 0);
 1666                 /* Resend the last message. */
 1667                 ncr_sched_msgout(sc, sc->sc_msgout);
 1668                 /* Reset icmd after scheduling the REJECT cmd - jwg */
 1669                 icmd = NCR5380_READ(sc, sci_icmd) & SCI_ICMD_RMASK;
 1670                 break;
 1671 
 1672         case MSG_MESSAGE_REJECT:
 1673                 /* The target rejects the last message we sent. */
 1674                 NCR_TRACE("msg_in: got reject for 0x%x\n", sc->sc_msgout);
 1675                 switch (sc->sc_msgout) {
 1676                 case SEND_IDENTIFY:
 1677                         /* Really old target controller? */
 1678                         /* XXX ... */
 1679                         break;
 1680                 case SEND_INIT_DET_ERR:
 1681                         goto abort;
 1682                 }
 1683                 break;
 1684 
 1685         case MSG_NOOP:
 1686                 NCR_TRACE("msg_in: NOOP\n", 0);
 1687                 break;
 1688 
 1689         case MSG_DISCONNECT:
 1690                 NCR_TRACE("msg_in: DISCONNECT\n", 0);
 1691                 /* Target is about to disconnect. */
 1692                 act_flags |= ACT_DISCONNECT;
 1693                 if ((xs->xs_periph->periph_quirks & PQUIRK_AUTOSAVE) == 0)
 1694                         break;
 1695                 /*FALLTHROUGH*/
 1696 
 1697         case MSG_SAVEDATAPOINTER:
 1698                 NCR_TRACE("msg_in: SAVE_PTRS\n", 0);
 1699                 sr->sr_dataptr = sc->sc_dataptr;
 1700                 sr->sr_datalen = sc->sc_datalen;
 1701                 break;
 1702 
 1703         case MSG_RESTOREPOINTERS:
 1704                 NCR_TRACE("msg_in: RESTORE_PTRS\n", 0);
 1705                 sc->sc_dataptr = sr->sr_dataptr;
 1706                 sc->sc_datalen = sr->sr_datalen;
 1707                 break;
 1708 
 1709         case MSG_EXTENDED:
 1710                 switch (sc->sc_imess[2]) {
 1711                 case MSG_EXT_SDTR:
 1712                 case MSG_EXT_WDTR:
 1713                         /* The ncr5380 can not do synchronous mode. */
 1714                         goto reject;
 1715                 default:
 1716                         printf("%s: unrecognized MESSAGE EXTENDED; "
 1717                             "sending REJECT\n",
 1718                             device_xname(sc->sc_dev));
 1719                         NCR_BREAK();
 1720                         goto reject;
 1721                 }
 1722                 break;
 1723 
 1724         default:
 1725                 NCR_TRACE("msg_in: eh? imsg=0x%x\n", sc->sc_imess[0]);
 1726                 printf("%s: unrecognized MESSAGE; sending REJECT\n",
 1727                     device_xname(sc->sc_dev));
 1728                 NCR_BREAK();
 1729                 /* fallthrough */
 1730         reject:
 1731                 ncr_sched_msgout(sc, SEND_REJECT);
 1732                 /* Reset icmd after scheduling the REJECT cmd - jwg */
 1733                 icmd = NCR5380_READ(sc, sci_icmd) & SCI_ICMD_RMASK;
 1734                 break;
 1735 
 1736         abort:
 1737                 sc->sc_state |= NCR_ABORTING;
 1738                 ncr_sched_msgout(sc, SEND_ABORT);
 1739                 break;
 1740         }
 1741 
 1742         /* Ack the last byte read. */
 1743         icmd |= SCI_ICMD_ACK;
 1744         NCR5380_WRITE(sc, sci_icmd, icmd);
 1745 
 1746         if (ncr5380_wait_not_req(sc)) {
 1747                 NCR_TRACE("msg_in: last, stuck REQ, n=%d\n", n);
 1748                 act_flags |= ACT_RESET_BUS;
 1749         }
 1750 
 1751         icmd &= ~SCI_ICMD_ACK;
 1752         NCR5380_WRITE(sc, sci_icmd, icmd);
 1753 
 1754         /* Go get the next message, if any. */
 1755         if (act_flags == ACT_CONTINUE)
 1756                 goto nextmsg;
 1757 
 1758         return act_flags;
 1759 }
 1760 
 1761 
 1762 /*
 1763  * The message out (and in) stuff is a bit complicated:
 1764  * If the target requests another message (sequence) without
 1765  * having changed phase in between it really asks for a
 1766  * retransmit, probably due to parity error(s).
 1767  * The following messages can be sent:
 1768  * IDENTIFY        @ These 4 stem from SCSI command activity
 1769  * SDTR            @
 1770  * WDTR            @
 1771  * DEV_RESET       @
 1772  * REJECT if MSGI doesn't make sense
 1773  * PARITY_ERROR if parity error while in MSGI
 1774  * INIT_DET_ERR if parity error while not in MSGI
 1775  * ABORT if INIT_DET_ERR rejected
 1776  * NOOP if asked for a message and there's nothing to send
 1777  *
 1778  * Note that we call this one with (sc_current == NULL)
 1779  * when sending ABORT for unwanted reselections.
 1780  */
 1781 static int
 1782 ncr5380_msg_out(struct ncr5380_softc *sc)
 1783 {
 1784         struct sci_req *sr = sc->sc_current;
 1785         int act_flags, n, phase, progress;
 1786         uint8_t icmd, msg;
 1787 
 1788         /* acknowledge phase change */
 1789         NCR5380_WRITE(sc, sci_tcmd, PHASE_MSG_OUT);
 1790 
 1791         progress = 0;   /* did we send any messages? */
 1792         act_flags = ACT_CONTINUE;
 1793 
 1794         /*
 1795          * Set ATN.  If we're just sending a trivial 1-byte message,
 1796          * we'll clear ATN later on anyway.  Also drive the data bus.
 1797          */
 1798         icmd = NCR5380_READ(sc, sci_icmd) & SCI_ICMD_RMASK;
 1799         icmd |= (SCI_ICMD_ATN | SCI_ICMD_DATA);
 1800         NCR5380_WRITE(sc, sci_icmd, icmd);
 1801 
 1802         if (sc->sc_prevphase == PHASE_MSG_OUT) {
 1803                 if (sc->sc_omp == sc->sc_omess) {
 1804                         /*
 1805                          * This is a retransmission.
 1806                          *
 1807                          * We get here if the target stayed in MESSAGE OUT
 1808                          * phase.  Section 5.1.9.2 of the SCSI 2 spec indicates
 1809                          * that all of the previously transmitted messages must
 1810                          * be sent again, in the same order.  Therefore, we
 1811                          * requeue all the previously transmitted messages, and
 1812                          * start again from the top.  Our simple priority
 1813                          * scheme keeps the messages in the right order.
 1814                          */
 1815                         sc->sc_msgpriq |= sc->sc_msgoutq;
 1816                         NCR_TRACE("msg_out: retrans priq=0x%x\n",
 1817                             sc->sc_msgpriq);
 1818                 } else {
 1819                         /* This is a continuation of the previous message. */
 1820                         n = sc->sc_omp - sc->sc_omess;
 1821                         NCR_TRACE("msg_out: continuation, n=%d\n", n);
 1822                         goto nextbyte;
 1823                 }
 1824         }
 1825 
 1826         /* No messages transmitted so far. */
 1827         sc->sc_msgoutq = 0;
 1828 
 1829 nextmsg:
 1830         /* Pick up highest priority message. */
 1831         sc->sc_msgout = sc->sc_msgpriq & -sc->sc_msgpriq;
 1832         sc->sc_msgpriq &= ~sc->sc_msgout;
 1833         sc->sc_msgoutq |= sc->sc_msgout;
 1834 
 1835         /* Build the outgoing message data. */
 1836         switch (sc->sc_msgout) {
 1837         case SEND_IDENTIFY:
 1838                 NCR_TRACE("msg_out: SEND_IDENTIFY\n", 0);
 1839                 if (sr == NULL) {
 1840                         printf("%s: SEND_IDENTIFY while not connected; "
 1841                             "sending NOOP\n",
 1842                             device_xname(sc->sc_dev));
 1843                         NCR_BREAK();
 1844                         goto noop;
 1845                 }
 1846                 /*
 1847                  * The identify message we send determines whether
 1848                  * disconnect/reselect is allowed for this command.
 1849                  * 0xC0+LUN: allows it, 0x80+LUN disallows it.
 1850                  */
 1851                 msg = 0xc0;     /* MSG_IDENTIFY(0,1) */
 1852                 if (sc->sc_no_disconnect & (1 << sr->sr_target))
 1853                         msg = 0x80;
 1854                 if (sr->sr_flags & (SR_IMMED))
 1855                         msg = 0x80;
 1856                 sc->sc_omess[0] = msg | sr->sr_lun;
 1857                 n = 1;
 1858                 break;
 1859 
 1860         case SEND_DEV_RESET:
 1861                 NCR_TRACE("msg_out: SEND_DEV_RESET\n", 0);
 1862                 /* Expect disconnect after this! */
 1863                 /* XXX: Kill jobs for this target? */
 1864                 act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
 1865                 sc->sc_omess[0] = MSG_BUS_DEV_RESET;
 1866                 n = 1;
 1867                 break;
 1868 
 1869         case SEND_REJECT:
 1870                 NCR_TRACE("msg_out: SEND_REJECT\n", 0);
 1871                 sc->sc_omess[0] = MSG_MESSAGE_REJECT;
 1872                 n = 1;
 1873                 break;
 1874 
 1875         case SEND_PARITY_ERROR:
 1876                 NCR_TRACE("msg_out: SEND_PARITY_ERROR\n", 0);
 1877                 sc->sc_omess[0] = MSG_PARITY_ERROR;
 1878                 n = 1;
 1879                 break;
 1880 
 1881         case SEND_INIT_DET_ERR:
 1882                 NCR_TRACE("msg_out: SEND_INIT_DET_ERR\n", 0);
 1883                 sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
 1884                 n = 1;
 1885                 break;
 1886 
 1887         case SEND_ABORT:
 1888                 NCR_TRACE("msg_out: SEND_ABORT\n", 0);
 1889                 /* Expect disconnect after this! */
 1890                 /* XXX: Set error flag? */
 1891                 act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
 1892                 sc->sc_omess[0] = MSG_ABORT;
 1893                 n = 1;
 1894                 break;
 1895 
 1896         case 0:
 1897                 printf("%s: unexpected MESSAGE OUT; sending NOOP\n",
 1898                     device_xname(sc->sc_dev));
 1899                 NCR_BREAK();
 1900         noop:
 1901                 NCR_TRACE("msg_out: send NOOP\n", 0);
 1902                 sc->sc_omess[0] = MSG_NOOP;
 1903                 n = 1;
 1904                 break;
 1905 
 1906         default:
 1907                 printf("%s: weird MESSAGE OUT; sending NOOP\n",
 1908                     device_xname(sc->sc_dev));
 1909                 NCR_BREAK();
 1910                 goto noop;
 1911         }
 1912         sc->sc_omp = &sc->sc_omess[n];
 1913 
 1914 nextbyte:
 1915         /* Send message bytes. */
 1916         while (n > 0) {
 1917                 /*
 1918                  * Send a message byte.
 1919                  * First check BSY, REQ, phase...
 1920                  */
 1921                 if (!SCI_BUSY(sc)) {
 1922                         NCR_TRACE("msg_out: lost BSY, n=%d\n", n);
 1923                         goto out;
 1924                 }
 1925                 if (ncr5380_wait_req(sc)) {
 1926                         NCR_TRACE("msg_out: no REQ, n=%d\n", n);
 1927                         goto out;
 1928                 }
 1929                 phase = SCI_BUS_PHASE(NCR5380_READ(sc, sci_bus_csr));
 1930                 if (phase != PHASE_MSG_OUT) {
 1931                         /*
 1932                          * Target left MESSAGE OUT, possibly to reject
 1933                          * our message.
 1934                          */
 1935                         NCR_TRACE("msg_out: new phase=%d\n", phase);
 1936                         goto out;
 1937                 }
 1938 
 1939                 /* Yes, we can send this message byte. */
 1940                 --n;
 1941 
 1942                 /* Clear ATN before last byte if this is the last message. */
 1943                 if (n == 0 && sc->sc_msgpriq == 0) {
 1944                         icmd &= ~SCI_ICMD_ATN;
 1945                         NCR5380_WRITE(sc, sci_icmd, icmd);
 1946                         /* 2 deskew delays */
 1947                         delay(2);       /* XXX */
 1948                 }
 1949 
 1950                 /* Put data on the bus. */
 1951                 NCR5380_WRITE(sc, sci_odata, *--sc->sc_omp);
 1952 
 1953                 /* Raise ACK to tell target data is on the bus. */
 1954                 icmd |= SCI_ICMD_ACK;
 1955                 NCR5380_WRITE(sc, sci_icmd, icmd);
 1956 
 1957                 /* Wait for REQ to be negated. */
 1958                 if (ncr5380_wait_not_req(sc)) {
 1959                         NCR_TRACE("msg_out: stuck REQ, n=%d\n", n);
 1960                         act_flags |= ACT_RESET_BUS;
 1961                 }
 1962 
 1963                 /* Finally, drop ACK. */
 1964                 icmd &= ~SCI_ICMD_ACK;
 1965                 NCR5380_WRITE(sc, sci_icmd, icmd);
 1966 
 1967                 /* Stuck bus or something... */
 1968                 if (act_flags & ACT_RESET_BUS)
 1969                         goto out;
 1970 
 1971         }
 1972         progress++;
 1973 
 1974         /* We get here only if the entire message has been transmitted. */
 1975         if (sc->sc_msgpriq != 0) {
 1976                 /* There are more outgoing messages. */
 1977                 goto nextmsg;
 1978         }
 1979 
 1980         /*
 1981          * The last message has been transmitted.  We need to remember the last
 1982          * message transmitted (in case the target switches to MESSAGE IN phase
 1983          * and sends a MESSAGE REJECT), and the list of messages transmitted
 1984          * this time around (in case the target stays in MESSAGE OUT phase to
 1985          * request a retransmit).
 1986          */
 1987 
 1988 out:
 1989         /* Stop driving the data bus. */
 1990         icmd &= ~SCI_ICMD_DATA;
 1991         NCR5380_WRITE(sc, sci_icmd, icmd);
 1992 
 1993         if (!progress)
 1994                 act_flags |= ACT_RESET_BUS;
 1995 
 1996         return act_flags;
 1997 }
 1998 
 1999 
 2000 /*
 2001  * Handle command phase.
 2002  */
 2003 static int
 2004 ncr5380_command(struct ncr5380_softc *sc)
 2005 {
 2006         struct sci_req *sr = sc->sc_current;
 2007         struct scsipi_xfer *xs = sr->sr_xs;
 2008         int len;
 2009 
 2010         /* acknowledge phase change */
 2011         NCR5380_WRITE(sc, sci_tcmd, PHASE_COMMAND);
 2012 
 2013         /* Assume command can be sent in one go. */
 2014         /* XXX: Do this using DMA, and get a phase change intr? */
 2015         len = ncr5380_pio_out(sc, PHASE_COMMAND, xs->cmdlen,
 2016                 (uint8_t *)xs->cmd);
 2017 
 2018         if (len != xs->cmdlen) {
 2019 #ifdef  NCR5380_DEBUG
 2020                 printf("%s: short transfer: wanted %d got %d.\n",
 2021                     __func__, xs->cmdlen, len);
 2022                 ncr5380_show_scsi_cmd(xs);
 2023                 NCR_BREAK();
 2024 #endif
 2025                 if (len < 6) {
 2026                         xs->error = XS_DRIVER_STUFFUP;
 2027                         sc->sc_state |= NCR_ABORTING;
 2028                         ncr_sched_msgout(sc, SEND_ABORT);
 2029                 }
 2030 
 2031         }
 2032 
 2033         return ACT_CONTINUE;
 2034 }
 2035 
 2036 
 2037 /*
 2038  * Handle either data_in or data_out
 2039  */
 2040 static int
 2041 ncr5380_data_xfer(struct ncr5380_softc *sc, int phase)
 2042 {
 2043         struct sci_req *sr = sc->sc_current;
 2044         struct scsipi_xfer *xs = sr->sr_xs;
 2045         int expected_phase;
 2046         int len;
 2047 
 2048         /*
 2049          * When aborting a command, disallow any data phase.
 2050          */
 2051         if (sc->sc_state & NCR_ABORTING) {
 2052                 printf("%s: aborting, but phase=%s (reset)\n",
 2053                     device_xname(sc->sc_dev), phase_names[phase & 7]);
 2054                 return ACT_RESET_BUS;   /* XXX */
 2055         }
 2056 
 2057         /* Validate expected phase (data_in or data_out) */
 2058         expected_phase = (xs->xs_control & XS_CTL_DATA_OUT) ?
 2059                 PHASE_DATA_OUT : PHASE_DATA_IN;
 2060         if (phase != expected_phase) {
 2061                 printf("%s: data phase error\n", device_xname(sc->sc_dev));
 2062                 goto abort;
 2063         }
 2064 
 2065         /* Make sure we have some data to move. */
 2066         if (sc->sc_datalen <= 0) {
 2067                 /* Device needs padding. */
 2068                 if (phase == PHASE_DATA_IN)
 2069                         ncr5380_pio_in(sc, phase, 4096, NULL);
 2070                 else
 2071                         ncr5380_pio_out(sc, phase, 4096, NULL);
 2072                 /* Make sure that caused a phase change. */
 2073                 if (SCI_BUS_PHASE(NCR5380_READ(sc, sci_bus_csr)) == phase) {
 2074                         /* More than 4k is just too much! */
 2075                         printf("%s: too much data padding\n",
 2076                             device_xname(sc->sc_dev));
 2077                         goto abort;
 2078                 }
 2079                 return ACT_CONTINUE;
 2080         }
 2081 
 2082         /*
 2083          * Attempt DMA only if dma_alloc gave us a DMA handle AND
 2084          * there is enough left to transfer so DMA is worth while.
 2085          */
 2086         if (sr->sr_dma_hand &&
 2087                 (sc->sc_datalen >= sc->sc_min_dma_len))
 2088         {
 2089                 /*
 2090                  * OK, really start DMA.  Note, the MD start function
 2091                  * is responsible for setting the TCMD register, etc.
 2092                  * (Acknowledge the phase change there, not here.)
 2093                  */
 2094                 NCR_TRACE("data_xfer: dma_start, dh=0x%x\n",
 2095                           (long) sr->sr_dma_hand);
 2096                 (*sc->sc_dma_start)(sc);
 2097                 return ACT_WAIT_DMA;
 2098         }
 2099 
 2100         /*
 2101          * Doing PIO for data transfer.  (Possibly "Pseudo DMA")
 2102          * XXX:  Do PDMA functions need to set tcmd later?
 2103          */
 2104         NCR_TRACE("data_xfer: doing PIO, len=%d\n", sc->sc_datalen);
 2105         /* acknowledge phase change */
 2106         NCR5380_WRITE(sc, sci_tcmd, phase);     /* XXX: OK for PDMA? */
 2107         if (phase == PHASE_DATA_OUT) {
 2108                 len = (*sc->sc_pio_out)(sc, phase, sc->sc_datalen,
 2109                     sc->sc_dataptr);
 2110         } else {
 2111                 len = (*sc->sc_pio_in)(sc, phase, sc->sc_datalen,
 2112                     sc->sc_dataptr);
 2113         }
 2114         sc->sc_dataptr += len;
 2115         sc->sc_datalen -= len;
 2116 
 2117         NCR_TRACE("data_xfer: did PIO, resid=%d\n", sc->sc_datalen);
 2118         return ACT_CONTINUE;
 2119 
 2120 abort:
 2121         sc->sc_state |= NCR_ABORTING;
 2122         ncr_sched_msgout(sc, SEND_ABORT);
 2123         return ACT_CONTINUE;
 2124 }
 2125 
 2126 
 2127 static int
 2128 ncr5380_status(struct ncr5380_softc *sc)
 2129 {
 2130         int len;
 2131         uint8_t status;
 2132         struct sci_req *sr = sc->sc_current;
 2133 
 2134         /* acknowledge phase change */
 2135         NCR5380_WRITE(sc, sci_tcmd, PHASE_STATUS);
 2136 
 2137         len = ncr5380_pio_in(sc, PHASE_STATUS, 1, &status);
 2138         if (len) {
 2139                 sr->sr_status = status;
 2140         } else {
 2141                 printf("%s: none?\n", __func__);
 2142         }
 2143 
 2144         return ACT_CONTINUE;
 2145 }
 2146 
 2147 
 2148 /*
 2149  * This is the big state machine that follows SCSI phase changes.
 2150  * This is somewhat like a co-routine.  It will do a SCSI command,
 2151  * and exit if the command is complete, or if it must wait, i.e.
 2152  * for DMA to complete or for reselect to resume the job.
 2153  *
 2154  * The bus must be selected, and we need to know which command is
 2155  * being undertaken.
 2156  */
 2157 static void
 2158 ncr5380_machine(struct ncr5380_softc *sc)
 2159 {
 2160         struct sci_req *sr;
 2161         struct scsipi_xfer *xs;
 2162         int act_flags, phase, timo;
 2163 
 2164 #ifdef  DIAGNOSTIC
 2165         if (sc->sc_state == NCR_IDLE)
 2166                 panic("%s: state=idle", __func__);
 2167         if (sc->sc_current == NULL)
 2168                 panic("%s: no current cmd", __func__);
 2169 #endif
 2170 
 2171         sr = sc->sc_current;
 2172         xs = sr->sr_xs;
 2173         act_flags = ACT_CONTINUE;
 2174 
 2175         /*
 2176          * This will be called by ncr5380_intr() when DMA is
 2177          * complete.  Must stop DMA before touching the 5380 or
 2178          * there will be "register conflict" errors.
 2179          */
 2180         if (sc->sc_state & NCR_DOINGDMA) {
 2181                 /* Pick-up where where we left off... */
 2182                 goto dma_done;
 2183         }
 2184 
 2185 next_phase:
 2186 
 2187         if (!SCI_BUSY(sc)) {
 2188                 /* Unexpected disconnect */
 2189                 printf("%s: unexpected disconnect.\n", __func__);
 2190                 xs->error = XS_DRIVER_STUFFUP;
 2191                 act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
 2192                 goto do_actions;
 2193         }
 2194 
 2195         /*
 2196          * Wait for REQ before reading the phase.
 2197          * Need to wait longer than usual here, because
 2198          * some devices are just plain slow...
 2199          */
 2200         timo = ncr5380_wait_phase_timo;
 2201         for (;;) {
 2202                 if (NCR5380_READ(sc, sci_bus_csr) & SCI_BUS_REQ)
 2203                         break;
 2204                 if (--timo <= 0) {
 2205                         if (sc->sc_state & NCR_ABORTING) {
 2206                                 printf("%s: no REQ while aborting, reset\n",
 2207                                     device_xname(sc->sc_dev));
 2208                                 act_flags |= ACT_RESET_BUS;
 2209                                 goto do_actions;
 2210                         }
 2211                         printf("%s: no REQ for next phase, abort\n",
 2212                             device_xname(sc->sc_dev));
 2213                         sc->sc_state |= NCR_ABORTING;
 2214                         ncr_sched_msgout(sc, SEND_ABORT);
 2215                         goto next_phase;
 2216                 }
 2217                 delay(100);
 2218         }
 2219 
 2220         phase = SCI_BUS_PHASE(NCR5380_READ(sc, sci_bus_csr));
 2221         NCR_TRACE("machine: phase=%s\n",
 2222                           (long) phase_names[phase & 7]);
 2223 
 2224         /*
 2225          * We assume that the device knows what it's doing,
 2226          * so any phase is good.
 2227          */
 2228 
 2229 #if 0
 2230         /*
 2231          * XXX: Do not ACK the phase yet! do it later...
 2232          * XXX: ... each phase routine does that itself.
 2233          * In particular, DMA needs it done LATER.
 2234          */
 2235         NCR5380_WRITE(sc, sci_tcmd, phase);     /* acknowledge phase change */
 2236 #endif
 2237 
 2238         switch (phase) {
 2239 
 2240         case PHASE_DATA_OUT:
 2241         case PHASE_DATA_IN:
 2242                 act_flags = ncr5380_data_xfer(sc, phase);
 2243                 break;
 2244 
 2245         case PHASE_COMMAND:
 2246                 act_flags = ncr5380_command(sc);
 2247                 break;
 2248 
 2249         case PHASE_STATUS:
 2250                 act_flags = ncr5380_status(sc);
 2251                 break;
 2252 
 2253         case PHASE_MSG_OUT:
 2254                 act_flags = ncr5380_msg_out(sc);
 2255                 break;
 2256 
 2257         case PHASE_MSG_IN:
 2258                 act_flags = ncr5380_msg_in(sc);
 2259                 break;
 2260 
 2261         default:
 2262                 printf("%s: Unexpected phase 0x%x\n", __func__, phase);
 2263                 sc->sc_state |= NCR_ABORTING;
 2264                 ncr_sched_msgout(sc, SEND_ABORT);
 2265                 goto next_phase;
 2266 
 2267         } /* switch */
 2268         sc->sc_prevphase = phase;
 2269 
 2270 do_actions:
 2271 
 2272         if (act_flags & ACT_WAIT_DMA) {
 2273                 act_flags &= ~ACT_WAIT_DMA;
 2274                 /* Wait for DMA to complete (polling, or interrupt). */
 2275                 if ((sr->sr_flags & SR_IMMED) == 0) {
 2276                         NCR_TRACE("machine: wait for DMA intr.\n", 0);
 2277                         return;         /* will resume at dma_done */
 2278                 }
 2279                 /* Busy-wait for it to finish. */
 2280                 NCR_TRACE("machine: dma_poll, dh=0x%x\n",
 2281                                   (long) sr->sr_dma_hand);
 2282                 (*sc->sc_dma_poll)(sc);
 2283         dma_done:
 2284                 /* Return here after interrupt. */
 2285                 if (sr->sr_flags & SR_OVERDUE)
 2286                         sc->sc_state |= NCR_ABORTING;
 2287                 NCR_TRACE("machine: dma_stop, dh=0x%x\n",
 2288                                   (long) sr->sr_dma_hand);
 2289                 (*sc->sc_dma_stop)(sc);
 2290                 SCI_CLR_INTR(sc);       /* XXX */
 2291                 /*
 2292                  * While DMA is running we can not touch the SBC,
 2293                  * so various places just set NCR_ABORTING and
 2294                  * expect us the "kick it" when DMA is done.
 2295                  */
 2296                 if (sc->sc_state & NCR_ABORTING) {
 2297                         ncr_sched_msgout(sc, SEND_ABORT);
 2298                 }
 2299         }
 2300 
 2301         /*
 2302          * Check for parity error.
 2303          * XXX - better place to check?
 2304          */
 2305         if (NCR5380_READ(sc, sci_csr) & SCI_CSR_PERR) {
 2306                 printf("%s: parity error!\n", device_xname(sc->sc_dev));
 2307                 /* XXX: sc->sc_state |= NCR_ABORTING; */
 2308                 ncr_sched_msgout(sc, SEND_PARITY_ERROR);
 2309         }
 2310 
 2311         if (act_flags == ACT_CONTINUE)
 2312                 goto next_phase;
 2313         /* All other actions "break" from the loop. */
 2314 
 2315         NCR_TRACE("machine: act_flags=0x%x\n", act_flags);
 2316 
 2317         if (act_flags & ACT_RESET_BUS) {
 2318                 act_flags |= ACT_CMD_DONE;
 2319                 /*
 2320                  * Reset the SCSI bus, usually due to a timeout.
 2321                  * The error code XS_TIMEOUT allows retries.
 2322                  */
 2323                 sc->sc_state |= NCR_ABORTING;
 2324                 printf("%s: reset SCSI bus for TID=%d LUN=%d\n",
 2325                     device_xname(sc->sc_dev), sr->sr_target, sr->sr_lun);
 2326                 ncr5380_reset_scsibus(sc);
 2327         }
 2328 
 2329         if (act_flags & ACT_CMD_DONE) {
 2330                 act_flags |= ACT_DISCONNECT;
 2331                 /* Need to call scsipi_done() */
 2332                 /* XXX: from the aic6360 driver, but why? */
 2333                 if (sc->sc_datalen < 0) {
 2334                         printf("%s: %d extra bytes from %d:%d\n",
 2335                             device_xname(sc->sc_dev), -sc->sc_datalen,
 2336                             sr->sr_target, sr->sr_lun);
 2337                         sc->sc_datalen = 0;
 2338                 }
 2339                 xs->resid = sc->sc_datalen;
 2340                 /* Note: this will clear sc_current */
 2341                 NCR_TRACE("machine: call done, cur=0x%x\n", (long)sr);
 2342                 ncr5380_done(sc);
 2343         }
 2344 
 2345         if (act_flags & ACT_DISCONNECT) {
 2346                 /*
 2347                  * The device has dropped BSY (or will soon).
 2348                  * We have to wait here for BSY to drop, otherwise
 2349                  * the next command may decide we need a bus reset.
 2350                  */
 2351                 timo = ncr5380_wait_req_timo;   /* XXX */
 2352                 for (;;) {
 2353                         if (!SCI_BUSY(sc))
 2354                                 goto busfree;
 2355                         if (--timo <= 0)
 2356                                 break;
 2357                         delay(2);
 2358                 }
 2359                 /* Device is sitting on the bus! */
 2360                 printf("%s: Target %d LUN %d stuck busy, resetting...\n",
 2361                     device_xname(sc->sc_dev), sr->sr_target, sr->sr_lun);
 2362                 ncr5380_reset_scsibus(sc);
 2363         busfree:
 2364                 NCR_TRACE("machine: discon, waited %d\n",
 2365                         ncr5380_wait_req_timo - timo);
 2366 
 2367                 NCR5380_WRITE(sc, sci_icmd, 0);
 2368                 NCR5380_WRITE(sc, sci_mode, 0);
 2369                 NCR5380_WRITE(sc, sci_tcmd, PHASE_INVALID);
 2370                 NCR5380_WRITE(sc, sci_sel_enb, 0);
 2371                 SCI_CLR_INTR(sc);
 2372                 NCR5380_WRITE(sc, sci_sel_enb, 0x80);
 2373 
 2374                 if ((act_flags & ACT_CMD_DONE) == 0) {
 2375                         NCR_TRACE("machine: discon, cur=0x%x\n", (long)sr);
 2376                 }
 2377 
 2378                 /*
 2379                  * We may be here due to a disconnect message,
 2380                  * in which case we did NOT call ncr5380_done,
 2381                  * and we need to clear sc_current.
 2382                  */
 2383                 sc->sc_state = NCR_IDLE;
 2384                 sc->sc_current = NULL;
 2385 
 2386                 /* Paranoia: clear everything. */
 2387                 sc->sc_dataptr = NULL;
 2388                 sc->sc_datalen = 0;
 2389                 sc->sc_prevphase = PHASE_INVALID;
 2390                 sc->sc_msgpriq = 0;
 2391                 sc->sc_msgoutq = 0;
 2392                 sc->sc_msgout  = 0;
 2393 
 2394                 /* Our caller will re-enable interrupts. */
 2395         }
 2396 }
 2397 
 2398 
 2399 #ifdef  NCR5380_DEBUG
 2400 
 2401 static void
 2402 ncr5380_show_scsi_cmd(struct scsipi_xfer *xs)
 2403 {
 2404         uint8_t *b = (uint8_t *)xs->cmd;
 2405         int i = 0;
 2406 
 2407         scsipi_printaddr(xs->xs_periph);
 2408         if ((xs->xs_control & XS_CTL_RESET) == 0) {
 2409                 while (i < xs->cmdlen) {
 2410                         if (i)
 2411                                 printf(",");
 2412                         printf("%x",b[i++]);
 2413                 }
 2414                 printf("\n");
 2415         } else {
 2416                 printf("RESET\n");
 2417         }
 2418 }
 2419 
 2420 
 2421 int ncr5380_traceidx = 0;
 2422 
 2423 #define TRACE_MAX       1024
 2424 struct trace_ent {
 2425         const char *msg;
 2426         long  val;
 2427 } ncr5380_tracebuf[TRACE_MAX];
 2428 
 2429 void
 2430 ncr5380_trace(const char *msg, long val)
 2431 {
 2432         struct trace_ent *tr;
 2433         int s;
 2434 
 2435         s = splbio();
 2436 
 2437         tr = &ncr5380_tracebuf[ncr5380_traceidx];
 2438 
 2439         ncr5380_traceidx++;
 2440         if (ncr5380_traceidx >= TRACE_MAX)
 2441                 ncr5380_traceidx = 0;
 2442 
 2443         tr->msg = msg;
 2444         tr->val = val;
 2445 
 2446         splx(s);
 2447 }
 2448 
 2449 #ifdef  DDB
 2450 void
 2451 ncr5380_clear_trace(void)
 2452 {
 2453 
 2454         ncr5380_traceidx = 0;
 2455         memset((char *)ncr5380_tracebuf, 0, sizeof(ncr5380_tracebuf));
 2456 }
 2457 
 2458 void
 2459 ncr5380_show_trace(void)
 2460 {
 2461         struct trace_ent *tr;
 2462         int idx;
 2463 
 2464         idx = ncr5380_traceidx;
 2465         do {
 2466                 tr = &ncr5380_tracebuf[idx];
 2467                 idx++;
 2468                 if (idx >= TRACE_MAX)
 2469                         idx = 0;
 2470                 if (tr->msg)
 2471                         db_printf(tr->msg, tr->val);
 2472         } while (idx != ncr5380_traceidx);
 2473 }
 2474 
 2475 void
 2476 ncr5380_show_req(struct sci_req *sr)
 2477 {
 2478         struct scsipi_xfer *xs = sr->sr_xs;
 2479 
 2480         db_printf("TID=%d ",    sr->sr_target);
 2481         db_printf("LUN=%d ",    sr->sr_lun);
 2482         db_printf("dh=%p ",     sr->sr_dma_hand);
 2483         db_printf("dptr=%p ",   sr->sr_dataptr);
 2484         db_printf("dlen=0x%x ", sr->sr_datalen);
 2485         db_printf("flags=%d ",  sr->sr_flags);
 2486         db_printf("stat=%d ",   sr->sr_status);
 2487 
 2488         if (xs == NULL) {
 2489                 db_printf("(xs=NULL)\n");
 2490                 return;
 2491         }
 2492         db_printf("\n");
 2493 #ifdef SCSIPI_DEBUG
 2494         show_scsipi_xs(xs);
 2495 #else
 2496         db_printf("xs=%p\n", xs);
 2497 #endif
 2498 }
 2499 
 2500 void
 2501 ncr5380_show_state(void)
 2502 {
 2503         struct ncr5380_softc *sc;
 2504         struct sci_req *sr;
 2505         int i, j, k;
 2506 
 2507         sc = ncr5380_debug_sc;
 2508 
 2509         if (sc == NULL) {
 2510                 db_printf("ncr5380_debug_sc == NULL\n");
 2511                 return;
 2512         }
 2513 
 2514         db_printf("sc_ncmds=%d\n",      sc->sc_ncmds);
 2515         k = -1; /* which is current? */
 2516         for (i = 0; i < SCI_OPENINGS; i++) {
 2517                 sr = &sc->sc_ring[i];
 2518                 if (sr->sr_xs) {
 2519                         if (sr == sc->sc_current)
 2520                                 k = i;
 2521                         db_printf("req %d: (sr=%p)", i, sr);
 2522                         ncr5380_show_req(sr);
 2523                 }
 2524         }
 2525         db_printf("sc_rr=%d, current=%d\n", sc->sc_rr, k);
 2526 
 2527         db_printf("Active request matrix:\n");
 2528         for(i = 0; i < 8; i++) {                /* targets */
 2529                 for (j = 0; j < 8; j++) {       /* LUN */
 2530                         sr = sc->sc_matrix[i][j];
 2531                         if (sr) {
 2532                                 db_printf("TID=%d LUN=%d sr=%p\n", i, j, sr);
 2533                         }
 2534                 }
 2535         }
 2536 
 2537         db_printf("sc_state=0x%x\n",    sc->sc_state);
 2538         db_printf("sc_current=%p\n",    sc->sc_current);
 2539         db_printf("sc_dataptr=%p\n",    sc->sc_dataptr);
 2540         db_printf("sc_datalen=0x%x\n",  sc->sc_datalen);
 2541 
 2542         db_printf("sc_prevphase=%d\n",  sc->sc_prevphase);
 2543         db_printf("sc_msgpriq=0x%x\n",  sc->sc_msgpriq);
 2544 }
 2545 #endif  /* DDB */
 2546 #endif  /* NCR5380_DEBUG */
 2547 
 2548 void
 2549 ncr5380_attach(struct ncr5380_softc *sc)
 2550 {
 2551         struct scsipi_adapter *adapt = &sc->sc_adapter;
 2552         struct scsipi_channel *chan = &sc->sc_channel;
 2553 
 2554         /*
 2555          * Fill in the scsipi_adapter.
 2556          */
 2557         adapt->adapt_request = ncr5380_scsipi_request;
 2558         adapt->adapt_dev = sc->sc_dev;
 2559         adapt->adapt_nchannels = 1;
 2560         adapt->adapt_openings = SCI_OPENINGS;
 2561         adapt->adapt_max_periph = 1;
 2562         if (sc->sc_flags & NCR5380_FORCE_POLLING)
 2563                 adapt->adapt_flags |= SCSIPI_ADAPT_POLL_ONLY;
 2564         /* adapt_minphys filled in by front-end */
 2565 
 2566         /*
 2567          * Fill in the scsipi_channel.
 2568          */
 2569         chan->chan_adapter = adapt;
 2570         chan->chan_bustype = &scsi_bustype;
 2571         chan->chan_channel = 0;
 2572         chan->chan_ntargets = 8;
 2573         chan->chan_nluns = 8;
 2574         /* chan_id filled in by front-end */
 2575 
 2576         /*
 2577          * Add reference to adapter so that we drop the reference after
 2578          * config_found() to make sure the adatper is disabled.
 2579          */
 2580         if (scsipi_adapter_addref(adapt) != 0) {
 2581                 aprint_error_dev(sc->sc_dev, "unable to enable controller\n");
 2582                 return;
 2583         }
 2584 
 2585         ncr5380_init(sc);       /* Init chip and driver */
 2586         ncr5380_reset_scsibus(sc);
 2587 
 2588         /*
 2589          * Ask the adapter what subunits are present
 2590          */
 2591         (void)config_found(sc->sc_dev, chan, scsiprint);
 2592         scsipi_adapter_delref(adapt);
 2593 }
 2594 
 2595 int
 2596 ncr5380_detach(struct ncr5380_softc *sc, int flags)
 2597 {
 2598 
 2599         return EOPNOTSUPP;
 2600 }

Cache object: bc6ec8b0127287160feb5b01eee49043


[ 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.