LCOV - code coverage report
Current view: top level - dev/ic - aic6360.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 840 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 30 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13