root/dev/ic/ncr5380sbc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ncr5380_wait_req
  2. ncr5380_wait_not_req
  3. ncr_sched_msgout
  4. ncr5380_pio_out
  5. ncr5380_pio_in
  6. ncr5380_init
  7. ncr5380_reset_scsibus
  8. ncr5380_intr
  9. ncr5380_abort
  10. ncr5380_cmd_timeout
  11. ncr5380_scsi_cmd
  12. ncr5380_done
  13. ncr5380_sched
  14. ncr5380_reselect
  15. ncr5380_select
  16. ncr5380_msg_in
  17. ncr5380_msg_out
  18. ncr5380_command
  19. ncr5380_data_xfer
  20. ncr5380_status
  21. ncr5380_machine
  22. ncr5380_show_scsi_cmd
  23. ncr5380_show_sense
  24. ncr5380_trace
  25. ncr5380_clear_trace
  26. ncr5380_show_trace
  27. ncr5380_show_req
  28. ncr5380_show_state

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

/* [<][>][^][v][top][bottom][index][help] */