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


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

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

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

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

Cache object: 07cbff9609ec159fc89d39f683b3d5c8


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


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