[BACK]Return to trm.c CVS log [TXT][DIR] Up to [local] / sys / dev / ic

Annotation of sys/dev/ic/trm.c, Revision 1.1

1.1     ! nbrk        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: }

CVSweb