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

          Line data    Source code
       1             : /*      $OpenBSD: iha.c,v 1.43 2015/03/14 03:38:47 jsg Exp $ */
       2             : /*-------------------------------------------------------------------------
       3             :  *
       4             :  * Device driver for the INI-9XXXU/UW or INIC-940/950  PCI SCSI Controller.
       5             :  *
       6             :  * Written for 386bsd and FreeBSD by
       7             :  *      Winston Hung            <winstonh@initio.com>
       8             :  *
       9             :  * Copyright (c) 1997-1999 Initio Corp
      10             :  * Copyright (c) 2000-2002 Ken Westerback
      11             :  *
      12             :  * Redistribution and use in source and binary forms, with or without
      13             :  * modification, are permitted provided that the following conditions
      14             :  * are met:
      15             :  * 1. Redistributions of source code must retain the above copyright
      16             :  *    notice, this list of conditions and the following disclaimer,
      17             :  *    without modification, immediately at the beginning of the file.
      18             :  * 2. The name of the author may not be used to endorse or promote products
      19             :  *    derived from this software without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      22             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      23             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      24             :  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
      25             :  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      26             :  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      27             :  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      29             :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
      30             :  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
      31             :  * THE POSSIBILITY OF SUCH DAMAGE.
      32             :  *
      33             :  *-------------------------------------------------------------------------
      34             :  */
      35             : #include <sys/param.h>
      36             : #include <sys/systm.h>
      37             : #include <sys/buf.h>
      38             : #include <sys/device.h>
      39             : 
      40             : #include <machine/bus.h>
      41             : #include <machine/intr.h>
      42             : 
      43             : #include <scsi/scsi_all.h>
      44             : #include <scsi/scsiconf.h>
      45             : #include <scsi/scsi_message.h>
      46             : 
      47             : #include <dev/ic/iha.h>
      48             : 
      49             : /* #define IHA_DEBUG_STATE */
      50             : 
      51             : struct cfdriver iha_cd = {
      52             :         NULL, "iha", DV_DULL
      53             : };
      54             : 
      55             : struct scsi_adapter iha_switch = {
      56             :         iha_scsi_cmd,   /* scsi_cmd() */
      57             :         iha_minphys,    /* scsi_minphys() */
      58             :         NULL,           /* probe_dev(void) */
      59             :         NULL            /* free_dev() */
      60             : };
      61             : 
      62             : /*
      63             :  * SCSI Rate Table, indexed by FLAG_SCSI_RATE field of
      64             :  * TCS_Flags.
      65             :  */
      66             : static const u_int8_t iha_rate_tbl[] = {
      67             :         /* fast 20                */
      68             :         /* nanosecond divide by 4 */
      69             :         12,     /* 50ns,  20M     */
      70             :         18,     /* 75ns,  13.3M   */
      71             :         25,     /* 100ns, 10M     */
      72             :         31,     /* 125ns, 8M      */
      73             :         37,     /* 150ns, 6.6M    */
      74             :         43,     /* 175ns, 5.7M    */
      75             :         50,     /* 200ns, 5M      */
      76             :         62      /* 250ns, 4M      */
      77             : };
      78             : 
      79             : int iha_setup_sg_list(struct iha_softc *, struct iha_scb *);
      80             : u_int8_t iha_data_over_run(struct iha_scb *);
      81             : int iha_push_sense_request(struct iha_softc *, struct iha_scb *);
      82             : void iha_timeout(void *);
      83             : int  iha_alloc_scbs(struct iha_softc *);
      84             : void iha_read_eeprom(bus_space_tag_t, bus_space_handle_t,
      85             :                              struct iha_nvram *);
      86             : void iha_se2_instr(bus_space_tag_t, bus_space_handle_t, u_int8_t);
      87             : u_int16_t iha_se2_rd(bus_space_tag_t, bus_space_handle_t, u_int8_t);
      88             : void iha_reset_scsi_bus(struct iha_softc *);
      89             : void iha_reset_chip(struct iha_softc *,
      90             :                             bus_space_tag_t, bus_space_handle_t);
      91             : void iha_reset_dma(bus_space_tag_t, bus_space_handle_t);
      92             : void iha_reset_tcs(struct tcs *, u_int8_t);
      93             : void iha_print_info(struct iha_softc *, int);
      94             : void iha_done_scb(struct iha_softc *, struct iha_scb *);
      95             : void iha_exec_scb(struct iha_softc *, struct iha_scb *);
      96             : void iha_main(struct iha_softc *, bus_space_tag_t, bus_space_handle_t);
      97             : void iha_scsi(struct iha_softc *, bus_space_tag_t, bus_space_handle_t);
      98             : int  iha_wait(struct iha_softc *, bus_space_tag_t, bus_space_handle_t,
      99             :                       u_int8_t);
     100             : void iha_mark_busy_scb(struct iha_scb *);
     101             : void *iha_scb_alloc(void *);
     102             : void iha_scb_free(void *, void *);
     103             : void iha_append_done_scb(struct iha_softc *, struct iha_scb *,
     104             :                                  u_int8_t);
     105             : struct iha_scb *iha_pop_done_scb(struct iha_softc *);
     106             : void iha_append_pend_scb(struct iha_softc *, struct iha_scb *);
     107             : void iha_push_pend_scb(struct iha_softc *, struct iha_scb *);
     108             : struct iha_scb *iha_find_pend_scb(struct iha_softc *);
     109             : void iha_sync_done(struct iha_softc *,
     110             :                            bus_space_tag_t, bus_space_handle_t);
     111             : void iha_wide_done(struct iha_softc *,
     112             :                            bus_space_tag_t, bus_space_handle_t);
     113             : void iha_bad_seq(struct iha_softc *);
     114             : int  iha_next_state(struct iha_softc *,
     115             :                             bus_space_tag_t, bus_space_handle_t);
     116             : int  iha_state_1(struct iha_softc *,
     117             :                          bus_space_tag_t, bus_space_handle_t);
     118             : int  iha_state_2(struct iha_softc *,
     119             :                          bus_space_tag_t, bus_space_handle_t);
     120             : int  iha_state_3(struct iha_softc *,
     121             :                          bus_space_tag_t, bus_space_handle_t);
     122             : int  iha_state_4(struct iha_softc *,
     123             :                          bus_space_tag_t, bus_space_handle_t);
     124             : int  iha_state_5(struct iha_softc *,
     125             :                          bus_space_tag_t, bus_space_handle_t);
     126             : int  iha_state_6(struct iha_softc *,
     127             :                          bus_space_tag_t, bus_space_handle_t);
     128             : int  iha_state_8(struct iha_softc *,
     129             :                          bus_space_tag_t, bus_space_handle_t);
     130             : void iha_set_ssig(bus_space_tag_t,
     131             :                           bus_space_handle_t, u_int8_t, u_int8_t);
     132             : int  iha_xpad_in(struct iha_softc *,
     133             :                          bus_space_tag_t, bus_space_handle_t);
     134             : int  iha_xpad_out(struct iha_softc *,
     135             :                           bus_space_tag_t, bus_space_handle_t);
     136             : int  iha_xfer_data(struct iha_scb *,
     137             :                            bus_space_tag_t, bus_space_handle_t,
     138             :                            int direction);
     139             : int  iha_status_msg(struct iha_softc *,
     140             :                             bus_space_tag_t, bus_space_handle_t);
     141             : int  iha_msgin(struct iha_softc *, bus_space_tag_t, bus_space_handle_t);
     142             : int  iha_msgin_sdtr(struct iha_softc *);
     143             : int  iha_msgin_extended(struct iha_softc *,
     144             :                                 bus_space_tag_t, bus_space_handle_t);
     145             : int  iha_msgin_ignore_wid_resid(struct iha_softc *,
     146             :                                         bus_space_tag_t, bus_space_handle_t);
     147             : int  iha_msgout(struct iha_softc *,
     148             :                         bus_space_tag_t, bus_space_handle_t, u_int8_t);
     149             : int  iha_msgout_extended(struct iha_softc *,
     150             :                                  bus_space_tag_t, bus_space_handle_t);
     151             : void iha_msgout_abort(struct iha_softc *,
     152             :                               bus_space_tag_t, bus_space_handle_t,  u_int8_t);
     153             : int  iha_msgout_reject(struct iha_softc *,
     154             :                                bus_space_tag_t, bus_space_handle_t);
     155             : int  iha_msgout_sdtr(struct iha_softc *,
     156             :                              bus_space_tag_t, bus_space_handle_t);
     157             : int  iha_msgout_wdtr(struct iha_softc *,
     158             :                              bus_space_tag_t, bus_space_handle_t);
     159             : void iha_select(struct iha_softc *,
     160             :                         bus_space_tag_t, bus_space_handle_t,
     161             :                         struct iha_scb *, u_int8_t);
     162             : void iha_busfree(struct iha_softc *,
     163             :                          bus_space_tag_t, bus_space_handle_t);
     164             : int  iha_resel(struct iha_softc *, bus_space_tag_t, bus_space_handle_t);
     165             : void iha_abort_xs(struct iha_softc *, struct scsi_xfer *, u_int8_t);
     166             : 
     167             : /*
     168             :  * iha_intr - the interrupt service routine for the iha driver
     169             :  */
     170             : int
     171           0 : iha_intr(void *arg)
     172             : {
     173             :         bus_space_handle_t ioh;
     174             :         struct iha_softc *sc;
     175             :         bus_space_tag_t iot;
     176             :         int s;
     177             : 
     178           0 :         sc  = (struct iha_softc *)arg;
     179           0 :         iot = sc->sc_iot;
     180           0 :         ioh = sc->sc_ioh;
     181             : 
     182           0 :         if ((bus_space_read_1(iot, ioh, TUL_STAT0) & INTPD) == 0)
     183           0 :                 return (0);
     184             : 
     185           0 :         s = splbio(); /* XXX - Or are interrupts off when ISR's are called? */
     186             : 
     187           0 :         if (sc->HCS_Semaph != SEMAPH_IN_MAIN) {
     188             :                 /* XXX - need these inside a splbio()/splx()? */
     189           0 :                 bus_space_write_1(iot, ioh, TUL_IMSK, MASK_ALL);
     190           0 :                 sc->HCS_Semaph = SEMAPH_IN_MAIN;
     191             : 
     192           0 :                 iha_main(sc, iot, ioh);
     193             : 
     194           0 :                 sc->HCS_Semaph = ~SEMAPH_IN_MAIN;
     195           0 :                 bus_space_write_1(iot, ioh, TUL_IMSK, (MASK_ALL & ~MSCMP));
     196           0 :         }
     197             : 
     198           0 :         splx(s);
     199             : 
     200           0 :         return (1);
     201           0 : }
     202             : 
     203             : /*
     204             :  * iha_setup_sg_list -  initialize scatter gather list of pScb from
     205             :  *                      pScb->SCB_DataDma.
     206             :  */
     207             : int
     208           0 : iha_setup_sg_list(struct iha_softc *sc, struct iha_scb *pScb)
     209             : {
     210           0 :         bus_dma_segment_t *segs = pScb->SCB_DataDma->dm_segs;
     211           0 :         int i, error, nseg = pScb->SCB_DataDma->dm_nsegs;
     212             : 
     213           0 :         if (nseg > 1) {
     214           0 :                 error = bus_dmamap_load(sc->sc_dmat, pScb->SCB_SGDma,
     215             :                                 pScb->SCB_SGList, sizeof(pScb->SCB_SGList), NULL,
     216             :                                 (pScb->SCB_Flags & SCSI_NOSLEEP) ?
     217             :                                         BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
     218           0 :                 if (error) {
     219           0 :                         sc_print_addr(pScb->SCB_Xs->sc_link);
     220           0 :                         printf("error %d loading SG list dma map\n", error);
     221           0 :                         return (error);
     222             :                 }
     223             : 
     224             :                 /*
     225             :                  * Only set FLAG_SG when SCB_SGDma is loaded so iha_scsi_done
     226             :                  * will not unload an unloaded map.
     227             :                  */
     228           0 :                 pScb->SCB_Flags      |= FLAG_SG;
     229           0 :                 bzero(pScb->SCB_SGList, sizeof(pScb->SCB_SGList));
     230             : 
     231           0 :                 pScb->SCB_SGIdx        = 0;
     232           0 :                 pScb->SCB_SGCount = nseg;
     233             : 
     234           0 :                 for (i=0; i < nseg; i++) {
     235           0 :                         pScb->SCB_SGList[i].SG_Len  = segs[i].ds_len;
     236           0 :                         pScb->SCB_SGList[i].SG_Addr = segs[i].ds_addr;
     237             :                 }
     238             : 
     239           0 :                 bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma, 
     240             :                         0, sizeof(pScb->SCB_SGList), BUS_DMASYNC_PREWRITE);
     241           0 :         }
     242             : 
     243           0 :         return (0);
     244           0 : }
     245             : 
     246             : /*
     247             :  * iha_scsi_cmd - start execution of a SCSI command. This is called
     248             :  *                from the generic SCSI driver via the field
     249             :  *                sc_adapter.scsi_cmd of iha_softc.
     250             :  */
     251             : void
     252           0 : iha_scsi_cmd(struct scsi_xfer *xs)
     253             : {
     254             :         struct iha_scb *pScb;
     255           0 :         struct scsi_link *sc_link = xs->sc_link;
     256           0 :         struct iha_softc *sc = sc_link->adapter_softc;
     257             :         int error;
     258             : 
     259           0 :         if ((xs->cmdlen > 12) || (sc_link->target >= IHA_MAX_TARGETS)) {
     260           0 :                 xs->error = XS_DRIVER_STUFFUP;
     261           0 :                 scsi_done(xs);
     262           0 :                 return;
     263             :         }
     264             : 
     265           0 :         pScb = xs->io;
     266             : 
     267           0 :         pScb->SCB_Target = sc_link->target;
     268           0 :         pScb->SCB_Lun         = sc_link->lun;
     269           0 :         pScb->SCB_Tcs         = &sc->HCS_Tcs[pScb->SCB_Target];
     270           0 :         pScb->SCB_Flags       = xs->flags;
     271           0 :         pScb->SCB_Ident  = MSG_IDENTIFYFLAG |
     272           0 :                 (pScb->SCB_Lun & MSG_IDENTIFY_LUNMASK);
     273             : 
     274           0 :         if ((xs->cmd->opcode != REQUEST_SENSE)
     275           0 :             && ((pScb->SCB_Flags & SCSI_POLL) == 0))
     276           0 :                 pScb->SCB_Ident |= MSG_IDENTIFY_DISCFLAG;
     277             : 
     278           0 :         pScb->SCB_Xs  = xs;
     279           0 :         pScb->SCB_CDBLen = xs->cmdlen;
     280           0 :         bcopy(xs->cmd, &pScb->SCB_CDB, xs->cmdlen);
     281             : 
     282           0 :         pScb->SCB_BufCharsLeft = pScb->SCB_BufChars = xs->datalen;
     283             : 
     284           0 :         if ((pScb->SCB_Flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) != 0) {
     285           0 :                 error = bus_dmamap_load(sc->sc_dmat, pScb->SCB_DataDma,
     286             :                     xs->data, pScb->SCB_BufChars, NULL,
     287             :                     (pScb->SCB_Flags & SCSI_NOSLEEP) ?
     288             :                     BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
     289             : 
     290           0 :                 if (error) {
     291           0 :                         sc_print_addr(xs->sc_link);
     292           0 :                         if (error == EFBIG)
     293           0 :                                 printf("buffer needs >%d dma segments\n",
     294             :                                     IHA_MAX_SG_ENTRIES);
     295             :                         else
     296           0 :                                 printf("error %d loading buffer dma map\n",
     297             :                                     error);
     298             : 
     299           0 :                         xs->error = XS_DRIVER_STUFFUP;
     300           0 :                         scsi_done(xs);
     301           0 :                         return;
     302             :                 }
     303           0 :                 bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma, 
     304             :                         0, pScb->SCB_BufChars,
     305             :                         (pScb->SCB_Flags & SCSI_DATA_IN) ?
     306             :                                 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
     307             : 
     308           0 :                 error = iha_setup_sg_list(sc, pScb);
     309           0 :                 if (error) {
     310           0 :                         bus_dmamap_unload(sc->sc_dmat, pScb->SCB_DataDma);
     311           0 :                         xs->error = XS_DRIVER_STUFFUP;
     312           0 :                         scsi_done(xs);
     313           0 :                         return;
     314             :                 }
     315             : 
     316             :         }
     317             : 
     318             :         /*
     319             :          * Always initialize the stimeout structure as it may 
     320             :          * contain garbage that confuses timeout_del() later on.
     321             :          * But, timeout_add() ONLY if we are not polling.
     322             :          */
     323           0 :         timeout_set(&xs->stimeout, iha_timeout, pScb);
     324             : 
     325           0 :         iha_exec_scb(sc, pScb);
     326           0 : }
     327             : 
     328             : /*
     329             :  * iha_init_tulip - initialize the inic-940/950 card and the rest of the
     330             :  *                  iha_softc structure supplied
     331             :  */
     332             : int
     333           0 : iha_init_tulip(struct iha_softc *sc)
     334             : {
     335             :         struct iha_scb *pScb;
     336             :         struct iha_nvram_scsi *pScsi;
     337             :         bus_space_handle_t ioh;
     338           0 :         struct iha_nvram iha_nvram;
     339             :         bus_space_tag_t iot;
     340             :         int i, error;
     341             : 
     342           0 :         iot = sc->sc_iot;
     343           0 :         ioh = sc->sc_ioh;
     344             : 
     345           0 :         iha_read_eeprom(iot, ioh, &iha_nvram);
     346             : 
     347           0 :         pScsi = &iha_nvram.NVM_Scsi[0];
     348             : 
     349           0 :         TAILQ_INIT(&sc->HCS_FreeScb);
     350           0 :         TAILQ_INIT(&sc->HCS_PendScb);
     351           0 :         TAILQ_INIT(&sc->HCS_DoneScb);
     352             : 
     353           0 :         mtx_init(&sc->sc_scb_mtx, IPL_BIO);
     354           0 :         scsi_iopool_init(&sc->sc_iopool, sc, iha_scb_alloc, iha_scb_free);
     355             : 
     356             :         /*
     357             :          * fill in the prototype scsi_link.
     358             :          */
     359           0 :         sc->sc_link.adapter_softc    = sc;
     360           0 :         sc->sc_link.adapter       = &iha_switch;
     361           0 :         sc->sc_link.openings      = 4; /* # xs's allowed per device */
     362           0 :         sc->sc_link.adapter_target   = pScsi->NVM_SCSI_Id;
     363           0 :         sc->sc_link.adapter_buswidth = pScsi->NVM_SCSI_Targets;
     364           0 :         sc->sc_link.pool             = &sc->sc_iopool;
     365             : 
     366             :         /*
     367             :          * fill in the rest of the iha_softc fields
     368             :          */
     369           0 :         sc->HCS_Semaph         = ~SEMAPH_IN_MAIN;
     370           0 :         sc->HCS_JSStatus0 = 0;
     371           0 :         sc->HCS_ActScb         = NULL;
     372             : 
     373           0 :         error = iha_alloc_scbs(sc);
     374           0 :         if (error != 0)
     375           0 :                 return (error);
     376             : 
     377           0 :         for (i = 0, pScb = sc->HCS_Scb; i < IHA_MAX_SCB; i++, pScb++) {
     378           0 :                 pScb->SCB_TagId = i;
     379             : 
     380           0 :                 error = bus_dmamap_create(sc->sc_dmat,
     381             :                     (IHA_MAX_SG_ENTRIES-1) * PAGE_SIZE, IHA_MAX_SG_ENTRIES,
     382             :                     (IHA_MAX_SG_ENTRIES-1) * PAGE_SIZE, 0,
     383             :                     BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &pScb->SCB_DataDma);
     384             : 
     385           0 :                 if (error != 0) {
     386           0 :                         printf("%s: couldn't create SCB data DMA map, error = %d\n",
     387           0 :                             sc->sc_dev.dv_xname, error);
     388           0 :                         return (error);
     389             :                 }
     390             : 
     391           0 :                 error = bus_dmamap_create(sc->sc_dmat,
     392             :                                 sizeof(pScb->SCB_SGList), 1,
     393             :                                 sizeof(pScb->SCB_SGList), 0,
     394             :                                 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
     395             :                                 &pScb->SCB_SGDma);
     396           0 :                 if (error != 0) {
     397           0 :                         printf("%s: couldn't create SCB SG DMA map, error = %d\n",
     398           0 :                             sc->sc_dev.dv_xname, error);
     399           0 :                         return (error);
     400             :                 }
     401             : 
     402           0 :                 TAILQ_INSERT_TAIL(&sc->HCS_FreeScb, pScb, SCB_ScbList);
     403             :         }
     404             : 
     405             :         /* Mask all the interrupts */
     406           0 :         bus_space_write_1(iot, ioh, TUL_IMSK, MASK_ALL);
     407             : 
     408             :         /* Stop any I/O and reset the scsi module */
     409           0 :         iha_reset_dma(iot, ioh);
     410           0 :         bus_space_write_1(iot, ioh, TUL_SCTRL0, RSMOD);
     411             : 
     412             :         /* Program HBA's SCSI ID */
     413           0 :         bus_space_write_1(iot, ioh, TUL_SID, sc->sc_link.adapter_target << 4);
     414             : 
     415             :         /*
     416             :          * Configure the channel as requested by the NVRAM settings read 
     417             :          * into iha_nvram by iha_read_eeprom() above.
     418             :          */
     419             : 
     420           0 :         if ((pScsi->NVM_SCSI_Cfg & CFG_EN_PAR) != 0)
     421           0 :                 sc->HCS_SConf1 = (SCONFIG0DEFAULT | SPCHK);
     422             :         else
     423           0 :                 sc->HCS_SConf1 = (SCONFIG0DEFAULT);
     424           0 :         bus_space_write_1(iot, ioh, TUL_SCONFIG0, sc->HCS_SConf1);
     425             : 
     426             :         /* selection time out in units of 1.6385 millisecond = 250 ms */
     427           0 :         bus_space_write_1(iot, ioh, TUL_STIMO, 153);
     428             : 
     429             :         /* Enable desired SCSI termination configuration read from eeprom */
     430           0 :         bus_space_write_1(iot, ioh, TUL_DCTRL0,
     431             :             (pScsi->NVM_SCSI_Cfg & (CFG_ACT_TERM1 | CFG_ACT_TERM2)));
     432             : 
     433           0 :         bus_space_write_1(iot, ioh, TUL_GCTRL1,
     434             :             ((pScsi->NVM_SCSI_Cfg & CFG_AUTO_TERM) >> 4) 
     435             :                 | (bus_space_read_1(iot, ioh, TUL_GCTRL1) & (~ATDEN)));
     436             : 
     437           0 :         for (i = 0; i < IHA_MAX_TARGETS; i++) {
     438           0 :                 sc->HCS_Tcs[i].TCS_Flags = pScsi->NVM_SCSI_TargetFlags[i];
     439           0 :                 iha_reset_tcs(&sc->HCS_Tcs[i], sc->HCS_SConf1);
     440             :         }
     441             : 
     442           0 :         iha_reset_chip(sc, iot, ioh);
     443           0 :         bus_space_write_1(iot, ioh, TUL_SIEN, ALL_INTERRUPTS);
     444             : 
     445           0 :         return (0);
     446           0 : }
     447             : 
     448             : /*
     449             :  * iha_minphys - reduce bp->b_bcount to something less than
     450             :  *               or equal to the largest I/O possible through
     451             :  *               the adapter. Called from higher layers
     452             :  *               via sc->sc_adapter.scsi_minphys.
     453             :  */
     454             : void
     455           0 : iha_minphys(struct buf *bp, struct scsi_link *sl)
     456             : {
     457           0 :         if (bp->b_bcount > ((IHA_MAX_SG_ENTRIES - 1) * PAGE_SIZE))
     458           0 :                 bp->b_bcount = ((IHA_MAX_SG_ENTRIES - 1) * PAGE_SIZE);
     459             : 
     460           0 :         minphys(bp);
     461           0 : }
     462             : 
     463             : /*
     464             :  * iha_reset_dma - abort any active DMA xfer, reset tulip FIFO.
     465             :  */
     466             : void
     467           0 : iha_reset_dma(bus_space_tag_t iot, bus_space_handle_t ioh)
     468             : {
     469           0 :         if ((bus_space_read_1(iot, ioh, TUL_ISTUS1) & XPEND) != 0) {
     470             :                 /* if DMA xfer is pending, abort DMA xfer */
     471           0 :                 bus_space_write_1(iot, ioh, TUL_DCMD, ABTXFR);
     472             :                 /* wait Abort DMA xfer done */
     473           0 :                 while ((bus_space_read_1(iot, ioh, TUL_ISTUS0) & DABT) == 0)
     474             :                         ;
     475             :         }
     476             : 
     477           0 :         bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
     478           0 : }
     479             : 
     480             : /*
     481             :  * iha_scb_alloc - return the first free SCB, or NULL if there are none.
     482             :  */
     483             : void *
     484           0 : iha_scb_alloc(void *xsc)
     485             : {
     486           0 :         struct iha_softc *sc = xsc;
     487             :         struct iha_scb *pScb;
     488             : 
     489           0 :         mtx_enter(&sc->sc_scb_mtx);
     490           0 :         pScb = TAILQ_FIRST(&sc->HCS_FreeScb);
     491           0 :         if (pScb != NULL) {
     492           0 :                 pScb->SCB_Status = STATUS_RENT;
     493           0 :                 TAILQ_REMOVE(&sc->HCS_FreeScb, pScb, SCB_ScbList);
     494           0 :         }
     495           0 :         mtx_leave(&sc->sc_scb_mtx);
     496             : 
     497           0 :         return (pScb);
     498             : }
     499             : 
     500             : /*
     501             :  * iha_scb_free - append the supplied SCB to the tail of the
     502             :  *                HCS_FreeScb queue after clearing and resetting
     503             :  *                everything possible.
     504             :  */
     505             : void
     506           0 : iha_scb_free(void *xsc, void *xscb)
     507             : {
     508           0 :         struct iha_softc *sc = xsc;
     509           0 :         struct iha_scb *pScb = xscb;
     510             :         int s;
     511             : 
     512           0 :         s = splbio();
     513           0 :         if (pScb == sc->HCS_ActScb)
     514           0 :                 sc->HCS_ActScb = NULL;
     515           0 :         splx(s);
     516             : 
     517           0 :         pScb->SCB_Status = STATUS_QUEUED;
     518           0 :         pScb->SCB_HaStat = HOST_OK;
     519           0 :         pScb->SCB_TaStat = SCSI_OK;
     520             : 
     521           0 :         pScb->SCB_NxtStat  = 0;
     522           0 :         pScb->SCB_Flags         = 0;
     523           0 :         pScb->SCB_Target   = 0;
     524           0 :         pScb->SCB_Lun           = 0;
     525           0 :         pScb->SCB_CDBLen   = 0;
     526           0 :         pScb->SCB_Ident         = 0;
     527           0 :         pScb->SCB_TagMsg   = 0;
     528             : 
     529           0 :         pScb->SCB_BufChars     = 0;
     530           0 :         pScb->SCB_BufCharsLeft = 0;
     531             : 
     532           0 :         pScb->SCB_Xs  = NULL;
     533           0 :         pScb->SCB_Tcs = NULL;
     534             : 
     535           0 :         bzero(pScb->SCB_CDB, sizeof(pScb->SCB_CDB));
     536             : 
     537             :         /*
     538             :          * SCB_TagId is set at initialization and never changes
     539             :          */
     540             : 
     541           0 :         mtx_enter(&sc->sc_scb_mtx);
     542           0 :         TAILQ_INSERT_TAIL(&sc->HCS_FreeScb, pScb, SCB_ScbList);
     543           0 :         mtx_leave(&sc->sc_scb_mtx);
     544           0 : }
     545             : 
     546             : void
     547           0 : iha_append_pend_scb(struct iha_softc *sc, struct iha_scb *pScb)
     548             : {
     549             :         /* ASSUMPTION: only called within a splbio()/splx() pair */
     550             : 
     551           0 :         if (pScb == sc->HCS_ActScb)
     552           0 :                 sc->HCS_ActScb = NULL;
     553             : 
     554           0 :         pScb->SCB_Status = STATUS_QUEUED;
     555             : 
     556           0 :         TAILQ_INSERT_TAIL(&sc->HCS_PendScb, pScb, SCB_ScbList);
     557           0 : }
     558             : 
     559             : void
     560           0 : iha_push_pend_scb(struct iha_softc *sc, struct iha_scb *pScb)
     561             : {
     562             :         int s;
     563             : 
     564           0 :         s = splbio();
     565             : 
     566           0 :         if (pScb == sc->HCS_ActScb)
     567           0 :                 sc->HCS_ActScb = NULL;
     568             : 
     569           0 :         pScb->SCB_Status = STATUS_QUEUED;
     570             : 
     571           0 :         TAILQ_INSERT_HEAD(&sc->HCS_PendScb, pScb, SCB_ScbList);
     572             : 
     573           0 :         splx(s);
     574           0 : }
     575             : 
     576             : /*
     577             :  * iha_find_pend_scb - scan the pending queue for a SCB that can be
     578             :  *                     processed immediately. Return NULL if none found
     579             :  *                     and a pointer to the SCB if one is found. If there
     580             :  *                     is an active SCB, return NULL!
     581             :  */
     582             : struct iha_scb *
     583           0 : iha_find_pend_scb(struct iha_softc *sc)
     584             : {
     585             :         struct iha_scb *pScb;
     586             :         struct tcs *pTcs;
     587             :         int s;
     588             : 
     589           0 :         s = splbio();
     590             : 
     591           0 :         if (sc->HCS_ActScb != NULL)
     592           0 :                 pScb = NULL;
     593             : 
     594             :         else
     595           0 :                 TAILQ_FOREACH(pScb, &sc->HCS_PendScb, SCB_ScbList) {
     596           0 :                         if ((pScb->SCB_Flags & SCSI_RESET) != 0)
     597             :                                 /* ALWAYS willing to reset a device */
     598             :                                 break;
     599             : 
     600           0 :                         pTcs = pScb->SCB_Tcs;
     601             : 
     602           0 :                         if ((pScb->SCB_TagMsg) != 0) {
     603             :                                 /*
     604             :                                  * A Tagged I/O. OK to start If no
     605             :                                  * non-tagged I/O is active on the same
     606             :                                  * target
     607             :                                  */
     608           0 :                                 if (pTcs->TCS_NonTagScb == NULL)
     609             :                                         break;
     610             : 
     611           0 :                         } else  if (pScb->SCB_CDB[0] == REQUEST_SENSE) {
     612             :                                 /*
     613             :                                  * OK to do a non-tagged request sense
     614             :                                  * even if a non-tagged I/O has been
     615             :                                  * started, because we don't allow any
     616             :                                  * disconnect during a request sense op
     617             :                                  */
     618             :                                 break;
     619             : 
     620           0 :                         } else  if (pTcs->TCS_TagCnt == 0) {
     621             :                                 /*
     622             :                                  * No tagged I/O active on this target,
     623             :                                  * ok to start a non-tagged one if one
     624             :                                  * is not already active
     625             :                                  */
     626           0 :                                 if (pTcs->TCS_NonTagScb == NULL)
     627             :                                         break;
     628             :                         }
     629             :                 }
     630             : 
     631           0 :         splx(s);
     632             : 
     633           0 :         return (pScb);
     634             : }
     635             : 
     636             : void
     637           0 : iha_mark_busy_scb(struct iha_scb *pScb)
     638             : {
     639             :         int  s;
     640             : 
     641           0 :         s = splbio();
     642             : 
     643           0 :         pScb->SCB_Status = STATUS_BUSY;
     644             : 
     645           0 :         if (pScb->SCB_TagMsg == 0)
     646           0 :                 pScb->SCB_Tcs->TCS_NonTagScb = pScb;
     647             :         else
     648           0 :                 pScb->SCB_Tcs->TCS_TagCnt++;
     649             : 
     650           0 :         splx(s);
     651           0 : }
     652             : 
     653             : void
     654           0 : iha_append_done_scb(struct iha_softc *sc, struct iha_scb *pScb, u_int8_t hastat)
     655             : {
     656             :         struct tcs *pTcs;
     657             :         int s;
     658             : 
     659           0 :         s = splbio();
     660             : 
     661           0 :         if (pScb->SCB_Xs != NULL)
     662           0 :                 timeout_del(&pScb->SCB_Xs->stimeout);
     663             : 
     664           0 :         if (pScb == sc->HCS_ActScb)
     665           0 :                 sc->HCS_ActScb = NULL;
     666             : 
     667           0 :         pTcs = pScb->SCB_Tcs;
     668             : 
     669           0 :         if (pScb->SCB_TagMsg != 0) {
     670           0 :                 if (pTcs->TCS_TagCnt)
     671           0 :                         pTcs->TCS_TagCnt--;
     672           0 :         } else if (pTcs->TCS_NonTagScb == pScb)
     673           0 :                 pTcs->TCS_NonTagScb = NULL;
     674             : 
     675           0 :         pScb->SCB_Status = STATUS_QUEUED;
     676           0 :         pScb->SCB_HaStat = hastat;
     677             : 
     678           0 :         TAILQ_INSERT_TAIL(&sc->HCS_DoneScb, pScb, SCB_ScbList);
     679             : 
     680           0 :         splx(s);
     681           0 : }
     682             : 
     683             : struct iha_scb *
     684           0 : iha_pop_done_scb(struct iha_softc *sc)
     685             : {
     686             :         struct iha_scb *pScb;
     687             :         int s;
     688             : 
     689           0 :         s = splbio();
     690             : 
     691           0 :         pScb = TAILQ_FIRST(&sc->HCS_DoneScb);
     692             : 
     693           0 :         if (pScb != NULL) {
     694           0 :                 pScb->SCB_Status = STATUS_RENT;
     695           0 :                 TAILQ_REMOVE(&sc->HCS_DoneScb, pScb, SCB_ScbList);
     696           0 :         }
     697             : 
     698           0 :         splx(s);
     699             : 
     700           0 :         return (pScb);
     701             : }
     702             : 
     703             : /*
     704             :  * iha_abort_xs - find the SCB associated with the supplied xs and
     705             :  *                stop all processing on it, moving it to the done
     706             :  *                queue with the supplied host status value.
     707             :  */
     708             : void
     709           0 : iha_abort_xs(struct iha_softc *sc, struct scsi_xfer *xs, u_int8_t hastat)
     710             : {
     711             :         struct iha_scb *pScb, *next;
     712             :         int i, s;
     713             : 
     714           0 :         s = splbio();
     715             : 
     716             :         /* Check the pending queue for the SCB pointing to xs */
     717             : 
     718           0 :         for (pScb = TAILQ_FIRST(&sc->HCS_PendScb); pScb != NULL; pScb = next) {
     719           0 :                 next = TAILQ_NEXT(pScb, SCB_ScbList);
     720           0 :                 if (pScb->SCB_Xs == xs) {
     721           0 :                         TAILQ_REMOVE(&sc->HCS_PendScb, pScb, SCB_ScbList);
     722           0 :                         iha_append_done_scb(sc, pScb, hastat);
     723           0 :                         splx(s);
     724           0 :                         return;
     725             :                 }
     726             :         }
     727             : 
     728             :         /*
     729             :          * If that didn't work, check all BUSY/SELECTING SCB's for one
     730             :          * pointing to xs
     731             :          */
     732             : 
     733           0 :         for (i = 0, pScb = sc->HCS_Scb; i < IHA_MAX_SCB; i++, pScb++)
     734           0 :                 switch (pScb->SCB_Status) {
     735             :                 case STATUS_BUSY:
     736             :                 case STATUS_SELECT:
     737           0 :                         if (pScb->SCB_Xs == xs) {
     738           0 :                                 iha_append_done_scb(sc, pScb, hastat);
     739           0 :                                 splx(s);
     740           0 :                                 return;
     741             :                         }
     742             :                         break;
     743             :                 default:
     744             :                         break;
     745             :                 }
     746             :         
     747           0 :         splx(s);
     748           0 : }
     749             : 
     750             : /*
     751             :  * iha_bad_seq - a SCSI bus phase was encountered out of the
     752             :  *               correct/expected sequence. Reset the SCSI bus.
     753             :  */
     754             : void
     755           0 : iha_bad_seq(struct iha_softc *sc)
     756             : {
     757           0 :         struct iha_scb *pScb = sc->HCS_ActScb;
     758             : 
     759           0 :         if (pScb != NULL)
     760           0 :                 iha_append_done_scb(sc, pScb, HOST_BAD_PHAS);
     761             : 
     762           0 :         iha_reset_scsi_bus(sc);
     763           0 :         iha_reset_chip(sc, sc->sc_iot, sc->sc_ioh);
     764           0 : }
     765             : 
     766             : /*
     767             :  * iha_push_sense_request - obtain auto sense data by pushing the
     768             :  *                          SCB needing it back onto the pending
     769             :  *                          queue with a REQUEST_SENSE CDB.
     770             :  */
     771             : int
     772           0 : iha_push_sense_request(struct iha_softc *sc, struct iha_scb *pScb)
     773             : {
     774             :         struct scsi_sense *sensecmd;
     775             :         int error;
     776             : 
     777             :         /* First sync & unload any existing DataDma and SGDma maps */
     778           0 :         if ((pScb->SCB_Flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) != 0) {
     779           0 :                 bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,
     780             :                         0, pScb->SCB_BufChars,
     781             :                         ((pScb->SCB_Flags & SCSI_DATA_IN) ? 
     782             :                                 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
     783           0 :                 bus_dmamap_unload(sc->sc_dmat, pScb->SCB_DataDma);
     784             :                 /* Don't unload this map again until it is reloaded */
     785           0 :                 pScb->SCB_Flags &= ~(SCSI_DATA_IN | SCSI_DATA_OUT);
     786           0 :         }
     787           0 :         if ((pScb->SCB_Flags & FLAG_SG) != 0) {
     788           0 :                 bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma,
     789             :                         0, sizeof(pScb->SCB_SGList),
     790             :                         BUS_DMASYNC_POSTWRITE);
     791           0 :                 bus_dmamap_unload(sc->sc_dmat, pScb->SCB_SGDma);
     792             :                 /* Don't unload this map again until it is reloaded */
     793           0 :                 pScb->SCB_Flags &= ~FLAG_SG;
     794           0 :         }
     795             : 
     796           0 :         pScb->SCB_BufChars     = sizeof(pScb->SCB_ScsiSenseData);
     797           0 :         pScb->SCB_BufCharsLeft = sizeof(pScb->SCB_ScsiSenseData);
     798           0 :         bzero(&pScb->SCB_ScsiSenseData, sizeof(pScb->SCB_ScsiSenseData)); 
     799             : 
     800           0 :         error = bus_dmamap_load(sc->sc_dmat, pScb->SCB_DataDma,
     801             :                         &pScb->SCB_ScsiSenseData,
     802             :                         sizeof(pScb->SCB_ScsiSenseData), NULL,
     803             :                         (pScb->SCB_Flags & SCSI_NOSLEEP) ?
     804             :                                 BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
     805           0 :         if (error) {
     806           0 :                 sc_print_addr(pScb->SCB_Xs->sc_link);
     807           0 :                 printf("error %d loading request sense buffer dma map\n",
     808             :                         error);
     809           0 :                 return (error);
     810             :         }
     811           0 :         bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma, 
     812             :                 0, pScb->SCB_BufChars, BUS_DMASYNC_PREREAD);
     813             : 
     814             :         /* Save _POLL and _NOSLEEP flags. */ 
     815           0 :         pScb->SCB_Flags &= SCSI_POLL | SCSI_NOSLEEP;
     816           0 :         pScb->SCB_Flags |= FLAG_RSENS | SCSI_DATA_IN;
     817             : 
     818           0 :         error = iha_setup_sg_list(sc, pScb);
     819           0 :         if (error)
     820           0 :                 return (error);
     821             : 
     822           0 :         pScb->SCB_Ident &= ~MSG_IDENTIFY_DISCFLAG;
     823             : 
     824           0 :         pScb->SCB_TagMsg = 0;
     825           0 :         pScb->SCB_TaStat = SCSI_OK;
     826             : 
     827           0 :         bzero(pScb->SCB_CDB, sizeof(pScb->SCB_CDB));
     828             : 
     829           0 :         sensecmd = (struct scsi_sense *)pScb->SCB_CDB;
     830           0 :         pScb->SCB_CDBLen = sizeof(*sensecmd);
     831           0 :         sensecmd->opcode = REQUEST_SENSE;
     832           0 :         sensecmd->byte2  = pScb->SCB_Xs->sc_link->lun << 5;
     833           0 :         sensecmd->length = sizeof(pScb->SCB_ScsiSenseData);
     834             : 
     835           0 :         if ((pScb->SCB_Flags & SCSI_POLL) == 0)
     836           0 :                 timeout_add_msec(&pScb->SCB_Xs->stimeout,
     837           0 :                     pScb->SCB_Xs->timeout);
     838             : 
     839           0 :         iha_push_pend_scb(sc, pScb);
     840             : 
     841           0 :         return (0);
     842           0 : }
     843             : 
     844             : /*
     845             :  * iha_main - process the active SCB, taking one off pending and making it
     846             :  *            active if necessary, and any done SCB's created as
     847             :  *            a result until there are no interrupts pending and no pending
     848             :  *            SCB's that can be started.
     849             :  */
     850             : void
     851           0 : iha_main(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
     852             : {
     853             :         struct iha_scb *pScb;
     854             : 
     855           0 :         for (;;) {
     856             : iha_scsi_label:
     857           0 :                 iha_scsi(sc, iot, ioh);
     858             : 
     859           0 :                 while ((pScb = iha_pop_done_scb(sc)) != NULL) {
     860             : 
     861           0 :                         switch (pScb->SCB_TaStat) {
     862             :                         case SCSI_TERMINATED:
     863             :                         case SCSI_ACA_ACTIVE:
     864             :                         case SCSI_CHECK:
     865           0 :                                 pScb->SCB_Tcs->TCS_Flags &= 
     866             :                                     ~(FLAG_SYNC_DONE | FLAG_WIDE_DONE);
     867             : 
     868           0 :                                 if ((pScb->SCB_Flags & FLAG_RSENS) != 0)
     869             :                                         /* Check condition on check condition*/
     870           0 :                                         pScb->SCB_HaStat = HOST_BAD_PHAS;
     871           0 :                                 else if (iha_push_sense_request(sc, pScb) != 0)
     872             :                                         /* Could not push sense request */
     873           0 :                                         pScb->SCB_HaStat = HOST_BAD_PHAS;
     874             :                                 else
     875             :                                         /* REQUEST SENSE ready to process */
     876           0 :                                         goto iha_scsi_label;
     877             :                                 break;
     878             : 
     879             :                         default:
     880           0 :                                 if ((pScb->SCB_Flags & FLAG_RSENS) != 0)
     881             :                                         /*
     882             :                                          * Return the original SCSI_CHECK, not
     883             :                                          * the status of the request sense
     884             :                                          * command!             
     885             :                                          */
     886           0 :                                         pScb->SCB_TaStat = SCSI_CHECK;
     887             :                                 break;
     888             :                         }
     889             : 
     890           0 :                         iha_done_scb(sc, pScb);
     891             :                 }
     892             : 
     893             :                 /*
     894             :                  * If there are no interrupts pending, or we can't start
     895             :                  * a pending sc, break out of the for(;;). Otherwise
     896             :                  * continue the good work with another call to
     897             :                  * iha_scsi().
     898             :                  */
     899           0 :                 if (((bus_space_read_1(iot, ioh, TUL_STAT0) & INTPD) == 0) 
     900           0 :                     && (iha_find_pend_scb(sc) == NULL))
     901             :                         break;
     902             :         }
     903           0 : }
     904             : 
     905             : /*
     906             :  * iha_scsi - service any outstanding interrupts. If there are none, try to
     907             :  *            start another SCB currently in the pending queue.
     908             :  */
     909             : void
     910           0 : iha_scsi(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
     911             : {
     912             :         struct iha_scb *pScb;
     913             :         struct tcs *pTcs;
     914             :         u_int8_t stat;
     915             :         int i;
     916             : 
     917             :         /* service pending interrupts asap */
     918             : 
     919           0 :         stat = bus_space_read_1(iot, ioh, TUL_STAT0);
     920           0 :         if ((stat & INTPD) != 0) {
     921           0 :                 sc->HCS_JSStatus0 = stat;
     922           0 :                 sc->HCS_JSStatus1 = bus_space_read_1(iot, ioh, TUL_STAT1);
     923           0 :                 sc->HCS_JSInt     = bus_space_read_1(iot, ioh, TUL_SISTAT);
     924             : 
     925           0 :                 sc->HCS_Phase = sc->HCS_JSStatus0 & PH_MASK;
     926             :                 
     927           0 :                 if ((sc->HCS_JSInt & SRSTD) != 0) {
     928           0 :                         iha_reset_scsi_bus(sc);
     929           0 :                         return;
     930             :                 }
     931             :                 
     932           0 :                 if ((sc->HCS_JSInt & RSELED) != 0) {
     933           0 :                         iha_resel(sc, iot, ioh);
     934           0 :                         return;
     935             :                 }
     936             : 
     937           0 :                 if ((sc->HCS_JSInt & (STIMEO | DISCD)) != 0) {
     938           0 :                         iha_busfree(sc, iot, ioh);
     939           0 :                         return;
     940             :                 }
     941             : 
     942           0 :                 if ((sc->HCS_JSInt & (SCMDN | SBSRV)) != 0) {
     943           0 :                         iha_next_state(sc, iot, ioh);
     944           0 :                         return;
     945             :                 }
     946             : 
     947           0 :                 if ((sc->HCS_JSInt & SELED) != 0)
     948           0 :                         iha_set_ssig(iot, ioh, 0, 0);
     949             :         }
     950             : 
     951             :         /*
     952             :          * There were no interrupts pending which required action elsewhere, so
     953             :          * see if it is possible to start the selection phase on a pending SCB
     954             :          */
     955           0 :         if ((pScb = iha_find_pend_scb(sc)) == NULL)
     956           0 :                 return;
     957             : 
     958           0 :         pTcs = pScb->SCB_Tcs;
     959             : 
     960             :         /* program HBA's SCSI ID & target SCSI ID */
     961           0 :         bus_space_write_1(iot, ioh, TUL_SID,
     962             :             (sc->sc_link.adapter_target << 4) | pScb->SCB_Target);
     963             : 
     964           0 :         if ((pScb->SCB_Flags & SCSI_RESET) == 0) {
     965           0 :                 bus_space_write_1(iot, ioh, TUL_SYNCM, pTcs->TCS_JS_Period);
     966             : 
     967           0 :                 if (((pTcs->TCS_Flags & FLAG_NO_NEG_WIDE) == 0)
     968           0 :                     ||
     969           0 :                     ((pTcs->TCS_Flags & FLAG_NO_NEG_SYNC) == 0))
     970           0 :                         iha_select(sc, iot, ioh, pScb, SELATNSTOP);
     971             : 
     972           0 :                 else if (pScb->SCB_TagMsg != 0)
     973           0 :                         iha_select(sc, iot, ioh, pScb, SEL_ATN3);
     974             : 
     975             :                 else
     976           0 :                         iha_select(sc, iot, ioh, pScb, SEL_ATN);
     977             : 
     978             :         } else {
     979           0 :                 iha_select(sc, iot, ioh, pScb, SELATNSTOP);
     980           0 :                 pScb->SCB_NxtStat = 8;
     981             :         }
     982             : 
     983           0 :         if ((pScb->SCB_Flags & SCSI_POLL) != 0) {
     984           0 :                 for (i = pScb->SCB_Xs->timeout; i > 0; i--) {
     985           0 :                         if (iha_wait(sc, iot, ioh, NO_OP) == -1)
     986             :                                 break;
     987           0 :                         if (iha_next_state(sc, iot, ioh) == -1)
     988             :                                 break;
     989           0 :                         delay(1000); /* Only happens in boot, so it's ok */
     990             :                 }
     991             : 
     992             :                 /*
     993             :                  * Since done queue processing not done until AFTER this
     994             :                  * function returns, pScb is on the done queue, not
     995             :                  * the free queue at this point and still has valid data
     996             :                  *
     997             :                  * Conversely, xs->error has not been set yet
     998             :                  */
     999           0 :                 if (i == 0)
    1000           0 :                         iha_timeout(pScb);
    1001             : 
    1002           0 :                 else if ((pScb->SCB_CDB[0] == INQUIRY)
    1003           0 :                     && (pScb->SCB_Lun == 0)
    1004           0 :                     && (pScb->SCB_HaStat == HOST_OK)
    1005           0 :                     && (pScb->SCB_TaStat == SCSI_OK))
    1006           0 :                         iha_print_info(sc, pScb->SCB_Target);
    1007             :         }
    1008           0 : }
    1009             : 
    1010             : /*
    1011             :  * iha_data_over_run - return HOST_OK for all SCSI opcodes where BufCharsLeft
    1012             :  *                     is an 'Allocation Length'. All other SCSI opcodes
    1013             :  *                     get HOST_DO_DU as they SHOULD have xferred all the
    1014             :  *                     data requested.
    1015             :  * 
    1016             :  *                     The list of opcodes using 'Allocation Length' was
    1017             :  *                     found by scanning all the SCSI-3 T10 drafts. See
    1018             :  *                     www.t10.org for the curious with a .pdf reader.
    1019             :  */
    1020             : u_int8_t
    1021           0 : iha_data_over_run(struct iha_scb *pScb)
    1022             : {
    1023           0 :         switch (pScb->SCB_CDB[0]) {
    1024             :         case 0x03: /* Request Sense                   SPC-2 */
    1025             :         case 0x12: /* Inquiry                         SPC-2 */
    1026             :         case 0x1a: /* Mode Sense (6 byte version)     SPC-2 */
    1027             :         case 0x1c: /* Receive Diagnostic Results      SPC-2 */
    1028             :         case 0x23: /* Read Format Capacities          MMC-2 */
    1029             :         case 0x29: /* Read Generation                 SBC   */
    1030             :         case 0x34: /* Read Position                   SSC-2 */
    1031             :         case 0x37: /* Read Defect Data                SBC   */
    1032             :         case 0x3c: /* Read Buffer                     SPC-2 */
    1033             :         case 0x42: /* Read Sub Channel                MMC-2 */
    1034             :         case 0x43: /* Read TOC/PMA/ATIP               MMC   */
    1035             : 
    1036             :         /* XXX - 2 with same opcode of 0x44? */
    1037             :         case 0x44: /* Read Header/Read Density Suprt  MMC/SSC*/
    1038             : 
    1039             :         case 0x46: /* Get Configuration               MMC-2 */
    1040             :         case 0x4a: /* Get Event/Status Notification   MMC-2 */
    1041             :         case 0x4d: /* Log Sense                       SPC-2 */
    1042             :         case 0x51: /* Read Disc Information           MMC   */
    1043             :         case 0x52: /* Read Track Information          MMC   */
    1044             :         case 0x59: /* Read Master CUE                 MMC   */
    1045             :         case 0x5a: /* Mode Sense (10 byte version)    SPC-2 */
    1046             :         case 0x5c: /* Read Buffer Capacity            MMC   */
    1047             :         case 0x5e: /* Persistent Reserve In           SPC-2 */
    1048             :         case 0x84: /* Receive Copy Results            SPC-2 */
    1049             :         case 0xa0: /* Report LUNs                     SPC-2 */
    1050             :         case 0xa3: /* Various Report requests         SBC-2/SCC-2*/
    1051             :         case 0xa4: /* Report Key                      MMC-2 */
    1052             :         case 0xad: /* Read DVD Structure              MMC-2 */
    1053             :         case 0xb4: /* Read Element Status (Attached)  SMC   */
    1054             :         case 0xb5: /* Request Volume Element Address  SMC   */
    1055             :         case 0xb7: /* Read Defect Data (12 byte ver.) SBC   */
    1056             :         case 0xb8: /* Read Element Status (Independ.) SMC   */
    1057             :         case 0xba: /* Report Redundancy               SCC-2 */
    1058             :         case 0xbd: /* Mechanism Status                MMC   */
    1059             :         case 0xbe: /* Report Basic Redundancy         SCC-2 */
    1060             : 
    1061           0 :                 return (HOST_OK);
    1062             :                 break;
    1063             :                 
    1064             :         default:
    1065           0 :                 return (HOST_DO_DU);
    1066             :                 break;
    1067             :         }
    1068           0 : }
    1069             : 
    1070             : /*
    1071             :  * iha_next_state - process the current SCB as requested in its 
    1072             :  *                  SCB_NxtStat member.
    1073             :  */
    1074             : int
    1075           0 : iha_next_state(struct iha_softc *sc, bus_space_tag_t iot,
    1076             :     bus_space_handle_t ioh)
    1077             : {
    1078           0 :         if (sc->HCS_ActScb == NULL)
    1079           0 :                 return (-1);
    1080             : 
    1081           0 :         switch (sc->HCS_ActScb->SCB_NxtStat) {
    1082             :         case 1:
    1083           0 :                 if (iha_state_1(sc, iot, ioh) == 3)
    1084             :                         goto state_3;
    1085             :                 break;
    1086             : 
    1087             :         case 2:
    1088           0 :                 switch (iha_state_2(sc, iot, ioh)) {
    1089             :                 case 3:  goto state_3;
    1090             :                 case 4:  goto state_4;
    1091             :                 default: break;
    1092             :                 }
    1093             :                 break;
    1094             : 
    1095             :         case 3:
    1096             :         state_3:
    1097           0 :                 if (iha_state_3(sc, iot, ioh) == 4)
    1098             :                         goto state_4;
    1099             :                 break;
    1100             : 
    1101             :         case 4:
    1102             :         state_4:
    1103           0 :                 switch (iha_state_4(sc, iot, ioh)) {
    1104           0 :                 case 0:  return (0);
    1105             :                 case 6:  goto state_6;
    1106             :                 default: break;
    1107             :                 }
    1108             :                 break;
    1109             : 
    1110             :         case 5:
    1111           0 :                 switch (iha_state_5(sc, iot, ioh)) {
    1112             :                 case 4:  goto state_4;
    1113             :                 case 6:  goto state_6;
    1114             :                 default: break;
    1115             :                 }
    1116             :                 break;
    1117             : 
    1118             :         case 6:
    1119             :         state_6:
    1120           0 :                 iha_state_6(sc, iot, ioh);
    1121           0 :                 break;
    1122             : 
    1123             :         case 8:
    1124           0 :                 iha_state_8(sc, iot, ioh);
    1125           0 :                 break;
    1126             : 
    1127             :         default:
    1128             : #ifdef IHA_DEBUG_STATE
    1129             :                 sc_print_addr(sc->HCS_ActScb->SCB_Xs->sc_link);
    1130             :                 printf("[debug] -unknown state: %i-\n",
    1131             :                     sc->HCS_ActScb->SCB_NxtStat);
    1132             : #endif
    1133           0 :                 iha_bad_seq(sc);
    1134           0 :                 break;
    1135             :         }
    1136             : 
    1137           0 :         return (-1);
    1138           0 : }
    1139             : 
    1140             : /*
    1141             :  * iha_state_1 - selection is complete after a SELATNSTOP. If the target
    1142             :  *               has put the bus into MSG_OUT phase start wide/sync
    1143             :  *               negotiation. Otherwise clear the FIFO and go to state 3,
    1144             :  *               which will send the SCSI CDB to the target.
    1145             :  */
    1146             : int
    1147           0 : iha_state_1(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
    1148             : {
    1149           0 :         struct iha_scb *pScb = sc->HCS_ActScb;
    1150             :         struct tcs *pTcs;
    1151             :         u_int16_t flags;
    1152             : 
    1153           0 :         iha_mark_busy_scb(pScb);
    1154             : 
    1155           0 :         pTcs = pScb->SCB_Tcs;
    1156             : 
    1157           0 :         bus_space_write_1(iot, ioh, TUL_SCONFIG0, pTcs->TCS_SConfig0);
    1158             : 
    1159             :         /*
    1160             :          * If we are in PHASE_MSG_OUT, send
    1161             :          *     a) IDENT message (with tags if appropriate)
    1162             :          *     b) WDTR if the target is configured to negotiate wide xfers
    1163             :          *     ** OR **
    1164             :          *     c) SDTR if the target is configured to negotiate sync xfers
    1165             :          *        but not wide ones
    1166             :          *
    1167             :          * If we are NOT, then the target is not asking for anything but
    1168             :          * the data/command, so go straight to state 3.
    1169             :          */
    1170           0 :         if (sc->HCS_Phase == PHASE_MSG_OUT) {
    1171           0 :                 bus_space_write_1(iot, ioh, TUL_SCTRL1, (ESBUSIN | EHRSL));
    1172           0 :                 bus_space_write_1(iot, ioh, TUL_SFIFO,  pScb->SCB_Ident);
    1173             : 
    1174           0 :                 if (pScb->SCB_TagMsg != 0) {
    1175           0 :                         bus_space_write_1(iot, ioh, TUL_SFIFO,
    1176             :                             pScb->SCB_TagMsg);
    1177           0 :                         bus_space_write_1(iot, ioh, TUL_SFIFO,
    1178             :                             pScb->SCB_TagId);
    1179           0 :                 }
    1180             : 
    1181           0 :                 flags = pTcs->TCS_Flags;
    1182           0 :                 if ((flags & FLAG_NO_NEG_WIDE) == 0) {
    1183           0 :                         if (iha_msgout_wdtr(sc, iot, ioh) == -1)
    1184           0 :                                 return (-1);
    1185           0 :                 } else if ((flags & FLAG_NO_NEG_SYNC) == 0) {
    1186           0 :                         if (iha_msgout_sdtr(sc, iot, ioh) == -1)
    1187           0 :                                 return (-1);
    1188             :                 }
    1189             : 
    1190             :         } else {
    1191           0 :                 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
    1192           0 :                 iha_set_ssig(iot, ioh, REQ | BSY | SEL | ATN, 0);
    1193             :         }
    1194             : 
    1195           0 :         return (3);
    1196           0 : }
    1197             : 
    1198             : /*
    1199             :  * iha_state_2 - selection is complete after a SEL_ATN or SEL_ATN3. If the SCSI
    1200             :  *               CDB has already been send, go to state 4 to start the data
    1201             :  *               xfer. Otherwise reset the FIFO and go to state 3, sending 
    1202             :  *               the SCSI CDB.
    1203             :  */
    1204             : int
    1205           0 : iha_state_2(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
    1206             : {
    1207           0 :         struct iha_scb *pScb = sc->HCS_ActScb;
    1208             : 
    1209           0 :         iha_mark_busy_scb(pScb);
    1210             : 
    1211           0 :         bus_space_write_1(iot, ioh, TUL_SCONFIG0, pScb->SCB_Tcs->TCS_SConfig0);
    1212             : 
    1213           0 :         if ((sc->HCS_JSStatus1 & CPDNE) != 0)
    1214           0 :                 return (4);
    1215             : 
    1216           0 :         bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
    1217             : 
    1218           0 :         iha_set_ssig(iot, ioh, REQ | BSY | SEL | ATN, 0);
    1219             : 
    1220           0 :         return (3);
    1221           0 : }
    1222             : 
    1223             : /*
    1224             :  * iha_state_3 - send the SCSI CDB to the target, processing any status
    1225             :  *               or other messages received until that is done or
    1226             :  *               abandoned.
    1227             :  */
    1228             : int
    1229           0 : iha_state_3(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
    1230             : {
    1231           0 :         struct iha_scb *pScb = sc->HCS_ActScb;
    1232             :         u_int16_t flags;
    1233             : 
    1234           0 :         for (;;)
    1235           0 :                 switch (sc->HCS_Phase) {
    1236             :                 case PHASE_CMD_OUT:
    1237           0 :                         bus_space_write_multi_1(iot, ioh, TUL_SFIFO,
    1238             :                             pScb->SCB_CDB, pScb->SCB_CDBLen);
    1239           0 :                         if (iha_wait(sc, iot, ioh, XF_FIFO_OUT) == -1)
    1240           0 :                                 return (-1);
    1241           0 :                         else if (sc->HCS_Phase == PHASE_CMD_OUT) {
    1242           0 :                                 iha_bad_seq(sc);
    1243           0 :                                 return (-1);
    1244             :                         } else
    1245           0 :                                 return (4);
    1246             : 
    1247             :                 case PHASE_MSG_IN:
    1248           0 :                         pScb->SCB_NxtStat = 3;
    1249           0 :                         if (iha_msgin(sc, iot, ioh) == -1)
    1250           0 :                                 return (-1);
    1251             :                         break;
    1252             : 
    1253             :                 case PHASE_STATUS_IN:
    1254           0 :                         if (iha_status_msg(sc, iot, ioh) == -1)
    1255           0 :                                 return (-1);
    1256             :                         break;
    1257             : 
    1258             :                 case PHASE_MSG_OUT:
    1259           0 :                         flags = pScb->SCB_Tcs->TCS_Flags;
    1260           0 :                         if ((flags & FLAG_NO_NEG_SYNC) != 0) {
    1261           0 :                                 if (iha_msgout(sc, iot, ioh, MSG_NOOP) == -1)
    1262           0 :                                         return (-1);
    1263           0 :                         } else if (iha_msgout_sdtr(sc, iot, ioh) == -1)
    1264           0 :                                 return (-1);
    1265             :                         break;
    1266             : 
    1267             :                 default:
    1268             : #ifdef IHA_DEBUG_STATE
    1269             :                         sc_print_addr(pScb->SCB_Xs->sc_link);
    1270             :                         printf("[debug] -s3- bad phase = %d\n", sc->HCS_Phase);
    1271             : #endif
    1272           0 :                         iha_bad_seq(sc);
    1273           0 :                         return (-1);
    1274             :                 }
    1275           0 : }
    1276             : 
    1277             : /* 
    1278             :  * iha_state_4 - start a data xfer. Handle any bus state
    1279             :  *               transitions until PHASE_DATA_IN/_OUT
    1280             :  *               or the attempt is abandoned. If there is 
    1281             :  *               no data to xfer, go to state 6 and finish
    1282             :  *               processing the current SCB.
    1283             :  */
    1284             : int
    1285           0 : iha_state_4(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
    1286             : {
    1287           0 :         struct iha_scb *pScb = sc->HCS_ActScb;
    1288             : 
    1289           0 :         if ((pScb->SCB_Flags & FLAG_DIR) == FLAG_DIR)
    1290           0 :                 return (6); /* Both dir flags set => NO xfer was requested */
    1291             : 
    1292           0 :         for (;;) {
    1293           0 :                 if (pScb->SCB_BufCharsLeft == 0)
    1294           0 :                         return (6);
    1295             : 
    1296           0 :                 switch (sc->HCS_Phase) {
    1297             :                 case PHASE_STATUS_IN:
    1298           0 :                         if ((pScb->SCB_Flags & FLAG_DIR) != 0)
    1299           0 :                                 pScb->SCB_HaStat = iha_data_over_run(pScb);
    1300           0 :                         if ((iha_status_msg(sc, iot, ioh)) == -1)
    1301           0 :                                 return (-1);
    1302             :                         break;
    1303             : 
    1304             :                 case PHASE_MSG_IN:
    1305           0 :                         pScb->SCB_NxtStat = 4;
    1306           0 :                         if (iha_msgin(sc, iot, ioh) == -1)
    1307           0 :                                 return (-1);
    1308             :                         break;
    1309             : 
    1310             :                 case PHASE_MSG_OUT:
    1311           0 :                         if ((sc->HCS_JSStatus0 & SPERR) != 0) {
    1312           0 :                                 pScb->SCB_BufCharsLeft = 0;
    1313           0 :                                 pScb->SCB_HaStat = HOST_SPERR;
    1314           0 :                                 if (iha_msgout(sc, iot, ioh,
    1315           0 :                                         MSG_INITIATOR_DET_ERR) == -1)
    1316           0 :                                         return (-1);
    1317             :                                 else
    1318           0 :                                         return (6);
    1319             :                         } else {
    1320           0 :                                 if (iha_msgout(sc, iot, ioh, MSG_NOOP) == -1)
    1321           0 :                                         return (-1);
    1322             :                         }
    1323             :                         break;
    1324             : 
    1325             :                 case PHASE_DATA_IN:
    1326           0 :                         return (iha_xfer_data(pScb, iot, ioh, SCSI_DATA_IN));
    1327             : 
    1328             :                 case PHASE_DATA_OUT:
    1329           0 :                         return (iha_xfer_data(pScb, iot, ioh, SCSI_DATA_OUT));
    1330             : 
    1331             :                 default:
    1332           0 :                         iha_bad_seq(sc);
    1333           0 :                         return (-1);
    1334             :                 }
    1335             :         }
    1336           0 : }
    1337             : 
    1338             : /*
    1339             :  * iha_state_5 - handle the partial or final completion of the current
    1340             :  *               data xfer. If DMA is still active stop it. If there is 
    1341             :  *               more data to xfer, go to state 4 and start the xfer.
    1342             :  *               If not go to state 6 and finish the SCB.
    1343             :  */
    1344             : int
    1345           0 : iha_state_5(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
    1346             : {
    1347           0 :         struct iha_scb *pScb = sc->HCS_ActScb;
    1348             :         struct iha_sg_element *pSg;
    1349             :         u_int32_t cnt;
    1350             :         u_int16_t period;
    1351             :         u_int8_t stat;
    1352             :         long xcnt;  /* cannot use unsigned!! see code: if (xcnt < 0) */
    1353             : 
    1354           0 :         cnt = bus_space_read_4(iot, ioh, TUL_STCNT0) & TCNT;
    1355             :         
    1356             :         /*
    1357             :          * Stop any pending DMA activity and check for parity error.
    1358             :          */
    1359             : 
    1360           0 :         if ((bus_space_read_1(iot, ioh, TUL_DCMD) & XDIR) != 0) {
    1361             :                 /* Input Operation */
    1362           0 :                 if ((sc->HCS_JSStatus0 & SPERR) != 0)
    1363           0 :                         pScb->SCB_HaStat = HOST_SPERR;
    1364             : 
    1365           0 :                 if ((bus_space_read_1(iot, ioh, TUL_ISTUS1) & XPEND) != 0) {
    1366           0 :                         bus_space_write_1(iot, ioh, TUL_DCTRL0,
    1367             :                             bus_space_read_1(iot, ioh, TUL_DCTRL0) | SXSTP);
    1368           0 :                         while (bus_space_read_1(iot, ioh, TUL_ISTUS1) & XPEND)
    1369             :                                 ;
    1370             :                 }
    1371             : 
    1372             :         } else {
    1373             :                 /* Output Operation */
    1374           0 :                 if ((sc->HCS_JSStatus1 & SXCMP) == 0) {
    1375           0 :                         period = pScb->SCB_Tcs->TCS_JS_Period; 
    1376           0 :                         if ((period & PERIOD_WIDE_SCSI) != 0)
    1377           0 :                                 cnt += (bus_space_read_1(iot, ioh,
    1378           0 :                                             TUL_SFIFOCNT) & FIFOC) << 1;
    1379             :                         else
    1380           0 :                                 cnt += (bus_space_read_1(iot, ioh,
    1381             :                                             TUL_SFIFOCNT) & FIFOC);
    1382             :                 }
    1383             : 
    1384           0 :                 if ((bus_space_read_1(iot, ioh, TUL_ISTUS1) & XPEND) != 0) {
    1385           0 :                         bus_space_write_1(iot, ioh, TUL_DCMD, ABTXFR);
    1386           0 :                         do
    1387           0 :                                 stat = bus_space_read_1(iot, ioh, TUL_ISTUS0);
    1388           0 :                         while ((stat & DABT) == 0);
    1389             :                 }
    1390             : 
    1391           0 :                 if ((cnt == 1) && (sc->HCS_Phase == PHASE_DATA_OUT)) {
    1392           0 :                         if (iha_wait(sc, iot, ioh, XF_FIFO_OUT) == -1)
    1393           0 :                                 return (-1);
    1394             :                         cnt = 0;
    1395             : 
    1396           0 :                 } else if ((sc->HCS_JSStatus1 & SXCMP) == 0)
    1397           0 :                         bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
    1398             :         }
    1399             : 
    1400           0 :         if (cnt == 0) {
    1401           0 :                 pScb->SCB_BufCharsLeft = 0;
    1402           0 :                 return (6);
    1403             :         }
    1404             : 
    1405             :         /* Update active data pointer and restart the I/O at the new point */
    1406             : 
    1407           0 :         xcnt = pScb->SCB_BufCharsLeft - cnt; /* xcnt == bytes xferred */
    1408           0 :         pScb->SCB_BufCharsLeft = cnt;                /* cnt  == bytes left    */
    1409             : 
    1410           0 :         bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma, 
    1411             :                 0, sizeof(pScb->SCB_SGList), BUS_DMASYNC_POSTWRITE);
    1412             : 
    1413           0 :         if ((pScb->SCB_Flags & FLAG_SG) != 0) {
    1414           0 :                 pSg = &pScb->SCB_SGList[pScb->SCB_SGIdx];
    1415           0 :                 for (; pScb->SCB_SGIdx < pScb->SCB_SGCount; pSg++, pScb->SCB_SGIdx++) {
    1416           0 :                         xcnt -= pSg->SG_Len;
    1417           0 :                         if (xcnt < 0) {
    1418             :                                 xcnt += pSg->SG_Len;
    1419             : 
    1420           0 :                                 pSg->SG_Addr += xcnt;
    1421           0 :                                 pSg->SG_Len -= xcnt;
    1422             : 
    1423           0 :                                 bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma, 
    1424             :                                         0, sizeof(pScb->SCB_SGList),
    1425             :                                         BUS_DMASYNC_PREWRITE);
    1426             : 
    1427           0 :                                 return (4);
    1428             :                         }
    1429             :                 }
    1430           0 :                 return (6);
    1431             : 
    1432             :         }
    1433             : 
    1434           0 :         return (4);
    1435           0 : }
    1436             : 
    1437             : /*
    1438             :  * iha_state_6 - finish off the active scb (may require several
    1439             :  *               iterations if PHASE_MSG_IN) and return -1 to indicate 
    1440             :  *               the bus is free.
    1441             :  */
    1442             : int
    1443           0 : iha_state_6(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
    1444             : {
    1445           0 :         for (;;)
    1446           0 :                 switch (sc->HCS_Phase) {
    1447             :                 case PHASE_STATUS_IN:
    1448           0 :                         if (iha_status_msg(sc, iot, ioh) == -1)
    1449           0 :                                 return (-1);
    1450             :                         break;
    1451             : 
    1452             :                 case PHASE_MSG_IN:
    1453           0 :                         sc->HCS_ActScb->SCB_NxtStat = 6;
    1454           0 :                         if ((iha_msgin(sc, iot, ioh)) == -1)
    1455           0 :                                 return (-1);
    1456             :                         break;
    1457             : 
    1458             :                 case PHASE_MSG_OUT:
    1459           0 :                         if ((iha_msgout(sc, iot, ioh, MSG_NOOP)) == -1)
    1460           0 :                                 return (-1);
    1461             :                         break;
    1462             : 
    1463             :                 case PHASE_DATA_IN:
    1464           0 :                         if (iha_xpad_in(sc, iot, ioh) == -1)
    1465           0 :                                 return (-1);
    1466             :                         break;
    1467             : 
    1468             :                 case PHASE_DATA_OUT:
    1469           0 :                         if (iha_xpad_out(sc, iot, ioh) == -1)
    1470           0 :                                 return (-1);
    1471             :                         break;
    1472             : 
    1473             :                 default:
    1474           0 :                         iha_bad_seq(sc);
    1475           0 :                         return (-1);
    1476             :                 }
    1477           0 : }
    1478             : 
    1479             : /*
    1480             :  * iha_state_8 - reset the active device and all busy SCBs using it
    1481             :  */
    1482             : int
    1483           0 : iha_state_8(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
    1484             : {
    1485             :         struct iha_scb *pScb;
    1486             :         u_int32_t i;
    1487             :         u_int8_t tar;
    1488             : 
    1489           0 :         if (sc->HCS_Phase == PHASE_MSG_OUT) {
    1490           0 :                 bus_space_write_1(iot, ioh, TUL_SFIFO, MSG_BUS_DEV_RESET);
    1491             : 
    1492           0 :                 pScb = sc->HCS_ActScb;
    1493             :                 
    1494             :                 /* This SCB finished correctly -- resetting the device */
    1495           0 :                 iha_append_done_scb(sc, pScb, HOST_OK);
    1496             : 
    1497           0 :                 iha_reset_tcs(pScb->SCB_Tcs, sc->HCS_SConf1);
    1498             : 
    1499           0 :                 tar = pScb->SCB_Target;
    1500           0 :                 for (i = 0, pScb = sc->HCS_Scb; i < IHA_MAX_SCB; i++, pScb++)
    1501           0 :                         if (pScb->SCB_Target == tar)
    1502           0 :                                 switch (pScb->SCB_Status) {
    1503             :                                 case STATUS_BUSY:
    1504           0 :                                         iha_append_done_scb(sc,
    1505             :                                             pScb, HOST_DEV_RST);
    1506           0 :                                         break;
    1507             : 
    1508             :                                 case STATUS_SELECT:
    1509           0 :                                         iha_push_pend_scb(sc, pScb);
    1510           0 :                                         break;
    1511             :                                         
    1512             :                                 default:
    1513             :                                         break;
    1514             :                                 }
    1515             : 
    1516           0 :                 sc->HCS_Flags |= FLAG_EXPECT_DISC;
    1517             : 
    1518           0 :                 if (iha_wait(sc, iot, ioh, XF_FIFO_OUT) == -1)
    1519           0 :                         return (-1);
    1520             :         }
    1521             : 
    1522           0 :         iha_bad_seq(sc);
    1523           0 :         return (-1);
    1524           0 : }
    1525             : 
    1526             : /*
    1527             :  * iha_xfer_data - initiate the DMA xfer of the data
    1528             :  */
    1529             : int
    1530           0 : iha_xfer_data(struct iha_scb *pScb, bus_space_tag_t iot, bus_space_handle_t ioh,
    1531             :     int direction)
    1532             : {
    1533             :         u_int32_t xferaddr, xferlen;
    1534             :         u_int8_t xfertype;
    1535             : 
    1536           0 :         if ((pScb->SCB_Flags & FLAG_DIR) != direction)
    1537           0 :                 return (6); /* wrong direction, abandon I/O */
    1538             : 
    1539           0 :         bus_space_write_4(iot, ioh, TUL_STCNT0, pScb->SCB_BufCharsLeft);
    1540             : 
    1541           0 :         if ((pScb->SCB_Flags & FLAG_SG) == 0) {
    1542           0 :                 xferaddr = pScb->SCB_DataDma->dm_segs[0].ds_addr
    1543           0 :                                 + (pScb->SCB_BufChars - pScb->SCB_BufCharsLeft);
    1544             :                 xferlen  = pScb->SCB_BufCharsLeft;
    1545           0 :                 xfertype = (direction == SCSI_DATA_IN) ? ST_X_IN : ST_X_OUT;
    1546             : 
    1547           0 :         } else {
    1548           0 :                 xferaddr = pScb->SCB_SGDma->dm_segs[0].ds_addr
    1549           0 :                                 + (pScb->SCB_SGIdx * sizeof(struct iha_sg_element));
    1550           0 :                 xferlen  = (pScb->SCB_SGCount - pScb->SCB_SGIdx)
    1551           0 :                                 * sizeof(struct iha_sg_element);
    1552           0 :                 xfertype = (direction == SCSI_DATA_IN) ? ST_SG_IN : ST_SG_OUT;
    1553             :         }
    1554             : 
    1555           0 :         bus_space_write_4(iot, ioh, TUL_DXC,  xferlen);
    1556           0 :         bus_space_write_4(iot, ioh, TUL_DXPA, xferaddr);
    1557           0 :         bus_space_write_1(iot, ioh, TUL_DCMD, xfertype);
    1558             : 
    1559           0 :         bus_space_write_1(iot, ioh, TUL_SCMD,
    1560             :             (direction == SCSI_DATA_IN) ? XF_DMA_IN : XF_DMA_OUT);
    1561             : 
    1562           0 :         pScb->SCB_NxtStat = 5;
    1563             : 
    1564           0 :         return (0);
    1565           0 : }
    1566             : 
    1567             : int
    1568           0 : iha_xpad_in(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
    1569             : {
    1570           0 :         struct iha_scb *pScb = sc->HCS_ActScb;
    1571             : 
    1572           0 :         if ((pScb->SCB_Flags & FLAG_DIR) != 0)
    1573           0 :                 pScb->SCB_HaStat = HOST_DO_DU;
    1574             : 
    1575           0 :         for (;;) {
    1576           0 :                 if ((pScb->SCB_Tcs->TCS_JS_Period & PERIOD_WIDE_SCSI) != 0)
    1577           0 :                         bus_space_write_4(iot, ioh, TUL_STCNT0, 2);
    1578             :                 else
    1579           0 :                         bus_space_write_4(iot, ioh, TUL_STCNT0, 1);
    1580             : 
    1581           0 :                 switch (iha_wait(sc, iot, ioh, XF_FIFO_IN)) {
    1582             :                 case -1:
    1583           0 :                         return (-1);
    1584             : 
    1585             :                 case PHASE_DATA_IN:
    1586           0 :                         bus_space_read_1(iot, ioh, TUL_SFIFO);
    1587             :                         break;
    1588             : 
    1589             :                 default:
    1590           0 :                         bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
    1591           0 :                         return (6);
    1592             :                 }
    1593             :         }
    1594           0 : }
    1595             : 
    1596             : int
    1597           0 : iha_xpad_out(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
    1598             : {
    1599           0 :         struct iha_scb *pScb = sc->HCS_ActScb;
    1600             : 
    1601           0 :         if ((pScb->SCB_Flags & FLAG_DIR) != 0)
    1602           0 :                 pScb->SCB_HaStat = HOST_DO_DU;
    1603             : 
    1604           0 :         for (;;) {
    1605           0 :                 if ((pScb->SCB_Tcs->TCS_JS_Period & PERIOD_WIDE_SCSI) != 0)
    1606           0 :                         bus_space_write_4(iot, ioh, TUL_STCNT0, 2);
    1607             :                 else
    1608           0 :                         bus_space_write_4(iot, ioh, TUL_STCNT0, 1);
    1609             : 
    1610           0 :                 bus_space_write_1(iot, ioh, TUL_SFIFO, 0);
    1611             : 
    1612           0 :                 switch (iha_wait(sc, iot, ioh, XF_FIFO_OUT)) {
    1613             :                 case -1:
    1614           0 :                         return (-1);
    1615             : 
    1616             :                 case PHASE_DATA_OUT:
    1617             :                         break;
    1618             : 
    1619             :                 default:
    1620             :                         /* Disable wide CPU to allow read 16 bits */
    1621           0 :                         bus_space_write_1(iot, ioh, TUL_SCTRL1, EHRSL);
    1622           0 :                         bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
    1623           0 :                         return (6);
    1624             :                 }
    1625             :         }
    1626           0 : }
    1627             : 
    1628             : int
    1629           0 : iha_status_msg(struct iha_softc *sc, bus_space_tag_t iot,
    1630             :     bus_space_handle_t ioh)
    1631             : {
    1632             :         struct iha_scb *pScb;
    1633             :         u_int8_t msg;
    1634             :         int phase;
    1635             : 
    1636           0 :         if ((phase = iha_wait(sc, iot, ioh, CMD_COMP)) == -1)
    1637           0 :                 return (-1);
    1638             : 
    1639           0 :         pScb = sc->HCS_ActScb;
    1640             :         
    1641           0 :         pScb->SCB_TaStat = bus_space_read_1(iot, ioh, TUL_SFIFO);
    1642             : 
    1643           0 :         if (phase == PHASE_MSG_OUT) {
    1644           0 :                 if ((sc->HCS_JSStatus0 & SPERR) == 0)
    1645           0 :                         bus_space_write_1(iot, ioh, TUL_SFIFO,
    1646             :                             MSG_NOOP);
    1647             :                 else
    1648           0 :                         bus_space_write_1(iot, ioh, TUL_SFIFO,
    1649             :                             MSG_PARITY_ERROR);
    1650             : 
    1651           0 :                 return (iha_wait(sc, iot, ioh, XF_FIFO_OUT));
    1652             : 
    1653           0 :         } else if (phase == PHASE_MSG_IN) {
    1654           0 :                 msg = bus_space_read_1(iot, ioh, TUL_SFIFO);
    1655             : 
    1656           0 :                 if ((sc->HCS_JSStatus0 & SPERR) != 0)
    1657           0 :                         switch (iha_wait(sc, iot, ioh, MSG_ACCEPT)) {
    1658             :                         case -1:
    1659           0 :                                 return (-1);
    1660             :                         case PHASE_MSG_OUT:
    1661           0 :                                 bus_space_write_1(iot, ioh, TUL_SFIFO,
    1662             :                                     MSG_PARITY_ERROR);
    1663           0 :                                 return (iha_wait(sc, iot, ioh, XF_FIFO_OUT));
    1664             :                         default:
    1665           0 :                                 iha_bad_seq(sc);
    1666           0 :                                 return (-1);
    1667             :                         }
    1668             : 
    1669           0 :                 if (msg == MSG_CMDCOMPLETE) {
    1670           0 :                         if ((pScb->SCB_TaStat 
    1671           0 :                                 & (SCSI_INTERM | SCSI_BUSY)) == SCSI_INTERM) {
    1672           0 :                                 iha_bad_seq(sc);
    1673           0 :                                 return (-1);
    1674             :                         }
    1675           0 :                         sc->HCS_Flags |= FLAG_EXPECT_DONE_DISC;
    1676           0 :                         bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
    1677           0 :                         return (iha_wait(sc, iot, ioh, MSG_ACCEPT));
    1678             :                 }
    1679             : 
    1680           0 :                 if ((msg == MSG_LINK_CMD_COMPLETE)
    1681           0 :                     || (msg == MSG_LINK_CMD_COMPLETEF)) {
    1682           0 :                         if ((pScb->SCB_TaStat 
    1683           0 :                                  & (SCSI_INTERM | SCSI_BUSY)) == SCSI_INTERM)
    1684           0 :                                 return (iha_wait(sc, iot, ioh, MSG_ACCEPT));
    1685             :                 }
    1686             :         }
    1687             : 
    1688           0 :         iha_bad_seq(sc);
    1689           0 :         return (-1);
    1690           0 : }
    1691             : 
    1692             : /*
    1693             :  * iha_busfree - SCSI bus free detected as a result of a TIMEOUT or
    1694             :  *               DISCONNECT interrupt. Reset the tulip FIFO and
    1695             :  *               SCONFIG0 and enable hardware reselect. Move any active
    1696             :  *               SCB to HCS_DoneScb list. Return an appropriate host status
    1697             :  *               if an I/O was active.
    1698             :  */
    1699             : void
    1700           0 : iha_busfree(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
    1701             : {
    1702             :         struct iha_scb *pScb;
    1703             : 
    1704           0 :         bus_space_write_1(iot, ioh, TUL_SCTRL0,   RSFIFO);
    1705           0 :         bus_space_write_1(iot, ioh, TUL_SCONFIG0, SCONFIG0DEFAULT);
    1706           0 :         bus_space_write_1(iot, ioh, TUL_SCTRL1,   EHRSL);
    1707             : 
    1708           0 :         pScb = sc->HCS_ActScb;
    1709             : 
    1710           0 :         if (pScb != NULL) {
    1711           0 :                 if (pScb->SCB_Status == STATUS_SELECT)
    1712             :                         /* selection timeout   */
    1713           0 :                         iha_append_done_scb(sc, pScb, HOST_SEL_TOUT);
    1714             :                 else
    1715             :                         /* Unexpected bus free */
    1716           0 :                         iha_append_done_scb(sc, pScb, HOST_BAD_PHAS);
    1717             : 
    1718             :         }
    1719           0 : }
    1720             : 
    1721             : void
    1722           0 : iha_reset_scsi_bus(struct iha_softc *sc)
    1723             : {
    1724             :         struct iha_scb *pScb;
    1725             :         struct tcs *pTcs;
    1726             :         int i, s;
    1727             : 
    1728           0 :         s = splbio();
    1729             : 
    1730           0 :         iha_reset_dma(sc->sc_iot, sc->sc_ioh);
    1731             : 
    1732           0 :         for (i = 0, pScb = sc->HCS_Scb; i < IHA_MAX_SCB; i++, pScb++)
    1733           0 :                 switch (pScb->SCB_Status) {
    1734             :                 case STATUS_BUSY:
    1735           0 :                         iha_append_done_scb(sc, pScb, HOST_SCSI_RST);
    1736           0 :                         break;
    1737             : 
    1738             :                 case STATUS_SELECT:
    1739           0 :                         iha_push_pend_scb(sc, pScb);
    1740           0 :                         break;
    1741             : 
    1742             :                 default:
    1743             :                         break;
    1744             :                 }
    1745             : 
    1746           0 :         for (i = 0, pTcs = sc->HCS_Tcs; i < IHA_MAX_TARGETS; i++, pTcs++)
    1747           0 :                 iha_reset_tcs(pTcs, sc->HCS_SConf1);
    1748             : 
    1749           0 :         splx(s);
    1750           0 : }
    1751             : 
    1752             : /*
    1753             :  * iha_resel - handle a detected SCSI bus reselection request.
    1754             :  */
    1755             : int
    1756           0 : iha_resel(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
    1757             : {
    1758             :         struct iha_scb *pScb;
    1759             :         struct tcs *pTcs;
    1760             :         u_int8_t tag, target, lun, msg, abortmsg;
    1761             : 
    1762           0 :         if (sc->HCS_ActScb != NULL) {
    1763           0 :                 if (sc->HCS_ActScb->SCB_Status == STATUS_SELECT)
    1764           0 :                         iha_push_pend_scb(sc, sc->HCS_ActScb);
    1765           0 :                 sc->HCS_ActScb = NULL;
    1766           0 :         }
    1767             : 
    1768           0 :         target = bus_space_read_1(iot, ioh, TUL_SBID);
    1769           0 :         lun    = bus_space_read_1(iot, ioh, TUL_SALVC) & MSG_IDENTIFY_LUNMASK;
    1770             : 
    1771           0 :         pTcs = &sc->HCS_Tcs[target];
    1772             : 
    1773           0 :         bus_space_write_1(iot, ioh, TUL_SCONFIG0, pTcs->TCS_SConfig0);
    1774           0 :         bus_space_write_1(iot, ioh, TUL_SYNCM,    pTcs->TCS_JS_Period);
    1775             : 
    1776             :         abortmsg = MSG_ABORT; /* until a valid tag has been obtained */
    1777             : 
    1778           0 :         if (pTcs->TCS_NonTagScb != NULL)
    1779             :                 /* There is a non-tagged I/O active on the target */
    1780           0 :                 pScb = pTcs->TCS_NonTagScb;
    1781             : 
    1782             :         else {
    1783             :                 /* 
    1784             :                  * Since there is no active non-tagged operation
    1785             :                  * read the tag type, the tag itself, and find
    1786             :                  * the appropriate pScb by indexing HCS_Scb with
    1787             :                  * the tag.
    1788             :                  */
    1789             : 
    1790           0 :                 switch (iha_wait(sc, iot, ioh, MSG_ACCEPT)) {
    1791             :                 case -1:
    1792           0 :                         return (-1);
    1793             :                 case PHASE_MSG_IN:
    1794           0 :                         bus_space_write_4(iot, ioh, TUL_STCNT0, 1);
    1795           0 :                         if ((iha_wait(sc, iot, ioh, XF_FIFO_IN)) == -1)
    1796           0 :                                 return (-1);
    1797             :                         break;
    1798             :                 default:
    1799             :                         goto abort;
    1800             :                 }
    1801             : 
    1802           0 :                 msg = bus_space_read_1(iot, ioh, TUL_SFIFO); /* Read Tag Msg */
    1803             : 
    1804           0 :                 if ((msg < MSG_SIMPLE_Q_TAG) || (msg > MSG_ORDERED_Q_TAG))
    1805             :                         goto abort;
    1806             : 
    1807           0 :                 switch (iha_wait(sc, iot, ioh, MSG_ACCEPT)) {
    1808             :                 case -1:
    1809           0 :                         return (-1);
    1810             :                 case PHASE_MSG_IN:
    1811           0 :                         bus_space_write_4(iot, ioh, TUL_STCNT0, 1);
    1812           0 :                         if ((iha_wait(sc, iot, ioh, XF_FIFO_IN)) == -1)
    1813           0 :                                 return (-1);
    1814             :                         break;
    1815             :                 default:
    1816             :                         goto abort;
    1817             :                 }
    1818             : 
    1819           0 :                 tag  = bus_space_read_1(iot, ioh, TUL_SFIFO); /* Read Tag ID */
    1820           0 :                 pScb = &sc->HCS_Scb[tag];
    1821             : 
    1822             :                 abortmsg = MSG_ABORT_TAG; /* Now that we have valdid tag! */
    1823             :         }
    1824             : 
    1825           0 :         if ((pScb->SCB_Target != target)  
    1826           0 :             || (pScb->SCB_Lun != lun)
    1827           0 :             || (pScb->SCB_Status != STATUS_BUSY)) {
    1828             : abort:
    1829           0 :                 iha_msgout_abort(sc, iot, ioh, abortmsg);
    1830           0 :                 return (-1);
    1831             :         }
    1832             : 
    1833           0 :         sc->HCS_ActScb = pScb;
    1834             : 
    1835           0 :         if (iha_wait(sc, iot, ioh, MSG_ACCEPT) == -1)
    1836           0 :                 return (-1);
    1837             : 
    1838           0 :         return(iha_next_state(sc, iot, ioh));
    1839           0 : }
    1840             : 
    1841             : int
    1842           0 : iha_msgin(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
    1843             : {
    1844             :         u_int16_t flags;
    1845             :         u_int8_t msg;
    1846             :         int phase;
    1847             : 
    1848           0 :         for (;;) {
    1849           0 :                 if ((bus_space_read_1(iot, ioh, TUL_SFIFOCNT) & FIFOC) > 0)
    1850           0 :                         bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
    1851             : 
    1852           0 :                 bus_space_write_4(iot, ioh, TUL_STCNT0, 1);
    1853             : 
    1854           0 :                 phase = iha_wait(sc, iot, ioh, XF_FIFO_IN);
    1855           0 :                 msg   = bus_space_read_1(iot, ioh, TUL_SFIFO);
    1856             : 
    1857           0 :                 switch (msg) {
    1858             :                 case MSG_DISCONNECT:
    1859           0 :                         sc->HCS_Flags |= FLAG_EXPECT_DISC;
    1860           0 :                         if (iha_wait(sc, iot, ioh, MSG_ACCEPT) != -1)
    1861           0 :                                 iha_bad_seq(sc);
    1862             :                         phase = -1;
    1863           0 :                         break;
    1864             :                 case MSG_SAVEDATAPOINTER:
    1865             :                 case MSG_RESTOREPOINTERS:
    1866             :                 case MSG_NOOP:
    1867           0 :                         phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
    1868           0 :                         break;
    1869             :                 case MSG_MESSAGE_REJECT:
    1870             :                         /* XXX - need to clear FIFO like other 'Clear ATN'?*/
    1871           0 :                         iha_set_ssig(iot, ioh, REQ | BSY | SEL | ATN, 0);
    1872           0 :                         flags = sc->HCS_ActScb->SCB_Tcs->TCS_Flags;
    1873           0 :                         if ((flags & FLAG_NO_NEG_SYNC) == 0)
    1874           0 :                                 iha_set_ssig(iot, ioh, REQ | BSY | SEL, ATN);
    1875           0 :                         phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
    1876           0 :                         break;
    1877             :                 case MSG_EXTENDED:
    1878           0 :                         phase = iha_msgin_extended(sc, iot, ioh);
    1879           0 :                         break;
    1880             :                 case MSG_IGN_WIDE_RESIDUE:
    1881           0 :                         phase = iha_msgin_ignore_wid_resid(sc, iot, ioh);
    1882           0 :                         break;
    1883             :                 case MSG_CMDCOMPLETE:
    1884           0 :                         sc->HCS_Flags |= FLAG_EXPECT_DONE_DISC;
    1885           0 :                         bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
    1886           0 :                         phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
    1887           0 :                         if (phase != -1) {
    1888           0 :                                 iha_bad_seq(sc);
    1889           0 :                                 return (-1);
    1890             :                         }
    1891             :                         break;
    1892             :                 default:
    1893             : #ifdef IHA_DEBUG_STATE
    1894             :                         printf("[debug] iha_msgin: bad msg type: %d\n", msg);
    1895             : #endif
    1896           0 :                         phase = iha_msgout_reject(sc, iot, ioh);
    1897           0 :                         break;
    1898             :                 }
    1899             : 
    1900           0 :                 if (phase != PHASE_MSG_IN)
    1901           0 :                         return (phase);
    1902             :         }
    1903             :         /* NOTREACHED */
    1904           0 : }
    1905             : 
    1906             : int
    1907           0 : iha_msgin_ignore_wid_resid(struct iha_softc *sc, bus_space_tag_t iot,
    1908             :     bus_space_handle_t ioh)
    1909             : {
    1910             :         int phase;
    1911             : 
    1912           0 :         phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
    1913             : 
    1914           0 :         if (phase == PHASE_MSG_IN) {
    1915           0 :                 phase = iha_wait(sc, iot, ioh, XF_FIFO_IN);
    1916             : 
    1917           0 :                 if (phase != -1) {
    1918           0 :                         bus_space_write_1(iot, ioh, TUL_SFIFO, 0);
    1919           0 :                         bus_space_read_1 (iot, ioh, TUL_SFIFO);
    1920           0 :                         bus_space_read_1 (iot, ioh, TUL_SFIFO);
    1921             : 
    1922           0 :                         phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
    1923           0 :                 }
    1924             :         }
    1925             : 
    1926           0 :         return (phase);
    1927             : }
    1928             : 
    1929             : int
    1930           0 : iha_msgin_extended(struct iha_softc *sc, bus_space_tag_t iot,
    1931             :     bus_space_handle_t ioh)
    1932             : {
    1933             :         u_int16_t flags;
    1934             :         int i, phase, msglen, msgcode;
    1935             : 
    1936             :         /* XXX - can we just stop reading and reject, or do we have to
    1937             :          *       read all input, discarding the excess, and then reject
    1938             :          */
    1939           0 :         for (i = 0; i < IHA_MAX_EXTENDED_MSG; i++) {
    1940           0 :                 phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
    1941             : 
    1942           0 :                 if (phase != PHASE_MSG_IN)
    1943           0 :                         return (phase);
    1944             : 
    1945           0 :                 bus_space_write_4(iot, ioh, TUL_STCNT0, 1);
    1946             : 
    1947           0 :                 if (iha_wait(sc, iot, ioh, XF_FIFO_IN) == -1)
    1948           0 :                         return (-1);
    1949             : 
    1950           0 :                 sc->HCS_Msg[i] = bus_space_read_1(iot, ioh, TUL_SFIFO);
    1951             : 
    1952           0 :                 if (sc->HCS_Msg[0] == i)
    1953             :                         break;
    1954             :         }
    1955             : 
    1956           0 :         msglen  = sc->HCS_Msg[0];
    1957           0 :         msgcode = sc->HCS_Msg[1];
    1958             : 
    1959           0 :         if ((msglen == MSG_EXT_SDTR_LEN) && (msgcode == MSG_EXT_SDTR)) {
    1960           0 :                 if (iha_msgin_sdtr(sc) == 0) {
    1961           0 :                         iha_sync_done(sc, iot, ioh);
    1962           0 :                         return (iha_wait(sc, iot, ioh, MSG_ACCEPT));
    1963             :                 }
    1964             : 
    1965           0 :                 iha_set_ssig(iot, ioh, REQ | BSY | SEL, ATN);
    1966             : 
    1967           0 :                 phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
    1968           0 :                 if (phase != PHASE_MSG_OUT)
    1969           0 :                         return (phase);
    1970             : 
    1971             :                 /* Clear FIFO for important message - final SYNC offer */
    1972           0 :                 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
    1973             : 
    1974           0 :                 iha_sync_done(sc, iot, ioh); /* This is our final offer */
    1975             : 
    1976           0 :         } else if ((msglen == MSG_EXT_WDTR_LEN) && (msgcode == MSG_EXT_WDTR)) {
    1977             : 
    1978           0 :                 flags = sc->HCS_ActScb->SCB_Tcs->TCS_Flags;
    1979             : 
    1980           0 :                 if ((flags & FLAG_NO_WIDE) != 0)
    1981             :                         /* Offer 8 bit xfers only */
    1982           0 :                         sc->HCS_Msg[2] = MSG_EXT_WDTR_BUS_8_BIT;
    1983             : 
    1984           0 :                 else if (sc->HCS_Msg[2] > MSG_EXT_WDTR_BUS_32_BIT)
    1985           0 :                         return (iha_msgout_reject(sc, iot, ioh));
    1986             : 
    1987           0 :                 else if (sc->HCS_Msg[2] == MSG_EXT_WDTR_BUS_32_BIT)
    1988             :                         /* Offer 16 instead */
    1989           0 :                         sc->HCS_Msg[2] = MSG_EXT_WDTR_BUS_32_BIT;
    1990             : 
    1991             :                 else {
    1992           0 :                         iha_wide_done(sc, iot, ioh);
    1993           0 :                         if ((flags & FLAG_NO_NEG_SYNC) == 0)
    1994           0 :                                 iha_set_ssig(iot, ioh, REQ | BSY | SEL, ATN);
    1995           0 :                         return (iha_wait(sc, iot, ioh, MSG_ACCEPT));
    1996             :                 }
    1997             : 
    1998           0 :                 iha_set_ssig(iot, ioh, REQ | BSY | SEL, ATN);
    1999             : 
    2000           0 :                 phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
    2001           0 :                 if (phase != PHASE_MSG_OUT)
    2002           0 :                         return (phase);
    2003             : 
    2004             :         } else
    2005           0 :                 return (iha_msgout_reject(sc, iot, ioh));
    2006             : 
    2007             :         /* Send message built in sc->HCS_Msg[] */
    2008           0 :         return (iha_msgout_extended(sc, iot, ioh));
    2009           0 : }
    2010             : 
    2011             : /*
    2012             :  * iha_msgin_sdtr - check SDTR msg in HCS_Msg. If the offer is
    2013             :  *                  acceptable leave HCS_Msg as is and return 0.
    2014             :  *                  If the negotiation must continue, modify HCS_Msg
    2015             :  *                  as needed and return 1. Else return 0.
    2016             :  */
    2017             : int
    2018           0 : iha_msgin_sdtr(struct iha_softc *sc)
    2019             : {
    2020             :         u_int16_t flags;
    2021             :         u_int8_t default_period;
    2022             :         int newoffer;
    2023             : 
    2024           0 :         flags = sc->HCS_ActScb->SCB_Tcs->TCS_Flags;
    2025             : 
    2026           0 :         default_period = iha_rate_tbl[flags & FLAG_SCSI_RATE];
    2027             : 
    2028           0 :         if (sc->HCS_Msg[3] == 0) /* target offered async only. Accept it. */
    2029           0 :                 return (0);
    2030             : 
    2031             :         newoffer = 0;
    2032             : 
    2033           0 :         if ((flags & FLAG_NO_SYNC) != 0) {
    2034           0 :                 sc->HCS_Msg[3] = 0;
    2035             :                 newoffer   = 1;
    2036           0 :         }
    2037             : 
    2038           0 :         if (sc->HCS_Msg[3] > IHA_MAX_TARGETS-1) {
    2039           0 :                 sc->HCS_Msg[3] = IHA_MAX_TARGETS-1;
    2040             :                 newoffer   = 1;
    2041           0 :         }
    2042             : 
    2043           0 :         if (sc->HCS_Msg[2] < default_period) {
    2044           0 :                 sc->HCS_Msg[2] = default_period;
    2045             :                 newoffer   = 1;
    2046           0 :         }
    2047             : 
    2048           0 :         if (sc->HCS_Msg[2] >= 59) {
    2049           0 :                 sc->HCS_Msg[3] = 0;
    2050             :                 newoffer   = 1;
    2051           0 :         }
    2052             : 
    2053           0 :         return (newoffer);
    2054           0 : }
    2055             : 
    2056             : int
    2057           0 : iha_msgout(struct iha_softc *sc, bus_space_tag_t iot,
    2058             :     bus_space_handle_t ioh, u_int8_t msg)
    2059             : {
    2060           0 :         bus_space_write_1(iot, ioh, TUL_SFIFO, msg);
    2061             : 
    2062           0 :         return (iha_wait(sc, iot, ioh, XF_FIFO_OUT));
    2063             : }
    2064             : 
    2065             : void
    2066           0 : iha_msgout_abort(struct iha_softc *sc, bus_space_tag_t iot,
    2067             :     bus_space_handle_t ioh, u_int8_t aborttype)
    2068             : {
    2069           0 :         iha_set_ssig(iot, ioh, REQ | BSY | SEL, ATN);
    2070             : 
    2071           0 :         switch (iha_wait(sc, iot, ioh, MSG_ACCEPT)) {
    2072             :         case -1:
    2073             :                 break;
    2074             : 
    2075             :         case PHASE_MSG_OUT:
    2076           0 :                 sc->HCS_Flags |= FLAG_EXPECT_DISC;
    2077           0 :                 if (iha_msgout(sc, iot, ioh, aborttype) != -1)
    2078           0 :                         iha_bad_seq(sc);
    2079             :                 break;
    2080             : 
    2081             :         default:
    2082           0 :                 iha_bad_seq(sc);
    2083           0 :                 break;
    2084             :         }
    2085           0 : }
    2086             : 
    2087             : int
    2088           0 : iha_msgout_reject(struct iha_softc *sc, bus_space_tag_t iot,
    2089             :     bus_space_handle_t ioh)
    2090             : {
    2091           0 :         iha_set_ssig(iot, ioh, REQ | BSY | SEL, ATN);
    2092             : 
    2093           0 :         if (iha_wait(sc, iot, ioh, MSG_ACCEPT) == PHASE_MSG_OUT)
    2094           0 :                 return (iha_msgout(sc, iot, ioh, MSG_MESSAGE_REJECT));
    2095             : 
    2096           0 :         return (-1);
    2097           0 : }
    2098             : 
    2099             : int
    2100           0 : iha_msgout_extended(struct iha_softc *sc, bus_space_tag_t iot,
    2101             :     bus_space_handle_t ioh)
    2102             : {
    2103             :         int phase;
    2104             : 
    2105           0 :         bus_space_write_1(iot, ioh, TUL_SFIFO, MSG_EXTENDED);
    2106             : 
    2107           0 :         bus_space_write_multi_1(iot, ioh, TUL_SFIFO, 
    2108             :             sc->HCS_Msg, sc->HCS_Msg[0]+1);
    2109             : 
    2110           0 :         phase = iha_wait(sc, iot, ioh, XF_FIFO_OUT);
    2111             : 
    2112           0 :         bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
    2113           0 :         iha_set_ssig(iot, ioh, REQ | BSY | SEL | ATN, 0);
    2114             : 
    2115           0 :         return (phase);
    2116             : }
    2117             : 
    2118             : int
    2119           0 : iha_msgout_wdtr(struct iha_softc *sc, bus_space_tag_t iot,
    2120             :     bus_space_handle_t ioh)
    2121             : {
    2122           0 :         sc->HCS_ActScb->SCB_Tcs->TCS_Flags |= FLAG_WIDE_DONE;
    2123             : 
    2124           0 :         sc->HCS_Msg[0] = MSG_EXT_WDTR_LEN;
    2125           0 :         sc->HCS_Msg[1] = MSG_EXT_WDTR;
    2126           0 :         sc->HCS_Msg[2] = MSG_EXT_WDTR_BUS_16_BIT;
    2127             : 
    2128           0 :         return (iha_msgout_extended(sc, iot, ioh));
    2129             : }
    2130             : 
    2131             : int
    2132           0 : iha_msgout_sdtr(struct iha_softc *sc, bus_space_tag_t iot,
    2133             :     bus_space_handle_t ioh)
    2134             : {
    2135             :         u_int16_t rateindex;
    2136             :         u_int8_t sync_rate;
    2137             : 
    2138           0 :         rateindex = sc->HCS_ActScb->SCB_Tcs->TCS_Flags & FLAG_SCSI_RATE;
    2139             : 
    2140           0 :         sync_rate = iha_rate_tbl[rateindex];
    2141             : 
    2142           0 :         sc->HCS_Msg[0] = MSG_EXT_SDTR_LEN;
    2143           0 :         sc->HCS_Msg[1] = MSG_EXT_SDTR;
    2144           0 :         sc->HCS_Msg[2] = sync_rate;
    2145           0 :         sc->HCS_Msg[3] = IHA_MAX_TARGETS-1; /* REQ/ACK */
    2146             : 
    2147           0 :         return (iha_msgout_extended(sc, iot, ioh));
    2148             : }
    2149             : 
    2150             : void
    2151           0 : iha_wide_done(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
    2152             : {
    2153           0 :         struct tcs *pTcs = sc->HCS_ActScb->SCB_Tcs;
    2154             : 
    2155           0 :         pTcs->TCS_JS_Period = 0;
    2156             : 
    2157           0 :         if (sc->HCS_Msg[2] != 0)
    2158           0 :                 pTcs->TCS_JS_Period |= PERIOD_WIDE_SCSI;
    2159             : 
    2160           0 :         pTcs->TCS_SConfig0 &= ~ALTPD;
    2161           0 :         pTcs->TCS_Flags         &= ~FLAG_SYNC_DONE;
    2162           0 :         pTcs->TCS_Flags         |=  FLAG_WIDE_DONE;
    2163             : 
    2164           0 :         bus_space_write_1(iot, ioh, TUL_SCONFIG0, pTcs->TCS_SConfig0);
    2165           0 :         bus_space_write_1(iot, ioh, TUL_SYNCM,    pTcs->TCS_JS_Period);
    2166           0 : }
    2167             : 
    2168             : void
    2169           0 : iha_sync_done(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
    2170             : {
    2171           0 :         struct tcs *pTcs = sc->HCS_ActScb->SCB_Tcs;
    2172             :         int i;
    2173             : 
    2174           0 :         if ((pTcs->TCS_Flags & FLAG_SYNC_DONE) == 0) {
    2175           0 :                 if (sc->HCS_Msg[3] != 0) {
    2176           0 :                         pTcs->TCS_JS_Period |= sc->HCS_Msg[3];
    2177             : 
    2178             :                         /* pick the highest possible rate */
    2179           0 :                         for (i = 0; i < sizeof(iha_rate_tbl); i++)
    2180           0 :                                 if (iha_rate_tbl[i] >= sc->HCS_Msg[2])
    2181             :                                         break;
    2182             : 
    2183           0 :                         pTcs->TCS_JS_Period |= (i << 4);
    2184           0 :                         pTcs->TCS_SConfig0  |= ALTPD;
    2185           0 :                 }
    2186             : 
    2187           0 :                 pTcs->TCS_Flags |= FLAG_SYNC_DONE;
    2188             : 
    2189           0 :                 bus_space_write_1(iot, ioh, TUL_SCONFIG0, pTcs->TCS_SConfig0);
    2190           0 :                 bus_space_write_1(iot, ioh, TUL_SYNCM,    pTcs->TCS_JS_Period);
    2191           0 :         }
    2192           0 : }
    2193             : 
    2194             : void
    2195           0 : iha_reset_chip(struct iha_softc *sc, bus_space_tag_t iot,
    2196             :     bus_space_handle_t ioh)
    2197             : {
    2198             :         int i;
    2199             : 
    2200             :         /* reset tulip chip */
    2201             : 
    2202           0 :         bus_space_write_1(iot, ioh, TUL_SCTRL0, RSCSI);
    2203             : 
    2204           0 :         do
    2205           0 :                 sc->HCS_JSInt = bus_space_read_1(iot, ioh, TUL_SISTAT);
    2206           0 :         while((sc->HCS_JSInt & SRSTD) == 0);
    2207             : 
    2208           0 :         iha_set_ssig(iot, ioh, 0, 0);
    2209             : 
    2210             :         /*
    2211             :          * Stall for 2 seconds, wait for target's firmware ready.
    2212             :          */
    2213           0 :         for (i = 0; i < 2000; i++)
    2214           0 :                 DELAY (1000);
    2215             : 
    2216           0 :         bus_space_read_1(iot, ioh, TUL_SISTAT); /* Clear any active interrupt*/
    2217           0 : }
    2218             : 
    2219             : void
    2220           0 : iha_select(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh,
    2221             :     struct iha_scb *pScb, u_int8_t select_type)
    2222             : {
    2223             :         int s;
    2224             : 
    2225           0 :         switch (select_type) {
    2226             :         case SEL_ATN:
    2227           0 :                 bus_space_write_1(iot, ioh, TUL_SFIFO, pScb->SCB_Ident);
    2228           0 :                 bus_space_write_multi_1(iot, ioh, TUL_SFIFO,
    2229             :                     pScb->SCB_CDB, pScb->SCB_CDBLen);
    2230             : 
    2231           0 :                 pScb->SCB_NxtStat = 2;
    2232           0 :                 break;
    2233             : 
    2234             :         case SELATNSTOP:
    2235           0 :                 pScb->SCB_NxtStat = 1;
    2236           0 :                 break;
    2237             : 
    2238             :         case SEL_ATN3:
    2239           0 :                 bus_space_write_1(iot, ioh, TUL_SFIFO, pScb->SCB_Ident);
    2240           0 :                 bus_space_write_1(iot, ioh, TUL_SFIFO, pScb->SCB_TagMsg);
    2241           0 :                 bus_space_write_1(iot, ioh, TUL_SFIFO, pScb->SCB_TagId);
    2242             : 
    2243           0 :                 bus_space_write_multi_1(iot, ioh, TUL_SFIFO, pScb->SCB_CDB,
    2244             :                     pScb->SCB_CDBLen);
    2245             : 
    2246           0 :                 pScb->SCB_NxtStat = 2;
    2247           0 :                 break;
    2248             : 
    2249             :         default:
    2250             : #ifdef IHA_DEBUG_STATE
    2251             :                 sc_print_addr(pScb->SCB_Xs->sc_link);
    2252             :                 printf("[debug] iha_select() - unknown select type = 0x%02x\n",
    2253             :                     select_type);
    2254             : #endif
    2255           0 :                 return;
    2256             :         }
    2257             : 
    2258           0 :         s = splbio();
    2259           0 :         TAILQ_REMOVE(&sc->HCS_PendScb, pScb, SCB_ScbList);
    2260           0 :         splx(s);
    2261             : 
    2262           0 :         pScb->SCB_Status = STATUS_SELECT;
    2263             : 
    2264           0 :         sc->HCS_ActScb = pScb;
    2265             : 
    2266           0 :         bus_space_write_1(iot, ioh, TUL_SCMD, select_type);
    2267           0 : }
    2268             : 
    2269             : /*
    2270             :  * iha_wait - wait for an interrupt to service or a SCSI bus phase change
    2271             :  *            after writing the supplied command to the tulip chip. If 
    2272             :  *            the command is NO_OP, skip the command writing.
    2273             :  */
    2274             : int
    2275           0 : iha_wait(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh,
    2276             :     u_int8_t cmd)
    2277             : {
    2278           0 :         if (cmd != NO_OP)
    2279           0 :                 bus_space_write_1(iot, ioh, TUL_SCMD, cmd);
    2280             : 
    2281             :         /* 
    2282             :          * Have to do this here, in addition to in iha_isr, because
    2283             :          * interrupts might be turned off when we get here.
    2284             :          */
    2285           0 :         do
    2286           0 :                 sc->HCS_JSStatus0 = bus_space_read_1(iot, ioh, TUL_STAT0);
    2287           0 :         while ((sc->HCS_JSStatus0 & INTPD) == 0);
    2288             : 
    2289           0 :         sc->HCS_JSStatus1 = bus_space_read_1(iot, ioh, TUL_STAT1);
    2290           0 :         sc->HCS_JSInt     = bus_space_read_1(iot, ioh, TUL_SISTAT);
    2291             : 
    2292           0 :         sc->HCS_Phase = sc->HCS_JSStatus0 & PH_MASK;
    2293             : 
    2294           0 :         if ((sc->HCS_JSInt & SRSTD) != 0) {
    2295             :                 /* SCSI bus reset interrupt */
    2296           0 :                 iha_reset_scsi_bus(sc);
    2297           0 :                 return (-1);
    2298             :         }
    2299             : 
    2300           0 :         if ((sc->HCS_JSInt & RSELED) != 0)
    2301             :                 /* Reselection interrupt */
    2302           0 :                 return (iha_resel(sc, iot, ioh));
    2303             : 
    2304           0 :         if ((sc->HCS_JSInt & STIMEO) != 0) {
    2305             :                 /* selected/reselected timeout interrupt */
    2306           0 :                 iha_busfree(sc, iot, ioh);
    2307           0 :                 return (-1);
    2308             :         }
    2309             : 
    2310           0 :         if ((sc->HCS_JSInt & DISCD) != 0) {
    2311             :                 /* BUS disconnection interrupt */
    2312           0 :                 if ((sc->HCS_Flags & FLAG_EXPECT_DONE_DISC) != 0) {
    2313           0 :                         bus_space_write_1(iot, ioh, TUL_SCTRL0,   RSFIFO);
    2314           0 :                         bus_space_write_1(iot, ioh, TUL_SCONFIG0,
    2315             :                             SCONFIG0DEFAULT);
    2316           0 :                         bus_space_write_1(iot, ioh, TUL_SCTRL1,   EHRSL);
    2317           0 :                         iha_append_done_scb(sc, sc->HCS_ActScb, HOST_OK);
    2318           0 :                         sc->HCS_Flags &= ~FLAG_EXPECT_DONE_DISC;
    2319             : 
    2320           0 :                 } else if ((sc->HCS_Flags & FLAG_EXPECT_DISC) != 0) {
    2321           0 :                         bus_space_write_1(iot, ioh, TUL_SCTRL0,   RSFIFO);
    2322           0 :                         bus_space_write_1(iot, ioh, TUL_SCONFIG0,
    2323             :                             SCONFIG0DEFAULT);
    2324           0 :                         bus_space_write_1(iot, ioh, TUL_SCTRL1,   EHRSL);
    2325           0 :                         sc->HCS_ActScb = NULL;
    2326           0 :                         sc->HCS_Flags &= ~FLAG_EXPECT_DISC;
    2327             : 
    2328           0 :                 } else
    2329           0 :                         iha_busfree(sc, iot, ioh);
    2330             : 
    2331           0 :                 return (-1);
    2332             :         }
    2333             : 
    2334           0 :         return (sc->HCS_Phase);
    2335           0 : }
    2336             : 
    2337             : /*
    2338             :  * iha_done_scb - We have a scb which has been processed by the
    2339             :  *                adaptor, now we look to see how the operation went.
    2340             :  */
    2341             : void
    2342           0 : iha_done_scb(struct iha_softc *sc, struct iha_scb *pScb)
    2343             : {
    2344             :         struct scsi_sense_data *s1, *s2;
    2345           0 :         struct scsi_xfer *xs = pScb->SCB_Xs;
    2346             : 
    2347           0 :         if (xs != NULL) {
    2348           0 :                 timeout_del(&xs->stimeout);
    2349             : 
    2350           0 :                 xs->status = pScb->SCB_TaStat;
    2351             : 
    2352           0 :                 if ((pScb->SCB_Flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) != 0) {
    2353           0 :                         bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,
    2354             :                                 0, pScb->SCB_BufChars,
    2355             :                                 ((pScb->SCB_Flags & SCSI_DATA_IN) ? 
    2356             :                                         BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
    2357           0 :                         bus_dmamap_unload(sc->sc_dmat, pScb->SCB_DataDma);
    2358           0 :                 }
    2359           0 :                 if ((pScb->SCB_Flags & FLAG_SG) != 0) {
    2360           0 :                         bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma,
    2361             :                                 0, sizeof(pScb->SCB_SGList),
    2362             :                                 BUS_DMASYNC_POSTWRITE);
    2363           0 :                         bus_dmamap_unload(sc->sc_dmat, pScb->SCB_SGDma);
    2364           0 :                 }
    2365             : 
    2366           0 :                 switch (pScb->SCB_HaStat) {
    2367             :                 case HOST_OK:
    2368           0 :                         switch (pScb->SCB_TaStat) {
    2369             :                         case SCSI_OK:
    2370             :                         case SCSI_COND_MET:
    2371             :                         case SCSI_INTERM:
    2372             :                         case SCSI_INTERM_COND_MET:
    2373           0 :                                 xs->resid = pScb->SCB_BufCharsLeft;
    2374           0 :                                 xs->error = XS_NOERROR;
    2375           0 :                                 break;
    2376             : 
    2377             :                         case SCSI_RESV_CONFLICT:
    2378             :                         case SCSI_BUSY:
    2379             :                         case SCSI_QUEUE_FULL:
    2380           0 :                                 xs->error = XS_BUSY;
    2381           0 :                                 break;
    2382             : 
    2383             :                         case SCSI_TERMINATED:
    2384             :                         case SCSI_ACA_ACTIVE:
    2385             :                         case SCSI_CHECK:
    2386           0 :                                 s1 = &pScb->SCB_ScsiSenseData;
    2387           0 :                                 s2 = &xs->sense;
    2388           0 :                                 *s2 = *s1;
    2389             : 
    2390           0 :                                 xs->error = XS_SENSE;
    2391           0 :                                 break;
    2392             : 
    2393             :                         default:
    2394           0 :                                 xs->error = XS_DRIVER_STUFFUP;
    2395           0 :                                 break;
    2396             :                         }
    2397             :                         break;
    2398             : 
    2399             :                 case HOST_SEL_TOUT:
    2400           0 :                         xs->error = XS_SELTIMEOUT;
    2401           0 :                         break;
    2402             : 
    2403             :                 case HOST_SCSI_RST:
    2404             :                 case HOST_DEV_RST:
    2405           0 :                         xs->error = XS_RESET;
    2406           0 :                         break;
    2407             : 
    2408             :                 case HOST_SPERR:
    2409           0 :                         sc_print_addr(xs->sc_link);
    2410           0 :                         printf("SCSI Parity error detected\n");
    2411           0 :                         xs->error = XS_DRIVER_STUFFUP;
    2412           0 :                         break;
    2413             : 
    2414             :                 case HOST_TIMED_OUT:
    2415           0 :                         xs->error = XS_TIMEOUT;
    2416           0 :                         break;
    2417             : 
    2418             :                 case HOST_DO_DU:
    2419             :                 case HOST_BAD_PHAS:
    2420             :                 default:
    2421           0 :                         xs->error = XS_DRIVER_STUFFUP;
    2422           0 :                         break;
    2423             :                 }
    2424           0 :                 scsi_done(xs);
    2425           0 :         }
    2426           0 : }
    2427             : 
    2428             : void
    2429           0 : iha_timeout(void *arg)
    2430             : {
    2431           0 :         struct iha_scb *pScb = (struct iha_scb *)arg;
    2432           0 :         struct scsi_xfer *xs = pScb->SCB_Xs;
    2433             : 
    2434           0 :         if (xs != NULL) {
    2435           0 :                 sc_print_addr(xs->sc_link);
    2436           0 :                 printf("SCSI OpCode 0x%02x timed out\n", xs->cmd->opcode);
    2437           0 :                 iha_abort_xs(xs->sc_link->adapter_softc, xs, HOST_TIMED_OUT);
    2438           0 :         }
    2439           0 : }
    2440             : 
    2441             : void
    2442           0 : iha_exec_scb(struct iha_softc *sc, struct iha_scb *pScb)
    2443             : {
    2444           0 :         struct scsi_xfer *xs = pScb->SCB_Xs;
    2445             :         bus_space_handle_t ioh;
    2446             :         bus_space_tag_t iot;
    2447             :         int s;
    2448             : 
    2449           0 :         s = splbio();
    2450             : 
    2451           0 :         if ((pScb->SCB_Flags & SCSI_POLL) == 0)
    2452           0 :                 timeout_add_msec(&xs->stimeout, xs->timeout);
    2453             : 
    2454           0 :         if (((pScb->SCB_Flags & SCSI_RESET) != 0)
    2455           0 :             || (pScb->SCB_CDB[0] == REQUEST_SENSE))
    2456           0 :                 iha_push_pend_scb(sc, pScb);   /* Insert SCB at head of Pend */
    2457             :         else
    2458           0 :                 iha_append_pend_scb(sc, pScb); /* Append SCB to tail of Pend */
    2459             : 
    2460             :         /*
    2461             :          * Run through iha_main() to ensure something is active, if
    2462             :          * only this new SCB.
    2463             :          */
    2464           0 :         if (sc->HCS_Semaph != SEMAPH_IN_MAIN) {
    2465           0 :                 iot = sc->sc_iot;
    2466           0 :                 ioh = sc->sc_ioh;
    2467             : 
    2468           0 :                 bus_space_write_1(iot, ioh, TUL_IMSK, MASK_ALL);
    2469           0 :                 sc->HCS_Semaph = SEMAPH_IN_MAIN;
    2470             : 
    2471           0 :                 splx(s);
    2472           0 :                 iha_main(sc, iot, ioh);
    2473           0 :                 s = splbio();
    2474             : 
    2475           0 :                 sc->HCS_Semaph = ~SEMAPH_IN_MAIN;
    2476           0 :                 bus_space_write_1(iot, ioh, TUL_IMSK, (MASK_ALL & ~MSCMP));
    2477           0 :         }
    2478             : 
    2479           0 :         splx(s);
    2480           0 : }
    2481             : 
    2482             : 
    2483             : /*
    2484             :  * iha_set_ssig - read the current scsi signal mask, then write a new
    2485             :  *                one which turns off/on the specified signals.
    2486             :  */
    2487             : void
    2488           0 : iha_set_ssig(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t offsigs,
    2489             :     u_int8_t onsigs)
    2490             : {
    2491             :         u_int8_t currsigs;
    2492             : 
    2493           0 :         currsigs = bus_space_read_1(iot, ioh, TUL_SSIGI);
    2494           0 :         bus_space_write_1(iot, ioh, TUL_SSIGO, (currsigs & ~offsigs) | onsigs);
    2495           0 : }
    2496             : 
    2497             : void
    2498           0 : iha_print_info(struct iha_softc *sc, int target)
    2499             : {
    2500           0 :         u_int8_t period = sc->HCS_Tcs[target].TCS_JS_Period;
    2501           0 :         u_int8_t config = sc->HCS_Tcs[target].TCS_SConfig0;
    2502             :         int rate;
    2503             : 
    2504           0 :         printf("%s: target %d using %d bit ", sc->sc_dev.dv_xname, target,
    2505           0 :                 (period & PERIOD_WIDE_SCSI) ? 16 : 8);
    2506             :  
    2507           0 :         if ((period & PERIOD_SYOFS) == 0)
    2508           0 :                 printf("async ");
    2509             :         else {
    2510           0 :                 rate = (period & PERIOD_SYXPD) >> 4;
    2511           0 :                 if ((config & ALTPD) == 0)
    2512           0 :                         rate = 100 + rate * 50;
    2513             :                 else
    2514           0 :                         rate =  50 + rate * 25;
    2515           0 :                 rate = 1000000000 / rate;
    2516           0 :                 printf("%d.%d MHz %d REQ/ACK offset ", rate / 1000000,
    2517           0 :                     (rate % 1000000 + 99999) / 100000, period & PERIOD_SYOFS);
    2518             :         }
    2519             : 
    2520           0 :         printf("xfers\n");
    2521           0 : }
    2522             : 
    2523             : 
    2524             : /*
    2525             :  * iha_alloc_scbs - allocate and map the SCB's for the supplied iha_softc
    2526             :  */
    2527             : int
    2528           0 : iha_alloc_scbs(struct iha_softc *sc)
    2529             : {
    2530           0 :         bus_dma_segment_t seg;
    2531           0 :         int error, rseg;
    2532             : 
    2533             :         /*
    2534             :          * Allocate dma-safe memory for the SCB's
    2535             :          */
    2536           0 :         if ((error = bus_dmamem_alloc(sc->sc_dmat,
    2537             :                  sizeof(struct iha_scb)*IHA_MAX_SCB,
    2538             :                  NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT | BUS_DMA_ZERO))
    2539           0 :             != 0) {
    2540           0 :                 printf("%s: unable to allocate SCBs,"
    2541           0 :                        " error = %d\n", sc->sc_dev.dv_xname, error);
    2542           0 :                 return (error);
    2543             :         }
    2544           0 :         if ((error = bus_dmamem_map(sc->sc_dmat,
    2545             :                  &seg, rseg, sizeof(struct iha_scb)*IHA_MAX_SCB,
    2546             :                  (caddr_t *)&sc->HCS_Scb, BUS_DMA_NOWAIT | BUS_DMA_COHERENT))
    2547           0 :             != 0) {
    2548           0 :                 printf("%s: unable to map SCBs, error = %d\n",
    2549           0 :                        sc->sc_dev.dv_xname, error);
    2550           0 :                 return (error);
    2551             :         }
    2552             : 
    2553           0 :         return (0);
    2554           0 : }
    2555             : 
    2556             : /*
    2557             :  * iha_read_eeprom - read contents of serial EEPROM into iha_nvram pointed at
    2558             :  *                                        by parameter nvram.
    2559             :  */
    2560             : void
    2561           0 : iha_read_eeprom(bus_space_tag_t iot, bus_space_handle_t ioh,
    2562             :     struct iha_nvram *nvram)
    2563             : {
    2564             :         u_int32_t chksum;
    2565             :         u_int16_t *np;
    2566             :         u_int8_t gctrl, addr;
    2567             : 
    2568             :         const int chksum_addr = offsetof(struct iha_nvram, NVM_CheckSum) / 2;
    2569             : 
    2570             :         /* Enable EEProm programming */
    2571           0 :         gctrl = bus_space_read_1(iot, ioh, TUL_GCTRL0) | EEPRG;
    2572           0 :         bus_space_write_1(iot, ioh, TUL_GCTRL0, gctrl);
    2573             : 
    2574             :         /* Read EEProm */
    2575           0 :         np = (u_int16_t *)nvram;
    2576           0 :         for (addr=0, chksum=0; addr < chksum_addr; addr++, np++) {
    2577           0 :                 *np = iha_se2_rd(iot, ioh, addr);
    2578           0 :                 chksum += *np;
    2579             :         }
    2580             : 
    2581           0 :         chksum &= 0x0000ffff;
    2582           0 :         nvram->NVM_CheckSum = iha_se2_rd(iot, ioh, chksum_addr);
    2583             : 
    2584             :         /* Disable EEProm programming */
    2585           0 :         gctrl = bus_space_read_1(iot, ioh, TUL_GCTRL0) & ~EEPRG;
    2586           0 :         bus_space_write_1(iot, ioh, TUL_GCTRL0, gctrl);
    2587             : 
    2588           0 :         if ((nvram->NVM_Signature != SIGNATURE)
    2589           0 :             ||
    2590           0 :             (nvram->NVM_CheckSum  != chksum))
    2591           0 :                 panic("iha: invalid EEPROM,  bad signature or checksum");
    2592           0 : }
    2593             : 
    2594             : /*
    2595             :  * iha_se2_rd - read & return the 16 bit value at the specified
    2596             :  *              offset in the Serial E2PROM
    2597             :  *
    2598             :  */
    2599             : u_int16_t
    2600           0 : iha_se2_rd(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t addr)
    2601             : {
    2602             :         u_int16_t readWord;
    2603             :         u_int8_t bit;
    2604             :         int i;
    2605             : 
    2606             :         /* Send 'READ' instruction == address | READ bit */
    2607           0 :         iha_se2_instr(iot, ioh, (addr | NVREAD));
    2608             : 
    2609             :         readWord = 0;
    2610           0 :         for (i = 15; i >= 0; i--) {
    2611           0 :                 bus_space_write_1(iot, ioh, TUL_NVRAM, NVRCS | NVRCK);
    2612           0 :                 DELAY(5);
    2613             : 
    2614           0 :                 bus_space_write_1(iot, ioh, TUL_NVRAM, NVRCS);
    2615           0 :                 DELAY(5);
    2616             : 
    2617             :                 /* sample data after the following edge of clock     */
    2618           0 :                 bit = bus_space_read_1(iot, ioh, TUL_NVRAM) & NVRDI;
    2619           0 :                 DELAY(5);
    2620             : 
    2621           0 :                 readWord += bit << i;
    2622             :         }
    2623             : 
    2624           0 :         bus_space_write_1(iot, ioh, TUL_NVRAM, 0);
    2625           0 :         DELAY(5);
    2626             : 
    2627           0 :         return (readWord);
    2628             : }
    2629             : 
    2630             : /*
    2631             :  * iha_se2_instr - write an octet to serial E2PROM one bit at a time
    2632             :  */
    2633             : void
    2634           0 : iha_se2_instr(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t instr)
    2635             : {
    2636             :         u_int8_t b;
    2637             :         int i;
    2638             : 
    2639             :         b = NVRCS | NVRDO; /* Write the start bit (== 1) */
    2640             : 
    2641           0 :         bus_space_write_1(iot, ioh, TUL_NVRAM, b);
    2642           0 :         DELAY(5);
    2643           0 :         bus_space_write_1(iot, ioh, TUL_NVRAM, b | NVRCK);
    2644           0 :         DELAY(5);
    2645             : 
    2646           0 :         for (i = 0; i < 8; i++, instr <<= 1) {
    2647           0 :                 if (instr & 0x80)
    2648           0 :                         b = NVRCS | NVRDO; /* Write a 1 bit */
    2649             :                 else
    2650             :                         b = NVRCS;         /* Write a 0 bit */
    2651             : 
    2652           0 :                 bus_space_write_1(iot, ioh, TUL_NVRAM, b);
    2653           0 :                 DELAY(5);
    2654           0 :                 bus_space_write_1(iot, ioh, TUL_NVRAM, b | NVRCK);
    2655           0 :                 DELAY(5);
    2656             :         }
    2657             : 
    2658           0 :         bus_space_write_1(iot, ioh, TUL_NVRAM, NVRCS);
    2659           0 :         DELAY(5);
    2660             : 
    2661             :         return;
    2662           0 : }
    2663             : 
    2664             : /*
    2665             :  * iha_reset_tcs - reset the target control structure pointed
    2666             :  *                 to by pTcs to default values. TCS_Flags
    2667             :  *                 only has the negotiation done bits reset as
    2668             :  *                 the other bits are fixed at initialization.
    2669             :  */
    2670             : void
    2671           0 : iha_reset_tcs(struct tcs *pTcs, u_int8_t config0)
    2672             : {
    2673           0 :         pTcs->TCS_Flags          &= ~(FLAG_SYNC_DONE | FLAG_WIDE_DONE);
    2674           0 :         pTcs->TCS_JS_Period  = 0;
    2675           0 :         pTcs->TCS_SConfig0   = config0;
    2676           0 :         pTcs->TCS_TagCnt     = 0;
    2677           0 :         pTcs->TCS_NonTagScb  = NULL;
    2678           0 : }

Generated by: LCOV version 1.13