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-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: b12a84624df9727e4571000342a7e239


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