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

Cache object: 6cb4eb7dee43a3866dc94d9bdabfed30


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