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


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

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

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

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

Cache object: eeb333513524ff7c0fe07a16ea374cc9


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


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