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/aic6360.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: aic6360.c,v 1.105 2022/01/01 21:07:14 andvar Exp $     */
    2 
    3 /*
    4  * Copyright (c) 1994, 1995, 1996 Charles M. Hannum.  All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. All advertising materials mentioning features or use of this software
   15  *    must display the following acknowledgement:
   16  *      This product includes software developed by Charles M. Hannum.
   17  * 4. The name of the author may not be used to endorse or promote products
   18  *    derived from this software without specific prior written permission.
   19  *
   20  * Copyright (c) 1994 Jarle Greipsland
   21  * All rights reserved.
   22  *
   23  * Redistribution and use in source and binary forms, with or without
   24  * modification, are permitted provided that the following conditions
   25  * are met:
   26  * 1. Redistributions of source code must retain the above copyright
   27  *    notice, this list of conditions and the following disclaimer.
   28  * 2. Redistributions in binary form must reproduce the above copyright
   29  *    notice, this list of conditions and the following disclaimer in the
   30  *    documentation and/or other materials provided with the distribution.
   31  * 3. The name of the author may not be used to endorse or promote products
   32  *    derived from this software without specific prior written permission.
   33  *
   34  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   35  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   36  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   37  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   38  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   39  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   40  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   41  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   42  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   43  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   44  * POSSIBILITY OF SUCH DAMAGE.
   45  */
   46 
   47 /*
   48  * Acknowledgements: Many of the algorithms used in this driver are
   49  * inspired by the work of Julian Elischer (julian@tfs.com) and
   50  * Charles Hannum (mycroft@duality.gnu.ai.mit.edu).  Thanks a million!
   51  */
   52 
   53 /* TODO list:
   54  * 1) Get the DMA stuff working.
   55  * 2) Get the iov/uio stuff working. Is this a good thing ???
   56  * 3) Get the synch stuff working.
   57  * 4) Rewrite it to use malloc for the acb structs instead of static alloc.?
   58  */
   59 
   60 #include <sys/cdefs.h>
   61 __KERNEL_RCSID(0, "$NetBSD: aic6360.c,v 1.105 2022/01/01 21:07:14 andvar Exp $");
   62 
   63 #include "opt_ddb.h"
   64 
   65 /*
   66  * A few customizable items:
   67  */
   68 
   69 /* Use doubleword transfers to/from SCSI chip.  Note: This requires
   70  * motherboard support.  Basically, some motherboard chipsets are able to
   71  * split a 32 bit I/O operation into two 16 bit I/O operations,
   72  * transparently to the processor.  This speeds up some things, notably long
   73  * data transfers.
   74  */
   75 #define AIC_USE_DWORDS          0
   76 
   77 /* Synchronous data transfers? */
   78 #define AIC_USE_SYNCHRONOUS     0
   79 #define AIC_SYNC_REQ_ACK_OFS    8
   80 
   81 /* Wide data transfers? */
   82 #define AIC_USE_WIDE            0
   83 #define AIC_MAX_WIDTH           0
   84 
   85 /* Max attempts made to transmit a message */
   86 #define AIC_MSG_MAX_ATTEMPT     3 /* Not used now XXX */
   87 
   88 /* Use DMA (else we do programmed I/O using string instructions) (not yet!)*/
   89 #define AIC_USE_EISA_DMA        0
   90 #define AIC_USE_ISA_DMA         0
   91 
   92 /* How to behave on the (E)ISA bus when/if DMAing (on<<4) + off in us */
   93 #define EISA_BRST_TIM ((15<<4) + 1)     /* 15us on, 1us off */
   94 
   95 /* Some spin loop parameters (essentially how long to wait some places)
   96  * The problem(?) is that sometimes we expect either to be able to transmit a
   97  * byte or to get a new one from the SCSI bus pretty soon.  In order to avoid
   98  * returning from the interrupt just to get yanked back for the next byte we
   99  * may spin in the interrupt routine waiting for this byte to come.  How long?
  100  * This is really (SCSI) device and processor dependent.  Tuneable, I guess.
  101  */
  102 #define AIC_MSGIN_SPIN          1       /* Will spinwait upto ?ms for a new msg byte */
  103 #define AIC_MSGOUT_SPIN         1
  104 
  105 /* Include debug functions?  At the end of this file there are a bunch of
  106  * functions that will print out various information regarding queued SCSI
  107  * commands, driver state and chip contents.  You can call them from the
  108  * kernel debugger.  If you set AIC_DEBUG to 0 they are not included (the
  109  * kernel uses less memory) but you lose the debugging facilities.
  110  */
  111 #define AIC_DEBUG               1
  112 
  113 #define AIC_ABORT_TIMEOUT       2000    /* time to wait for abort */
  114 
  115 /* End of customizable parameters */
  116 
  117 #if AIC_USE_EISA_DMA || AIC_USE_ISA_DMA
  118 #error "I said not yet! Start paying attention... grumble"
  119 #endif
  120 
  121 #include <sys/param.h>
  122 #include <sys/systm.h>
  123 #include <sys/callout.h>
  124 #include <sys/kernel.h>
  125 #include <sys/errno.h>
  126 #include <sys/ioctl.h>
  127 #include <sys/device.h>
  128 #include <sys/buf.h>
  129 #include <sys/proc.h>
  130 #include <sys/queue.h>
  131 
  132 #include <sys/bus.h>
  133 #include <sys/intr.h>
  134 
  135 #include <dev/scsipi/scsi_spc.h>
  136 #include <dev/scsipi/scsi_all.h>
  137 #include <dev/scsipi/scsipi_all.h>
  138 #include <dev/scsipi/scsi_message.h>
  139 #include <dev/scsipi/scsiconf.h>
  140 
  141 #include <dev/ic/aic6360reg.h>
  142 #include <dev/ic/aic6360var.h>
  143 
  144 #include "ioconf.h"
  145 
  146 #ifndef DDB
  147 #define Debugger() panic("should call debugger here (aic6360.c)")
  148 #endif /* ! DDB */
  149 
  150 #if AIC_DEBUG
  151 int aic_debug = 0x00; /* AIC_SHOWSTART|AIC_SHOWMISC|AIC_SHOWTRACE; */
  152 #endif
  153 
  154 static void     aic_minphys(struct buf *);
  155 static void     aic_done(struct aic_softc *, struct aic_acb *);
  156 static void     aic_dequeue(struct aic_softc *, struct aic_acb *);
  157 static void     aic_scsipi_request(struct scsipi_channel *,
  158                                    scsipi_adapter_req_t, void *);
  159 static int      aic_poll(struct aic_softc *, struct scsipi_xfer *, int);
  160 static void     aic_select(struct aic_softc *, struct aic_acb *);
  161 static void     aic_timeout(void *);
  162 static void     aic_sched(struct aic_softc *);
  163 static void     aic_scsi_reset(struct aic_softc *);
  164 static void     aic_reset(struct aic_softc *);
  165 static void     aic_free_acb(struct aic_softc *, struct aic_acb *);
  166 static struct aic_acb* aic_get_acb(struct aic_softc *);
  167 static int      aic_reselect(struct aic_softc *, int);
  168 static void     aic_sense(struct aic_softc *, struct aic_acb *);
  169 static void     aic_msgin(struct aic_softc *);
  170 static void     aic_abort(struct aic_softc *, struct aic_acb *);
  171 static void     aic_msgout(struct aic_softc *);
  172 static int      aic_dataout_pio(struct aic_softc *, u_char *, int);
  173 static int      aic_datain_pio(struct aic_softc *, u_char *, int);
  174 static void     aic_update_xfer_mode(struct aic_softc *, int);
  175 #if AIC_DEBUG
  176 static void     aic_print_acb(struct aic_acb *);
  177 void    aic_dump_driver(struct aic_softc *);
  178 void    aic_dump6360(struct aic_softc *);
  179 static void     aic_show_scsi_cmd(struct aic_acb *);
  180 void    aic_print_active_acb(void);
  181 #endif
  182 
  183 /*
  184  * INITIALIZATION ROUTINES (probe, attach ++)
  185  */
  186 
  187 /* Do the real search-for-device.
  188  * Prerequisite: sc->sc_iobase should be set to the proper value
  189  */
  190 int
  191 aic_find(bus_space_tag_t iot, bus_space_handle_t ioh)
  192 {
  193         char chip_id[sizeof(IDSTRING)]; /* For chips that support it */
  194         int i;
  195 
  196         /* Remove aic6360 from possible powerdown mode */
  197         bus_space_write_1(iot, ioh, DMACNTRL0, 0);
  198 
  199         /* Thanks to mark@aggregate.com for the new method for detecting
  200          * whether the chip is present or not.  Bonus: may also work for
  201          * the AIC-6260!
  202          */
  203         AIC_TRACE(("aic: probing for aic-chip\n"));
  204         /*
  205          * Linux also init's the stack to 1-16 and then clears it,
  206          *  6260's don't appear to have an ID reg - mpg
  207          */
  208         /* Push the sequence 0,1,..,15 on the stack */
  209 #define STSIZE 16
  210         bus_space_write_1(iot, ioh, DMACNTRL1, 0); /* Reset stack pointer */
  211         for (i = 0; i < STSIZE; i++)
  212                 bus_space_write_1(iot, ioh, STACK, i);
  213 
  214         /* See if we can pull out the same sequence */
  215         bus_space_write_1(iot, ioh, DMACNTRL1, 0);
  216         for (i = 0; i < STSIZE && bus_space_read_1(iot, ioh, STACK) == i; i++)
  217                 ;
  218         if (i != STSIZE) {
  219                 AIC_START(("STACK futzed at %d.\n", i));
  220                 return 0;
  221         }
  222 
  223         /* See if we can pull the id string out of the ID register,
  224          * now only used for informational purposes.
  225          */
  226         memset(chip_id, 0, sizeof(chip_id));
  227         bus_space_read_multi_1(iot, ioh, ID, chip_id, sizeof(IDSTRING) - 1);
  228         AIC_START(("AIC found ID: %s ",chip_id));
  229         AIC_START(("chip revision %d\n",
  230             (int)bus_space_read_1(iot, ioh, REV)));
  231 
  232         return 1;
  233 }
  234 
  235 /*
  236  * Attach the AIC6360, fill out some high and low level data structures
  237  */
  238 void
  239 aicattach(struct aic_softc *sc)
  240 {
  241         struct scsipi_adapter *adapt = &sc->sc_adapter;
  242         struct scsipi_channel *chan = &sc->sc_channel;
  243 
  244         AIC_TRACE(("aicattach  "));
  245         sc->sc_state = AIC_INIT;
  246 
  247         sc->sc_initiator = 7;
  248         sc->sc_freq = 20;       /* XXXX Assume 20 MHz. */
  249 
  250         /*
  251          * These are the bounds of the sync period, based on the frequency of
  252          * the chip's clock input and the size and offset of the sync period
  253          * register.
  254          *
  255          * For a 20MHz clock, this gives us 25, or 100nS, or 10MB/s, as a
  256          * maximum transfer rate, and 112.5, or 450nS, or 2.22MB/s, as a
  257          * minimum transfer rate.
  258          */
  259         sc->sc_minsync = (2 * 250) / sc->sc_freq;
  260         sc->sc_maxsync = (9 * 250) / sc->sc_freq;
  261 
  262         /*
  263          * Fill in the scsipi_adapter.
  264          */
  265         adapt->adapt_dev = sc->sc_dev;
  266         adapt->adapt_nchannels = 1;
  267         adapt->adapt_openings = 8;
  268         adapt->adapt_max_periph = 1;
  269         adapt->adapt_request = aic_scsipi_request;
  270         adapt->adapt_minphys = aic_minphys;
  271 
  272         /*
  273          * Fill in the scsipi_channel.
  274          */
  275         chan->chan_adapter = adapt;
  276         chan->chan_bustype = &scsi_bustype;
  277         chan->chan_channel = 0;
  278         chan->chan_ntargets = 8;
  279         chan->chan_nluns = 8;
  280         chan->chan_id = sc->sc_initiator;
  281 
  282         /*
  283          * Add reference to adapter so that we drop the reference after
  284          * config_found() to make sure the adapter is disabled.
  285          */
  286         if (scsipi_adapter_addref(adapt) != 0) {
  287                 aprint_error_dev(sc->sc_dev, "unable to enable controller\n");
  288                 return;
  289         }
  290 
  291         aic_init(sc, 1);        /* Init chip and driver */
  292 
  293         /*
  294          * Ask the adapter what subunits are present
  295          */
  296         sc->sc_child = config_found(sc->sc_dev, &sc->sc_channel, scsiprint,
  297             CFARGS_NONE);
  298         scsipi_adapter_delref(adapt);
  299 }
  300 
  301 int
  302 aic_detach(device_t self, int flags)
  303 {
  304         struct aic_softc *sc = device_private(self);
  305         int rv = 0;
  306 
  307         if (sc->sc_child != NULL)
  308                 rv = config_detach(sc->sc_child, flags);
  309 
  310         return (rv);
  311 }
  312 
  313 /* Initialize AIC6360 chip itself
  314  * The following conditions should hold:
  315  * aic_isa_probe should have succeeded, i.e. the iobase address in aic_softc
  316  * must be valid.
  317  */
  318 static void
  319 aic_reset(struct aic_softc *sc)
  320 {
  321         bus_space_tag_t iot = sc->sc_iot;
  322         bus_space_handle_t ioh = sc->sc_ioh;
  323 
  324         /*
  325          * Doc. recommends to clear these two registers before
  326          * operations commence
  327          */
  328         bus_space_write_1(iot, ioh, SCSITEST, 0);
  329         bus_space_write_1(iot, ioh, TEST, 0);
  330 
  331         /* Reset SCSI-FIFO and abort any transfers */
  332         bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | CLRCH | CLRSTCNT);
  333 
  334         /* Reset DMA-FIFO */
  335         bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO);
  336         bus_space_write_1(iot, ioh, DMACNTRL1, 0);
  337 
  338         /* Disable all selection features */
  339         bus_space_write_1(iot, ioh, SCSISEQ, 0);
  340         bus_space_write_1(iot, ioh, SXFRCTL1, 0);
  341 
  342         /* Disable some interrupts */
  343         bus_space_write_1(iot, ioh, SIMODE0, 0x00);
  344         /* Clear a slew of interrupts */
  345         bus_space_write_1(iot, ioh, CLRSINT0, 0x7f);
  346 
  347         /* Disable some more interrupts */
  348         bus_space_write_1(iot, ioh, SIMODE1, 0x00);
  349         /* Clear another slew of interrupts */
  350         bus_space_write_1(iot, ioh, CLRSINT1, 0xef);
  351 
  352         /* Disable synchronous transfers */
  353         bus_space_write_1(iot, ioh, SCSIRATE, 0);
  354 
  355         /* Haven't seen ant errors (yet) */
  356         bus_space_write_1(iot, ioh, CLRSERR, 0x07);
  357 
  358         /* Set our SCSI-ID */
  359         bus_space_write_1(iot, ioh, SCSIID, sc->sc_initiator << OID_S);
  360         bus_space_write_1(iot, ioh, BRSTCNTRL, EISA_BRST_TIM);
  361 }
  362 
  363 /* Pull the SCSI RST line for 500 us */
  364 static void
  365 aic_scsi_reset(struct aic_softc *sc)
  366 {
  367         bus_space_tag_t iot = sc->sc_iot;
  368         bus_space_handle_t ioh = sc->sc_ioh;
  369 
  370         bus_space_write_1(iot, ioh, SCSISEQ, SCSIRSTO);
  371         delay(500);
  372         bus_space_write_1(iot, ioh, SCSISEQ, 0);
  373         delay(50);
  374 }
  375 
  376 /*
  377  * Initialize aic SCSI driver.
  378  */
  379 void
  380 aic_init(struct aic_softc *sc, int bus_reset)
  381 {
  382         struct aic_acb *acb;
  383         int r;
  384 
  385         if (bus_reset) {
  386                 aic_reset(sc);
  387                 aic_scsi_reset(sc);
  388         }
  389         aic_reset(sc);
  390 
  391         if (sc->sc_state == AIC_INIT) {
  392                 /* First time through; initialize. */
  393                 TAILQ_INIT(&sc->ready_list);
  394                 TAILQ_INIT(&sc->nexus_list);
  395                 TAILQ_INIT(&sc->free_list);
  396                 sc->sc_nexus = NULL;
  397                 acb = sc->sc_acb;
  398                 memset(acb, 0, sizeof(sc->sc_acb));
  399                 for (r = 0; r < sizeof(sc->sc_acb) / sizeof(*acb); r++) {
  400                         TAILQ_INSERT_TAIL(&sc->free_list, acb, chain);
  401                         acb++;
  402                 }
  403                 memset(&sc->sc_tinfo, 0, sizeof(sc->sc_tinfo));
  404         } else {
  405                 /* Cancel any active commands. */
  406                 sc->sc_state = AIC_CLEANING;
  407                 if ((acb = sc->sc_nexus) != NULL) {
  408                         acb->xs->error = XS_DRIVER_STUFFUP;
  409                         callout_stop(&acb->xs->xs_callout);
  410                         aic_done(sc, acb);
  411                 }
  412                 while ((acb = sc->nexus_list.tqh_first) != NULL) {
  413                         acb->xs->error = XS_DRIVER_STUFFUP;
  414                         callout_stop(&acb->xs->xs_callout);
  415                         aic_done(sc, acb);
  416                 }
  417         }
  418 
  419         sc->sc_prevphase = PH_INVALID;
  420         for (r = 0; r < 8; r++) {
  421                 struct aic_tinfo *ti = &sc->sc_tinfo[r];
  422 
  423                 ti->flags = 0;
  424                 ti->period = ti->offset = 0;
  425                 ti->width = 0;
  426         }
  427 
  428         sc->sc_state = AIC_IDLE;
  429         bus_space_write_1(sc->sc_iot, sc->sc_ioh, DMACNTRL0, INTEN);
  430 }
  431 
  432 static void
  433 aic_free_acb(struct aic_softc *sc, struct aic_acb *acb)
  434 {
  435         int s;
  436 
  437         s = splbio();
  438         acb->flags = 0;
  439         TAILQ_INSERT_HEAD(&sc->free_list, acb, chain);
  440         splx(s);
  441 }
  442 
  443 static struct aic_acb *
  444 aic_get_acb(struct aic_softc *sc)
  445 {
  446         struct aic_acb *acb;
  447         int s;
  448 
  449         s = splbio();
  450         acb = TAILQ_FIRST(&sc->free_list);
  451         if (acb != NULL) {
  452                 TAILQ_REMOVE(&sc->free_list, acb, chain);
  453                 acb->flags |= ACB_ALLOC;
  454         }
  455         splx(s);
  456         return (acb);
  457 }
  458 
  459 /*
  460  * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
  461  */
  462 
  463 /*
  464  * Expected sequence:
  465  * 1) Command inserted into ready list
  466  * 2) Command selected for execution
  467  * 3) Command won arbitration and has selected target device
  468  * 4) Send message out (identify message, eventually also sync.negotiations)
  469  * 5) Send command
  470  * 5a) Receive disconnect message, disconnect.
  471  * 5b) Reselected by target
  472  * 5c) Receive identify message from target.
  473  * 6) Send or receive data
  474  * 7) Receive status
  475  * 8) Receive message (command complete etc.)
  476  * 9) If status == SCSI_CHECK construct a synthetic request sense SCSI cmd.
  477  *    Repeat 2-8 (no disconnects please...)
  478  */
  479 
  480 /*
  481  * Perform a request from the SCSIPI midlayer.
  482  */
  483 static void
  484 aic_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
  485     void *arg)
  486 {
  487         struct scsipi_xfer *xs;
  488         struct scsipi_periph *periph;
  489         struct aic_softc *sc = device_private(chan->chan_adapter->adapt_dev);
  490         struct aic_acb *acb;
  491         int s, flags;
  492 
  493         AIC_TRACE(("aic_request  "));
  494 
  495         switch (req) {
  496         case ADAPTER_REQ_RUN_XFER:
  497                 xs = arg;
  498                 periph = xs->xs_periph;
  499 
  500                 AIC_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
  501                     periph->periph_target));
  502 
  503                 if (!device_is_active(sc->sc_dev)) {
  504                         xs->error = XS_DRIVER_STUFFUP;
  505                         scsipi_done(xs);
  506                         return;
  507                 }
  508 
  509                 flags = xs->xs_control;
  510                 acb = aic_get_acb(sc);
  511 #ifdef DIAGNOSTIC
  512                 /*
  513                  * This should never happen as we track the resources
  514                  * in the mid-layer.
  515                  */
  516                 if (acb == NULL) {
  517                         scsipi_printaddr(periph);
  518                         printf("unable to allocate acb\n");
  519                         panic("aic_scsipi_request");
  520                 }
  521 #endif
  522 
  523                 /* Initialize acb */
  524                 acb->xs = xs;
  525                 acb->timeout = xs->timeout;
  526 
  527                 if (xs->xs_control & XS_CTL_RESET) {
  528                         acb->flags |= ACB_RESET;
  529                         acb->scsipi_cmd_length = 0;
  530                         acb->data_length = 0;
  531                 } else {
  532                         memcpy(&acb->scsipi_cmd, xs->cmd, xs->cmdlen);
  533                         acb->scsipi_cmd_length = xs->cmdlen;
  534                         acb->data_addr = xs->data;
  535                         acb->data_length = xs->datalen;
  536                 }
  537                 acb->target_stat = 0;
  538 
  539                 s = splbio();
  540 
  541                 TAILQ_INSERT_TAIL(&sc->ready_list, acb, chain);
  542                 if (sc->sc_state == AIC_IDLE)
  543                         aic_sched(sc);
  544 
  545                 splx(s);
  546 
  547                 if ((flags & XS_CTL_POLL) == 0)
  548                         return;
  549 
  550                 /* Not allowed to use interrupts, use polling instead */
  551                 if (aic_poll(sc, xs, acb->timeout)) {
  552                         aic_timeout(acb);
  553                         if (aic_poll(sc, xs, acb->timeout))
  554                                 aic_timeout(acb);
  555                 }
  556                 return;
  557 
  558         case ADAPTER_REQ_GROW_RESOURCES:
  559                 /* XXX Not supported. */
  560                 return;
  561 
  562         case ADAPTER_REQ_SET_XFER_MODE:
  563             {
  564                 struct aic_tinfo *ti;
  565                 struct scsipi_xfer_mode *xm = arg;
  566 
  567                 ti = &sc->sc_tinfo[xm->xm_target];
  568                 ti->flags &= ~(DO_SYNC|DO_WIDE);
  569                 ti->period = 0;
  570                 ti->offset = 0;
  571 
  572 #if AIC_USE_SYNCHRONOUS
  573                 if (xm->xm_mode & PERIPH_CAP_SYNC) {
  574                         ti->flags |= DO_SYNC;
  575                         ti->period = sc->sc_minsync;
  576                         ti->offset = AIC_SYNC_REQ_ACK_OFS;
  577                 }
  578 #endif
  579 #if AIC_USE_WIDE
  580                 if (xm->xm_mode & PERIPH_CAP_WIDE16) {
  581                         ti->flags |= DO_WIDE;
  582                         ti->width = AIC_MAX_WIDTH;
  583                 }
  584 #endif
  585                 /*
  586                  * If we're not going to negotiate, send the notification
  587                  * now, since it won't happen later.
  588                  */
  589                 if ((ti->flags & (DO_SYNC|DO_WIDE)) == 0)
  590                         aic_update_xfer_mode(sc, xm->xm_target);
  591                 return;
  592             }
  593         }
  594 }
  595 
  596 static void
  597 aic_update_xfer_mode(struct aic_softc *sc, int target)
  598 {
  599         struct scsipi_xfer_mode xm;
  600         struct aic_tinfo *ti = &sc->sc_tinfo[target];
  601 
  602         xm.xm_target = target;
  603         xm.xm_mode = 0;
  604         xm.xm_period = 0;
  605         xm.xm_offset = 0;
  606 
  607         if (ti->offset != 0) {
  608                 xm.xm_mode |= PERIPH_CAP_SYNC;
  609                 xm.xm_period = ti->period;
  610                 xm.xm_offset = ti->offset;
  611         }
  612         switch (ti->width) {
  613         case 2:
  614                 xm.xm_mode |= PERIPH_CAP_WIDE32;
  615                 break;
  616         case 1:
  617                 xm.xm_mode |= PERIPH_CAP_WIDE16;
  618                 break;
  619         }
  620 
  621         scsipi_async_event(&sc->sc_channel, ASYNC_EVENT_XFER_MODE, &xm);
  622 }
  623 
  624 /*
  625  * Adjust transfer size in buffer structure
  626  */
  627 static void
  628 aic_minphys(struct buf *bp)
  629 {
  630 
  631         AIC_TRACE(("aic_minphys  "));
  632         if (bp->b_bcount > (AIC_NSEG << PGSHIFT))
  633                 bp->b_bcount = (AIC_NSEG << PGSHIFT);
  634         minphys(bp);
  635 }
  636 
  637 /*
  638  * Used when interrupt driven I/O isn't allowed, e.g. during boot.
  639  */
  640 static int
  641 aic_poll(struct aic_softc *sc, struct scsipi_xfer *xs, int count)
  642 {
  643         bus_space_tag_t iot = sc->sc_iot;
  644         bus_space_handle_t ioh = sc->sc_ioh;
  645 
  646         AIC_TRACE(("aic_poll  "));
  647         while (count) {
  648                 /*
  649                  * If we had interrupts enabled, would we
  650                  * have got an interrupt?
  651                  */
  652                 if ((bus_space_read_1(iot, ioh, DMASTAT) & INTSTAT) != 0)
  653                         aicintr(sc);
  654                 if ((xs->xs_status & XS_STS_DONE) != 0)
  655                         return 0;
  656                 delay(1000);
  657                 count--;
  658         }
  659         return 1;
  660 }
  661 
  662 /*
  663  * LOW LEVEL SCSI UTILITIES
  664  */
  665 
  666 static inline void
  667 aic_sched_msgout(struct aic_softc *sc, u_char m)
  668 {
  669         bus_space_tag_t iot = sc->sc_iot;
  670         bus_space_handle_t ioh = sc->sc_ioh;
  671 
  672         if (sc->sc_msgpriq == 0)
  673                 bus_space_write_1(iot, ioh, SCSISIG, sc->sc_phase | ATNO);
  674         sc->sc_msgpriq |= m;
  675 }
  676 
  677 /*
  678  * Set synchronous transfer offset and period.
  679  */
  680 #if !AIC_USE_SYNCHRONOUS
  681 /* ARGSUSED */
  682 #endif
  683 static inline void
  684 aic_setsync(struct aic_softc *sc, struct aic_tinfo *ti)
  685 {
  686 #if AIC_USE_SYNCHRONOUS
  687         bus_space_tag_t iot = sc->sc_iot;
  688         bus_space_handle_t ioh = sc->sc_ioh;
  689 
  690         if (ti->offset != 0)
  691                 bus_space_write_1(iot, ioh, SCSIRATE,
  692                     ((ti->period * sc->sc_freq) / 250 - 2) << 4 | ti->offset);
  693         else
  694                 bus_space_write_1(iot, ioh, SCSIRATE, 0);
  695 #endif
  696 }
  697 
  698 /*
  699  * Start a selection.  This is used by aic_sched() to select an idle target,
  700  * and by aic_done() to immediately reselect a target to get sense information.
  701  */
  702 static void
  703 aic_select(struct aic_softc *sc, struct aic_acb *acb)
  704 {
  705         struct scsipi_periph *periph = acb->xs->xs_periph;
  706         int target = periph->periph_target;
  707         struct aic_tinfo *ti = &sc->sc_tinfo[target];
  708         bus_space_tag_t iot = sc->sc_iot;
  709         bus_space_handle_t ioh = sc->sc_ioh;
  710 
  711         bus_space_write_1(iot, ioh, SCSIID,
  712             sc->sc_initiator << OID_S | target);
  713         aic_setsync(sc, ti);
  714         bus_space_write_1(iot, ioh, SXFRCTL1, STIMO_256ms | ENSTIMER);
  715 
  716         /* Always enable reselections. */
  717         bus_space_write_1(iot, ioh, SIMODE0, ENSELDI | ENSELDO);
  718         bus_space_write_1(iot, ioh, SIMODE1, ENSCSIRST | ENSELTIMO);
  719         bus_space_write_1(iot, ioh, SCSISEQ, ENRESELI | ENSELO | ENAUTOATNO);
  720 
  721         sc->sc_state = AIC_SELECTING;
  722 }
  723 
  724 static int
  725 aic_reselect(struct aic_softc *sc, int message)
  726 {
  727         u_char selid, target, lun;
  728         struct aic_acb *acb;
  729         struct scsipi_periph *periph;
  730         struct aic_tinfo *ti;
  731 
  732         /*
  733          * The SCSI chip made a snapshot of the data bus while the reselection
  734          * was being negotiated.  This enables us to determine which target did
  735          * the reselect.
  736          */
  737         selid = sc->sc_selid & ~(1 << sc->sc_initiator);
  738         if (selid & (selid - 1)) {
  739                 aprint_error_dev(sc->sc_dev,
  740                     "reselect with invalid selid %02x; "
  741                     "sending DEVICE RESET\n", selid);
  742                 AIC_BREAK();
  743                 goto reset;
  744         }
  745 
  746         /* Search wait queue for disconnected cmd
  747          * The list should be short, so I haven't bothered with
  748          * any more sophisticated structures than a simple
  749          * singly linked list.
  750          */
  751         target = ffs(selid) - 1;
  752         lun = message & 0x07;
  753         for (acb = sc->nexus_list.tqh_first; acb != NULL;
  754              acb = acb->chain.tqe_next) {
  755                 periph = acb->xs->xs_periph;
  756                 if (periph->periph_target == target &&
  757                     periph->periph_lun == lun)
  758                         break;
  759         }
  760         if (acb == NULL) {
  761                 printf("%s: reselect from target %d lun %d with no nexus; "
  762                     "sending ABORT\n", device_xname(sc->sc_dev), target, lun);
  763                 AIC_BREAK();
  764                 goto abort;
  765         }
  766 
  767         /* Make this nexus active again. */
  768         TAILQ_REMOVE(&sc->nexus_list, acb, chain);
  769         sc->sc_state = AIC_CONNECTED;
  770         sc->sc_nexus = acb;
  771         ti = &sc->sc_tinfo[target];
  772         ti->lubusy |= (1 << lun);
  773         aic_setsync(sc, ti);
  774 
  775         if (acb->flags & ACB_RESET)
  776                 aic_sched_msgout(sc, SEND_DEV_RESET);
  777         else if (acb->flags & ACB_ABORT)
  778                 aic_sched_msgout(sc, SEND_ABORT);
  779 
  780         /* Do an implicit RESTORE POINTERS. */
  781         sc->sc_dp = acb->data_addr;
  782         sc->sc_dleft = acb->data_length;
  783         sc->sc_cp = (u_char *)&acb->scsipi_cmd;
  784         sc->sc_cleft = acb->scsipi_cmd_length;
  785 
  786         return (0);
  787 
  788 reset:
  789         aic_sched_msgout(sc, SEND_DEV_RESET);
  790         return (1);
  791 
  792 abort:
  793         aic_sched_msgout(sc, SEND_ABORT);
  794         return (1);
  795 }
  796 
  797 /*
  798  * Schedule a SCSI operation.  This has now been pulled out of the interrupt
  799  * handler so that we may call it from aic_scsipi_request and aic_done.  This
  800  * may save us an unnecessary interrupt just to get things going.  Should only
  801  * be called when state == AIC_IDLE and at bio pl.
  802  */
  803 static void
  804 aic_sched(struct aic_softc *sc)
  805 {
  806         struct aic_acb *acb;
  807         struct scsipi_periph *periph;
  808         struct aic_tinfo *ti;
  809         bus_space_tag_t iot = sc->sc_iot;
  810         bus_space_handle_t ioh = sc->sc_ioh;
  811 
  812         if (!device_is_active(sc->sc_dev))
  813                 return;
  814 
  815         /*
  816          * Find first acb in ready queue that is for a target/lunit pair that
  817          * is not busy.
  818          */
  819         bus_space_write_1(iot, ioh, CLRSINT1,
  820             CLRSELTIMO | CLRBUSFREE | CLRSCSIPERR);
  821         for (acb = sc->ready_list.tqh_first; acb != NULL;
  822             acb = acb->chain.tqe_next) {
  823                 periph = acb->xs->xs_periph;
  824                 ti = &sc->sc_tinfo[periph->periph_target];
  825                 if ((ti->lubusy & (1 << periph->periph_lun)) == 0) {
  826                         AIC_MISC(("selecting %d:%d  ",
  827                             periph->periph_target, periph->periph_lun));
  828                         TAILQ_REMOVE(&sc->ready_list, acb, chain);
  829                         sc->sc_nexus = acb;
  830                         aic_select(sc, acb);
  831                         return;
  832                 } else
  833                         AIC_MISC(("%d:%d busy\n",
  834                             periph->periph_target, periph->periph_lun));
  835         }
  836         AIC_MISC(("idle  "));
  837         /* Nothing to start; just enable reselections and wait. */
  838         bus_space_write_1(iot, ioh, SIMODE0, ENSELDI);
  839         bus_space_write_1(iot, ioh, SIMODE1, ENSCSIRST);
  840         bus_space_write_1(iot, ioh, SCSISEQ, ENRESELI);
  841 }
  842 
  843 static void
  844 aic_sense(struct aic_softc *sc, struct aic_acb *acb)
  845 {
  846         struct scsipi_xfer *xs = acb->xs;
  847         struct scsipi_periph *periph = xs->xs_periph;
  848         struct aic_tinfo *ti = &sc->sc_tinfo[periph->periph_target];
  849         struct scsi_request_sense *ss = (void *)&acb->scsipi_cmd;
  850 
  851         AIC_MISC(("requesting sense  "));
  852         /* Next, setup a request sense command block */
  853         memset(ss, 0, sizeof(*ss));
  854         ss->opcode = SCSI_REQUEST_SENSE;
  855         ss->byte2 = periph->periph_lun << 5;
  856         ss->length = sizeof(struct scsi_sense_data);
  857         acb->scsipi_cmd_length = sizeof(*ss);
  858         acb->data_addr = (char *)&xs->sense.scsi_sense;
  859         acb->data_length = sizeof(struct scsi_sense_data);
  860         acb->flags |= ACB_SENSE;
  861         ti->senses++;
  862         if (acb->flags & ACB_NEXUS)
  863                 ti->lubusy &= ~(1 << periph->periph_lun);
  864         if (acb == sc->sc_nexus) {
  865                 aic_select(sc, acb);
  866         } else {
  867                 aic_dequeue(sc, acb);
  868                 TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
  869                 if (sc->sc_state == AIC_IDLE)
  870                         aic_sched(sc);
  871         }
  872 }
  873 
  874 /*
  875  * POST PROCESSING OF SCSI_CMD (usually current)
  876  */
  877 static void
  878 aic_done(struct aic_softc *sc, struct aic_acb *acb)
  879 {
  880         struct scsipi_xfer *xs = acb->xs;
  881         struct scsipi_periph *periph = xs->xs_periph;
  882         struct aic_tinfo *ti = &sc->sc_tinfo[periph->periph_target];
  883 
  884         AIC_TRACE(("aic_done  "));
  885 
  886         /*
  887          * Now, if we've come here with no error code, i.e. we've kept the
  888          * initial XS_NOERROR, and the status code signals that we should
  889          * check sense, we'll need to set up a request sense cmd block and
  890          * push the command back into the ready queue *before* any other
  891          * commands for this target/lunit, else we lose the sense info.
  892          * We don't support chk sense conditions for the request sense cmd.
  893          */
  894         if (xs->error == XS_NOERROR) {
  895                 if (acb->flags & ACB_ABORT) {
  896                         xs->error = XS_DRIVER_STUFFUP;
  897                 } else if (acb->flags & ACB_SENSE) {
  898                         xs->error = XS_SENSE;
  899                 } else if (acb->target_stat == SCSI_CHECK) {
  900                         /* First, save the return values */
  901                         xs->resid = acb->data_length;
  902                         xs->status = acb->target_stat;
  903                         aic_sense(sc, acb);
  904                         return;
  905                 } else {
  906                         xs->resid = acb->data_length;
  907                 }
  908         }
  909 
  910 #if AIC_DEBUG
  911         if ((aic_debug & AIC_SHOWMISC) != 0) {
  912                 if (xs->resid != 0)
  913                         printf("resid=%d ", xs->resid);
  914                 if (xs->error == XS_SENSE)
  915                         printf("sense=0x%02x\n", xs->sense.scsi_sense.response_code);
  916                 else
  917                         printf("error=%d\n", xs->error);
  918         }
  919 #endif
  920 
  921         /*
  922          * Remove the ACB from whatever queue it happens to be on.
  923          */
  924         if (acb->flags & ACB_NEXUS)
  925                 ti->lubusy &= ~(1 << periph->periph_lun);
  926         if (acb == sc->sc_nexus) {
  927                 sc->sc_nexus = NULL;
  928                 sc->sc_state = AIC_IDLE;
  929                 aic_sched(sc);
  930         } else
  931                 aic_dequeue(sc, acb);
  932 
  933         aic_free_acb(sc, acb);
  934         ti->cmds++;
  935         scsipi_done(xs);
  936 }
  937 
  938 static void
  939 aic_dequeue(struct aic_softc *sc, struct aic_acb *acb)
  940 {
  941 
  942         if (acb->flags & ACB_NEXUS) {
  943                 TAILQ_REMOVE(&sc->nexus_list, acb, chain);
  944         } else {
  945                 TAILQ_REMOVE(&sc->ready_list, acb, chain);
  946         }
  947 }
  948 
  949 /*
  950  * INTERRUPT/PROTOCOL ENGINE
  951  */
  952 
  953 /*
  954  * Precondition:
  955  * The SCSI bus is already in the MSGI phase and there is a message byte
  956  * on the bus, along with an asserted REQ signal.
  957  */
  958 static void
  959 aic_msgin(struct aic_softc *sc)
  960 {
  961         bus_space_tag_t iot = sc->sc_iot;
  962         bus_space_handle_t ioh = sc->sc_ioh;
  963         u_char sstat1;
  964         int n;
  965 
  966         AIC_TRACE(("aic_msgin  "));
  967 
  968         if (sc->sc_prevphase == PH_MSGIN) {
  969                 /* This is a continuation of the previous message. */
  970                 n = sc->sc_imp - sc->sc_imess;
  971                 goto nextbyte;
  972         }
  973 
  974         /* This is a new MESSAGE IN phase.  Clean up our state. */
  975         sc->sc_flags &= ~AIC_DROP_MSGIN;
  976 
  977 nextmsg:
  978         n = 0;
  979         sc->sc_imp = &sc->sc_imess[n];
  980 
  981 nextbyte:
  982         /*
  983          * Read a whole message, but don't ack the last byte.  If we reject the
  984          * message, we have to assert ATN during the message transfer phase
  985          * itself.
  986          */
  987         for (;;) {
  988                 for (;;) {
  989                         sstat1 = bus_space_read_1(iot, ioh, SSTAT1);
  990                         if ((sstat1 & (REQINIT | PHASECHG | BUSFREE)) != 0)
  991                                 break;
  992                         /* Wait for REQINIT.  XXX Need timeout. */
  993                 }
  994                 if ((sstat1 & (PHASECHG | BUSFREE)) != 0) {
  995                         /*
  996                          * Target left MESSAGE IN, probably because it
  997                          * a) noticed our ATN signal, or
  998                          * b) ran out of messages.
  999                          */
 1000                         goto out;
 1001                 }
 1002 
 1003                 /* If parity error, just dump everything on the floor. */
 1004                 if ((sstat1 & SCSIPERR) != 0) {
 1005                         sc->sc_flags |= AIC_DROP_MSGIN;
 1006                         aic_sched_msgout(sc, SEND_PARITY_ERROR);
 1007                 }
 1008 
 1009                 /* Gather incoming message bytes if needed. */
 1010                 if ((sc->sc_flags & AIC_DROP_MSGIN) == 0) {
 1011                         if (n >= AIC_MAX_MSG_LEN) {
 1012                                 (void) bus_space_read_1(iot, ioh, SCSIDAT);
 1013                                 sc->sc_flags |= AIC_DROP_MSGIN;
 1014                                 aic_sched_msgout(sc, SEND_REJECT);
 1015                         } else {
 1016                                 *sc->sc_imp++ = bus_space_read_1(iot, ioh,
 1017                                     SCSIDAT);
 1018                                 n++;
 1019                                 /*
 1020                                  * This testing is suboptimal, but most
 1021                                  * messages will be of the one byte variety, so
 1022                                  * it should not affect performance
 1023                                  * significantly.
 1024                                  */
 1025                                 if (n == 1 && MSG_IS1BYTE(sc->sc_imess[0]))
 1026                                         break;
 1027                                 if (n == 2 && MSG_IS2BYTE(sc->sc_imess[0]))
 1028                                         break;
 1029                                 if (n >= 3 && MSG_ISEXTENDED(sc->sc_imess[0]) &&
 1030                                     n == sc->sc_imess[1] + 2)
 1031                                         break;
 1032                         }
 1033                 } else
 1034                         (void) bus_space_read_1(iot, ioh, SCSIDAT);
 1035 
 1036                 /*
 1037                  * If we reach this spot we're either:
 1038                  * a) in the middle of a multi-byte message, or
 1039                  * b) dropping bytes.
 1040                  */
 1041                 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
 1042                 /* Ack the last byte read. */
 1043                 (void) bus_space_read_1(iot, ioh, SCSIDAT);
 1044                 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
 1045                 while ((bus_space_read_1(iot, ioh, SCSISIG) & ACKI) != 0)
 1046                         ;
 1047         }
 1048 
 1049         AIC_MISC(("n=%d imess=0x%02x  ", n, sc->sc_imess[0]));
 1050 
 1051         /* We now have a complete message.  Parse it. */
 1052         switch (sc->sc_state) {
 1053                 struct aic_acb *acb;
 1054                 struct aic_tinfo *ti;
 1055 
 1056         case AIC_CONNECTED:
 1057                 AIC_ASSERT(sc->sc_nexus != NULL);
 1058                 acb = sc->sc_nexus;
 1059                 ti = &sc->sc_tinfo[acb->xs->xs_periph->periph_target];
 1060 
 1061                 switch (sc->sc_imess[0]) {
 1062                 case MSG_CMDCOMPLETE:
 1063 #if 0
 1064                         /* impossible dleft is unsigned */
 1065                         if (sc->sc_dleft < 0) {
 1066                                 periph = acb->xs->xs_periph;
 1067                                 printf("%s: %ld extra bytes from %d:%d\n",
 1068                                     device_xname(sc->sc_dev),
 1069                                     (long)-sc->sc_dleft,
 1070                                     periph->periph_target, periph->periph_lun);
 1071                                 sc->sc_dleft = 0;
 1072                         }
 1073 #endif
 1074                         acb->xs->resid = acb->data_length = sc->sc_dleft;
 1075                         sc->sc_state = AIC_CMDCOMPLETE;
 1076                         break;
 1077 
 1078                 case MSG_PARITY_ERROR:
 1079                         /* Resend the last message. */
 1080                         aic_sched_msgout(sc, sc->sc_lastmsg);
 1081                         break;
 1082 
 1083                 case MSG_MESSAGE_REJECT:
 1084                         AIC_MISC(("message rejected %02x  ", sc->sc_lastmsg));
 1085                         switch (sc->sc_lastmsg) {
 1086 #if AIC_USE_SYNCHRONOUS + AIC_USE_WIDE
 1087                         case SEND_IDENTIFY:
 1088                                 ti->flags &= ~(DO_SYNC | DO_WIDE);
 1089                                 ti->period = ti->offset = 0;
 1090                                 aic_setsync(sc, ti);
 1091                                 ti->width = 0;
 1092                                 break;
 1093 #endif
 1094 #if AIC_USE_SYNCHRONOUS
 1095                         case SEND_SDTR:
 1096                                 ti->flags &= ~DO_SYNC;
 1097                                 ti->period = ti->offset = 0;
 1098                                 aic_setsync(sc, ti);
 1099                                 aic_update_xfer_mode(sc,
 1100                                     acb->xs->xs_periph->periph_target);
 1101                                 break;
 1102 #endif
 1103 #if AIC_USE_WIDE
 1104                         case SEND_WDTR:
 1105                                 ti->flags &= ~DO_WIDE;
 1106                                 ti->width = 0;
 1107                                 aic_update_xfer_mode(sc,
 1108                                     acb->xs->xs_periph->periph_target);
 1109                                 break;
 1110 #endif
 1111                         case SEND_INIT_DET_ERR:
 1112                                 aic_sched_msgout(sc, SEND_ABORT);
 1113                                 break;
 1114                         }
 1115                         break;
 1116 
 1117                 case MSG_NOOP:
 1118                         break;
 1119 
 1120                 case MSG_DISCONNECT:
 1121                         ti->dconns++;
 1122                         sc->sc_state = AIC_DISCONNECT;
 1123                         break;
 1124 
 1125                 case MSG_SAVEDATAPOINTER:
 1126                         acb->data_addr = sc->sc_dp;
 1127                         acb->data_length = sc->sc_dleft;
 1128                         break;
 1129 
 1130                 case MSG_RESTOREPOINTERS:
 1131                         sc->sc_dp = acb->data_addr;
 1132                         sc->sc_dleft = acb->data_length;
 1133                         sc->sc_cp = (u_char *)&acb->scsipi_cmd;
 1134                         sc->sc_cleft = acb->scsipi_cmd_length;
 1135                         break;
 1136 
 1137                 case MSG_EXTENDED:
 1138                         switch (sc->sc_imess[2]) {
 1139 #if AIC_USE_SYNCHRONOUS
 1140                         case MSG_EXT_SDTR:
 1141                                 if (sc->sc_imess[1] != 3)
 1142                                         goto reject;
 1143                                 ti->period = sc->sc_imess[3];
 1144                                 ti->offset = sc->sc_imess[4];
 1145                                 ti->flags &= ~DO_SYNC;
 1146                                 if (ti->offset == 0) {
 1147                                 } else if (ti->period < sc->sc_minsync ||
 1148                                            ti->period > sc->sc_maxsync ||
 1149                                            ti->offset > 8) {
 1150                                         ti->period = ti->offset = 0;
 1151                                         aic_sched_msgout(sc, SEND_SDTR);
 1152                                 } else {
 1153                                         aic_update_xfer_mode(sc,
 1154                                             acb->xs->xs_periph->periph_target);
 1155                                 }
 1156                                 aic_setsync(sc, ti);
 1157                                 break;
 1158 #endif
 1159 
 1160 #if AIC_USE_WIDE
 1161                         case MSG_EXT_WDTR:
 1162                                 if (sc->sc_imess[1] != 2)
 1163                                         goto reject;
 1164                                 ti->width = sc->sc_imess[3];
 1165                                 ti->flags &= ~DO_WIDE;
 1166                                 if (ti->width == 0) {
 1167                                 } else if (ti->width > AIC_MAX_WIDTH) {
 1168                                         ti->width = 0;
 1169                                         aic_sched_msgout(sc, SEND_WDTR);
 1170                                 } else {
 1171                                         aic_update_xfer_mode(sc,
 1172                                             acb->xs->xs_periph->periph_target);
 1173                                 }
 1174                                 break;
 1175 #endif
 1176 
 1177                         default:
 1178                                 printf("%s: unrecognized MESSAGE EXTENDED; "
 1179                                     "sending REJECT\n",
 1180                                     device_xname(sc->sc_dev));
 1181                                 AIC_BREAK();
 1182                                 goto reject;
 1183                         }
 1184                         break;
 1185 
 1186                 default:
 1187                         printf("%s: unrecognized MESSAGE; sending REJECT\n",
 1188                             device_xname(sc->sc_dev));
 1189                         AIC_BREAK();
 1190                 reject:
 1191                         aic_sched_msgout(sc, SEND_REJECT);
 1192                         break;
 1193                 }
 1194                 break;
 1195 
 1196         case AIC_RESELECTED:
 1197                 if (!MSG_ISIDENTIFY(sc->sc_imess[0])) {
 1198                         printf("%s: reselect without IDENTIFY; "
 1199                             "sending DEVICE RESET\n", device_xname(sc->sc_dev));
 1200                         AIC_BREAK();
 1201                         goto reset;
 1202                 }
 1203 
 1204                 (void) aic_reselect(sc, sc->sc_imess[0]);
 1205                 break;
 1206 
 1207         default:
 1208                 aprint_error_dev(sc->sc_dev,
 1209                     "unexpected MESSAGE IN; sending DEVICE RESET\n");
 1210                 AIC_BREAK();
 1211         reset:
 1212                 aic_sched_msgout(sc, SEND_DEV_RESET);
 1213                 break;
 1214 
 1215 #ifdef notdef
 1216         abort:
 1217                 aic_sched_msgout(sc, SEND_ABORT);
 1218                 break;
 1219 #endif
 1220         }
 1221 
 1222         bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
 1223         /* Ack the last message byte. */
 1224         (void) bus_space_read_1(iot, ioh, SCSIDAT);
 1225         bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
 1226         while ((bus_space_read_1(iot, ioh, SCSISIG) & ACKI) != 0)
 1227                 ;
 1228 
 1229         /* Go get the next message, if any. */
 1230         goto nextmsg;
 1231 
 1232 out:
 1233         AIC_MISC(("n=%d imess=0x%02x  ", n, sc->sc_imess[0]));
 1234 }
 1235 
 1236 /*
 1237  * Send the highest priority, scheduled message.
 1238  */
 1239 static void
 1240 aic_msgout(struct aic_softc *sc)
 1241 {
 1242         bus_space_tag_t iot = sc->sc_iot;
 1243         bus_space_handle_t ioh = sc->sc_ioh;
 1244 #if AIC_USE_SYNCHRONOUS
 1245         struct aic_tinfo *ti;
 1246 #endif
 1247         u_char sstat1;
 1248         int n;
 1249 
 1250         AIC_TRACE(("aic_msgout  "));
 1251 
 1252         /* Reset the FIFO. */
 1253         bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO);
 1254         /* Enable REQ/ACK protocol. */
 1255         bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
 1256 
 1257         if (sc->sc_prevphase == PH_MSGOUT) {
 1258                 if (sc->sc_omp == sc->sc_omess) {
 1259                         /*
 1260                          * This is a retransmission.
 1261                          *
 1262                          * We get here if the target stayed in MESSAGE OUT
 1263                          * phase.  Section 5.1.9.2 of the SCSI 2 spec indicates
 1264                          * that all of the previously transmitted messages must
 1265                          * be sent again, in the same order.  Therefore, we
 1266                          * requeue all the previously transmitted messages, and
 1267                          * start again from the top.  Our simple priority
 1268                          * scheme keeps the messages in the right order.
 1269                          */
 1270                         AIC_MISC(("retransmitting  "));
 1271                         sc->sc_msgpriq |= sc->sc_msgoutq;
 1272                         /*
 1273                          * Set ATN.  If we're just sending a trivial 1-byte
 1274                          * message, we'll clear ATN later on anyway.
 1275                          */
 1276                         bus_space_write_1(iot, ioh, SCSISIG, PH_MSGOUT | ATNO);
 1277                 } else {
 1278                         /* This is a continuation of the previous message. */
 1279                         n = sc->sc_omp - sc->sc_omess;
 1280                         goto nextbyte;
 1281                 }
 1282         }
 1283 
 1284         /* No messages transmitted so far. */
 1285         sc->sc_msgoutq = 0;
 1286         sc->sc_lastmsg = 0;
 1287 
 1288 nextmsg:
 1289         /* Pick up highest priority message. */
 1290         sc->sc_currmsg = sc->sc_msgpriq & -sc->sc_msgpriq;
 1291         sc->sc_msgpriq &= ~sc->sc_currmsg;
 1292         sc->sc_msgoutq |= sc->sc_currmsg;
 1293 
 1294         /* Build the outgoing message data. */
 1295         switch (sc->sc_currmsg) {
 1296         case SEND_IDENTIFY:
 1297                 AIC_ASSERT(sc->sc_nexus != NULL);
 1298                 sc->sc_omess[0] =
 1299                     MSG_IDENTIFY(sc->sc_nexus->xs->xs_periph->periph_lun, 1);
 1300                 n = 1;
 1301                 break;
 1302 
 1303 #if AIC_USE_SYNCHRONOUS
 1304         case SEND_SDTR:
 1305                 AIC_ASSERT(sc->sc_nexus != NULL);
 1306                 ti = &sc->sc_tinfo[sc->sc_nexus->xs->xs_periph->periph_target];
 1307                 sc->sc_omess[4] = MSG_EXTENDED;
 1308                 sc->sc_omess[3] = 3;
 1309                 sc->sc_omess[2] = MSG_EXT_SDTR;
 1310                 sc->sc_omess[1] = ti->period >> 2;
 1311                 sc->sc_omess[0] = ti->offset;
 1312                 n = 5;
 1313                 break;
 1314 #endif
 1315 
 1316 #if AIC_USE_WIDE
 1317         case SEND_WDTR:
 1318                 AIC_ASSERT(sc->sc_nexus != NULL);
 1319                 ti = &sc->sc_tinfo[sc->sc_nexus->xs->xs_periph->periph_target];
 1320                 sc->sc_omess[3] = MSG_EXTENDED;
 1321                 sc->sc_omess[2] = 2;
 1322                 sc->sc_omess[1] = MSG_EXT_WDTR;
 1323                 sc->sc_omess[0] = ti->width;
 1324                 n = 4;
 1325                 break;
 1326 #endif
 1327 
 1328         case SEND_DEV_RESET:
 1329                 sc->sc_flags |= AIC_ABORTING;
 1330                 sc->sc_omess[0] = MSG_BUS_DEV_RESET;
 1331                 n = 1;
 1332                 break;
 1333 
 1334         case SEND_REJECT:
 1335                 sc->sc_omess[0] = MSG_MESSAGE_REJECT;
 1336                 n = 1;
 1337                 break;
 1338 
 1339         case SEND_PARITY_ERROR:
 1340                 sc->sc_omess[0] = MSG_PARITY_ERROR;
 1341                 n = 1;
 1342                 break;
 1343 
 1344         case SEND_INIT_DET_ERR:
 1345                 sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
 1346                 n = 1;
 1347                 break;
 1348 
 1349         case SEND_ABORT:
 1350                 sc->sc_flags |= AIC_ABORTING;
 1351                 sc->sc_omess[0] = MSG_ABORT;
 1352                 n = 1;
 1353                 break;
 1354 
 1355         default:
 1356                 aprint_error_dev(sc->sc_dev,
 1357                     "unexpected MESSAGE OUT; sending NOOP\n");
 1358                 AIC_BREAK();
 1359                 sc->sc_omess[0] = MSG_NOOP;
 1360                 n = 1;
 1361                 break;
 1362         }
 1363         sc->sc_omp = &sc->sc_omess[n];
 1364 
 1365 nextbyte:
 1366         /* Send message bytes. */
 1367         for (;;) {
 1368                 for (;;) {
 1369                         sstat1 = bus_space_read_1(iot, ioh, SSTAT1);
 1370                         if ((sstat1 & (REQINIT | PHASECHG | BUSFREE)) != 0)
 1371                                 break;
 1372                         /* Wait for REQINIT.  XXX Need timeout. */
 1373                 }
 1374                 if ((sstat1 & (PHASECHG | BUSFREE)) != 0) {
 1375                         /*
 1376                          * Target left MESSAGE OUT, possibly to reject
 1377                          * our message.
 1378                          *
 1379                          * If this is the last message being sent, then we
 1380                          * deassert ATN, since either the target is going to
 1381                          * ignore this message, or it's going to ask for a
 1382                          * retransmission via MESSAGE PARITY ERROR (in which
 1383                          * case we reassert ATN anyway).
 1384                          */
 1385                         if (sc->sc_msgpriq == 0)
 1386                                 bus_space_write_1(iot, ioh, CLRSINT1, CLRATNO);
 1387                         goto out;
 1388                 }
 1389 
 1390                 /* Clear ATN before last byte if this is the last message. */
 1391                 if (n == 1 && sc->sc_msgpriq == 0)
 1392                         bus_space_write_1(iot, ioh, CLRSINT1, CLRATNO);
 1393                 /* Send message byte. */
 1394                 bus_space_write_1(iot, ioh, SCSIDAT, *--sc->sc_omp);
 1395                 --n;
 1396                 /* Keep track of the last message we've sent any bytes of. */
 1397                 sc->sc_lastmsg = sc->sc_currmsg;
 1398                 /* Wait for ACK to be negated.  XXX Need timeout. */
 1399                 while ((bus_space_read_1(iot, ioh, SCSISIG) & ACKI) != 0)
 1400                         ;
 1401 
 1402                 if (n == 0)
 1403                         break;
 1404         }
 1405 
 1406         /* We get here only if the entire message has been transmitted. */
 1407         if (sc->sc_msgpriq != 0) {
 1408                 /* There are more outgoing messages. */
 1409                 goto nextmsg;
 1410         }
 1411 
 1412         /*
 1413          * The last message has been transmitted.  We need to remember the last
 1414          * message transmitted (in case the target switches to MESSAGE IN phase
 1415          * and sends a MESSAGE REJECT), and the list of messages transmitted
 1416          * this time around (in case the target stays in MESSAGE OUT phase to
 1417          * request a retransmit).
 1418          */
 1419 
 1420 out:
 1421         /* Disable REQ/ACK protocol. */
 1422         bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
 1423 }
 1424 
 1425 /* aic_dataout_pio: perform a data transfer using the FIFO datapath in the
 1426  * aic6360
 1427  * Precondition: The SCSI bus should be in the DOUT phase, with REQ asserted
 1428  * and ACK deasserted (i.e. waiting for a data byte)
 1429  * This new revision has been optimized (I tried) to make the common case fast,
 1430  * and the rarer cases (as a result) somewhat more complex
 1431  */
 1432 static int
 1433 aic_dataout_pio(struct aic_softc *sc, u_char *p, int n)
 1434 {
 1435         bus_space_tag_t iot = sc->sc_iot;
 1436         bus_space_handle_t ioh = sc->sc_ioh;
 1437         u_char dmastat = 0;
 1438         int out = 0;
 1439 #define DOUTAMOUNT 128          /* Full FIFO */
 1440 
 1441         AIC_MISC(("%02x%02x  ", bus_space_read_1(iot, ioh, FIFOSTAT),
 1442             bus_space_read_1(iot, ioh, SSTAT2)));
 1443 
 1444         /* Clear host FIFO and counter. */
 1445         bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO | WRITE);
 1446         /* Enable FIFOs. */
 1447         bus_space_write_1(iot, ioh, DMACNTRL0, ENDMA | DWORDPIO | WRITE);
 1448         bus_space_write_1(iot, ioh, SXFRCTL0, SCSIEN | DMAEN | CHEN);
 1449 
 1450         /* Turn off ENREQINIT for now. */
 1451         bus_space_write_1(iot, ioh, SIMODE1,
 1452             ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENPHASECHG);
 1453 
 1454         /* I have tried to make the main loop as tight as possible.  This
 1455          * means that some of the code following the loop is a bit more
 1456          * complex than otherwise.
 1457          */
 1458         while (n > 0) {
 1459                 for (;;) {
 1460                         dmastat = bus_space_read_1(iot, ioh, DMASTAT);
 1461                         if ((dmastat & (DFIFOEMP | INTSTAT)) != 0)
 1462                                 break;
 1463                 }
 1464 
 1465                 if ((dmastat & INTSTAT) != 0)
 1466                         goto phasechange;
 1467 
 1468                 if (n >= DOUTAMOUNT) {
 1469                         n -= DOUTAMOUNT;
 1470                         out += DOUTAMOUNT;
 1471 
 1472 #if AIC_USE_DWORDS
 1473                         bus_space_write_multi_4(iot, ioh, DMADATALONG,
 1474                             (u_int32_t *) p, DOUTAMOUNT >> 2);
 1475 #else
 1476                         bus_space_write_multi_2(iot, ioh, DMADATA,
 1477                             (u_int16_t *) p, DOUTAMOUNT >> 1);
 1478 #endif
 1479 
 1480                         p += DOUTAMOUNT;
 1481                 } else {
 1482                         int xfer;
 1483 
 1484                         xfer = n;
 1485                         AIC_MISC(("%d> ", xfer));
 1486 
 1487                         n -= xfer;
 1488                         out += xfer;
 1489 
 1490 #if AIC_USE_DWORDS
 1491                         if (xfer >= 12) {
 1492                                 bus_space_write_multi_4(iot, ioh, DMADATALONG,
 1493                                     (u_int32_t *) p, xfer >> 2);
 1494                                 p += xfer & ~3;
 1495                                 xfer &= 3;
 1496                         }
 1497 #else
 1498                         if (xfer >= 8) {
 1499                                 bus_space_write_multi_2(iot, ioh, DMADATA,
 1500                                     (u_int16_t *) p, xfer >> 1);
 1501                                 p += xfer & ~1;
 1502                                 xfer &= 1;
 1503                         }
 1504 #endif
 1505 
 1506                         if (xfer > 0) {
 1507                                 bus_space_write_1(iot, ioh, DMACNTRL0,
 1508                                     ENDMA | B8MODE | WRITE);
 1509                                 bus_space_write_multi_1(iot, ioh, DMADATA,
 1510                                     p, xfer);
 1511                                 p += xfer;
 1512                                 bus_space_write_1(iot, ioh, DMACNTRL0,
 1513                                     ENDMA | DWORDPIO | WRITE);
 1514                         }
 1515                 }
 1516         }
 1517 
 1518         if (out == 0) {
 1519                 bus_space_write_1(iot, ioh, SXFRCTL1, BITBUCKET);
 1520                 for (;;) {
 1521                         if ((bus_space_read_1(iot, ioh, DMASTAT) & INTSTAT)
 1522                             != 0)
 1523                                 break;
 1524                 }
 1525                 bus_space_write_1(iot, ioh, SXFRCTL1, 0);
 1526                 AIC_MISC(("extra data  "));
 1527         } else {
 1528                 /* See the bytes off chip */
 1529                 for (;;) {
 1530                         dmastat = bus_space_read_1(iot, ioh, DMASTAT);
 1531                         if ((dmastat & INTSTAT) != 0)
 1532                                 goto phasechange;
 1533                         if ((dmastat & DFIFOEMP) != 0 &&
 1534                             (bus_space_read_1(iot, ioh, SSTAT2) & SEMPTY) != 0)
 1535                                 break;
 1536                 }
 1537         }
 1538 
 1539 phasechange:
 1540         if ((dmastat & INTSTAT) != 0) {
 1541                 /* Some sort of phase change. */
 1542                 int amount;
 1543 
 1544                 /* Stop transfers, do some accounting */
 1545                 amount = bus_space_read_1(iot, ioh, FIFOSTAT)
 1546                     + (bus_space_read_1(iot, ioh, SSTAT2) & 15);
 1547                 if (amount > 0) {
 1548                         out -= amount;
 1549                         bus_space_write_1(iot, ioh, DMACNTRL0,
 1550                             RSTFIFO | WRITE);
 1551                         bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | CLRCH);
 1552                         AIC_MISC(("+%d ", amount));
 1553                 }
 1554         }
 1555 
 1556         /* Turn on ENREQINIT again. */
 1557         bus_space_write_1(iot, ioh, SIMODE1,
 1558             ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENREQINIT | ENPHASECHG);
 1559 
 1560         /* Stop the FIFO data path. */
 1561         bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
 1562         bus_space_write_1(iot, ioh, DMACNTRL0, 0);
 1563 
 1564         return out;
 1565 }
 1566 
 1567 /* aic_datain_pio: perform data transfers using the FIFO datapath in the
 1568  * aic6360
 1569  * Precondition: The SCSI bus should be in the DIN phase, with REQ asserted
 1570  * and ACK deasserted (i.e. at least one byte is ready).
 1571  * For now, uses a pretty dumb algorithm, hangs around until all data has been
 1572  * transferred.  This, is OK for fast targets, but not so smart for slow
 1573  * targets which don't disconnect or for huge transfers.
 1574  */
 1575 static int
 1576 aic_datain_pio(struct aic_softc *sc, u_char *p, int n)
 1577 {
 1578         bus_space_tag_t iot = sc->sc_iot;
 1579         bus_space_handle_t ioh = sc->sc_ioh;
 1580         u_char dmastat;
 1581         int in = 0;
 1582 #define DINAMOUNT 128           /* Full FIFO */
 1583 
 1584         AIC_MISC(("%02x%02x  ", bus_space_read_1(iot, ioh, FIFOSTAT),
 1585             bus_space_read_1(iot, ioh, SSTAT2)));
 1586 
 1587         /* Clear host FIFO and counter. */
 1588         bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO);
 1589         /* Enable FIFOs. */
 1590         bus_space_write_1(iot, ioh, DMACNTRL0, ENDMA | DWORDPIO);
 1591         bus_space_write_1(iot, ioh, SXFRCTL0, SCSIEN | DMAEN | CHEN);
 1592 
 1593         /* Turn off ENREQINIT for now. */
 1594         bus_space_write_1(iot, ioh, SIMODE1,
 1595             ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENPHASECHG);
 1596 
 1597         /* We leave this loop if one or more of the following is true:
 1598          * a) phase != PH_DATAIN && FIFOs are empty
 1599          * b) SCSIRSTI is set (a reset has occurred) or busfree is detected.
 1600          */
 1601         while (n > 0) {
 1602                 /* Wait for fifo half full or phase mismatch */
 1603                 for (;;) {
 1604                         dmastat = bus_space_read_1(iot, ioh, DMASTAT);
 1605                         if ((dmastat & (DFIFOFULL | INTSTAT)) != 0)
 1606                                 break;
 1607                 }
 1608 
 1609                 if ((dmastat & DFIFOFULL) != 0) {
 1610                         n -= DINAMOUNT;
 1611                         in += DINAMOUNT;
 1612 
 1613 #if AIC_USE_DWORDS
 1614                         bus_space_read_multi_4(iot, ioh, DMADATALONG,
 1615                             (u_int32_t *) p, DINAMOUNT >> 2);
 1616 #else
 1617                         bus_space_read_multi_2(iot, ioh, DMADATA,
 1618                             (u_int16_t *) p, DINAMOUNT >> 1);
 1619 #endif
 1620 
 1621                         p += DINAMOUNT;
 1622                 } else {
 1623                         int xfer;
 1624 
 1625                         xfer = uimin(bus_space_read_1(iot, ioh, FIFOSTAT), n);
 1626                         AIC_MISC((">%d ", xfer));
 1627 
 1628                         n -= xfer;
 1629                         in += xfer;
 1630 
 1631 #if AIC_USE_DWORDS
 1632                         if (xfer >= 12) {
 1633                                 bus_space_read_multi_4(iot, ioh, DMADATALONG,
 1634                                     (u_int32_t *) p, xfer >> 2);
 1635                                 p += xfer & ~3;
 1636                                 xfer &= 3;
 1637                         }
 1638 #else
 1639                         if (xfer >= 8) {
 1640                                 bus_space_read_multi_2(iot, ioh, DMADATA,
 1641                                     (u_int16_t *) p, xfer >> 1);
 1642                                 p += xfer & ~1;
 1643                                 xfer &= 1;
 1644                         }
 1645 #endif
 1646 
 1647                         if (xfer > 0) {
 1648                                 bus_space_write_1(iot, ioh, DMACNTRL0,
 1649                                     ENDMA | B8MODE);
 1650                                 bus_space_read_multi_1(iot, ioh, DMADATA,
 1651                                     p, xfer);
 1652                                 p += xfer;
 1653                                 bus_space_write_1(iot, ioh, DMACNTRL0,
 1654                                     ENDMA | DWORDPIO);
 1655                         }
 1656                 }
 1657 
 1658                 if ((dmastat & INTSTAT) != 0)
 1659                         goto phasechange;
 1660         }
 1661 
 1662         /* Some SCSI-devices are rude enough to transfer more data than what
 1663          * was requested, e.g. 2048 bytes from a CD-ROM instead of the
 1664          * requested 512.  Test for progress, i.e. real transfers.  If no real
 1665          * transfers have been performed (n is probably already zero) and the
 1666          * FIFO is not empty, waste some bytes....
 1667          */
 1668         if (in == 0) {
 1669                 bus_space_write_1(iot, ioh, SXFRCTL1, BITBUCKET);
 1670                 for (;;) {
 1671                         if ((bus_space_read_1(iot, ioh, DMASTAT) & INTSTAT)
 1672                             != 0)
 1673                                 break;
 1674                 }
 1675                 bus_space_write_1(iot, ioh, SXFRCTL1, 0);
 1676                 AIC_MISC(("extra data  "));
 1677         }
 1678 
 1679 phasechange:
 1680         /* Turn on ENREQINIT again. */
 1681         bus_space_write_1(iot, ioh, SIMODE1,
 1682             ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENREQINIT | ENPHASECHG);
 1683 
 1684         /* Stop the FIFO data path. */
 1685         bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
 1686         bus_space_write_1(iot, ioh, DMACNTRL0, 0);
 1687 
 1688         return in;
 1689 }
 1690 
 1691 /*
 1692  * This is the workhorse routine of the driver.
 1693  * Deficiencies (for now):
 1694  * 1) always uses programmed I/O
 1695  */
 1696 int
 1697 aicintr(void *arg)
 1698 {
 1699         struct aic_softc *sc = arg;
 1700         bus_space_tag_t iot = sc->sc_iot;
 1701         bus_space_handle_t ioh = sc->sc_ioh;
 1702         u_char sstat0, sstat1;
 1703         struct aic_acb *acb;
 1704         struct scsipi_periph *periph;
 1705         struct aic_tinfo *ti;
 1706         int n;
 1707 
 1708         if (!device_is_active(sc->sc_dev))
 1709                 return (0);
 1710 
 1711         /*
 1712          * Clear INTEN.  We enable it again before returning.  This makes the
 1713          * interrupt esssentially level-triggered.
 1714          */
 1715         bus_space_write_1(iot, ioh, DMACNTRL0, 0);
 1716 
 1717         AIC_TRACE(("aicintr  "));
 1718 
 1719 loop:
 1720         /*
 1721          * First check for abnormal conditions, such as reset.
 1722          */
 1723         sstat1 = bus_space_read_1(iot, ioh, SSTAT1);
 1724         AIC_MISC(("sstat1:0x%02x ", sstat1));
 1725 
 1726         if ((sstat1 & SCSIRSTI) != 0) {
 1727                 printf("%s: SCSI bus reset\n", device_xname(sc->sc_dev));
 1728                 goto reset;
 1729         }
 1730 
 1731         /*
 1732          * Check for less serious errors.
 1733          */
 1734         if ((sstat1 & SCSIPERR) != 0) {
 1735                 printf("%s: SCSI bus parity error\n", device_xname(sc->sc_dev));
 1736                 bus_space_write_1(iot, ioh, CLRSINT1, CLRSCSIPERR);
 1737                 if (sc->sc_prevphase == PH_MSGIN) {
 1738                         sc->sc_flags |= AIC_DROP_MSGIN;
 1739                         aic_sched_msgout(sc, SEND_PARITY_ERROR);
 1740                 } else
 1741                         aic_sched_msgout(sc, SEND_INIT_DET_ERR);
 1742         }
 1743 
 1744         /*
 1745          * If we're not already busy doing something test for the following
 1746          * conditions:
 1747          * 1) We have been reselected by something
 1748          * 2) We have selected something successfully
 1749          * 3) Our selection process has timed out
 1750          * 4) This is really a bus free interrupt just to get a new command
 1751          *    going?
 1752          * 5) Spurious interrupt?
 1753          */
 1754         switch (sc->sc_state) {
 1755         case AIC_IDLE:
 1756         case AIC_SELECTING:
 1757                 sstat0 = bus_space_read_1(iot, ioh, SSTAT0);
 1758                 AIC_MISC(("sstat0:0x%02x ", sstat0));
 1759 
 1760                 if ((sstat0 & TARGET) != 0) {
 1761                         /*
 1762                          * We don't currently support target mode.
 1763                          */
 1764                         printf("%s: target mode selected; going to BUS FREE\n",
 1765                             device_xname(sc->sc_dev));
 1766                         bus_space_write_1(iot, ioh, SCSISIG, 0);
 1767 
 1768                         goto sched;
 1769                 } else if ((sstat0 & SELDI) != 0) {
 1770                         AIC_MISC(("reselected  "));
 1771 
 1772                         /*
 1773                          * If we're trying to select a target ourselves,
 1774                          * push our command back into the ready list.
 1775                          */
 1776                         if (sc->sc_state == AIC_SELECTING) {
 1777                                 AIC_MISC(("backoff selector  "));
 1778                                 AIC_ASSERT(sc->sc_nexus != NULL);
 1779                                 acb = sc->sc_nexus;
 1780                                 sc->sc_nexus = NULL;
 1781                                 TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
 1782                         }
 1783 
 1784                         /* Save reselection ID. */
 1785                         sc->sc_selid = bus_space_read_1(iot, ioh, SELID);
 1786 
 1787                         sc->sc_state = AIC_RESELECTED;
 1788                 } else if ((sstat0 & SELDO) != 0) {
 1789                         AIC_MISC(("selected  "));
 1790 
 1791                         /* We have selected a target. Things to do:
 1792                          * a) Determine what message(s) to send.
 1793                          * b) Verify that we're still selecting the target.
 1794                          * c) Mark device as busy.
 1795                          */
 1796                         if (sc->sc_state != AIC_SELECTING) {
 1797                                 printf("%s: selection out while idle; "
 1798                                     "resetting\n", device_xname(sc->sc_dev));
 1799                                 AIC_BREAK();
 1800                                 goto reset;
 1801                         }
 1802                         AIC_ASSERT(sc->sc_nexus != NULL);
 1803                         acb = sc->sc_nexus;
 1804                         periph = acb->xs->xs_periph;
 1805                         ti = &sc->sc_tinfo[periph->periph_target];
 1806 
 1807                         sc->sc_msgpriq = SEND_IDENTIFY;
 1808                         if (acb->flags & ACB_RESET)
 1809                                 sc->sc_msgpriq |= SEND_DEV_RESET;
 1810                         else if (acb->flags & ACB_ABORT)
 1811                                 sc->sc_msgpriq |= SEND_ABORT;
 1812                         else {
 1813 #if AIC_USE_SYNCHRONOUS
 1814                                 if ((ti->flags & DO_SYNC) != 0)
 1815                                         sc->sc_msgpriq |= SEND_SDTR;
 1816 #endif
 1817 #if AIC_USE_WIDE
 1818                                 if ((ti->flags & DO_WIDE) != 0)
 1819                                         sc->sc_msgpriq |= SEND_WDTR;
 1820 #endif
 1821                         }
 1822 
 1823                         acb->flags |= ACB_NEXUS;
 1824                         ti->lubusy |= (1 << periph->periph_lun);
 1825 
 1826                         /* Do an implicit RESTORE POINTERS. */
 1827                         sc->sc_dp = acb->data_addr;
 1828                         sc->sc_dleft = acb->data_length;
 1829                         sc->sc_cp = (u_char *)&acb->scsipi_cmd;
 1830                         sc->sc_cleft = acb->scsipi_cmd_length;
 1831 
 1832                         /* On our first connection, schedule a timeout. */
 1833                         if ((acb->xs->xs_control & XS_CTL_POLL) == 0)
 1834                                 callout_reset(&acb->xs->xs_callout,
 1835                                     mstohz(acb->timeout), aic_timeout, acb);
 1836 
 1837                         sc->sc_state = AIC_CONNECTED;
 1838                 } else if ((sstat1 & SELTO) != 0) {
 1839                         AIC_MISC(("selection timeout  "));
 1840 
 1841                         if (sc->sc_state != AIC_SELECTING) {
 1842                                 printf("%s: selection timeout while idle; "
 1843                                     "resetting\n", device_xname(sc->sc_dev));
 1844                                 AIC_BREAK();
 1845                                 goto reset;
 1846                         }
 1847                         AIC_ASSERT(sc->sc_nexus != NULL);
 1848                         acb = sc->sc_nexus;
 1849 
 1850                         bus_space_write_1(iot, ioh, SXFRCTL1, 0);
 1851                         bus_space_write_1(iot, ioh, SCSISEQ, ENRESELI);
 1852                         bus_space_write_1(iot, ioh, CLRSINT1, CLRSELTIMO);
 1853                         delay(250);
 1854 
 1855                         acb->xs->error = XS_SELTIMEOUT;
 1856                         goto finish;
 1857                 } else {
 1858                         if (sc->sc_state != AIC_IDLE) {
 1859                                 printf("%s: BUS FREE while not idle; "
 1860                                     "state=%d\n",
 1861                                     device_xname(sc->sc_dev), sc->sc_state);
 1862                                 AIC_BREAK();
 1863                                 goto out;
 1864                         }
 1865 
 1866                         goto sched;
 1867                 }
 1868 
 1869                 /*
 1870                  * Turn off selection stuff, and prepare to catch bus free
 1871                  * interrupts, parity errors, and phase changes.
 1872                  */
 1873                 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | CLRSTCNT | CLRCH);
 1874                 bus_space_write_1(iot, ioh, SXFRCTL1, 0);
 1875                 bus_space_write_1(iot, ioh, SCSISEQ, ENAUTOATNP);
 1876                 bus_space_write_1(iot, ioh, CLRSINT0, CLRSELDI | CLRSELDO);
 1877                 bus_space_write_1(iot, ioh, CLRSINT1,
 1878                     CLRBUSFREE | CLRPHASECHG);
 1879                 bus_space_write_1(iot, ioh, SIMODE0, 0);
 1880                 bus_space_write_1(iot, ioh, SIMODE1,
 1881                     ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENREQINIT |
 1882                     ENPHASECHG);
 1883 
 1884                 sc->sc_flags = 0;
 1885                 sc->sc_prevphase = PH_INVALID;
 1886                 goto dophase;
 1887         }
 1888 
 1889         if ((sstat1 & BUSFREE) != 0) {
 1890                 /* We've gone to BUS FREE phase. */
 1891                 bus_space_write_1(iot, ioh, CLRSINT1,
 1892                     CLRBUSFREE | CLRPHASECHG);
 1893 
 1894                 switch (sc->sc_state) {
 1895                 case AIC_RESELECTED:
 1896                         goto sched;
 1897 
 1898                 case AIC_CONNECTED:
 1899                         AIC_ASSERT(sc->sc_nexus != NULL);
 1900                         acb = sc->sc_nexus;
 1901 
 1902 #if AIC_USE_SYNCHRONOUS + AIC_USE_WIDE
 1903                         if (sc->sc_prevphase == PH_MSGOUT) {
 1904                                 /*
 1905                                  * If the target went to BUS FREE phase during
 1906                                  * or immediately after sending a SDTR or WDTR
 1907                                  * message, disable negotiation.
 1908                                  */
 1909                                 periph = acb->xs->xs_periph;
 1910                                 ti = &sc->sc_tinfo[periph->periph_target];
 1911                                 switch (sc->sc_lastmsg) {
 1912 #if AIC_USE_SYNCHRONOUS
 1913                                 case SEND_SDTR:
 1914                                         ti->flags &= ~DO_SYNC;
 1915                                         ti->period = ti->offset = 0;
 1916                                         break;
 1917 #endif
 1918 #if AIC_USE_WIDE
 1919                                 case SEND_WDTR:
 1920                                         ti->flags &= ~DO_WIDE;
 1921                                         ti->width = 0;
 1922                                         break;
 1923 #endif
 1924                                 }
 1925                         }
 1926 #endif
 1927 
 1928                         if ((sc->sc_flags & AIC_ABORTING) == 0) {
 1929                                 /*
 1930                                  * Section 5.1.1 of the SCSI 2 spec suggests
 1931                                  * issuing a REQUEST SENSE following an
 1932                                  * unexpected disconnect.  Some devices go into
 1933                                  * a contingent allegiance condition when
 1934                                  * disconnecting, and this is necessary to
 1935                                  * clean up their state.
 1936                                  */
 1937                                 aprint_error_dev(sc->sc_dev,
 1938                                     "unexpected disconnect; "
 1939                                     "sending REQUEST SENSE\n");
 1940                                 AIC_BREAK();
 1941                                 aic_sense(sc, acb);
 1942                                 goto out;
 1943                         }
 1944 
 1945                         acb->xs->error = XS_DRIVER_STUFFUP;
 1946                         goto finish;
 1947 
 1948                 case AIC_DISCONNECT:
 1949                         AIC_ASSERT(sc->sc_nexus != NULL);
 1950                         acb = sc->sc_nexus;
 1951 #if 1 /* XXXX */
 1952                         acb->data_addr = sc->sc_dp;
 1953                         acb->data_length = sc->sc_dleft;
 1954 #endif
 1955                         TAILQ_INSERT_HEAD(&sc->nexus_list, acb, chain);
 1956                         sc->sc_nexus = NULL;
 1957                         goto sched;
 1958 
 1959                 case AIC_CMDCOMPLETE:
 1960                         AIC_ASSERT(sc->sc_nexus != NULL);
 1961                         acb = sc->sc_nexus;
 1962                         goto finish;
 1963                 }
 1964         }
 1965 
 1966         bus_space_write_1(iot, ioh, CLRSINT1, CLRPHASECHG);
 1967 
 1968 dophase:
 1969         if ((sstat1 & REQINIT) == 0) {
 1970                 /* Wait for REQINIT. */
 1971                 goto out;
 1972         }
 1973 
 1974         sc->sc_phase = bus_space_read_1(iot, ioh, SCSISIG) & PH_MASK;
 1975         bus_space_write_1(iot, ioh, SCSISIG, sc->sc_phase);
 1976 
 1977         switch (sc->sc_phase) {
 1978         case PH_MSGOUT:
 1979                 if (sc->sc_state != AIC_CONNECTED &&
 1980                     sc->sc_state != AIC_RESELECTED)
 1981                         break;
 1982                 aic_msgout(sc);
 1983                 sc->sc_prevphase = PH_MSGOUT;
 1984                 goto loop;
 1985 
 1986         case PH_MSGIN:
 1987                 if (sc->sc_state != AIC_CONNECTED &&
 1988                     sc->sc_state != AIC_RESELECTED)
 1989                         break;
 1990                 aic_msgin(sc);
 1991                 sc->sc_prevphase = PH_MSGIN;
 1992                 goto loop;
 1993 
 1994         case PH_CMD:
 1995                 if (sc->sc_state != AIC_CONNECTED)
 1996                         break;
 1997 #if AIC_DEBUG
 1998                 if ((aic_debug & AIC_SHOWMISC) != 0) {
 1999                         AIC_ASSERT(sc->sc_nexus != NULL);
 2000                         acb = sc->sc_nexus;
 2001                         printf("cmd=0x%02x+%d ",
 2002                             acb->scsipi_cmd.opcode, acb->scsipi_cmd_length-1);
 2003                 }
 2004 #endif
 2005                 n = aic_dataout_pio(sc, sc->sc_cp, sc->sc_cleft);
 2006                 sc->sc_cp += n;
 2007                 sc->sc_cleft -= n;
 2008                 sc->sc_prevphase = PH_CMD;
 2009                 goto loop;
 2010 
 2011         case PH_DATAOUT:
 2012                 if (sc->sc_state != AIC_CONNECTED)
 2013                         break;
 2014                 AIC_MISC(("dataout %ld ", (long)sc->sc_dleft));
 2015                 n = aic_dataout_pio(sc, sc->sc_dp, sc->sc_dleft);
 2016                 sc->sc_dp += n;
 2017                 sc->sc_dleft -= n;
 2018                 sc->sc_prevphase = PH_DATAOUT;
 2019                 goto loop;
 2020 
 2021         case PH_DATAIN:
 2022                 if (sc->sc_state != AIC_CONNECTED)
 2023                         break;
 2024                 AIC_MISC(("datain %ld ", (long)sc->sc_dleft));
 2025                 n = aic_datain_pio(sc, sc->sc_dp, sc->sc_dleft);
 2026                 sc->sc_dp += n;
 2027                 sc->sc_dleft -= n;
 2028                 sc->sc_prevphase = PH_DATAIN;
 2029                 goto loop;
 2030 
 2031         case PH_STAT:
 2032                 if (sc->sc_state != AIC_CONNECTED)
 2033                         break;
 2034                 AIC_ASSERT(sc->sc_nexus != NULL);
 2035                 acb = sc->sc_nexus;
 2036                 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
 2037                 acb->target_stat = bus_space_read_1(iot, ioh, SCSIDAT);
 2038                 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
 2039                 AIC_MISC(("target_stat=0x%02x  ", acb->target_stat));
 2040                 sc->sc_prevphase = PH_STAT;
 2041                 goto loop;
 2042         }
 2043 
 2044         aprint_error_dev(sc->sc_dev, "unexpected bus phase; resetting\n");
 2045         AIC_BREAK();
 2046 reset:
 2047         aic_init(sc, 1);
 2048         return 1;
 2049 
 2050 finish:
 2051         callout_stop(&acb->xs->xs_callout);
 2052         aic_done(sc, acb);
 2053         goto out;
 2054 
 2055 sched:
 2056         sc->sc_state = AIC_IDLE;
 2057         aic_sched(sc);
 2058         goto out;
 2059 
 2060 out:
 2061         bus_space_write_1(iot, ioh, DMACNTRL0, INTEN);
 2062         return 1;
 2063 }
 2064 
 2065 static void
 2066 aic_abort(struct aic_softc *sc, struct aic_acb *acb)
 2067 {
 2068 
 2069         /* 2 secs for the abort */
 2070         acb->timeout = AIC_ABORT_TIMEOUT;
 2071         acb->flags |= ACB_ABORT;
 2072 
 2073         if (acb == sc->sc_nexus) {
 2074                 /*
 2075                  * If we're still selecting, the message will be scheduled
 2076                  * after selection is complete.
 2077                  */
 2078                 if (sc->sc_state == AIC_CONNECTED)
 2079                         aic_sched_msgout(sc, SEND_ABORT);
 2080         } else {
 2081                 aic_dequeue(sc, acb);
 2082                 TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
 2083                 if (sc->sc_state == AIC_IDLE)
 2084                         aic_sched(sc);
 2085         }
 2086 }
 2087 
 2088 static void
 2089 aic_timeout(void *arg)
 2090 {
 2091         struct aic_acb *acb = arg;
 2092         struct scsipi_xfer *xs = acb->xs;
 2093         struct scsipi_periph *periph = xs->xs_periph;
 2094         struct aic_softc *sc =
 2095             device_private(periph->periph_channel->chan_adapter->adapt_dev);
 2096         int s;
 2097 
 2098         scsipi_printaddr(periph);
 2099         printf("timed out");
 2100 
 2101         s = splbio();
 2102 
 2103         if (acb->flags & ACB_ABORT) {
 2104                 /* abort timed out */
 2105                 printf(" AGAIN\n");
 2106                 /* XXX Must reset! */
 2107         } else {
 2108                 /* abort the operation that has timed out */
 2109                 printf("\n");
 2110                 acb->xs->error = XS_TIMEOUT;
 2111                 aic_abort(sc, acb);
 2112         }
 2113 
 2114         splx(s);
 2115 }
 2116 
 2117 #ifdef AIC_DEBUG
 2118 /*
 2119  * The following functions are mostly used for debugging purposes, either
 2120  * directly called from the driver or from the kernel debugger.
 2121  */
 2122 
 2123 static void
 2124 aic_show_scsi_cmd(struct aic_acb *acb)
 2125 {
 2126         u_char  *b = (u_char *)&acb->scsipi_cmd;
 2127         struct scsipi_periph *periph = acb->xs->xs_periph;
 2128         int i;
 2129 
 2130         scsipi_printaddr(periph);
 2131         if ((acb->xs->xs_control & XS_CTL_RESET) == 0) {
 2132                 for (i = 0; i < acb->scsipi_cmd_length; i++) {
 2133                         if (i)
 2134                                 printf(",");
 2135                         printf("%x", b[i]);
 2136                 }
 2137                 printf("\n");
 2138         } else
 2139                 printf("RESET\n");
 2140 }
 2141 
 2142 static void
 2143 aic_print_acb(struct aic_acb *acb)
 2144 {
 2145 
 2146         printf("acb@%p xs=%p flags=%x", acb, acb->xs, acb->flags);
 2147         printf(" dp=%p dleft=%d target_stat=%x\n",
 2148                acb->data_addr, acb->data_length, acb->target_stat);
 2149         aic_show_scsi_cmd(acb);
 2150 }
 2151 
 2152 void
 2153 aic_print_active_acb(void)
 2154 {
 2155         struct aic_acb *acb;
 2156         struct aic_softc *sc = device_lookup_private(&aic_cd, 0);
 2157 
 2158         printf("ready list:\n");
 2159         for (acb = sc->ready_list.tqh_first; acb != NULL;
 2160             acb = acb->chain.tqe_next)
 2161                 aic_print_acb(acb);
 2162         printf("nexus:\n");
 2163         if (sc->sc_nexus != NULL)
 2164                 aic_print_acb(sc->sc_nexus);
 2165         printf("nexus list:\n");
 2166         for (acb = sc->nexus_list.tqh_first; acb != NULL;
 2167             acb = acb->chain.tqe_next)
 2168                 aic_print_acb(acb);
 2169 }
 2170 
 2171 void
 2172 aic_dump6360(struct aic_softc *sc)
 2173 {
 2174         bus_space_tag_t iot = sc->sc_iot;
 2175         bus_space_handle_t ioh = sc->sc_ioh;
 2176 
 2177         printf("aic6360: SCSISEQ=%x SXFRCTL0=%x SXFRCTL1=%x SCSISIG=%x\n",
 2178             bus_space_read_1(iot, ioh, SCSISEQ),
 2179             bus_space_read_1(iot, ioh, SXFRCTL0),
 2180             bus_space_read_1(iot, ioh, SXFRCTL1),
 2181             bus_space_read_1(iot, ioh, SCSISIG));
 2182         printf("         SSTAT0=%x SSTAT1=%x SSTAT2=%x SSTAT3=%x SSTAT4=%x\n",
 2183             bus_space_read_1(iot, ioh, SSTAT0),
 2184             bus_space_read_1(iot, ioh, SSTAT1),
 2185             bus_space_read_1(iot, ioh, SSTAT2),
 2186             bus_space_read_1(iot, ioh, SSTAT3),
 2187             bus_space_read_1(iot, ioh, SSTAT4));
 2188         printf("         SIMODE0=%x SIMODE1=%x DMACNTRL0=%x DMACNTRL1=%x "
 2189             "DMASTAT=%x\n",
 2190             bus_space_read_1(iot, ioh, SIMODE0),
 2191             bus_space_read_1(iot, ioh, SIMODE1),
 2192             bus_space_read_1(iot, ioh, DMACNTRL0),
 2193             bus_space_read_1(iot, ioh, DMACNTRL1),
 2194             bus_space_read_1(iot, ioh, DMASTAT));
 2195         printf("         FIFOSTAT=%d SCSIBUS=0x%x\n",
 2196             bus_space_read_1(iot, ioh, FIFOSTAT),
 2197             bus_space_read_1(iot, ioh, SCSIBUS));
 2198 }
 2199 
 2200 void
 2201 aic_dump_driver(struct aic_softc *sc)
 2202 {
 2203         struct aic_tinfo *ti;
 2204         int i;
 2205 
 2206         printf("nexus=%p prevphase=%x\n", sc->sc_nexus, sc->sc_prevphase);
 2207         printf("state=%x msgin=%x msgpriq=%x msgoutq=%x lastmsg=%x "
 2208             "currmsg=%x\n",
 2209             sc->sc_state, sc->sc_imess[0],
 2210             sc->sc_msgpriq, sc->sc_msgoutq, sc->sc_lastmsg, sc->sc_currmsg);
 2211         for (i = 0; i < 7; i++) {
 2212                 ti = &sc->sc_tinfo[i];
 2213                 printf("tinfo%d: %d cmds %d disconnects %d timeouts",
 2214                     i, ti->cmds, ti->dconns, ti->touts);
 2215                 printf(" %d senses flags=%x\n", ti->senses, ti->flags);
 2216         }
 2217 }
 2218 #endif

Cache object: def4176f315eed84348be0615463f729


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