root/dev/ic/trm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. trm_GetFreeSRB
  2. trm_RewaitSRB
  3. trm_StartWaitingSRB
  4. trm_scsi_cmd
  5. trm_ResetAllDevParam
  6. trm_ResetDevParam
  7. trm_RecoverSRB
  8. trm_reset
  9. trm_timeout
  10. trm_StartSRB
  11. trm_Interrupt
  12. trm_MsgOutPhase0
  13. trm_MsgOutPhase1
  14. trm_CommandPhase1
  15. trm_DataOutPhase0
  16. trm_DataOutPhase1
  17. trm_DataInPhase0
  18. trm_DataInPhase1
  19. trm_DataIO_transfer
  20. trm_StatusPhase0
  21. trm_StatusPhase1
  22. trm_MsgInPhase0
  23. trm_MsgInPhase1
  24. trm_Nop
  25. trm_SetXferParams
  26. trm_Disconnect
  27. trm_Reselect
  28. trm_FinishSRB
  29. trm_ReleaseSRB
  30. trm_GoingSRB_Done
  31. trm_ResetSCSIBus
  32. trm_ScsiRstDetect
  33. trm_RequestSense
  34. trm_EnableMsgOut
  35. trm_linkSRB
  36. trm_minphys
  37. trm_initACB
  38. trm_write_all
  39. trm_set_data
  40. trm_read_all
  41. trm_get_data
  42. trm_wait_30us
  43. trm_write_cmd
  44. trm_check_eeprom
  45. trm_initAdapter
  46. trm_init
  47. trm_print_info

    1 /*      $OpenBSD: trm.c,v 1.7 2005/12/03 16:53:16 krw Exp $
    2  * ------------------------------------------------------------
    3  *   O.S       : OpenBSD
    4  *   File Name : trm.c
    5  *   Device Driver for Tekram DC395U/UW/F,DC315/U
    6  *   PCI SCSI Bus Master Host Adapter
    7  *   (SCSI chip set used Tekram ASIC TRM-S1040)
    8  *
    9  * (C)Copyright 1995-1999 Tekram Technology Co., Ltd.
   10  * (C)Copyright 2001-2002 Ashley R. Martens and Kenneth R Westerback
   11  * ------------------------------------------------------------
   12  *    HISTORY:                    
   13  *                        
   14  *  REV#   DATE      NAME                  DESCRIPTION
   15  *  1.00   05/01/99  ERICH CHEN            First released for NetBSD 1.4.x
   16  *  1.01   00/00/00  MARTIN AKESSON        Port to OpenBSD 2.8
   17  *  1.02   09/19/01  ASHLEY MARTENS        Cleanup and formatting
   18  *  2.00   01/00/02  KENNETH R WESTERBACK  Rewrite of the bus and code logic
   19  * ------------------------------------------------------------
   20  *
   21  * Redistribution and use in source and binary forms, with or without
   22  * modification, are permitted provided that the following conditions
   23  * are met:
   24  * 1. Redistributions of source code must retain the above copyright
   25  *    notice, this list of conditions and the following disclaimer.
   26  * 2. Redistributions in binary form must reproduce the above copyright
   27  *    notice, this list of conditions and the following disclaimer in the
   28  *    documentation and/or other materials provided with the distribution.
   29  * 3. The name of the author may not be used to endorse or promote products
   30  *    derived from this software without specific prior written permission.
   31  *
   32  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   33  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   34  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   35  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   36  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   37  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   38  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   39  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   40  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   41  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   42  *
   43  * ------------------------------------------------------------
   44  */
   45 
   46 #include <sys/param.h>
   47 #include <sys/systm.h>
   48 #include <sys/kernel.h>
   49 #include <sys/malloc.h>
   50 #include <sys/buf.h>
   51 #include <sys/device.h>
   52 
   53 #include <machine/bus.h>
   54 
   55 #include <scsi/scsi_all.h>
   56 #include <scsi/scsiconf.h>
   57 #include <scsi/scsi_message.h>
   58 
   59 #include <dev/pci/pcidevs.h>
   60 #include <dev/ic/trm.h>
   61 
   62 /* #define TRM_DEBUG0 */
   63 
   64 void    trm_minphys(struct buf *);
   65 
   66 void    trm_initSRB(struct trm_scsi_req_q *);
   67 
   68 void    trm_check_eeprom(struct trm_adapter_nvram *, bus_space_tag_t, bus_space_handle_t);
   69 void    trm_read_all    (struct trm_adapter_nvram *, bus_space_tag_t, bus_space_handle_t);
   70 void    trm_write_all   (struct trm_adapter_nvram *, bus_space_tag_t, bus_space_handle_t);
   71 
   72 void    trm_set_data (bus_space_tag_t, bus_space_handle_t, u_int8_t, u_int8_t);
   73 void    trm_write_cmd(bus_space_tag_t, bus_space_handle_t, u_int8_t, u_int8_t);
   74 
   75 u_int8_t trm_get_data(bus_space_tag_t, bus_space_handle_t, u_int8_t);
   76 
   77 void    trm_wait_30us(bus_space_tag_t, bus_space_handle_t);
   78 
   79 int     trm_scsi_cmd(struct scsi_xfer *);
   80 
   81 struct trm_scsi_req_q *trm_GetFreeSRB(struct trm_softc *);
   82 
   83 void    trm_DataOutPhase0(struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
   84 void    trm_DataInPhase0 (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
   85 void    trm_StatusPhase0 (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
   86 void    trm_MsgOutPhase0 (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
   87 void    trm_MsgInPhase0  (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
   88 void    trm_DataOutPhase1(struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
   89 void    trm_DataInPhase1 (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
   90 void    trm_CommandPhase1(struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
   91 void    trm_StatusPhase1 (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
   92 void    trm_MsgOutPhase1 (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
   93 void    trm_MsgInPhase1  (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
   94 void    trm_Nop          (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
   95 
   96 void    trm_SetXferParams  (struct trm_softc *, struct trm_dcb *, int);
   97 
   98 void    trm_DataIO_transfer(struct trm_softc *, struct trm_scsi_req_q *, u_int16_t);
   99 
  100 int     trm_StartSRB    (struct trm_softc *, struct trm_scsi_req_q *);
  101 void    trm_ReleaseSRB  (struct trm_softc *, struct trm_scsi_req_q *);
  102 void    trm_RewaitSRB   (struct trm_softc *, struct trm_scsi_req_q *);
  103 void    trm_FinishSRB   (struct trm_softc *, struct trm_scsi_req_q *);
  104 void    trm_RequestSense(struct trm_softc *, struct trm_scsi_req_q *);
  105 
  106 void    trm_initAdapter     (struct trm_softc *);
  107 void    trm_Disconnect      (struct trm_softc *);
  108 void    trm_Reselect        (struct trm_softc *);
  109 void    trm_GoingSRB_Done   (struct trm_softc *);
  110 void    trm_ScsiRstDetect   (struct trm_softc *);
  111 void    trm_ResetSCSIBus    (struct trm_softc *);
  112 void    trm_reset           (struct trm_softc *);
  113 void    trm_StartWaitingSRB (struct trm_softc *);
  114 void    trm_ResetAllDevParam(struct trm_softc *);
  115 void    trm_RecoverSRB      (struct trm_softc *);
  116 void    trm_linkSRB         (struct trm_softc *);
  117 
  118 void    trm_initACB(struct trm_softc *, int);
  119 
  120 void    trm_ResetDevParam(struct trm_softc *, struct trm_dcb *, u_int8_t);
  121 
  122 void    trm_EnableMsgOut(struct trm_softc *, u_int8_t);
  123 
  124 void    trm_timeout(void *);
  125 
  126 void    trm_print_info(struct trm_softc *, struct trm_dcb *);
  127 
  128 /*
  129  * Define structures
  130  */
  131 struct  cfdriver trm_cd = {
  132         NULL, "trm", DV_DULL
  133 };
  134 
  135 struct scsi_adapter trm_switch = {
  136         trm_scsi_cmd,
  137         trm_minphys,
  138         NULL,
  139         NULL
  140 };
  141 
  142 static struct scsi_device trm_device = {
  143         NULL,            /* Use default error handler */
  144         NULL,            /* have a queue, served by this */
  145         NULL,            /* have no async handler */
  146         NULL,            /* Use default 'done' routine */
  147 };
  148 
  149 /* 
  150  * ------------------------------------------------------------
  151  *
  152  *          stateV = (void *) trm_SCSI_phase0[phase]
  153  *
  154  * ------------------------------------------------------------
  155  */
  156 static void *trm_SCSI_phase0[8] = {
  157         trm_DataOutPhase0,    /* phase:0 */
  158         trm_DataInPhase0,     /* phase:1 */
  159         trm_Nop,              /* phase:2 */
  160         trm_StatusPhase0,     /* phase:3 */
  161         trm_Nop,              /* phase:4 */
  162         trm_Nop,              /* phase:5 */
  163         trm_MsgOutPhase0,     /* phase:6 */
  164         trm_MsgInPhase0,      /* phase:7 */
  165 };
  166 
  167 /*
  168  * ------------------------------------------------------------
  169  *
  170  *          stateV = (void *) trm_SCSI_phase1[phase]
  171  *
  172  * ------------------------------------------------------------
  173  */
  174 static void *trm_SCSI_phase1[8] = {
  175         trm_DataOutPhase1,    /* phase:0 */
  176         trm_DataInPhase1,     /* phase:1 */
  177         trm_CommandPhase1,    /* phase:2 */
  178         trm_StatusPhase1,     /* phase:3 */
  179         trm_Nop,              /* phase:4 */
  180         trm_Nop,              /* phase:5 */
  181         trm_MsgOutPhase1,     /* phase:6 */
  182         trm_MsgInPhase1,      /* phase:7 */
  183 };
  184 
  185 
  186 struct trm_adapter_nvram trm_eepromBuf[TRM_MAX_ADAPTER_NUM];
  187 /*
  188  *Fast20:  000     50ns, 20.0 Mbytes/s
  189  *         001     75ns, 13.3 Mbytes/s
  190  *         010    100ns, 10.0 Mbytes/s
  191  *         011    125ns,  8.0 Mbytes/s
  192  *         100    150ns,  6.6 Mbytes/s
  193  *         101    175ns,  5.7 Mbytes/s
  194  *         110    200ns,  5.0 Mbytes/s
  195  *         111    250ns,  4.0 Mbytes/s
  196  *
  197  *Fast40:  000     25ns, 40.0 Mbytes/s
  198  *         001     50ns, 20.0 Mbytes/s
  199  *         010     75ns, 13.3 Mbytes/s
  200  *         011    100ns, 10.0 Mbytes/s
  201  *         100    125ns,  8.0 Mbytes/s
  202  *         101    150ns,  6.6 Mbytes/s
  203  *         110    175ns,  5.7 Mbytes/s
  204  *         111    200ns,  5.0 Mbytes/s
  205  */
  206 
  207 /*
  208  * real period:
  209  */
  210 u_int8_t trm_clock_period[8] = {
  211         /* nanosecond divided by 4 */
  212         12,     /*  48 ns 20   MB/sec */
  213         18,     /*  72 ns 13.3 MB/sec */
  214         25,     /* 100 ns 10.0 MB/sec */
  215         31,     /* 124 ns  8.0 MB/sec */
  216         37,     /* 148 ns  6.6 MB/sec */
  217         43,     /* 172 ns  5.7 MB/sec */
  218         50,     /* 200 ns  5.0 MB/sec */
  219         62      /* 248 ns  4.0 MB/sec */
  220 };
  221 
  222 /*
  223  * ------------------------------------------------------------
  224  * Function : trm_GetFreeSRB
  225  * Purpose  : Get the first free SRB
  226  * Inputs   : 
  227  * Return   : NULL or a free SCSI Request block
  228  * ------------------------------------------------------------
  229  */
  230 struct trm_scsi_req_q *
  231 trm_GetFreeSRB(struct trm_softc *sc)
  232 {
  233         struct trm_scsi_req_q *pSRB;
  234 
  235         /* ASSUME we are called from inside a splbio()/splx() region */
  236 
  237         pSRB = TAILQ_FIRST(&sc->freeSRB);
  238 
  239         if (pSRB != NULL)
  240                 TAILQ_REMOVE(&sc->freeSRB, pSRB, link);
  241 
  242 #ifdef TRM_DEBUG0
  243         printf("%s: trm_GetFreeSRB. pSRB = %p, next pSRB = %p\n",
  244             sc->sc_device.dv_xname, pSRB, TAILQ_FIRST(&sc->freeSRB));
  245 #endif
  246 
  247         return pSRB;
  248 }
  249 
  250 /*
  251  * ------------------------------------------------------------
  252  * Function : trm_RewaitSRB
  253  * Purpose  : Q back to pending Q
  254  * Inputs   : struct trm_dcb * - 
  255  *            struct trm_scsi_req_q * - 
  256  * ------------------------------------------------------------
  257  */
  258 void
  259 trm_RewaitSRB(struct trm_softc *sc, struct trm_scsi_req_q *pSRB)
  260 {
  261         int intflag;
  262 
  263         intflag = splbio();
  264 
  265         if ((pSRB->SRBFlag & TRM_ON_WAITING_SRB) != 0) {
  266                 pSRB->SRBFlag &= ~TRM_ON_WAITING_SRB;
  267                 TAILQ_REMOVE(&sc->waitingSRB, pSRB, link);
  268         }
  269 
  270         if ((pSRB->SRBFlag & TRM_ON_GOING_SRB) != 0) {
  271                 pSRB->SRBFlag &= ~TRM_ON_GOING_SRB;
  272                 TAILQ_REMOVE(&sc->goingSRB, pSRB, link);
  273         }
  274 
  275         pSRB->SRBState     = TRM_READY;
  276         pSRB->TargetStatus = SCSI_OK;
  277         pSRB->AdaptStatus  = TRM_STATUS_GOOD; 
  278 
  279         pSRB->SRBFlag |= TRM_ON_WAITING_SRB;
  280         TAILQ_INSERT_HEAD(&sc->waitingSRB, pSRB, link);
  281 
  282         splx(intflag);
  283 }
  284 
  285 /*
  286  * ------------------------------------------------------------
  287  * Function : trm_StartWaitingSRB
  288  * Purpose  : If there is no active DCB then run robin through
  289  *            the DCB's to find the next waiting SRB
  290  *            and move it to the going list.
  291  * Inputs   : struct trm_softc * - 
  292  * ------------------------------------------------------------
  293  */
  294 void
  295 trm_StartWaitingSRB(struct trm_softc *sc)
  296 {
  297         struct trm_scsi_req_q *pSRB, *next;
  298         int intflag;
  299 
  300         intflag = splbio();
  301 
  302         if ((sc->pActiveDCB != NULL) ||
  303             (TAILQ_EMPTY(&sc->waitingSRB)) ||
  304             (sc->sc_Flag & (RESET_DETECT | RESET_DONE | RESET_DEV)) != 0)
  305                 return;
  306 
  307         for (pSRB = TAILQ_FIRST(&sc->waitingSRB); pSRB != NULL; pSRB = next) {
  308                 next = TAILQ_NEXT(pSRB, link);
  309                 if (trm_StartSRB(sc, pSRB) == 0) {
  310                         pSRB->SRBFlag &= ~TRM_ON_WAITING_SRB;
  311                         TAILQ_REMOVE(&sc->waitingSRB, pSRB, link);
  312                         pSRB->SRBFlag |= TRM_ON_GOING_SRB;
  313                         TAILQ_INSERT_TAIL(&sc->goingSRB, pSRB, link);
  314                         break;
  315                 }
  316         }
  317 
  318         splx(intflag);
  319 }
  320 
  321 /*
  322  * ------------------------------------------------------------
  323  * Function : trm_scsi_cmd
  324  * Purpose  : enqueues a SCSI command
  325  * Inputs   :
  326  * Call By  : GENERIC SCSI driver
  327  * ------------------------------------------------------------
  328  */
  329 int
  330 trm_scsi_cmd(struct scsi_xfer *xs) 
  331 {
  332         struct trm_scsi_req_q *pSRB;
  333         bus_space_handle_t ioh;
  334         struct trm_softc *sc;
  335         bus_space_tag_t iot;
  336         struct trm_dcb *pDCB;
  337         u_int8_t target, lun;
  338         int i, error, intflag, xferflags;
  339 
  340         target = xs->sc_link->target;
  341         lun    = xs->sc_link->lun;
  342 
  343         sc  = (struct trm_softc *)xs->sc_link->adapter_softc;
  344         ioh = sc->sc_iohandle;
  345         iot = sc->sc_iotag;
  346 
  347 #ifdef TRM_DEBUG0
  348         if ((xs->flags & SCSI_POLL) != 0)
  349         printf("%s: trm_scsi_cmd. sc = %p, xs = %p, targ/lun = %d/%d opcode = 0x%02x\n",
  350             sc->sc_device.dv_xname, sc, xs, target, lun, xs->cmd->opcode);
  351 #endif
  352 
  353         if (target >= TRM_MAX_TARGETS) {
  354                 printf("%s: target=%d >= %d\n",
  355                     sc->sc_device.dv_xname, target, TRM_MAX_TARGETS);
  356                 xs->error = XS_DRIVER_STUFFUP;
  357                 return COMPLETE;
  358         }
  359         if (lun >= TRM_MAX_LUNS) {
  360                 printf("%s: lun=%d >= %d\n",
  361                     sc->sc_device.dv_xname, lun, TRM_MAX_LUNS);
  362                 xs->error = XS_DRIVER_STUFFUP;
  363                 return COMPLETE;
  364         }
  365 
  366         pDCB = sc->pDCB[target][lun];
  367         if (pDCB == NULL) {
  368                 /* Removed as a result of INQUIRY proving no device present */
  369                 xs->error = XS_DRIVER_STUFFUP;
  370                 return COMPLETE;
  371         }
  372  
  373         xferflags = xs->flags;
  374         if (xferflags & SCSI_RESET) {
  375 #ifdef TRM_DEBUG0
  376                 printf("%s: trm_reset\n", sc->sc_device.dv_xname);
  377 #endif
  378                 trm_reset(sc);
  379                 xs->error = XS_NOERROR;
  380                 return COMPLETE;
  381         }
  382 
  383         if (xferflags & ITSDONE) {
  384 #ifdef TRM_DEBUG0
  385                 printf("%s: Is it done?\n", sc->sc_device.dv_xname);
  386 #endif
  387                 xs->flags &= ~ITSDONE;
  388         }
  389 
  390         xs->error  = XS_NOERROR;
  391         xs->status = SCSI_OK;
  392         xs->resid  = 0;
  393 
  394         intflag = splbio();
  395 
  396         pSRB = trm_GetFreeSRB(sc);
  397 
  398         if (pSRB == NULL) {
  399                 splx(intflag);
  400                 return TRY_AGAIN_LATER;
  401         }
  402 
  403         /* 
  404          * BuildSRB(pSRB,pDCB);
  405          */
  406         if (xs->datalen != 0) {
  407 #ifdef TRM_DEBUG0
  408                 printf("%s: xs->datalen=%x\n", sc->sc_device.dv_xname,
  409                     (u_int32_t)xs->datalen);
  410                 printf("%s: sc->sc_dmatag=0x%x\n", sc->sc_device.dv_xname,
  411                     (u_int32_t)sc->sc_dmatag);
  412                 printf("%s: pSRB->dmamapxfer=0x%x\n", sc->sc_device.dv_xname,
  413                     (u_int32_t)pSRB->dmamapxfer);
  414                 printf("%s: xs->data=0x%x\n", sc->sc_device.dv_xname,
  415                     (u_int32_t)xs->data);
  416 #endif
  417                 if ((error = bus_dmamap_load(sc->sc_dmatag, pSRB->dmamapxfer,
  418                     xs->data, xs->datalen, NULL,
  419                     (xferflags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
  420                     BUS_DMA_WAITOK)) != 0) {
  421                         printf("%s: DMA transfer map unable to load, error = %d\n"
  422                             , sc->sc_device.dv_xname, error);
  423                         xs->error = XS_DRIVER_STUFFUP;
  424                         /*
  425                          * free SRB
  426                          */
  427                         TAILQ_INSERT_HEAD(&sc->freeSRB, pSRB, link);
  428                         splx(intflag);
  429                         return COMPLETE;
  430                 }
  431 
  432                 bus_dmamap_sync(sc->sc_dmatag, pSRB->dmamapxfer,
  433                     0, pSRB->dmamapxfer->dm_mapsize,
  434                     (xferflags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
  435 
  436                 /*
  437                  * Set up the scatter gather list
  438                  */
  439                 for (i = 0; i < pSRB->dmamapxfer->dm_nsegs; i++) {
  440                         pSRB->SegmentX[i].address = pSRB->dmamapxfer->dm_segs[i].ds_addr;
  441                         pSRB->SegmentX[i].length  = pSRB->dmamapxfer->dm_segs[i].ds_len;
  442                 }
  443                 pSRB->SRBTotalXferLength = xs->datalen;
  444                 pSRB->SRBSGCount         = pSRB->dmamapxfer->dm_nsegs;
  445         }
  446 
  447         pSRB->pSRBDCB    = pDCB;
  448         pSRB->xs         = xs;
  449         pSRB->ScsiCmdLen = xs->cmdlen;
  450 
  451         memcpy(pSRB->CmdBlock, xs->cmd, xs->cmdlen);
  452 
  453         splx (intflag);
  454 
  455         timeout_set(&xs->stimeout, trm_timeout, pSRB);
  456 
  457         intflag = splbio();
  458 
  459         pSRB->SRBFlag |= TRM_ON_WAITING_SRB;
  460         TAILQ_INSERT_TAIL(&sc->waitingSRB, pSRB, link);
  461         trm_StartWaitingSRB(sc);
  462 
  463         if ((xferflags & SCSI_POLL) == 0) {
  464                 timeout_add(&xs->stimeout, (xs->timeout * hz) / 1000);
  465                 splx(intflag);
  466                 return SUCCESSFULLY_QUEUED;
  467         }
  468 
  469         while ((--xs->timeout > 0) && ((xs->flags & ITSDONE) == 0)) {
  470                 trm_Interrupt(sc);
  471                 DELAY(1000);
  472         }
  473 
  474         if (xs->timeout == 0)
  475                 trm_timeout(pSRB);
  476 
  477         splx(intflag);
  478         return COMPLETE;
  479 }
  480 
  481 /*
  482  * ------------------------------------------------------------
  483  * Function : trm_ResetAllDevParam
  484  * Purpose  :
  485  * Inputs   : struct trm_softc * 
  486  * ------------------------------------------------------------
  487  */
  488 void
  489 trm_ResetAllDevParam(struct trm_softc *sc)
  490 {
  491         struct trm_adapter_nvram *pEEpromBuf;
  492         int target, quirks;
  493 
  494         pEEpromBuf = &trm_eepromBuf[sc->sc_AdapterUnit];
  495 
  496         for (target = 0; target < TRM_MAX_TARGETS; target++) {
  497                 if (target == sc->sc_AdaptSCSIID)
  498                         continue;
  499 
  500                 if ((sc->pDCB[target][0]->DCBFlag & TRM_QUIRKS_VALID) == 0)
  501                         quirks = SDEV_NOWIDE | SDEV_NOSYNC | SDEV_NOTAGS;
  502                 else
  503                         quirks = sc->pDCB[target][0]->sc_link->quirks;
  504 
  505                 trm_ResetDevParam(sc, sc->pDCB[target][0], quirks);
  506         }
  507 }
  508 
  509 /*
  510  * ------------------------------------------------------------
  511  * Function : trm_ResetDevParam
  512  * Purpose  :
  513  * Inputs   : 
  514  * ------------------------------------------------------------
  515  */
  516 void
  517 trm_ResetDevParam(struct trm_softc *sc, struct trm_dcb *pDCB, u_int8_t quirks)
  518 {
  519         struct trm_adapter_nvram *pEEpromBuf = &trm_eepromBuf[sc->sc_AdapterUnit];
  520         u_int8_t PeriodIndex;
  521         const int target = pDCB->target;
  522 
  523         pDCB->DCBFlag &= TRM_QUIRKS_VALID;
  524         pDCB->DCBFlag |= (TRM_WIDE_NEGO_ENABLE | TRM_SYNC_NEGO_ENABLE);
  525 
  526         pDCB->SyncPeriod    = 0;
  527         pDCB->SyncOffset    = 0;
  528         pDCB->MaxNegoPeriod = 0;
  529 
  530         pDCB->DevMode = pEEpromBuf->NvramTarget[target].NvmTarCfg0;
  531         
  532         pDCB->IdentifyMsg = MSG_IDENTIFY(pDCB->lun, ((pDCB->DevMode & TRM_DISCONNECT) != 0));
  533         
  534         if (((quirks & SDEV_NOWIDE) == 0) &&
  535             (pDCB->DevMode & TRM_WIDE) &&
  536             ((sc->sc_config & HCC_WIDE_CARD) != 0))
  537                 pDCB->DCBFlag |= TRM_WIDE_NEGO_16BIT;
  538         
  539         if (((quirks & SDEV_NOSYNC) == 0) &&
  540             ((pDCB->DevMode & TRM_SYNC) != 0)) {
  541                 PeriodIndex   = pEEpromBuf->NvramTarget[target].NvmTarPeriod & 0x07;
  542                 pDCB->MaxNegoPeriod = trm_clock_period[PeriodIndex];
  543         }
  544 
  545         if (((quirks & SDEV_NOTAGS) == 0) &&
  546             ((pDCB->DevMode & TRM_TAG_QUEUING) != 0) &&
  547             ((pDCB->DevMode & TRM_DISCONNECT) != 0))
  548                 /* TODO XXXX: Every device(lun) gets to queue TagMaxNum commands? */
  549                 pDCB->DCBFlag |= TRM_USE_TAG_QUEUING;
  550 
  551         trm_SetXferParams(sc, pDCB, 0);
  552 }
  553 
  554 /*
  555  * ------------------------------------------------------------
  556  * Function : trm_RecoverSRB
  557  * Purpose  : Moves all SRBs from Going to Waiting for all the Link DCBs
  558  * Inputs   : struct trm_softc * - 
  559  * ------------------------------------------------------------
  560  */
  561 void
  562 trm_RecoverSRB(struct trm_softc *sc)
  563 {
  564         struct trm_scsi_req_q *pSRB;
  565 
  566         /* ASSUME we are inside splbio()/splx() */
  567 
  568         while ((pSRB = TAILQ_FIRST(&sc->goingSRB)) != NULL) {
  569                 pSRB->SRBFlag &= ~TRM_ON_GOING_SRB;
  570                 TAILQ_REMOVE(&sc->goingSRB, pSRB, link);
  571                 pSRB->SRBFlag |= TRM_ON_WAITING_SRB;
  572                 TAILQ_INSERT_HEAD(&sc->waitingSRB, pSRB, link);
  573         }
  574 }
  575 
  576 /*
  577  * ------------------------------------------------------------
  578  * Function : trm_reset
  579  * Purpose  : perform a hard reset on the SCSI bus (and TRM_S1040 chip).
  580  * Inputs   : 
  581  * ------------------------------------------------------------
  582  */
  583 void
  584 trm_reset (struct trm_softc *sc)
  585 {
  586         const bus_space_handle_t ioh = sc->sc_iohandle;
  587         const bus_space_tag_t iot = sc->sc_iotag;
  588         int i, intflag;
  589 
  590 #ifdef TRM_DEBUG0
  591         printf("%s: trm_reset", sc->sc_device.dv_xname);
  592 #endif
  593 
  594         intflag = splbio();
  595 
  596         bus_space_write_1(iot, ioh, TRM_S1040_DMA_INTEN,  0);
  597         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_INTEN, 0);
  598 
  599         trm_ResetSCSIBus(sc);
  600         for (i = 0; i < 500; i++)
  601                 DELAY(1000);
  602 
  603         /*
  604          * Enable all SCSI interrupts except EN_SCAM
  605          */
  606         bus_space_write_1(iot, ioh,
  607             TRM_S1040_SCSI_INTEN,
  608             (EN_SELECT | EN_SELTIMEOUT | EN_DISCONNECT | EN_RESELECTED |
  609                 EN_SCSIRESET | EN_BUSSERVICE | EN_CMDDONE)); 
  610         /*
  611          * Enable DMA interrupt
  612          */
  613         bus_space_write_1(iot, ioh, TRM_S1040_DMA_INTEN, EN_SCSIINTR);
  614         /*
  615          * Clear DMA FIFO
  616          */
  617         bus_space_write_1(iot, ioh, TRM_S1040_DMA_CONTROL, CLRXFIFO);
  618         /*
  619          * Clear SCSI FIFO
  620          */
  621         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_CLRFIFO);
  622 
  623         trm_ResetAllDevParam(sc);
  624         trm_GoingSRB_Done(sc);
  625         sc->pActiveDCB = NULL;
  626 
  627         /*
  628          * RESET_DETECT, RESET_DONE, RESET_DEV
  629          */
  630         sc->sc_Flag = 0;
  631         trm_StartWaitingSRB(sc);
  632 
  633         splx(intflag);
  634 }
  635 
  636 /*
  637  * ------------------------------------------------------------
  638  * Function : trm_timeout
  639  * Purpose  : Prints a timeout message and aborts the timed out SCSI request
  640  * Inputs   : void * - A struct trm_scsi_req_q * structure pointer
  641  * ------------------------------------------------------------
  642  */
  643 void
  644 trm_timeout(void *arg1)
  645 {
  646         struct trm_scsi_req_q *pSRB;
  647         struct scsi_xfer *xs;
  648         struct trm_softc *sc;
  649  
  650         pSRB = (struct trm_scsi_req_q *)arg1;
  651         xs   = pSRB->xs;
  652 
  653         if (xs != NULL) {
  654                 sc = xs->sc_link->adapter_softc;
  655                 sc_print_addr(xs->sc_link);
  656                 printf("%s: SCSI OpCode 0x%02x for target %d lun %d timed out\n",
  657                     sc->sc_device.dv_xname, xs->cmd->opcode,
  658                     xs->sc_link->target, xs->sc_link->lun);
  659                 pSRB->SRBFlag |= TRM_SCSI_TIMED_OUT;
  660                 trm_FinishSRB(sc, pSRB);
  661                 trm_StartWaitingSRB(sc);
  662         }
  663 #ifdef TRM_DEBUG0
  664         else
  665                 printf("%s: trm_timeout called with xs == NULL\n",
  666                     sc->sc_device.dv_xname);
  667 #endif
  668 }
  669 
  670 /*
  671  * ------------------------------------------------------------
  672  * Function : trm_StartSRB
  673  * Purpose  : Send the commands in the SRB to the device
  674  * Inputs   : struct trm_softc * -
  675  *            struct trm_scsi_req_q * - 
  676  * Return   : 0 - SCSI processor is unoccupied
  677  *            1 - SCSI processor is occupied with an SRB
  678  * ------------------------------------------------------------
  679  */
  680 int
  681 trm_StartSRB(struct trm_softc *sc, struct trm_scsi_req_q *pSRB)
  682 {
  683         const bus_space_handle_t ioh = sc->sc_iohandle;
  684         const bus_space_tag_t iot = sc->sc_iotag;
  685         struct trm_dcb *pDCB = pSRB->pSRBDCB;
  686         u_int32_t tag_mask;
  687         u_int8_t tag_id, scsicommand;
  688 
  689 #ifdef TRM_DEBUG0
  690         printf("%s: trm_StartSRB. sc = %p, pDCB = %p, pSRB = %p\n",
  691             sc->sc_device.dv_xname, sc, pDCB, pSRB);
  692 #endif
  693         /* 
  694          * If the queue is full or the SCSI processor has a pending interrupt
  695          * then try again later.
  696          */
  697         if ((pDCB->DCBFlag & TRM_QUEUE_FULL) || (bus_space_read_2(iot, ioh,
  698             TRM_S1040_SCSI_STATUS) & SCSIINTERRUPT)) 
  699                 return (1);
  700 
  701         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_HOSTID, sc->sc_AdaptSCSIID);
  702         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_TARGETID, pDCB->target);
  703         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_SYNC, pDCB->SyncPeriod);
  704         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_OFFSET, pDCB->SyncOffset);
  705 
  706         if ((sc->pDCB[pDCB->target][0]->sc_link != NULL) &&
  707             ((sc->pDCB[pDCB->target][0]->DCBFlag & TRM_QUIRKS_VALID) == 0)) {
  708                 sc->pDCB[pDCB->target][0]->DCBFlag |= TRM_QUIRKS_VALID;
  709                 trm_ResetDevParam(sc, sc->pDCB[pDCB->target][0], sc->pDCB[pDCB->target][0]->sc_link->quirks);
  710         }
  711 
  712         /*
  713          * Flush FIFO
  714          */
  715         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_CLRFIFO);
  716 
  717         sc->MsgCnt = 1;
  718         sc->MsgBuf[0] = pDCB->IdentifyMsg;
  719         if (((pSRB->xs->flags & SCSI_POLL) != 0) ||
  720             (pSRB->CmdBlock[0] == INQUIRY) ||
  721             (pSRB->CmdBlock[0] == REQUEST_SENSE))
  722                 sc->MsgBuf[0] &= ~MSG_IDENTIFY_DISCFLAG;
  723 
  724         scsicommand = SCMD_SEL_ATN;
  725 
  726         if ((pDCB->DCBFlag & (TRM_WIDE_NEGO_ENABLE | TRM_SYNC_NEGO_ENABLE)) != 0) {
  727                 scsicommand = SCMD_SEL_ATNSTOP;
  728                 pSRB->SRBState = TRM_MSGOUT;
  729 
  730         } else if ((pDCB->DCBFlag & TRM_USE_TAG_QUEUING) == 0) {
  731                 pDCB->DCBFlag |= TRM_QUEUE_FULL;                        
  732 
  733         } else if ((sc->MsgBuf[0] & MSG_IDENTIFY_DISCFLAG) != 0) {
  734                 if (pSRB->TagNumber == TRM_NO_TAG) {
  735                         for (tag_id=1, tag_mask=2; tag_id < 32; tag_id++, tag_mask <<= 1)
  736                                 if ((tag_mask & pDCB->TagMask) == 0) {
  737                                         pDCB->TagMask  |= tag_mask;
  738                                         pSRB->TagNumber = tag_id;
  739                                         break;
  740                                 }
  741 
  742                         if (tag_id >= 32) {
  743                                 pDCB->DCBFlag |= TRM_QUEUE_FULL;
  744                                 sc->MsgCnt = 0;
  745                                 return 1;
  746                         }
  747                 }
  748 
  749                 /* TODO XXXX: Should send ORDERED_Q_TAG if metadata (non-block) i/o!? */
  750                 sc->MsgBuf[sc->MsgCnt++] = MSG_SIMPLE_Q_TAG;
  751                 sc->MsgBuf[sc->MsgCnt++] = pSRB->TagNumber;
  752                 
  753                 scsicommand = SCMD_SEL_ATN3;
  754         }
  755 
  756         pSRB->SRBState = TRM_START;
  757         pSRB->ScsiPhase = PH_BUS_FREE; /* SCSI bus free Phase */
  758         sc->pActiveDCB = pDCB;
  759         pDCB->pActiveSRB = pSRB;
  760 
  761         if (sc->MsgCnt > 0) {
  762                 bus_space_write_1(iot, ioh, TRM_S1040_SCSI_FIFO, sc->MsgBuf[0]);
  763                 if (sc->MsgCnt > 1) {
  764                         DELAY(30);
  765                         bus_space_write_multi_1(iot, ioh, TRM_S1040_SCSI_FIFO, &sc->MsgBuf[1], sc->MsgCnt - 1);
  766                 }
  767                 sc->MsgCnt = 0;
  768         }
  769 
  770         /*
  771          * it's important for atn stop
  772          */
  773         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH | DO_HWRESELECT);
  774         /*
  775          * SCSI command 
  776          */
  777         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, scsicommand);
  778 
  779         return 0;
  780 }
  781 
  782 /*
  783  * ------------------------------------------------------------
  784  * Function : trm_Interrupt
  785  * Purpose  : Catch an interrupt from the adapter           
  786  *            Process pending device interrupts.        
  787  * Inputs   : void * - struct trm_softc * structure pointer
  788  * ------------------------------------------------------------
  789  */
  790 int
  791 trm_Interrupt(void *vsc)
  792 {
  793         void   (*stateV)(struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
  794         struct trm_scsi_req_q *pSRB;
  795         bus_space_handle_t ioh;
  796         struct trm_softc *sc = (struct trm_softc *)vsc;
  797         bus_space_tag_t iot;
  798         u_int16_t phase;
  799         u_int8_t scsi_status, scsi_intstatus;
  800         int intflag;
  801 
  802         intflag = splbio();
  803 
  804         if (sc == NULL) {
  805                 splx(intflag);
  806                 return 0;
  807         }
  808 
  809         ioh = sc->sc_iohandle;
  810         iot = sc->sc_iotag;
  811 
  812         scsi_status = bus_space_read_2(iot, ioh, TRM_S1040_SCSI_STATUS);
  813         if (!(scsi_status & SCSIINTERRUPT)) {
  814                 splx(intflag);
  815                 return 0;
  816         }
  817         scsi_intstatus = bus_space_read_1(iot, ioh, TRM_S1040_SCSI_INTSTATUS);
  818 
  819 #ifdef TRM_DEBUG0
  820         printf("%s: trm_interrupt - scsi_status=0x%02x, scsi_intstatus=0x%02x\n",
  821             sc->sc_device.dv_xname, scsi_status, scsi_intstatus);
  822 #endif
  823         if ((scsi_intstatus & (INT_SELTIMEOUT | INT_DISCONNECT)) != 0)
  824                 trm_Disconnect(sc);
  825 
  826         else if ((scsi_intstatus &  INT_RESELECTED) != 0)
  827                 trm_Reselect(sc);
  828 
  829         else if ((scsi_intstatus &  INT_SCSIRESET) != 0)
  830                 trm_ScsiRstDetect(sc);
  831 
  832         else if ((sc->pActiveDCB != NULL) && ((scsi_intstatus & (INT_BUSSERVICE | INT_CMDDONE)) != 0)) {
  833                 pSRB = sc->pActiveDCB->pActiveSRB;
  834                 /*
  835                  * software sequential machine
  836                  */
  837                 phase = (u_int16_t) pSRB->ScsiPhase;  /* phase: */
  838                 /* 
  839                  * 62037 or 62137
  840                  * call  trm_SCSI_phase0[]... "phase entry"
  841                  * handle every phase before start transfer
  842                  */
  843                 stateV = trm_SCSI_phase0[phase];
  844                 stateV(sc, pSRB, &scsi_status);
  845                 /* 
  846                  * if any exception occurred
  847                  * scsi_status will be modified to bus free phase
  848                  * new scsi_status transfer out from previous stateV
  849                  */ 
  850                 /*
  851                  * phase:0,1,2,3,4,5,6,7
  852                  */
  853                 pSRB->ScsiPhase = scsi_status & PHASEMASK;
  854                 phase = (u_int16_t) scsi_status & PHASEMASK;       
  855                 /* 
  856                  * call  trm_SCSI_phase1[]... "phase entry"
  857                  * handle every phase do transfer
  858                  */
  859                 stateV = trm_SCSI_phase1[phase];
  860                 stateV(sc, pSRB, &scsi_status); 
  861 
  862         } else {
  863                 splx(intflag);
  864                 return 0;
  865         }
  866 
  867         splx(intflag);
  868         return 1;
  869 }
  870 
  871 /*
  872  * ------------------------------------------------------------
  873  * Function : trm_MsgOutPhase0
  874  * Purpose  : Check the state machine before sending a message out
  875  * Inputs   : struct trm_softc * -
  876  *            struct trm_scsi_req_q * -
  877  *            u_int8_t * - scsi status, set to PH_BUS_FREE if not ready
  878  * ------------------------------------------------------------
  879  */
  880 void
  881 trm_MsgOutPhase0(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
  882 {
  883         switch (pSRB->SRBState) {
  884         case TRM_UNEXPECT_RESEL:
  885         case TRM_ABORT_SENT:
  886                 *pscsi_status = PH_BUS_FREE; /* initial phase */
  887                 break;
  888                 
  889         default:
  890                 break;
  891         }
  892 }
  893 
  894 /*
  895  * ------------------------------------------------------------
  896  * Function : trm_MsgOutPhase1
  897  * Purpose  : Write the message out to the bus
  898  * Inputs   : struct trm_softc * -
  899  *            struct trm_scsi_req_q * -
  900  *            u_int8_t * - unused
  901  * ------------------------------------------------------------
  902  */
  903 void
  904 trm_MsgOutPhase1(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
  905 {
  906         const bus_space_handle_t ioh = sc->sc_iohandle;
  907         const bus_space_tag_t iot = sc->sc_iotag;
  908         struct trm_dcb *pDCB = sc->pActiveDCB;
  909 
  910         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_CLRFIFO);
  911 
  912         if ((pDCB->DCBFlag & TRM_WIDE_NEGO_ENABLE) != 0) {
  913                 /*
  914                  * WIDE DATA TRANSFER REQUEST code (03h)
  915                  */
  916                 pDCB->DCBFlag &= ~TRM_WIDE_NEGO_ENABLE;
  917                 pDCB->DCBFlag |=  TRM_DOING_WIDE_NEGO; 
  918 
  919                 sc->MsgBuf[0] = pDCB->IdentifyMsg & ~MSG_IDENTIFY_DISCFLAG;
  920                 sc->MsgBuf[1] = MSG_EXTENDED;
  921                 sc->MsgBuf[2] = MSG_EXT_WDTR_LEN;
  922                 sc->MsgBuf[3] = MSG_EXT_WDTR;
  923 
  924                 if ((pDCB->DCBFlag & TRM_WIDE_NEGO_16BIT) == 0)
  925                         sc->MsgBuf[4] = MSG_EXT_WDTR_BUS_8_BIT;
  926                 else
  927                         sc->MsgBuf[4] = MSG_EXT_WDTR_BUS_16_BIT;
  928 
  929                 sc->MsgCnt = 5;
  930                         
  931         } else if ((pDCB->DCBFlag & TRM_SYNC_NEGO_ENABLE) != 0) {
  932 
  933                 pDCB->DCBFlag &= ~TRM_SYNC_NEGO_ENABLE;
  934                 pDCB->DCBFlag |= TRM_DOING_SYNC_NEGO;
  935 
  936                 sc->MsgCnt = 0;
  937 
  938                 if ((pDCB->DCBFlag & TRM_WIDE_NEGO_DONE) == 0)
  939                         sc->MsgBuf[sc->MsgCnt++] = pDCB->IdentifyMsg & ~MSG_IDENTIFY_DISCFLAG;
  940 
  941                 sc->MsgBuf[sc->MsgCnt++] = MSG_EXTENDED;
  942                 sc->MsgBuf[sc->MsgCnt++] = MSG_EXT_SDTR_LEN;
  943                 sc->MsgBuf[sc->MsgCnt++] = MSG_EXT_SDTR;
  944                 sc->MsgBuf[sc->MsgCnt++] = pDCB->MaxNegoPeriod;
  945 
  946                 if (pDCB->MaxNegoPeriod > 0)
  947                         sc->MsgBuf[sc->MsgCnt++] = TRM_MAX_SYNC_OFFSET;
  948                 else
  949                         sc->MsgBuf[sc->MsgCnt++] = 0;
  950         }
  951 
  952         if (sc->MsgCnt > 0) {
  953                 bus_space_write_multi_1(iot, ioh, TRM_S1040_SCSI_FIFO, &sc->MsgBuf[0], sc->MsgCnt);
  954                 if (sc->MsgBuf[0] == MSG_ABORT)
  955                         pSRB->SRBState = TRM_ABORT_SENT;
  956                 sc->MsgCnt = 0;
  957         }
  958         /*
  959          * it's important for atn stop
  960          */
  961         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
  962         /*
  963          * Transfer information out
  964          */
  965         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT);
  966 }
  967 
  968 /*
  969  * ------------------------------------------------------------
  970  * Function : trm_CommandPhase1
  971  * Purpose  : Send commands to bus
  972  * Inputs   : 
  973  * ------------------------------------------------------------
  974  */
  975 void
  976 trm_CommandPhase1(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
  977 {
  978         const bus_space_handle_t ioh = sc->sc_iohandle;
  979         const bus_space_tag_t iot = sc->sc_iotag;
  980 
  981         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_CLRATN | DO_CLRFIFO);
  982 
  983         bus_space_write_multi_1(iot, ioh, TRM_S1040_SCSI_FIFO, &pSRB->CmdBlock[0], pSRB->ScsiCmdLen);
  984 
  985         pSRB->SRBState = TRM_COMMAND;
  986         /*
  987          * it's important for atn stop
  988          */
  989         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
  990         /*
  991          * Transfer information out
  992          */
  993         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT);
  994 }
  995 
  996 /*
  997  * ------------------------------------------------------------
  998  * Function : trm_DataOutPhase0
  999  * Purpose  : Ready for Data Out, clear FIFO
 1000  * Inputs   : u_int8_t * - SCSI status, used but not set
 1001  * ------------------------------------------------------------
 1002  */
 1003 void
 1004 trm_DataOutPhase0(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
 1005 {
 1006         const bus_space_handle_t ioh = sc->sc_iohandle;
 1007         const bus_space_tag_t iot = sc->sc_iotag;
 1008         struct SGentry *pseg;
 1009         struct trm_dcb *pDCB;
 1010         u_int32_t dLeftCounter, TempSRBXferredLength;
 1011         u_int16_t scsi_status;
 1012         u_int8_t TempDMAstatus, SGIndexTemp;
 1013 
 1014         dLeftCounter = 0;
 1015 
 1016         pDCB = pSRB->pSRBDCB;
 1017         scsi_status = *pscsi_status;
 1018 
 1019         if (pSRB->SRBState != TRM_XFERPAD) {
 1020                 if ((scsi_status & PARITYERROR) != 0)
 1021                         pSRB->SRBFlag |= TRM_PARITY_ERROR;
 1022                 if ((scsi_status & SCSIXFERDONE) == 0) {
 1023                         /*
 1024                          * when data transfer from DMA FIFO to SCSI FIFO
 1025                          * if there was some data left in SCSI FIFO
 1026                          */
 1027                         dLeftCounter = (u_int32_t)(bus_space_read_1(
 1028                             iot, ioh, TRM_S1040_SCSI_FIFOCNT) & 0x1F);
 1029                         if (pDCB->SyncPeriod & WIDE_SYNC) {
 1030                                 /*
 1031                                  * if WIDE scsi SCSI FIFOCNT unit is word
 1032                                  * so need to * 2
 1033                                  */
 1034                                 dLeftCounter <<= 1;
 1035                         }
 1036                 }
 1037                 /*
 1038                  * calculate all the residue data that not yet transferred
 1039                  * SCSI transfer counter + left in SCSI FIFO data
 1040                  *
 1041                  * .....TRM_S1040_SCSI_COUNTER (24bits)
 1042                  * The counter always decrement by one for every SCSI byte
 1043                  * transfer.
 1044                  * .....TRM_S1040_SCSI_FIFOCNT ( 5bits)
 1045                  * The counter is SCSI FIFO offset counter
 1046                  */
 1047                 dLeftCounter += bus_space_read_4(iot, ioh,
 1048                     TRM_S1040_SCSI_COUNTER);
 1049                 if (dLeftCounter == 1) {
 1050                         dLeftCounter = 0;
 1051                         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL,
 1052                             DO_CLRFIFO);
 1053                 }
 1054                 if (dLeftCounter == 0 ||
 1055                     (scsi_status & SCSIXFERCNT_2_ZERO) != 0) {   
 1056                         TempDMAstatus = bus_space_read_1(iot,
 1057                             ioh, TRM_S1040_DMA_STATUS);
 1058                         while ((TempDMAstatus & DMAXFERCOMP) == 0) {
 1059                                 TempDMAstatus = bus_space_read_1(iot,
 1060                                     ioh, TRM_S1040_DMA_STATUS);
 1061                         }
 1062                         pSRB->SRBTotalXferLength = 0;
 1063                 } else {
 1064                         /*
 1065                          * Update SG list
 1066                          */
 1067                         /*
 1068                          * if transfer not yet complete
 1069                          * there were some data residue in SCSI FIFO or
 1070                          * SCSI transfer counter not empty
 1071                          */
 1072                         if (pSRB->SRBTotalXferLength != dLeftCounter) {
 1073                                 /*
 1074                                  * data that had transferred length
 1075                                  */
 1076                                 TempSRBXferredLength = pSRB->SRBTotalXferLength
 1077                                     - dLeftCounter;
 1078                                 /*
 1079                                  * next time to be transferred length
 1080                                  */
 1081                                 pSRB->SRBTotalXferLength = dLeftCounter;
 1082                                 /*
 1083                                  * parsing from last time disconnect SRBSGIndex
 1084                                  */
 1085                                 pseg = &pSRB->SegmentX[pSRB->SRBSGIndex];
 1086                                 for (SGIndexTemp = pSRB->SRBSGIndex;
 1087                                     SGIndexTemp < pSRB->SRBSGCount;
 1088                                     SGIndexTemp++) {
 1089                                         /* 
 1090                                          * find last time which SG transfer be
 1091                                          * disconnect 
 1092                                          */
 1093                                         if (TempSRBXferredLength >= pseg->length)
 1094                                                 TempSRBXferredLength -= pseg->length;
 1095                                         else {
 1096                                                 /*
 1097                                                  * update last time disconnected
 1098                                                  * SG list
 1099                                                  */
 1100                                                 /*
 1101                                                  * residue data length
 1102                                                  */
 1103                                                 pseg->length -=
 1104                                                     TempSRBXferredLength;
 1105                                                 /*
 1106                                                  * residue data pointer
 1107                                                  */
 1108                                                 pseg->address +=
 1109                                                     TempSRBXferredLength;
 1110                                                 pSRB->SRBSGIndex = SGIndexTemp;
 1111                                                 break;
 1112                                         }
 1113                                         pseg++;
 1114                                 }
 1115                         }
 1116                 }
 1117         }
 1118         bus_space_write_1(iot, ioh, TRM_S1040_DMA_CONTROL, STOPDMAXFER);
 1119 }
 1120 
 1121 /*
 1122  * ------------------------------------------------------------
 1123  * Function : trm_DataOutPhase1
 1124  * Purpose  : Transfers data out, calls trm_DataIO_transfer
 1125  * Inputs   : 
 1126  * ------------------------------------------------------------
 1127  */
 1128 void
 1129 trm_DataOutPhase1(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
 1130 {
 1131         trm_DataIO_transfer(sc, pSRB, XFERDATAOUT);
 1132 }
 1133 
 1134 /*
 1135  * ------------------------------------------------------------
 1136  * Function : trm_DataInPhase0
 1137  * Purpose  : Prepare for reading data in from bus
 1138  * Inputs   : 
 1139  * ------------------------------------------------------------
 1140  */
 1141 void
 1142 trm_DataInPhase0(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
 1143 {
 1144         const bus_space_handle_t ioh = sc->sc_iohandle;
 1145         const bus_space_tag_t iot = sc->sc_iotag;
 1146         struct SGentry *pseg;
 1147         u_int32_t TempSRBXferredLength, dLeftCounter;
 1148         u_int16_t scsi_status;
 1149         u_int8_t SGIndexTemp;
 1150 
 1151         dLeftCounter = 0;
 1152 
 1153         scsi_status = *pscsi_status;
 1154         if (pSRB->SRBState != TRM_XFERPAD) {
 1155                 if ((scsi_status & PARITYERROR) != 0)
 1156                         pSRB->SRBFlag |= TRM_PARITY_ERROR;
 1157                 dLeftCounter += bus_space_read_4(iot, ioh,
 1158                     TRM_S1040_SCSI_COUNTER);
 1159                 if (dLeftCounter == 0 ||
 1160                     (scsi_status & SCSIXFERCNT_2_ZERO) != 0) {
 1161                         while ((bus_space_read_1(iot, ioh, TRM_S1040_DMA_STATUS) & DMAXFERCOMP) == 0)
 1162                                 ;
 1163                         pSRB->SRBTotalXferLength = 0;
 1164                 } else {  
 1165                         /*
 1166                          * phase changed
 1167                          *
 1168                          * parsing the case:
 1169                          * when a transfer not yet complete 
 1170                          * but be disconnected by uper layer
 1171                          * if transfer not yet complete
 1172                          * there were some data residue in SCSI FIFO or
 1173                          * SCSI transfer counter not empty
 1174                          */
 1175                         if (pSRB->SRBTotalXferLength != dLeftCounter) {
 1176                                 /*
 1177                                  * data that had transferred length
 1178                                  */
 1179                                 TempSRBXferredLength = pSRB->SRBTotalXferLength
 1180                                     - dLeftCounter;
 1181                                 /*
 1182                                  * next time to be transferred length
 1183                                  */
 1184                                 pSRB->SRBTotalXferLength = dLeftCounter;
 1185                                 /*
 1186                                  * parsing from last time disconnect SRBSGIndex
 1187                                  */
 1188                                 pseg = &pSRB->SegmentX[pSRB->SRBSGIndex];
 1189                                 for (SGIndexTemp = pSRB->SRBSGIndex;
 1190                                     SGIndexTemp < pSRB->SRBSGCount;
 1191                                     SGIndexTemp++) {
 1192                                         /* 
 1193                                          * find last time which SG transfer be
 1194                                          * disconnect 
 1195                                          */
 1196                                         if (TempSRBXferredLength >=
 1197                                             pseg->length) {
 1198                                                 TempSRBXferredLength -= pseg->length;
 1199                                         } else {
 1200                                                 /*
 1201                                                  * update last time disconnected
 1202                                                  * SG list
 1203                                                  *
 1204                                                  * residue data length
 1205                                                  */
 1206                                                 pseg->length -= TempSRBXferredLength;
 1207                                                 /*
 1208                                                  * residue data pointer
 1209                                                  */
 1210                                                 pseg->address += TempSRBXferredLength;
 1211                                                 pSRB->SRBSGIndex = SGIndexTemp;
 1212                                                 break;
 1213                                         } 
 1214                                         pseg++;
 1215                                 }
 1216                         }
 1217                 }
 1218         }
 1219 }
 1220 
 1221 /*
 1222  * ------------------------------------------------------------
 1223  * Function : trm_DataInPhase1
 1224  * Purpose  : Transfer data in from bus, calls trm_DataIO_transfer
 1225  * Inputs   : 
 1226  * ------------------------------------------------------------
 1227  */
 1228 void
 1229 trm_DataInPhase1(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
 1230 {
 1231         trm_DataIO_transfer(sc, pSRB, XFERDATAIN);
 1232 }
 1233 
 1234 /*
 1235  * ------------------------------------------------------------
 1236  * Function : trm_DataIO_transfer
 1237  * Purpose  : 
 1238  * Inputs   : 
 1239  * ------------------------------------------------------------
 1240  */
 1241 void
 1242 trm_DataIO_transfer(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int16_t ioDir)
 1243 {
 1244         const bus_space_handle_t ioh = sc->sc_iohandle;
 1245         const bus_space_tag_t iot = sc->sc_iotag;
 1246         struct trm_dcb *pDCB = pSRB->pSRBDCB;
 1247         u_int8_t bval;
 1248 
 1249         if (pSRB->SRBSGIndex < pSRB->SRBSGCount) {
 1250                 if (pSRB->SRBTotalXferLength != 0) {
 1251                         /* 
 1252                          * load what physical address of Scatter/Gather list
 1253                          * table want to be transfer 
 1254                          */
 1255                         pSRB->SRBState = TRM_DATA_XFER;
 1256                         bus_space_write_4(iot, ioh, TRM_S1040_DMA_XHIGHADDR, 0);
 1257                         bus_space_write_4(iot, ioh,
 1258                             TRM_S1040_DMA_XLOWADDR, (pSRB->SRBSGPhyAddr +
 1259                             ((u_int32_t)pSRB->SRBSGIndex << 3)));
 1260                         /*
 1261                          * load how many bytes in the Scatter/Gather list table
 1262                          */
 1263                         bus_space_write_4(iot, ioh, TRM_S1040_DMA_XCNT,
 1264                             ((u_int32_t)(pSRB->SRBSGCount -
 1265                             pSRB->SRBSGIndex) << 3));
 1266                         /*
 1267                          * load total transfer length (24bits,
 1268                          * pSRB->SRBTotalXferLength) max value 16Mbyte
 1269                          */
 1270                         bus_space_write_4(iot, ioh,
 1271                             TRM_S1040_SCSI_COUNTER, pSRB->SRBTotalXferLength);
 1272                         /*
 1273                          * Start DMA transfer
 1274                          */
 1275                         bus_space_write_2(iot,ioh,TRM_S1040_DMA_COMMAND, ioDir);
 1276                         /* bus_space_write_2(iot, ioh,
 1277                             TRM_S1040_DMA_CONTROL, STARTDMAXFER);*/
 1278                         /*
 1279                          * Set the transfer bus and direction
 1280                          */
 1281                         bval = ioDir == XFERDATAOUT ? SCMD_DMA_OUT :SCMD_DMA_IN;
 1282                 } else {
 1283                         /*
 1284                          * xfer pad
 1285                          */
 1286                         if (pSRB->SRBSGCount)
 1287                                 pSRB->AdaptStatus = TRM_OVER_UNDER_RUN;
 1288 
 1289                         if (pDCB->SyncPeriod & WIDE_SYNC) {
 1290                                 bus_space_write_4(iot, ioh,
 1291                                     TRM_S1040_SCSI_COUNTER, 2);
 1292                         } else {
 1293                                 bus_space_write_4(iot, ioh,
 1294                                     TRM_S1040_SCSI_COUNTER, 1);
 1295                         }
 1296 
 1297                         if (ioDir == XFERDATAOUT) {
 1298                                 bus_space_write_2(iot,
 1299                                     ioh, TRM_S1040_SCSI_FIFO, 0);
 1300                         } else {
 1301                                 bus_space_read_2(iot,
 1302                                     ioh, TRM_S1040_SCSI_FIFO);
 1303                         }
 1304                         pSRB->SRBState = TRM_XFERPAD;
 1305                         /*
 1306                          * Set the transfer bus and direction
 1307                          */
 1308                         bval = ioDir == XFERDATAOUT ? SCMD_FIFO_OUT : SCMD_FIFO_IN;
 1309                 }
 1310                 /*
 1311                  * it's important for atn stop
 1312                  */
 1313                 bus_space_write_2(iot,ioh,TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
 1314                 /*
 1315                  * Tell the bus to do the transfer
 1316                  */
 1317                 bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, bval);
 1318         }
 1319 }
 1320 
 1321 /*
 1322  * ------------------------------------------------------------
 1323  * Function : trm_StatusPhase0
 1324  * Purpose  : Update Target Status with data from SCSI FIFO
 1325  * Inputs   : u_int8_t * - Set to PH_BUS_FREE
 1326  * ------------------------------------------------------------
 1327  */
 1328 void
 1329 trm_StatusPhase0(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
 1330 {
 1331         const bus_space_handle_t ioh = sc->sc_iohandle;
 1332         const bus_space_tag_t iot = sc->sc_iotag;
 1333 
 1334         pSRB->TargetStatus = bus_space_read_1(iot, ioh, TRM_S1040_SCSI_FIFO);
 1335 
 1336         pSRB->SRBState = TRM_COMPLETED;
 1337         /*
 1338          * initial phase
 1339          */
 1340         *pscsi_status = PH_BUS_FREE;
 1341         /*
 1342          * it's important for atn stop
 1343          */
 1344         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
 1345         /*
 1346          * Tell bus that the message was accepted
 1347          */
 1348         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, SCMD_MSGACCEPT);
 1349 }
 1350 
 1351 /*
 1352  * ------------------------------------------------------------
 1353  * Function : trm_StatusPhase1
 1354  * Purpose  : Clear FIFO of DMA and SCSI
 1355  * Inputs   : 
 1356  * ------------------------------------------------------------
 1357  */
 1358 void
 1359 trm_StatusPhase1(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
 1360 {
 1361         const bus_space_handle_t ioh = sc->sc_iohandle;
 1362         const bus_space_tag_t iot = sc->sc_iotag;
 1363 
 1364         if ((bus_space_read_2(iot, ioh, TRM_S1040_DMA_COMMAND) & 0x0001) != 0) {
 1365                 if ((bus_space_read_1(iot, ioh, TRM_S1040_SCSI_FIFOCNT) & 0x40)
 1366                     == 0) {
 1367                         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL,
 1368                             DO_CLRFIFO);
 1369                 }        
 1370                 if ((bus_space_read_2(iot, ioh,
 1371                     TRM_S1040_DMA_FIFOCNT) & 0x8000) == 0) {
 1372                         bus_space_write_1(iot, ioh,
 1373                             TRM_S1040_DMA_CONTROL, CLRXFIFO);
 1374                 }
 1375         } else {
 1376                 if ((bus_space_read_2(iot, ioh,
 1377                     TRM_S1040_DMA_FIFOCNT) & 0x8000) == 0) {
 1378                         bus_space_write_1(iot, ioh,
 1379                             TRM_S1040_DMA_CONTROL, CLRXFIFO);
 1380                 }
 1381                 if ((bus_space_read_1(iot, ioh,
 1382                     TRM_S1040_SCSI_FIFOCNT) & 0x40) == 0) {
 1383                         bus_space_write_2(iot, ioh,
 1384                             TRM_S1040_SCSI_CONTROL, DO_CLRFIFO);
 1385                 }
 1386         }
 1387         pSRB->SRBState = TRM_STATUS;
 1388         /*
 1389          * it's important for atn stop
 1390          */
 1391         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
 1392         /*
 1393          * Tell the bus that the command is complete
 1394          */
 1395         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, SCMD_COMP);
 1396 }
 1397 
 1398 /*
 1399  * ------------------------------------------------------------
 1400  * Function : trm_MsgInPhase0
 1401  * Purpose  : 
 1402  * Inputs   : 
 1403  *
 1404  * extended message codes:
 1405  *   code        description
 1406  *   ----        -----------
 1407  *    02h        Reserved
 1408  *    00h        MODIFY DATA POINTER
 1409  *    01h        SYNCHRONOUS DATA TRANSFER REQUEST
 1410  *    03h        WIDE DATA TRANSFER REQUEST
 1411  * 04h - 7Fh     Reserved
 1412  * 80h - FFh     Vendor specific  
 1413  *                
 1414  * ------------------------------------------------------------
 1415  */
 1416 void
 1417 trm_MsgInPhase0(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
 1418 {
 1419         const bus_space_handle_t ioh = sc->sc_iohandle;
 1420         const bus_space_tag_t iot = sc->sc_iotag;
 1421         struct trm_dcb *pDCB;
 1422         u_int8_t message_in_code, bIndex, message_in_tag_id;
 1423 
 1424         pDCB = sc->pActiveDCB;
 1425 
 1426         message_in_code = bus_space_read_1(iot, ioh, TRM_S1040_SCSI_FIFO);
 1427 
 1428         if (pSRB->SRBState != TRM_EXTEND_MSGIN) {
 1429                 switch (message_in_code) {
 1430                 case MSG_DISCONNECT:
 1431                         pSRB->SRBState = TRM_DISCONNECTED;
 1432                         break;
 1433 
 1434                 case MSG_EXTENDED:
 1435                 case MSG_SIMPLE_Q_TAG:
 1436                 case MSG_HEAD_OF_Q_TAG:
 1437                 case MSG_ORDERED_Q_TAG:
 1438                         pSRB->SRBState = TRM_EXTEND_MSGIN;
 1439                         /*
 1440                          * extended message      (01h)
 1441                          */
 1442                         bzero(&sc->MsgBuf[0], sizeof(sc->MsgBuf));
 1443                         sc->MsgBuf[0] = message_in_code;
 1444                         sc->MsgCnt    = 1;
 1445                         /*
 1446                          * extended message length (n)
 1447                          */
 1448                         break;
 1449 
 1450                 case MSG_MESSAGE_REJECT:
 1451                         /*
 1452                          * Reject message
 1453                          */
 1454                         if ((pDCB->DCBFlag & TRM_DOING_WIDE_NEGO) != 0) {
 1455                                 /*
 1456                                  * do wide nego reject
 1457                                  */
 1458                                 pDCB = pSRB->pSRBDCB;
 1459 
 1460                                 pDCB->DCBFlag &= ~TRM_DOING_WIDE_NEGO;
 1461                                 pDCB->DCBFlag |= TRM_WIDE_NEGO_DONE;
 1462 
 1463                                 if ((pDCB->DCBFlag & TRM_SYNC_NEGO_ENABLE) != 0) {
 1464                                         /*
 1465                                          * Set ATN, in case ATN was clear
 1466                                          */
 1467                                         pSRB->SRBState = TRM_MSGOUT;
 1468                                         bus_space_write_2(iot, ioh,
 1469                                             TRM_S1040_SCSI_CONTROL, DO_SETATN);
 1470                                 } else {   
 1471                                         /*
 1472                                          * Clear ATN
 1473                                          */
 1474                                         bus_space_write_2(iot, ioh,
 1475                                             TRM_S1040_SCSI_CONTROL, DO_CLRATN);
 1476                                 }
 1477 
 1478                         } else if ((pDCB->DCBFlag & TRM_DOING_SYNC_NEGO) != 0) { 
 1479                                 /*
 1480                                  * do sync nego reject
 1481                                  */
 1482                                 pDCB = pSRB->pSRBDCB;
 1483 
 1484                                 pDCB->DCBFlag &= ~TRM_DOING_SYNC_NEGO;
 1485 
 1486                                 pDCB->SyncPeriod = 0;
 1487                                 pDCB->SyncOffset = 0;
 1488 
 1489                                 bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_CLRATN);
 1490                                 goto  re_prog;
 1491                         }
 1492                         break;
 1493 
 1494                 case MSG_IGN_WIDE_RESIDUE:
 1495                         bus_space_write_4(iot, ioh, TRM_S1040_SCSI_COUNTER, 1);
 1496                         bus_space_read_1(iot, ioh, TRM_S1040_SCSI_FIFO);
 1497                         break;
 1498 
 1499                 default:
 1500                         break;
 1501                 }
 1502 
 1503         } else {
 1504 
 1505                 /*
 1506                  * We are collecting an extended message. Save the latest byte and then
 1507                  * check to see if the message is complete. If so, process it.
 1508                  */
 1509                 sc->MsgBuf[sc->MsgCnt++] = message_in_code;
 1510 #ifdef TRM_DEBUG0
 1511                 printf("%s: sc->MsgBuf = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
 1512                     sc->sc_device.dv_xname,
 1513                     sc->MsgBuf[0], sc->MsgBuf[1], sc->MsgBuf[2], sc->MsgBuf[3], sc->MsgBuf[4], sc->MsgBuf[5] );
 1514 #endif
 1515                 switch (sc->MsgBuf[0]) {
 1516                 case MSG_SIMPLE_Q_TAG:
 1517                 case MSG_HEAD_OF_Q_TAG:
 1518                 case MSG_ORDERED_Q_TAG:
 1519                         if (sc->MsgCnt == 2) {
 1520                                 pSRB->SRBState = TRM_FREE;
 1521                                 message_in_tag_id = sc->MsgBuf[1];
 1522                                 sc->MsgCnt = 0;
 1523                                 TAILQ_FOREACH(pSRB, &sc->goingSRB, link) {
 1524                                         if ((pSRB->pSRBDCB == pDCB) && (pSRB->TagNumber == message_in_tag_id))
 1525                                                 break;
 1526                                 }
 1527                                 if ((pSRB != NULL) && (pSRB->SRBState == TRM_DISCONNECTED)) {
 1528                                         pDCB->pActiveSRB = pSRB;
 1529                                         pSRB->SRBState = TRM_DATA_XFER;
 1530                                 } else {
 1531                                         pSRB = &sc->SRB[0];
 1532                                         pSRB->SRBState = TRM_UNEXPECT_RESEL;
 1533                                         pDCB->pActiveSRB = pSRB;
 1534                                         trm_EnableMsgOut(sc, MSG_ABORT_TAG);
 1535                                 }
 1536                         }
 1537                         break;
 1538                         
 1539                 case  MSG_EXTENDED:
 1540                         /* TODO XXXX: Correctly handling target initiated negotiations? */
 1541                         if ((sc->MsgBuf[2] == MSG_EXT_WDTR) && (sc->MsgCnt == 4)) {
 1542                                 /*      
 1543                                  * ======================================
 1544                                  * WIDE DATA TRANSFER REQUEST   
 1545                                  * ======================================
 1546                                  * byte 0 :  Extended message (01h)     
 1547                                  * byte 1 :  Extended message length (02h)      
 1548                                  * byte 2 :  WIDE DATA TRANSFER code (03h)      
 1549                                  * byte 3 :  Transfer width exponent 
 1550                                  */
 1551                                 
 1552                                 pSRB->SRBState  = TRM_FREE;
 1553                                 pDCB->DCBFlag  &= ~(TRM_WIDE_NEGO_ENABLE | TRM_DOING_WIDE_NEGO);
 1554 
 1555                                 if (sc->MsgBuf[1] != MSG_EXT_WDTR_LEN)
 1556                                         goto reject_offer;
 1557 
 1558                                 switch (sc->MsgBuf[3]) {
 1559                                 case MSG_EXT_WDTR_BUS_32_BIT:
 1560                                         if ((pDCB->DCBFlag & TRM_WIDE_NEGO_16BIT) == 0)
 1561                                                 sc->MsgBuf[3] = MSG_EXT_WDTR_BUS_8_BIT;
 1562                                         else 
 1563                                                 sc->MsgBuf[3] = MSG_EXT_WDTR_BUS_16_BIT;
 1564                                         break;
 1565                                         
 1566                                 case MSG_EXT_WDTR_BUS_16_BIT:
 1567                                         if ((pDCB->DCBFlag & TRM_WIDE_NEGO_16BIT) == 0) {
 1568                                                 sc->MsgBuf[3] = MSG_EXT_WDTR_BUS_8_BIT;
 1569                                                 break;
 1570                                         }
 1571                                         pDCB->SyncPeriod |= WIDE_SYNC;
 1572                                         /* FALL THROUGH == ACCEPT OFFER */
 1573                                         
 1574                                 case MSG_EXT_WDTR_BUS_8_BIT:
 1575                                         pSRB->SRBState  =  TRM_MSGOUT;
 1576                                         pDCB->DCBFlag  |= (TRM_SYNC_NEGO_ENABLE | TRM_WIDE_NEGO_DONE);
 1577                                         
 1578                                         if (pDCB->MaxNegoPeriod == 0) {
 1579                                                 pDCB->SyncPeriod = 0;
 1580                                                 pDCB->SyncOffset = 0;
 1581                                                 goto re_prog;
 1582                                         }
 1583                                         break;
 1584                                         
 1585                                 default:
 1586                                         pDCB->DCBFlag &= ~TRM_WIDE_NEGO_ENABLE; 
 1587                                         pDCB->DCBFlag |= TRM_WIDE_NEGO_DONE;
 1588 reject_offer:
 1589                                         sc->MsgCnt    = 1;
 1590                                         sc->MsgBuf[0] = MSG_MESSAGE_REJECT;
 1591                                         break;
 1592                                 }
 1593                                 
 1594                                 /* Echo accepted offer, or send revised offer */
 1595                                 bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_SETATN);
 1596 
 1597                         } else if ((sc->MsgBuf[2] == MSG_EXT_SDTR) && (sc->MsgCnt == 5)) {
 1598                                 /*
 1599                                  * =================================
 1600                                  * SYNCHRONOUS DATA TRANSFER REQUEST
 1601                                  * =================================
 1602                                  * byte 0 :  Extended message (01h)
 1603                                  * byte 1 :  Extended message length (03)
 1604                                  * byte 2 :  SYNCHRONOUS DATA TRANSFER code (01h)
 1605                                  * byte 3 :  Transfer period factor 
 1606                                  * byte 4 :  REQ/ACK offset  
 1607                                  */
 1608 
 1609                                 pSRB->SRBState  = TRM_FREE;
 1610                                 pDCB->DCBFlag  &= ~(TRM_SYNC_NEGO_ENABLE | TRM_DOING_SYNC_NEGO);
 1611 
 1612                                 if (sc->MsgBuf[1] != MSG_EXT_SDTR_LEN)
 1613                                         goto reject_offer;
 1614                                 
 1615                                 if ((sc->MsgBuf[3] == 0) || (sc->MsgBuf[4] == 0)) {
 1616                                         /*
 1617                                          * Asynchronous transfers
 1618                                          */
 1619                                         pDCB->SyncPeriod  = 0;
 1620                                         pDCB->SyncOffset  = 0;
 1621                                         
 1622                                 } else {
 1623                                         /*      
 1624                                          * Synchronous transfers
 1625                                          */
 1626                                         /*
 1627                                          * REQ/ACK offset
 1628                                          */
 1629                                         pDCB->SyncOffset = sc->MsgBuf[4];
 1630 
 1631                                         for (bIndex = 0; bIndex < 7; bIndex++)
 1632                                                 if (sc->MsgBuf[3] <= trm_clock_period[bIndex])
 1633                                                         break;
 1634 
 1635                                         pDCB->SyncPeriod |= (bIndex | ALT_SYNC);
 1636                                 }
 1637 
 1638 re_prog:                        /*               
 1639                                  *   program SCSI control register
 1640                                  */
 1641                                 bus_space_write_1(iot, ioh, TRM_S1040_SCSI_SYNC, pDCB->SyncPeriod);
 1642                                 bus_space_write_1(iot, ioh, TRM_S1040_SCSI_OFFSET, pDCB->SyncOffset);
 1643 
 1644                                 trm_SetXferParams(sc, pDCB, (pDCB->DCBFlag & TRM_QUIRKS_VALID));
 1645                         }
 1646                         break;
 1647                         
 1648                 default:
 1649                         break;
 1650                 }
 1651         }
 1652 
 1653         /*
 1654          * initial phase
 1655          */
 1656         *pscsi_status = PH_BUS_FREE;
 1657         /*
 1658          * it's important for atn stop
 1659          */
 1660         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
 1661         /*
 1662          * Tell bus that the message was accepted
 1663          */
 1664         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, SCMD_MSGACCEPT);
 1665 }
 1666 
 1667 /*
 1668  * ------------------------------------------------------------
 1669  * Function : trm_MsgInPhase1
 1670  * Purpose  : Clear the FIFO
 1671  * Inputs   : 
 1672  * ------------------------------------------------------------
 1673  */
 1674 void
 1675 trm_MsgInPhase1(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
 1676 {
 1677         const bus_space_handle_t ioh = sc->sc_iohandle;
 1678         const bus_space_tag_t iot = sc->sc_iotag;
 1679 
 1680         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_CLRFIFO);
 1681         bus_space_write_4(iot, ioh, TRM_S1040_SCSI_COUNTER, 1);
 1682 
 1683         /*
 1684          * it's important for atn stop
 1685          */
 1686         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
 1687         /*
 1688          * SCSI command 
 1689          */
 1690         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_IN);
 1691 }
 1692 
 1693 /*
 1694  * ------------------------------------------------------------
 1695  * Function : trm_Nop
 1696  * Purpose  : EMPTY
 1697  * Inputs   : 
 1698  * ------------------------------------------------------------
 1699  */
 1700 void
 1701 trm_Nop(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
 1702 {
 1703 }
 1704 
 1705 /*
 1706  * ------------------------------------------------------------
 1707  * Function : trm_SetXferParams
 1708  * Purpose  : Set the Sync period, offset and mode for each device that has
 1709  *            the same target as the given one (struct trm_dcb *)
 1710  * Inputs   : 
 1711  * ------------------------------------------------------------
 1712  */
 1713 void
 1714 trm_SetXferParams(struct trm_softc *sc, struct trm_dcb *pDCB, int print_info)
 1715 {
 1716         struct trm_dcb *pDCBTemp;
 1717         int lun, target;
 1718 
 1719         /*
 1720          * set all lun device's period, offset
 1721          */
 1722 #ifdef TRM_DEBUG0
 1723         printf("%s: trm_SetXferParams\n", sc->sc_device.dv_xname);
 1724 #endif
 1725 
 1726         target = pDCB->target;
 1727         for(lun = 0; lun < TRM_MAX_LUNS; lun++) {
 1728                 pDCBTemp = sc->pDCB[target][lun];
 1729                 if (pDCBTemp != NULL) {
 1730                         pDCBTemp->DevMode       = pDCB->DevMode;
 1731                         pDCBTemp->MaxNegoPeriod = pDCB->MaxNegoPeriod;
 1732                         pDCBTemp->SyncPeriod    = pDCB->SyncPeriod;
 1733                         pDCBTemp->SyncOffset    = pDCB->SyncOffset;
 1734                         pDCBTemp->DCBFlag       = pDCB->DCBFlag;
 1735                 }
 1736         }
 1737 
 1738         if (print_info)
 1739                 trm_print_info(sc, pDCB);
 1740 }
 1741 
 1742 /*
 1743  * ------------------------------------------------------------
 1744  * Function : trm_Disconnect
 1745  * Purpose  :
 1746  * Inputs   : 
 1747  *
 1748  *    ---SCSI bus phase
 1749  *     PH_DATA_OUT          0x00     Data out phase                  
 1750  *     PH_DATA_IN           0x01     Data in phase                
 1751  *     PH_COMMAND           0x02     Command phase     
 1752  *     PH_STATUS            0x03     Status phase
 1753  *     PH_BUS_FREE          0x04     Invalid phase used as bus free    
 1754  *     PH_BUS_FREE          0x05     Invalid phase used as bus free    
 1755  *     PH_MSG_OUT           0x06     Message out phase
 1756  *     PH_MSG_IN            0x07     Message in phase
 1757  * ------------------------------------------------------------
 1758  */
 1759 void
 1760 trm_Disconnect(struct trm_softc *sc)
 1761 {
 1762         const bus_space_handle_t ioh = sc->sc_iohandle;
 1763         struct trm_scsi_req_q *pSRB, *pNextSRB;
 1764         const bus_space_tag_t iot = sc->sc_iotag;
 1765         struct trm_dcb *pDCB; 
 1766         int j;
 1767 
 1768 #ifdef TRM_DEBUG0
 1769         printf("%s: trm_Disconnect\n", sc->sc_device.dv_xname);
 1770 #endif
 1771 
 1772         pDCB = sc->pActiveDCB;
 1773         if (pDCB == NULL) {
 1774                 /* TODO: Why use a loop? Why not use DELAY(400)? */
 1775                 for(j = 400; j > 0; --j)
 1776                         DELAY(1); /* 1 msec */
 1777                 bus_space_write_2(iot, ioh,
 1778                     TRM_S1040_SCSI_CONTROL, (DO_CLRFIFO | DO_HWRESELECT));
 1779                 return;
 1780         }
 1781 
 1782         pSRB = pDCB->pActiveSRB;    
 1783         sc->pActiveDCB = NULL;
 1784         pSRB->ScsiPhase = PH_BUS_FREE; /* SCSI bus free Phase */
 1785         bus_space_write_2(iot, ioh,
 1786             TRM_S1040_SCSI_CONTROL, (DO_CLRFIFO | DO_HWRESELECT));
 1787         DELAY(100);
 1788 
 1789         switch (pSRB->SRBState) {
 1790         case TRM_UNEXPECT_RESEL:
 1791                 pSRB->SRBState = TRM_FREE;
 1792                 break;
 1793 
 1794         case TRM_ABORT_SENT:
 1795                 pSRB = TAILQ_FIRST(&sc->goingSRB);
 1796                 while (pSRB != NULL) {
 1797                         /*
 1798                          * Need to save pNextSRB because trm_FinishSRB() puts
 1799                          * pSRB in freeSRB queue, and thus its links no longer
 1800                          * point to members of the goingSRB queue. This is why
 1801                          * TAILQ_FOREACH() will not work for this traversal.
 1802                          */
 1803                         pNextSRB = TAILQ_NEXT(pSRB, link);
 1804                         if (pSRB->pSRBDCB == pDCB) {
 1805                                 /* TODO XXXX: Is TIMED_OUT the best state to report? */
 1806                                 pSRB->SRBFlag |= TRM_SCSI_TIMED_OUT;
 1807                                 trm_FinishSRB(sc, pSRB);
 1808                         }
 1809                         pSRB = pNextSRB;
 1810                 }
 1811                 break;
 1812 
 1813         case TRM_START:
 1814         case TRM_MSGOUT:
 1815                 /*
 1816                  * Selection time out
 1817                  */
 1818                 /* If not polling just keep trying until xs->stimeout expires */
 1819                 if ((pSRB->xs->flags & SCSI_POLL) == 0) {
 1820                         trm_RewaitSRB(sc, pSRB);
 1821                 } else {
 1822                         pSRB->TargetStatus = TRM_SCSI_SELECT_TIMEOUT;
 1823                         goto  disc1;
 1824                 }
 1825                 break;
 1826 
 1827         case TRM_COMPLETED:
 1828 disc1:
 1829                 /*
 1830                  * TRM_COMPLETED - remove id from mask of active tags
 1831                  */
 1832                 pDCB->pActiveSRB = NULL;
 1833                 trm_FinishSRB(sc, pSRB);
 1834                 break;
 1835                 
 1836         default:
 1837                 break;
 1838         }
 1839 
 1840         trm_StartWaitingSRB(sc);
 1841 }
 1842 
 1843 /*
 1844  * ------------------------------------------------------------
 1845  * Function : trm_Reselect
 1846  * Purpose  :
 1847  * Inputs   : 
 1848  * ------------------------------------------------------------
 1849  */
 1850 void
 1851 trm_Reselect(struct trm_softc *sc)
 1852 {
 1853         const bus_space_handle_t ioh = sc->sc_iohandle;
 1854         const bus_space_tag_t iot = sc->sc_iotag;
 1855         struct trm_scsi_req_q *pSRB;
 1856         struct trm_dcb *pDCB;
 1857         u_int16_t RselTarLunId;
 1858         u_int8_t target, lun;
 1859 
 1860 #ifdef TRM_DEBUG0
 1861         printf("%s: trm_Reselect\n", sc->sc_device.dv_xname);
 1862 #endif
 1863 
 1864         pDCB = sc->pActiveDCB;
 1865         if (pDCB != NULL) {
 1866                 /*
 1867                  * Arbitration lost but Reselection win
 1868                  */
 1869                 pSRB = pDCB->pActiveSRB;
 1870                 trm_RewaitSRB(sc, pSRB);
 1871         }
 1872 
 1873         /*
 1874          * Read Reselected Target Id and LUN
 1875          */
 1876         RselTarLunId = bus_space_read_2(iot, ioh, TRM_S1040_SCSI_TARGETID) & 0x1FFF;
 1877         /* TODO XXXX: Make endian independent! */
 1878         target = RselTarLunId & 0xff;
 1879         lun    = (RselTarLunId >> 8) & 0xff;
 1880 
 1881 #ifdef TRM_DEBUG0
 1882         printf("%s: reselect - target = %d, lun = %d\n",
 1883             sc->sc_device.dv_xname, target, lun);
 1884 #endif
 1885 
 1886         if ((target < TRM_MAX_TARGETS) && (lun < TRM_MAX_LUNS))
 1887                 pDCB = sc->pDCB[target][lun];
 1888         else
 1889                 pDCB = NULL;
 1890 
 1891         if (pDCB == NULL)
 1892                 printf("%s: reselect - target = %d, lun = %d not found\n",
 1893                     sc->sc_device.dv_xname, target, lun);
 1894 
 1895         sc->pActiveDCB = pDCB;
 1896 
 1897         /* TODO XXXX: This will crash if pDCB is ever NULL */
 1898         if ((pDCB->DCBFlag & TRM_USE_TAG_QUEUING) != 0) {
 1899                 pSRB = &sc->SRB[0];
 1900                 pDCB->pActiveSRB = pSRB;
 1901         } else {
 1902                 pSRB = pDCB->pActiveSRB;
 1903                 if (pSRB == NULL || (pSRB->SRBState != TRM_DISCONNECTED)) {
 1904                         /*
 1905                          * abort command
 1906                          */
 1907                         pSRB = &sc->SRB[0];
 1908                         pSRB->SRBState = TRM_UNEXPECT_RESEL;
 1909                         pDCB->pActiveSRB = pSRB;
 1910                         trm_EnableMsgOut(sc, MSG_ABORT);
 1911                 } else
 1912                         pSRB->SRBState = TRM_DATA_XFER;
 1913         }
 1914         pSRB->ScsiPhase = PH_BUS_FREE; /* SCSI bus free Phase */
 1915 
 1916         /* 
 1917          * Program HA ID, target ID, period and offset
 1918          */
 1919         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_TARGETID, target);
 1920         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_HOSTID, sc->sc_AdaptSCSIID);
 1921         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_SYNC, pDCB->SyncPeriod);
 1922         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_OFFSET, pDCB->SyncOffset);
 1923 
 1924         /*
 1925          * it's important for atn stop
 1926          */
 1927         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
 1928         DELAY(30);
 1929 
 1930         /*
 1931          * SCSI command 
 1932          * to rls the /ACK signal
 1933          */
 1934         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, SCMD_MSGACCEPT);
 1935 }
 1936 
 1937 /*
 1938  * ------------------------------------------------------------
 1939  * Function : trm_FinishSRB
 1940  * Purpose  : Complete execution of a SCSI command
 1941  *            Signal completion to the generic SCSI driver    
 1942  * Inputs   : 
 1943  * ------------------------------------------------------------
 1944  */
 1945 void
 1946 trm_FinishSRB(struct trm_softc *sc, struct trm_scsi_req_q *pSRB)
 1947 {
 1948         struct scsi_inquiry_data *ptr;
 1949         struct scsi_sense_data *s1, *s2;
 1950         struct scsi_xfer *xs = pSRB->xs;
 1951         struct trm_dcb *pDCB = pSRB->pSRBDCB;
 1952         int target, lun;
 1953 
 1954 #ifdef TRM_DEBUG0
 1955         printf("%s: trm_FinishSRB. sc = %p, pSRB = %p\n",
 1956             sc->sc_device.dv_xname, sc, pSRB);
 1957 #endif
 1958         pDCB->DCBFlag &= ~TRM_QUEUE_FULL;
 1959 
 1960         if (xs == NULL) {
 1961                 trm_ReleaseSRB(sc, pSRB);
 1962                 return;
 1963         }
 1964 
 1965         timeout_del(&xs->stimeout);
 1966 
 1967         xs->status = pSRB->TargetStatus;
 1968 
 1969         switch (xs->status) {
 1970         case SCSI_INTERM_COND_MET:
 1971         case SCSI_COND_MET:
 1972         case SCSI_INTERM:
 1973         case SCSI_OK:
 1974                 switch (pSRB->AdaptStatus) {
 1975                 case TRM_STATUS_GOOD:
 1976                         if ((pSRB->SRBFlag & TRM_PARITY_ERROR) != 0) {
 1977 #ifdef TRM_DEBUG0
 1978                                 printf("%s: trm_FinishSRB. TRM_PARITY_ERROR\n",
 1979                                     sc->sc_device.dv_xname);
 1980 #endif          
 1981                                 xs->error = XS_DRIVER_STUFFUP;
 1982 
 1983                         } else if ((pSRB->SRBFlag & TRM_SCSI_TIMED_OUT) != 0) {
 1984                                 xs->error = XS_TIMEOUT;
 1985 
 1986                         } else if ((pSRB->SRBFlag & TRM_AUTO_REQSENSE) != 0) {
 1987                                 s1 = &pSRB->scsisense;
 1988                                 s2 = &xs->sense;
 1989                                 
 1990                                 *s2 = *s1;
 1991                                 
 1992                                 xs->status = SCSI_CHECK;
 1993                                 xs->error  = XS_SENSE;
 1994 
 1995                         } else
 1996                                 xs->error = XS_NOERROR;
 1997                         break;
 1998 
 1999                 case TRM_OVER_UNDER_RUN:
 2000 #ifdef TRM_DEBUG0
 2001                         printf("%s: trm_FinishSRB. TRM_OVER_UNDER_RUN\n",
 2002                             sc->sc_device.dv_xname);
 2003 #endif
 2004                         xs->error = XS_DRIVER_STUFFUP;
 2005                         break;
 2006 
 2007                 default:
 2008 #ifdef TRM_DEBUG0
 2009                         printf("%s: trm_FinishSRB. AdaptStatus Error = 0x%02x\n",
 2010                             sc->sc_device.dv_xname, pSRB->AdaptStatus);
 2011 #endif  
 2012                         xs->error = XS_DRIVER_STUFFUP;
 2013                         break;
 2014                 }
 2015                 break;
 2016                 
 2017         case SCSI_TERMINATED:
 2018         case SCSI_ACA_ACTIVE:
 2019         case SCSI_CHECK:
 2020                 if ((pSRB->SRBFlag & TRM_AUTO_REQSENSE) != 0)
 2021                         xs->error = XS_DRIVER_STUFFUP;
 2022                 else {
 2023                         trm_RequestSense(sc, pSRB);
 2024                         return;
 2025                 }
 2026                 break;
 2027 
 2028         case SCSI_QUEUE_FULL:
 2029                 /* this says no more until someone completes */
 2030                 pDCB->DCBFlag |= TRM_QUEUE_FULL;
 2031                 trm_RewaitSRB(sc, pSRB);
 2032                 return;
 2033         
 2034         case SCSI_RESV_CONFLICT:
 2035         case SCSI_BUSY:
 2036                 xs->error = XS_BUSY;
 2037                 break;
 2038 
 2039         case TRM_SCSI_UNEXP_BUS_FREE:
 2040                 xs->status = SCSI_OK;
 2041                 xs->error  = XS_DRIVER_STUFFUP;
 2042                 break;
 2043 
 2044         case TRM_SCSI_BUS_RST_DETECTED:
 2045                 xs->status = SCSI_OK;
 2046                 xs->error  = XS_RESET;
 2047                 break;
 2048 
 2049         case TRM_SCSI_SELECT_TIMEOUT:
 2050                 xs->status = SCSI_OK;
 2051                 xs->error  = XS_SELTIMEOUT;
 2052                 break;
 2053 
 2054         default:
 2055                 xs->error = XS_DRIVER_STUFFUP;
 2056                 break;
 2057         }
 2058 
 2059         target = xs->sc_link->target;
 2060         lun    = xs->sc_link->lun;   
 2061 
 2062         if ((xs->flags & SCSI_POLL) != 0) {
 2063 
 2064                 if (xs->cmd->opcode == INQUIRY) {
 2065 
 2066                         ptr = (struct scsi_inquiry_data *) xs->data; 
 2067 
 2068                         if ((xs->error != XS_NOERROR) ||
 2069                             ((ptr->device & SID_QUAL_BAD_LU) == SID_QUAL_BAD_LU)) {
 2070 #ifdef TRM_DEBUG0
 2071                                 printf("%s: trm_FinishSRB NO Device:target= %d,lun= %d\n",
 2072                                     sc->sc_device.dv_xname, target, lun);
 2073 #endif          
 2074                                 free(pDCB, M_DEVBUF);
 2075                                 sc->pDCB[target][lun] = NULL;
 2076                                 pDCB = NULL;
 2077 
 2078                         } else
 2079                                 pDCB->sc_link = xs->sc_link;
 2080                 }
 2081         }
 2082 
 2083         trm_ReleaseSRB(sc, pSRB);
 2084 
 2085         xs->flags |= ITSDONE;
 2086 
 2087         /*
 2088          * Notify cmd done
 2089          */
 2090 #ifdef TRM_DEBUG0
 2091         if ((xs->error != 0) || (xs->status != 0) || ((xs->flags & SCSI_POLL) != 0))
 2092                 printf("%s: trm_FinishSRB. %d/%d xs->cmd->opcode = 0x%02x, xs->error = %d, xs->status = %d\n",
 2093                     sc->sc_device.dv_xname, target, lun, xs->cmd->opcode, xs->error, xs->status);
 2094 #endif
 2095 
 2096         scsi_done(xs);
 2097 }
 2098 
 2099 /*
 2100  * ------------------------------------------------------------
 2101  * Function : trm_ReleaseSRB
 2102  * Purpose  : 
 2103  * Inputs   : 
 2104  * ------------------------------------------------------------
 2105  */
 2106 void
 2107 trm_ReleaseSRB(struct trm_softc *sc, struct trm_scsi_req_q *pSRB)
 2108 {
 2109         struct scsi_xfer *xs = pSRB->xs;
 2110         int intflag;
 2111 
 2112         intflag = splbio();
 2113 
 2114         if (pSRB->TagNumber != TRM_NO_TAG) {
 2115                 pSRB->pSRBDCB->TagMask &= ~(1 << pSRB->TagNumber);
 2116                 pSRB->TagNumber = TRM_NO_TAG;
 2117         }
 2118 
 2119         if (xs != NULL) {
 2120                 timeout_del(&xs->stimeout);
 2121 
 2122                 if (xs->datalen != 0) {
 2123                         bus_dmamap_sync(sc->sc_dmatag, pSRB->dmamapxfer,
 2124                             0, pSRB->dmamapxfer->dm_mapsize,
 2125                             (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
 2126                             BUS_DMASYNC_POSTWRITE);
 2127                         bus_dmamap_unload(sc->sc_dmatag, pSRB->dmamapxfer);
 2128                 }
 2129         }
 2130 
 2131         /* SRB may have started & finished, or be waiting and timed out */
 2132         if ((pSRB->SRBFlag & TRM_ON_WAITING_SRB) != 0) {
 2133                 pSRB->SRBFlag &= ~TRM_ON_WAITING_SRB;
 2134                 TAILQ_REMOVE(&sc->waitingSRB, pSRB, link);
 2135         }
 2136         if ((pSRB->SRBFlag & TRM_ON_GOING_SRB) != 0) {
 2137                 pSRB->SRBFlag &= ~TRM_ON_GOING_SRB;
 2138                 TAILQ_REMOVE(&sc->goingSRB, pSRB, link);
 2139         }
 2140 
 2141         bzero(&pSRB->SegmentX[0], sizeof(pSRB->SegmentX));
 2142         bzero(&pSRB->CmdBlock[0], sizeof(pSRB->CmdBlock));
 2143         bzero(&pSRB->scsisense,   sizeof(pSRB->scsisense));
 2144 
 2145         pSRB->SRBTotalXferLength = 0;
 2146         pSRB->SRBSGCount         = 0;
 2147         pSRB->SRBSGIndex         = 0;
 2148         pSRB->SRBFlag            = 0;
 2149 
 2150         pSRB->SRBState     = TRM_FREE;
 2151         pSRB->AdaptStatus  = TRM_STATUS_GOOD;
 2152         pSRB->TargetStatus = SCSI_OK;
 2153         pSRB->ScsiPhase    = PH_BUS_FREE; /* SCSI bus free Phase */
 2154 
 2155         pSRB->xs      = NULL;
 2156         pSRB->pSRBDCB = NULL;
 2157 
 2158         if (pSRB != &sc->SRB[0])
 2159                 TAILQ_INSERT_TAIL(&sc->freeSRB, pSRB, link);
 2160 
 2161         splx(intflag);
 2162 }
 2163 
 2164 /*
 2165  * ------------------------------------------------------------
 2166  * Function : trm_GoingSRB_Done
 2167  * Purpose  :
 2168  * Inputs   : 
 2169  * ------------------------------------------------------------
 2170  */
 2171 void
 2172 trm_GoingSRB_Done(struct trm_softc *sc)
 2173 {
 2174         struct trm_scsi_req_q *pSRB;
 2175 
 2176         /* ASSUME we are inside a splbio()/splx() pair */
 2177 
 2178         while ((pSRB = TAILQ_FIRST(&sc->goingSRB)) != NULL) {
 2179                 /* TODO XXXX: Is TIMED_OUT the best status? */
 2180                 pSRB->SRBFlag |= TRM_SCSI_TIMED_OUT;
 2181                 trm_FinishSRB(sc, pSRB);
 2182         }
 2183 }
 2184 
 2185 /*
 2186  * ------------------------------------------------------------
 2187  * Function : trm_ResetSCSIBus
 2188  * Purpose  : Reset the SCSI bus
 2189  * Inputs   : struct trm_softc * - 
 2190  * ------------------------------------------------------------
 2191  */
 2192 void
 2193 trm_ResetSCSIBus(struct trm_softc *sc)
 2194 {
 2195         const bus_space_handle_t ioh = sc->sc_iohandle;
 2196         const bus_space_tag_t iot = sc->sc_iotag;
 2197         int intflag;
 2198 
 2199         intflag = splbio();
 2200 
 2201         sc->sc_Flag |= RESET_DEV;
 2202 
 2203         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_RSTSCSI);
 2204         while ((bus_space_read_2(iot, ioh,
 2205             TRM_S1040_SCSI_INTSTATUS) & INT_SCSIRESET) == 0);
 2206 
 2207         splx(intflag);
 2208 }
 2209 
 2210 /*
 2211  * ------------------------------------------------------------
 2212  * Function : trm_ScsiRstDetect
 2213  * Purpose  :
 2214  * Inputs   : 
 2215  * ------------------------------------------------------------
 2216  */
 2217 void
 2218 trm_ScsiRstDetect(struct trm_softc *sc)
 2219 {
 2220         const bus_space_handle_t ioh = sc->sc_iohandle;
 2221         const bus_space_tag_t iot = sc->sc_iotag;
 2222         int wlval;
 2223 
 2224 #ifdef TRM_DEBUG0
 2225         printf("%s: trm_ScsiRstDetect\n", sc->sc_device.dv_xname);
 2226 #endif
 2227 
 2228         wlval = 1000;
 2229         /*
 2230          * delay 1 sec
 2231          */
 2232         while (--wlval != 0)
 2233                 DELAY(1000);
 2234 
 2235         bus_space_write_1(iot, ioh, TRM_S1040_DMA_CONTROL, STOPDMAXFER);
 2236         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_CLRFIFO);
 2237 
 2238         if ((sc->sc_Flag & RESET_DEV) != 0)
 2239                 sc->sc_Flag |= RESET_DONE;
 2240         else {
 2241                 sc->sc_Flag |= RESET_DETECT;
 2242                 trm_ResetAllDevParam(sc);
 2243                 trm_RecoverSRB(sc);
 2244                 sc->pActiveDCB = NULL;
 2245                 sc->sc_Flag = 0;
 2246                 trm_StartWaitingSRB(sc);
 2247         }
 2248 }
 2249 
 2250 /*
 2251  * ------------------------------------------------------------
 2252  * Function : trm_RequestSense
 2253  * Purpose  :
 2254  * Inputs   : 
 2255  * ------------------------------------------------------------
 2256  */
 2257 void
 2258 trm_RequestSense(struct trm_softc *sc, struct trm_scsi_req_q *pSRB)
 2259 {
 2260         pSRB->SRBFlag |= TRM_AUTO_REQSENSE;
 2261 
 2262         /*
 2263          * Status of initiator/target
 2264          */
 2265         pSRB->AdaptStatus  = TRM_STATUS_GOOD;
 2266         pSRB->TargetStatus = SCSI_OK;
 2267         /*
 2268          * Status of initiator/target
 2269          */
 2270 
 2271         pSRB->SegmentX[0].address = pSRB->scsisensePhyAddr;
 2272         pSRB->SegmentX[0].length  = sizeof(struct scsi_sense_data);
 2273         pSRB->SRBTotalXferLength  = sizeof(struct scsi_sense_data);
 2274         pSRB->SRBSGCount          = 1;
 2275         pSRB->SRBSGIndex          = 0;
 2276 
 2277         bzero(&pSRB->CmdBlock[0], sizeof(pSRB->CmdBlock));
 2278 
 2279         pSRB->CmdBlock[0] = REQUEST_SENSE;
 2280         pSRB->CmdBlock[1] = (pSRB->xs->sc_link->lun) << 5;
 2281         pSRB->CmdBlock[4] = sizeof(struct scsi_sense_data);
 2282 
 2283         pSRB->ScsiCmdLen = 6;
 2284 
 2285         if ((pSRB->xs != NULL) && ((pSRB->xs->flags & SCSI_POLL) == 0))
 2286                 timeout_add(&pSRB->xs->stimeout, (pSRB->xs->timeout/1000) * hz);
 2287 
 2288         if (trm_StartSRB(sc, pSRB) != 0)
 2289                 trm_RewaitSRB(sc, pSRB);
 2290 }
 2291 
 2292 /*
 2293  * ------------------------------------------------------------
 2294  * Function : trm_EnableMsgOut
 2295  * Purpose  : set up MsgBuf to send out a single byte message
 2296  * Inputs   : 
 2297  * ------------------------------------------------------------
 2298  */
 2299 void
 2300 trm_EnableMsgOut(struct trm_softc *sc, u_int8_t msg)
 2301 {
 2302         sc->MsgBuf[0] = msg;
 2303         sc->MsgCnt    = 1;
 2304 
 2305         bus_space_write_2(sc->sc_iotag, sc->sc_iohandle, TRM_S1040_SCSI_CONTROL, DO_SETATN);
 2306 }
 2307 
 2308 /*
 2309  * ------------------------------------------------------------
 2310  * Function : trm_linkSRB
 2311  * Purpose  :
 2312  * Inputs   :
 2313  * ------------------------------------------------------------
 2314  */
 2315 void
 2316 trm_linkSRB(struct trm_softc *sc)
 2317 {
 2318         struct trm_scsi_req_q *pSRB;
 2319         int i, intflag;
 2320 
 2321         intflag = splbio();
 2322 
 2323         for (i = 0; i < TRM_MAX_SRB_CNT; i++) {
 2324                 pSRB = &sc->SRB[i];
 2325 
 2326                 pSRB->PhysSRB = sc->sc_dmamap_control->dm_segs[0].ds_addr
 2327                         + i * sizeof(struct trm_scsi_req_q);
 2328 
 2329                 pSRB->SRBSGPhyAddr = sc->sc_dmamap_control->dm_segs[0].ds_addr
 2330                         + i * sizeof(struct trm_scsi_req_q)
 2331                         + offsetof(struct trm_scsi_req_q, SegmentX);
 2332 
 2333                 pSRB->scsisensePhyAddr = sc->sc_dmamap_control->dm_segs[0].ds_addr
 2334                         + i * sizeof(struct trm_scsi_req_q)
 2335                         + offsetof(struct trm_scsi_req_q, scsisense);
 2336 
 2337                 /*
 2338                  * map all SRB space
 2339                  */
 2340                 if (bus_dmamap_create(sc->sc_dmatag, TRM_MAX_PHYSG_BYTE,
 2341                     TRM_MAX_SG_LISTENTRY, TRM_MAX_PHYSG_BYTE, 0,
 2342                     BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
 2343                     &pSRB->dmamapxfer) != 0) {
 2344                         printf("%s: unable to create DMA transfer map\n",
 2345                             sc->sc_device.dv_xname);
 2346                         splx(intflag);
 2347                         return;
 2348                 }
 2349 
 2350                 if (i > 0)
 2351                         /* We use sc->SRB[0] directly, so *don't* link it */
 2352                         TAILQ_INSERT_TAIL(&sc->freeSRB, pSRB, link);
 2353 #ifdef TRM_DEBUG0
 2354                 printf("pSRB = %p ", pSRB);
 2355 #endif
 2356         }
 2357 #ifdef TRM_DEBUG0
 2358         printf("\n ");
 2359 #endif
 2360         splx(intflag);
 2361 }
 2362 
 2363 /*
 2364  * ------------------------------------------------------------
 2365  * Function : trm_minphys
 2366  * Purpose  : limited by the number of segments in the dma segment list
 2367  * Inputs   : *buf
 2368  * ------------------------------------------------------------
 2369  */
 2370 void
 2371 trm_minphys(struct buf *bp)
 2372 {
 2373         if (bp->b_bcount > (TRM_MAX_SG_LISTENTRY-1) * (long) NBPG) {
 2374                 bp->b_bcount = (TRM_MAX_SG_LISTENTRY-1) * (long) NBPG;
 2375         }
 2376         minphys(bp);
 2377 }
 2378 
 2379 /*
 2380  * ------------------------------------------------------------
 2381  * Function : trm_initACB
 2382  * Purpose  : initialize the internal structures for a given SCSI host
 2383  * Inputs   : 
 2384  * ------------------------------------------------------------
 2385  */
 2386 void
 2387 trm_initACB(struct trm_softc *sc, int unit)
 2388 {
 2389         const bus_space_handle_t ioh = sc->sc_iohandle;
 2390         const bus_space_tag_t iot = sc->sc_iotag;
 2391         struct trm_adapter_nvram *pEEpromBuf;
 2392         struct trm_dcb *pDCB;
 2393         int target, lun;
 2394 
 2395         pEEpromBuf = &trm_eepromBuf[unit];
 2396         sc->sc_config = HCC_AUTOTERM | HCC_PARITY;
 2397 
 2398         if ((bus_space_read_1(iot, ioh, TRM_S1040_GEN_STATUS) & WIDESCSI) != 0)
 2399                 sc->sc_config |= HCC_WIDE_CARD;
 2400 
 2401         if ((pEEpromBuf->NvramChannelCfg & NAC_POWERON_SCSI_RESET) != 0)
 2402                 sc->sc_config |= HCC_SCSI_RESET;
 2403 
 2404         TAILQ_INIT(&sc->freeSRB);
 2405         TAILQ_INIT(&sc->waitingSRB);
 2406         TAILQ_INIT(&sc->goingSRB);
 2407 
 2408         sc->pActiveDCB     = NULL;
 2409         sc->sc_AdapterUnit = unit;
 2410         sc->sc_AdaptSCSIID = pEEpromBuf->NvramScsiId;
 2411         sc->sc_TagMaxNum   = 2 << pEEpromBuf->NvramMaxTag;
 2412         sc->sc_Flag        = 0;
 2413 
 2414         /* 
 2415          * put all SRB's (except [0]) onto the freeSRB list
 2416          */
 2417         trm_linkSRB(sc);
 2418 
 2419         /*
 2420          * allocate DCB array
 2421          */
 2422         for (target = 0; target < TRM_MAX_TARGETS; target++) {
 2423                 if (target == sc->sc_AdaptSCSIID)
 2424                         continue;
 2425 
 2426                 for (lun = 0; lun < TRM_MAX_LUNS; lun++) {
 2427                         pDCB = (struct trm_dcb *)malloc(sizeof(struct trm_dcb), M_DEVBUF, M_NOWAIT);
 2428                         sc->pDCB[target][lun] = pDCB;
 2429                         
 2430                         if (pDCB == NULL)
 2431                                 continue;
 2432 
 2433                         bzero(pDCB, sizeof(struct trm_dcb));
 2434 
 2435                         pDCB->target     = target;
 2436                         pDCB->lun        = lun;
 2437                         pDCB->pActiveSRB = NULL;
 2438                 }
 2439         }
 2440 
 2441         sc->sc_adapter.scsi_cmd     = trm_scsi_cmd; 
 2442         sc->sc_adapter.scsi_minphys = trm_minphys;
 2443 
 2444         sc->sc_link.adapter_softc    = sc;
 2445         sc->sc_link.adapter_target   = sc->sc_AdaptSCSIID;
 2446         sc->sc_link.openings         = 30; /* So TagMask (32 bit integer) always has space */
 2447         sc->sc_link.device           = &trm_device;
 2448         sc->sc_link.adapter          = &sc->sc_adapter;
 2449         sc->sc_link.adapter_buswidth = ((sc->sc_config & HCC_WIDE_CARD) == 0) ? 8:16;
 2450 
 2451         trm_reset(sc);
 2452 }
 2453 
 2454 /*
 2455  * ------------------------------------------------------------
 2456  * Function     : trm_write_all            
 2457  * Description  : write pEEpromBuf 128 bytes to seeprom    
 2458  * Input        : iot, ioh - chip's base address        
 2459  * Output       : none                        
 2460  * ------------------------------------------------------------
 2461  */
 2462 void
 2463 trm_write_all(struct trm_adapter_nvram *pEEpromBuf,  bus_space_tag_t iot,
 2464     bus_space_handle_t ioh)
 2465 {
 2466         u_int8_t *bpEeprom = (u_int8_t *)pEEpromBuf;
 2467         u_int8_t  bAddr;
 2468 
 2469         /*
 2470          * Enable SEEPROM
 2471          */
 2472         bus_space_write_1(iot, ioh, TRM_S1040_GEN_CONTROL,
 2473             (bus_space_read_1(iot, ioh, TRM_S1040_GEN_CONTROL) | EN_EEPROM));
 2474         /*
 2475          * Write enable
 2476          */
 2477         trm_write_cmd(iot, ioh, 0x04, 0xFF);
 2478         bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, 0);
 2479         trm_wait_30us(iot, ioh);
 2480         for (bAddr = 0; bAddr < 128; bAddr++, bpEeprom++)
 2481                 trm_set_data(iot, ioh, bAddr, *bpEeprom);
 2482         /* 
 2483          * Write disable
 2484          */
 2485         trm_write_cmd(iot, ioh, 0x04, 0x00);
 2486         bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, 0);
 2487         trm_wait_30us(iot, ioh);
 2488         /*
 2489          * Disable SEEPROM
 2490          */
 2491         bus_space_write_1(iot, ioh, TRM_S1040_GEN_CONTROL,
 2492             (bus_space_read_1(iot, ioh, TRM_S1040_GEN_CONTROL) & ~EN_EEPROM));
 2493 }
 2494 
 2495 /*
 2496  * ------------------------------------------------------------
 2497  * Function     : trm_set_data                    
 2498  * Description  : write one byte to seeprom
 2499  * Input        : iot, ioh - chip's base address    
 2500  *                  bAddr - address of SEEPROM        
 2501  *                  bData - data of SEEPROM    
 2502  * Output       : none                
 2503  * ------------------------------------------------------------
 2504  */
 2505 void
 2506 trm_set_data(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t bAddr,
 2507     u_int8_t bData)
 2508 {
 2509         u_int8_t bSendData;
 2510         int i;
 2511 
 2512         /* 
 2513          * Send write command & address    
 2514          */
 2515         trm_write_cmd(iot, ioh, 0x05, bAddr);
 2516         /* 
 2517          * Write data 
 2518          */
 2519         for (i = 0; i < 8; i++, bData <<= 1) {
 2520                 bSendData = NVR_SELECT;
 2521                 if ((bData & 0x80) != 0) {      /* Start from bit 7    */
 2522                         bSendData |= NVR_BITOUT;
 2523                 }
 2524                 bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, bSendData);
 2525                 trm_wait_30us(iot, ioh);
 2526                 bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM,
 2527                     (bSendData | NVR_CLOCK));
 2528                 trm_wait_30us(iot, ioh);
 2529         }
 2530         bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, NVR_SELECT);
 2531         trm_wait_30us(iot, ioh);
 2532         /*
 2533          * Disable chip select 
 2534          */
 2535         bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, 0);
 2536         trm_wait_30us(iot, ioh);
 2537         bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, NVR_SELECT);
 2538         trm_wait_30us(iot, ioh);
 2539         /* 
 2540          * Wait for write ready    
 2541          */
 2542         for (;;) {
 2543                 bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM,
 2544                     (NVR_SELECT | NVR_CLOCK));
 2545                 trm_wait_30us(iot, ioh);
 2546                 bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, NVR_SELECT);
 2547                 trm_wait_30us(iot, ioh);
 2548                 if (bus_space_read_1(iot, ioh, TRM_S1040_GEN_NVRAM) & NVR_BITIN)
 2549                         break;
 2550         }
 2551         /* 
 2552          * Disable chip select 
 2553          */
 2554         bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, 0);
 2555 }
 2556 
 2557 /*
 2558  * ------------------------------------------------------------
 2559  * Function     : trm_read_all                    
 2560  * Description  : read seeprom 128 bytes to pEEpromBuf
 2561  * Input        : pEEpromBuf, iot, ioh - chip's base address        
 2562  * Output       : none                        
 2563  * ------------------------------------------------------------
 2564  */
 2565 void
 2566 trm_read_all(struct trm_adapter_nvram *pEEpromBuf,  bus_space_tag_t iot,
 2567     bus_space_handle_t ioh)
 2568 {
 2569         u_int8_t *bpEeprom = (u_int8_t *)pEEpromBuf;
 2570         u_int8_t  bAddr;
 2571         
 2572         /*
 2573          * Enable SEEPROM 
 2574          */
 2575         bus_space_write_1(iot, ioh, TRM_S1040_GEN_CONTROL,
 2576             (bus_space_read_1(iot, ioh, TRM_S1040_GEN_CONTROL) | EN_EEPROM));
 2577 
 2578         for (bAddr = 0; bAddr < 128; bAddr++, bpEeprom++)
 2579                 *bpEeprom = trm_get_data(iot, ioh, bAddr);
 2580 
 2581         /* 
 2582          * Disable SEEPROM 
 2583          */
 2584         bus_space_write_1(iot, ioh, TRM_S1040_GEN_CONTROL,
 2585             (bus_space_read_1(iot, ioh, TRM_S1040_GEN_CONTROL) & ~EN_EEPROM));
 2586 }
 2587 
 2588 /*
 2589  * ------------------------------------------------------------
 2590  * Function     : trm_get_data                        
 2591  * Description  : read one byte from seeprom    
 2592  * Input        : iot, ioh - chip's base address
 2593  *                     bAddr - address of SEEPROM        
 2594  * Output       : bData - data of SEEPROM        
 2595  * ------------------------------------------------------------
 2596  */
 2597 u_int8_t
 2598 trm_get_data( bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t bAddr)
 2599 {
 2600         u_int8_t bReadData, bData;
 2601         int i;
 2602 
 2603         bData = 0;
 2604 
 2605         /* 
 2606          * Send read command & address
 2607          */
 2608         trm_write_cmd(iot, ioh, 0x06, bAddr);
 2609                                 
 2610         for (i = 0; i < 8; i++) {
 2611                 /* 
 2612                  * Read data
 2613                  */
 2614                 bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM,
 2615                     (NVR_SELECT | NVR_CLOCK));
 2616                 trm_wait_30us(iot, ioh);
 2617                 bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, NVR_SELECT);
 2618                 /* 
 2619                  * Get data bit while falling edge 
 2620                  */
 2621                 bReadData = bus_space_read_1(iot, ioh, TRM_S1040_GEN_NVRAM);
 2622                 bData <<= 1;
 2623                 if ((bReadData & NVR_BITIN) != 0)
 2624                         bData |= 1;
 2625                 trm_wait_30us(iot, ioh);
 2626         }
 2627         /* 
 2628          * Disable chip select 
 2629          */
 2630         bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, 0);
 2631 
 2632         return bData;
 2633 }
 2634 
 2635 /*
 2636  * ------------------------------------------------------------
 2637  * Function     : trm_wait_30us                    
 2638  * Description  : wait 30 us                        
 2639  * Input        : iot, ioh - chip's base address            
 2640  * Output       : none                            
 2641  * ------------------------------------------------------------
 2642  */
 2643 void
 2644 trm_wait_30us(bus_space_tag_t iot, bus_space_handle_t ioh)
 2645 {
 2646         bus_space_write_1(iot, ioh, TRM_S1040_GEN_TIMER, 5);
 2647 
 2648         while ((bus_space_read_1(iot, ioh, TRM_S1040_GEN_STATUS) & GTIMEOUT)
 2649             == 0);
 2650 }
 2651 
 2652 /*
 2653  * ------------------------------------------------------------
 2654  * Function     : trm_write_cmd                        
 2655  * Description  : write SB and Op Code into seeprom    
 2656  * Input        : iot, ioh - chip's base address            
 2657  *                  bCmd     - SB + Op Code                
 2658  *                  bAddr    - address of SEEPROM        
 2659  * Output       : none                    
 2660  * ------------------------------------------------------------
 2661  */
 2662 void
 2663 trm_write_cmd( bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t bCmd,
 2664     u_int8_t bAddr)
 2665 {
 2666         u_int8_t bSendData;
 2667         int i;
 2668 
 2669         for (i = 0; i < 3; i++, bCmd <<= 1) {
 2670                 /* 
 2671                  * Program SB + OP code        
 2672                  */
 2673                 bSendData = NVR_SELECT;
 2674                 if (bCmd & 0x04)        /* Start from bit 2        */
 2675                         bSendData |= NVR_BITOUT;
 2676                 bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, bSendData);
 2677                 trm_wait_30us(iot, ioh);
 2678                 bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM,
 2679                     (bSendData | NVR_CLOCK));
 2680                 trm_wait_30us(iot, ioh);
 2681         }
 2682                                 
 2683         for (i = 0; i < 7; i++, bAddr <<= 1) {
 2684                 /* 
 2685                  * Program address        
 2686                  */
 2687                 bSendData = NVR_SELECT;
 2688                 if (bAddr & 0x40) {        /* Start from bit 6        */
 2689                         bSendData |= NVR_BITOUT;
 2690                 }
 2691                 bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, bSendData);
 2692                 trm_wait_30us(iot, ioh);
 2693                 bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM,
 2694                     (bSendData | NVR_CLOCK));
 2695                 trm_wait_30us(iot, ioh);
 2696         }
 2697         bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, NVR_SELECT);
 2698         trm_wait_30us(iot, ioh);
 2699 }
 2700 
 2701 /*
 2702  * ------------------------------------------------------------
 2703  * Function     : trm_check_eeprom                
 2704  * Description  : read eeprom 128 bytes to pEEpromBuf and check
 2705  *                  checksum. If it is wrong, updated with default value.
 2706  * Input        : eeprom, iot, ioh - chip's base address        
 2707  * Output       : none                    
 2708  * ------------------------------------------------------------
 2709  */
 2710 void
 2711 trm_check_eeprom(struct trm_adapter_nvram *pEEpromBuf, bus_space_tag_t iot,
 2712     bus_space_handle_t ioh)
 2713 {
 2714         u_int32_t *dpEeprom = (u_int32_t *)pEEpromBuf->NvramTarget;
 2715         u_int32_t  dAddr;
 2716         u_int16_t *wpEeprom = (u_int16_t *)pEEpromBuf;
 2717         u_int16_t  wAddr, wCheckSum;
 2718 
 2719 #ifdef TRM_DEBUG0
 2720         printf("\ntrm_check_eeprom\n");
 2721 #endif
 2722         trm_read_all(pEEpromBuf, iot, ioh);
 2723         wCheckSum = 0;
 2724         for (wAddr = 0; wAddr < 64; wAddr++, wpEeprom++)
 2725                 wCheckSum += *wpEeprom;
 2726 
 2727         if (wCheckSum != 0x1234) {  
 2728 #ifdef TRM_DEBUG0
 2729                 printf("TRM_S1040 EEPROM Check Sum ERROR (load default)\n");
 2730 #endif
 2731                 /* 
 2732                  * Checksum error, load default    
 2733                  */
 2734                 pEEpromBuf->NvramSubVendorID[0] = (u_int8_t)PCI_VENDOR_TEKRAM2;
 2735                 pEEpromBuf->NvramSubVendorID[1] = (u_int8_t)(PCI_VENDOR_TEKRAM2
 2736                     >> 8);
 2737                 pEEpromBuf->NvramSubSysID[0] = (u_int8_t)
 2738                     PCI_PRODUCT_TEKRAM2_DC3X5U;
 2739                 pEEpromBuf->NvramSubSysID[1] = (u_int8_t)
 2740                     (PCI_PRODUCT_TEKRAM2_DC3X5U >> 8);
 2741                 pEEpromBuf->NvramSubClass    = 0;
 2742                 pEEpromBuf->NvramVendorID[0] = (u_int8_t)PCI_VENDOR_TEKRAM2;
 2743                 pEEpromBuf->NvramVendorID[1] = (u_int8_t)(PCI_VENDOR_TEKRAM2
 2744                     >> 8);
 2745                 pEEpromBuf->NvramDeviceID[0] = (u_int8_t)
 2746                     PCI_PRODUCT_TEKRAM2_DC3X5U;
 2747                 pEEpromBuf->NvramDeviceID[1] = (u_int8_t)
 2748                     (PCI_PRODUCT_TEKRAM2_DC3X5U >> 8);
 2749                 pEEpromBuf->NvramReserved    = 0;
 2750 
 2751                 for (dAddr = 0; dAddr < 16; dAddr++, dpEeprom++)
 2752                         /*
 2753                          * NvmTarCfg3,NvmTarCfg2,NvmTarPeriod,NvmTarCfg0
 2754                          */
 2755                         *dpEeprom = 0x00000077;
 2756 
 2757                 /*
 2758                  * NvramMaxTag,NvramDelayTime,NvramChannelCfg,NvramScsiId
 2759                  */
 2760                 *dpEeprom++ = 0x04000F07;
 2761 
 2762                 /*
 2763                  * NvramReserved1,NvramBootLun,NvramBootTarget,NvramReserved0
 2764                  */
 2765                 *dpEeprom++ = 0x00000015;
 2766                 for (dAddr = 0; dAddr < 12; dAddr++, dpEeprom++)
 2767                         *dpEeprom = 0;
 2768 
 2769                 pEEpromBuf->NvramCheckSum = 0;
 2770                 for (wAddr = 0, wCheckSum =0; wAddr < 63; wAddr++, wpEeprom++)
 2771                         wCheckSum += *wpEeprom;
 2772 
 2773                 *wpEeprom = 0x1234 - wCheckSum;
 2774                 trm_write_all(pEEpromBuf, iot, ioh);
 2775         }
 2776 }
 2777 
 2778 /*
 2779  * ------------------------------------------------------------
 2780  * Function : trm_initAdapter
 2781  * Purpose  : initialize the SCSI chip ctrl registers
 2782  * Inputs   : psh - pointer to this host adapter's structure
 2783  * ------------------------------------------------------------
 2784  */
 2785 void
 2786 trm_initAdapter(struct trm_softc *sc)
 2787 {
 2788         const bus_space_handle_t ioh = sc->sc_iohandle;
 2789         const bus_space_tag_t iot = sc->sc_iotag;
 2790         u_int16_t wval;
 2791         u_int8_t bval;
 2792 
 2793         /*
 2794          * program configuration 0
 2795          */
 2796         if ((sc->sc_config & HCC_PARITY) != 0) {
 2797                 bval = PHASELATCH | INITIATOR | BLOCKRST | PARITYCHECK;
 2798         } else {
 2799                 bval = PHASELATCH | INITIATOR | BLOCKRST;
 2800         }
 2801         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_CONFIG0, bval); 
 2802         /*
 2803          * program configuration 1
 2804          */
 2805         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_CONFIG1, 0x13); 
 2806         /*
 2807          * 250ms selection timeout
 2808          */
 2809         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_TIMEOUT, TRM_SEL_TIMEOUT);
 2810         /*
 2811          * Mask all the interrupt
 2812          */
 2813         bus_space_write_1(iot, ioh, TRM_S1040_DMA_INTEN,  0);    
 2814         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_INTEN, 0);     
 2815         /*
 2816          * Reset SCSI module
 2817          */
 2818         bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_RSTMODULE); 
 2819         /*
 2820          * program Host ID
 2821          */
 2822         bval = sc->sc_AdaptSCSIID;
 2823         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_HOSTID, bval); 
 2824         /*
 2825          * set ansynchronous transfer
 2826          */
 2827         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_OFFSET, 0); 
 2828         /*
 2829          * Turn LED control off
 2830          */
 2831         wval = bus_space_read_2(iot, ioh, TRM_S1040_GEN_CONTROL) & 0x7F;
 2832         bus_space_write_2(iot, ioh, TRM_S1040_GEN_CONTROL, wval); 
 2833         /*
 2834          * DMA config
 2835          */
 2836         wval = bus_space_read_2(iot, ioh, TRM_S1040_DMA_CONFIG) | DMA_ENHANCE;
 2837         bus_space_write_2(iot, ioh, TRM_S1040_DMA_CONFIG, wval); 
 2838         /*
 2839          * Clear pending interrupt status
 2840          */
 2841         bus_space_read_1(iot, ioh, TRM_S1040_SCSI_INTSTATUS);
 2842         /*
 2843          * Enable SCSI interrupts
 2844          */
 2845         bus_space_write_1(iot, ioh, TRM_S1040_SCSI_INTEN,
 2846             (EN_SELECT | EN_SELTIMEOUT | EN_DISCONNECT | EN_RESELECTED |
 2847                 EN_SCSIRESET | EN_BUSSERVICE | EN_CMDDONE)); 
 2848         bus_space_write_1(iot, ioh, TRM_S1040_DMA_INTEN, EN_SCSIINTR); 
 2849 }
 2850 
 2851 /*
 2852  * ------------------------------------------------------------
 2853  * Function      : trm_init
 2854  * Purpose       : initialize the internal structures for a given SCSI host
 2855  * Inputs        : host - pointer to this host adapter's structure
 2856  * Preconditions : when this function is called, the chip_type field of 
 2857  *                 the ACB structure MUST have been set.
 2858  * ------------------------------------------------------------
 2859  */
 2860 int
 2861 trm_init(struct trm_softc *sc, int unit)
 2862 {
 2863         const bus_space_handle_t ioh = sc->sc_iohandle;
 2864         const bus_space_tag_t iot = sc->sc_iotag;
 2865         bus_dma_segment_t seg;
 2866         int error, rseg, all_srbs_size;
 2867 
 2868         /*
 2869          * EEPROM CHECKSUM
 2870          */
 2871         trm_check_eeprom(&trm_eepromBuf[unit], iot, ioh);
 2872 
 2873         /*
 2874          * MEMORY ALLOCATE FOR ADAPTER CONTROL BLOCK
 2875          */
 2876         /*
 2877          * allocate the space for all SCSI control blocks (SRB) for DMA memory.
 2878          */
 2879         all_srbs_size = TRM_MAX_SRB_CNT * sizeof(struct trm_scsi_req_q);
 2880 
 2881         error = bus_dmamem_alloc(sc->sc_dmatag, all_srbs_size, NBPG, 0, &seg,
 2882             1, &rseg, BUS_DMA_NOWAIT);
 2883         if (error != 0) {
 2884                 printf("%s: unable to allocate SCSI REQUEST BLOCKS, error = %d\n",
 2885                     sc->sc_device.dv_xname, error);
 2886                 /*errx(error, "%s: unable to allocate SCSI request blocks",
 2887                     sc->sc_device.dv_xname);*/
 2888                 return -1;
 2889         }
 2890 
 2891         error = bus_dmamem_map(sc->sc_dmatag, &seg, rseg, all_srbs_size,
 2892             (caddr_t *)&sc->SRB, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
 2893         if (error != 0) {
 2894                 printf("%s: unable to map SCSI REQUEST BLOCKS, error = %d\n",
 2895                     sc->sc_device.dv_xname, error);
 2896                 /*errx(error, "unable to map SCSI request blocks");*/
 2897                 return -1;
 2898         }
 2899 
 2900         error = bus_dmamap_create(sc->sc_dmatag, all_srbs_size, 1,
 2901             all_srbs_size, 0, BUS_DMA_NOWAIT,&sc->sc_dmamap_control);
 2902         if (error != 0) {
 2903                 printf("%s: unable to create SRB DMA maps, error = %d\n",
 2904                     sc->sc_device.dv_xname, error);
 2905                 /*errx(error, "unable to create SRB DMA maps");*/
 2906                 return -1;
 2907         }
 2908 
 2909         error = bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap_control,
 2910             sc->SRB, all_srbs_size, NULL, BUS_DMA_NOWAIT);
 2911         if (error != 0) {
 2912                 printf("%s: unable to load SRB DMA maps, error = %d\n",
 2913                     sc->sc_device.dv_xname, error);
 2914                 /*errx(error, "unable to load SRB DMA maps");*/
 2915                 return -1;
 2916         }
 2917 #ifdef TRM_DEBUG0
 2918         printf("\n\n%s: all_srbs_size=%x\n", 
 2919             sc->sc_device.dv_xname, all_srbs_size);
 2920 #endif
 2921         bzero(sc->SRB, all_srbs_size);
 2922         trm_initACB(sc, unit);
 2923         trm_initAdapter(sc);
 2924 
 2925         return 0;
 2926 }
 2927 
 2928 /* ------------------------------------------------------------
 2929  * Function : trm_print_info
 2930  * Purpose  : Print the DCB negotiation information
 2931  * Inputs   : 
 2932  * ------------------------------------------------------------
 2933  */
 2934 void
 2935 trm_print_info(struct trm_softc *sc, struct trm_dcb *pDCB)
 2936 {
 2937         int syncXfer, index;
 2938 
 2939         index = pDCB->SyncPeriod & ~(WIDE_SYNC | ALT_SYNC);
 2940 
 2941         printf("%s: target %d using ", sc->sc_device.dv_xname, pDCB->target);
 2942         if ((pDCB->SyncPeriod & WIDE_SYNC) != 0)
 2943                 printf("16 bit ");
 2944         else
 2945                 printf("8 bit ");
 2946 
 2947         if (pDCB->SyncOffset == 0)
 2948                 printf("Asynchronous ");
 2949         else {
 2950                 syncXfer = 100000 / (trm_clock_period[index] * 4);
 2951                 printf("%d.%01d MHz, Offset %d ",
 2952                     syncXfer / 100, syncXfer % 100, pDCB->SyncOffset);
 2953         }
 2954         printf("data transfers ");
 2955 
 2956         if ((pDCB->DCBFlag & TRM_USE_TAG_QUEUING) != 0)
 2957                 printf("with Tag Queuing");
 2958 
 2959         printf("\n");
 2960 }

/* [<][>][^][v][top][bottom][index][help] */