[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

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