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

Annotation of sys/dev/ic/isp.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: isp.c,v 1.39 2007/05/23 01:32:25 ray Exp $ */
                      2: /*
                      3:  * Machine and OS Independent (well, as best as possible)
                      4:  * code for the Qlogic ISP SCSI adapters.
                      5:  *
                      6:  * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob
                      7:  * Feral Software
                      8:  * All rights reserved.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice immediately at the beginning of the file, without modification,
                     15:  *    this list of conditions, and the following disclaimer.
                     16:  * 2. The name of the author may not be used to endorse or promote products
                     17:  *    derived from this software without specific prior written permission.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     22:  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
                     23:  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     29:  * SUCH DAMAGE.
                     30:  */
                     31:
                     32: /*
                     33:  * Inspiration and ideas about this driver are from Erik Moe's Linux driver
                     34:  * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
                     35:  * ideas dredged from the Solaris driver.
                     36:  */
                     37:
                     38: /*
                     39:  * Include header file appropriate for platform we're building on.
                     40:  */
                     41:
                     42: #ifdef __NetBSD__
                     43: #include <dev/ic/isp_netbsd.h>
                     44: #endif
                     45: #ifdef __FreeBSD__
                     46: #include <dev/isp/isp_freebsd.h>
                     47: #endif
                     48: #ifdef __OpenBSD__
                     49: #include <dev/ic/isp_openbsd.h>
                     50: #endif
                     51: #ifdef __linux__
                     52: #include "isp_linux.h"
                     53: #endif
                     54: #ifdef __svr4__
                     55: #include "isp_solaris.h"
                     56: #endif
                     57:
                     58: /*
                     59:  * General defines
                     60:  */
                     61:
                     62: #define        MBOX_DELAY_COUNT        1000000 / 100
                     63:
                     64: /*
                     65:  * Local static data
                     66:  */
                     67: static const char portshift[] =
                     68:     "Target %d Loop ID 0x%x (Port 0x%x) => Loop 0x%x (Port 0x%x)";
                     69: static const char portdup[] =
                     70:     "Target %d duplicates Target %d- killing off both";
                     71: static const char retained[] =
                     72:     "Retaining Loop ID 0x%x for Target %d (Port 0x%x)";
                     73: static const char lretained[] =
                     74:     "Retained login of Target %d (Loop ID 0x%x) Port 0x%x";
                     75: static const char plogout[] =
                     76:     "Logging out Target %d at Loop ID 0x%x (Port 0x%x)";
                     77: static const char plogierr[] =
                     78:     "Command Error in PLOGI for Port 0x%x (0x%x)";
                     79: static const char nopdb[] =
                     80:     "Could not get PDB for Device @ Port 0x%x";
                     81: static const char pdbmfail1[] =
                     82:     "PDB Loop ID info for Device @ Port 0x%x does not match up (0x%x)";
                     83: static const char pdbmfail2[] =
                     84:     "PDB Port info for Device @ Port 0x%x does not match up (0x%x)";
                     85: static const char ldumped[] =
                     86:     "Target %d (Loop ID 0x%x) Port 0x%x dumped after login info mismatch";
                     87: static const char notresp[] =
                     88:   "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
                     89: static const char xact1[] =
                     90:     "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
                     91: static const char xact2[] =
                     92:     "HBA attempted queued transaction to target routine %d on target %d bus %d";
                     93: static const char xact3[] =
                     94:     "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
                     95: static const char pskip[] =
                     96:     "SCSI phase skipped for target %d.%d.%d";
                     97: static const char topology[] =
                     98:     "Loop ID %d, AL_PA 0x%x, Port ID 0x%x, Loop State 0x%x, Topology '%s'";
                     99: static const char swrej[] =
                    100:     "Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x";
                    101: static const char finmsg[] =
                    102:     "(%d.%d.%d): FIN dl%d resid %lu STS 0x%x SKEY %c XS_ERR=0x%x";
                    103: static const char sc0[] =
                    104:     "%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x";
                    105: static const char sc1[] =
                    106:     "%s RAAN 0x%x DLAN 0x%x DDMAB 0x%x CDMAB 0x%x SELTIME %d MQD %d";
                    107: static const char sc2[] = "%s CHAN %d TGT %d FLAGS 0x%x 0x%x/0x%x";
                    108: static const char sc3[] = "Generated";
                    109: static const char sc4[] = "NVRAM";
                    110: static const char bun[] =
                    111:     "bad underrun for %d.%d (count %d, resid %d, status %s)";
                    112:
                    113: /*
                    114:  * Local function prototypes.
                    115:  */
                    116: static int isp_parse_async(struct ispsoftc *, u_int16_t);
                    117: static int isp_handle_other_response(struct ispsoftc *, int, isphdr_t *,
                    118:     u_int16_t *);
                    119: static void
                    120: isp_parse_status(struct ispsoftc *, ispstatusreq_t *, XS_T *);
                    121: static void isp_fastpost_complete(struct ispsoftc *, u_int16_t);
                    122: static int isp_mbox_continue(struct ispsoftc *);
                    123: static void isp_scsi_init(struct ispsoftc *);
                    124: static void isp_scsi_channel_init(struct ispsoftc *, int);
                    125: static void isp_fibre_init(struct ispsoftc *);
                    126: static void isp_mark_getpdb_all(struct ispsoftc *);
                    127: static int isp_getmap(struct ispsoftc *, fcpos_map_t *);
                    128: static int isp_getpdb(struct ispsoftc *, int, isp_pdb_t *);
                    129: static u_int64_t isp_get_portname(struct ispsoftc *, int, int);
                    130: static int isp_fclink_test(struct ispsoftc *, int);
                    131: static char *isp2100_fw_statename(int);
                    132: static int isp_pdb_sync(struct ispsoftc *);
                    133: static int isp_scan_loop(struct ispsoftc *);
                    134: static int isp_fabric_mbox_cmd(struct ispsoftc *, mbreg_t *);
                    135: static int isp_scan_fabric(struct ispsoftc *, int);
                    136: static void isp_register_fc4_type(struct ispsoftc *);
                    137: static void isp_fw_state(struct ispsoftc *);
                    138: static void isp_mboxcmd_qnw(struct ispsoftc *, mbreg_t *, int);
                    139: static void isp_mboxcmd(struct ispsoftc *, mbreg_t *, int);
                    140:
                    141: static void isp_update(struct ispsoftc *);
                    142: static void isp_update_bus(struct ispsoftc *, int);
                    143: static void isp_setdfltparm(struct ispsoftc *, int);
                    144: static int isp_read_nvram(struct ispsoftc *);
                    145: static void isp_rdnvram_word(struct ispsoftc *, int, u_int16_t *);
                    146: static void isp_parse_nvram_1020(struct ispsoftc *, u_int8_t *);
                    147: static void isp_parse_nvram_1080(struct ispsoftc *, int, u_int8_t *);
                    148: static void isp_parse_nvram_12160(struct ispsoftc *, int, u_int8_t *);
                    149: static void isp_parse_nvram_2100(struct ispsoftc *, u_int8_t *);
                    150:
                    151: /*
                    152:  * Reset Hardware.
                    153:  *
                    154:  * Hit the chip over the head, download new f/w if available and set it running.
                    155:  *
                    156:  * Locking done elsewhere.
                    157:  */
                    158:
                    159: void
                    160: isp_reset(struct ispsoftc *isp)
                    161: {
                    162:        mbreg_t mbs;
                    163:        u_int16_t code_org;
                    164:        int loops, i, dodnld = 1;
                    165:        char *btype = "????";
                    166:
                    167:        isp->isp_state = ISP_NILSTATE;
                    168:
                    169:        /*
                    170:         * Basic types (SCSI, FibreChannel and PCI or SBus)
                    171:         * have been set in the MD code. We figure out more
                    172:         * here. Possibly more refined types based upon PCI
                    173:         * identification. Chip revision has been gathered.
                    174:         *
                    175:         * After we've fired this chip up, zero out the conf1 register
                    176:         * for SCSI adapters and do other settings for the 2100.
                    177:         */
                    178:
                    179:        /*
                    180:         * Get the current running firmware revision out of the
                    181:         * chip before we hit it over the head (if this is our
                    182:         * first time through). Note that we store this as the
                    183:         * 'ROM' firmware revision- which it may not be. In any
                    184:         * case, we don't really use this yet, but we may in
                    185:         * the future.
                    186:         */
                    187:        if (isp->isp_touched == 0) {
                    188:                /*
                    189:                 * First see whether or not we're sitting in the ISP PROM.
                    190:                 * If we've just been reset, we'll have the string "ISP   "
                    191:                 * spread through outgoing mailbox registers 1-3. We do
                    192:                 * this for PCI cards because otherwise we really don't
                    193:                 * know what state the card is in and we could hang if
                    194:                 * we try this command otherwise.
                    195:                 *
                    196:                 * For SBus cards, we just do this because they almost
                    197:                 * certainly will be running firmware by now.
                    198:                 */
                    199:                if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 ||
                    200:                    ISP_READ(isp, OUTMAILBOX2) != 0x5020 ||
                    201:                    ISP_READ(isp, OUTMAILBOX3) != 0x2020) {
                    202:                        /*
                    203:                         * Just in case it was paused...
                    204:                         */
                    205:                        ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
                    206:                        mbs.param[0] = MBOX_ABOUT_FIRMWARE;
                    207:                        isp_mboxcmd(isp, &mbs, MBLOGNONE);
                    208:                        if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
                    209:                                isp->isp_romfw_rev[0] = mbs.param[1];
                    210:                                isp->isp_romfw_rev[1] = mbs.param[2];
                    211:                                isp->isp_romfw_rev[2] = mbs.param[3];
                    212:                        }
                    213:                }
                    214:                isp->isp_touched = 1;
                    215:        }
                    216:
                    217:        DISABLE_INTS(isp);
                    218:
                    219:        /*
                    220:         * Set up default request/response queue in-pointer/out-pointer
                    221:         * register indices.
                    222:         */
                    223:        if (IS_23XX(isp)) {
                    224:                isp->isp_rqstinrp = BIU_REQINP;
                    225:                isp->isp_rqstoutrp = BIU_REQOUTP;
                    226:                isp->isp_respinrp = BIU_RSPINP;
                    227:                isp->isp_respoutrp = BIU_RSPOUTP;
                    228:        } else {
                    229:                isp->isp_rqstinrp = INMAILBOX4;
                    230:                isp->isp_rqstoutrp = OUTMAILBOX4;
                    231:                isp->isp_respinrp = OUTMAILBOX5;
                    232:                isp->isp_respoutrp = INMAILBOX5;
                    233:        }
                    234:
                    235:        /*
                    236:         * Put the board into PAUSE mode (so we can read the SXP registers
                    237:         * or write FPM/FBM registers).
                    238:         */
                    239:        ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
                    240:
                    241:        if (IS_FC(isp)) {
                    242:                switch (isp->isp_type) {
                    243:                case ISP_HA_FC_2100:
                    244:                        btype = "2100";
                    245:                        break;
                    246:                case ISP_HA_FC_2200:
                    247:                        btype = "2200";
                    248:                        break;
                    249:                case ISP_HA_FC_2300:
                    250:                        btype = "2300";
                    251:                        break;
                    252:                case ISP_HA_FC_2312:
                    253:                        btype = "2312";
                    254:                        break;
                    255:                default:
                    256:                        break;
                    257:                }
                    258:                /*
                    259:                 * While we're paused, reset the FPM module and FBM fifos.
                    260:                 */
                    261:                ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
                    262:                ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
                    263:                ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
                    264:                ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
                    265:                ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
                    266:        } else if (IS_1240(isp)) {
                    267:                sdparam *sdp = isp->isp_param;
                    268:                btype = "1240";
                    269:                isp->isp_clock = 60;
                    270:                sdp->isp_ultramode = 1;
                    271:                sdp++;
                    272:                sdp->isp_ultramode = 1;
                    273:                /*
                    274:                 * XXX: Should probably do some bus sensing.
                    275:                 */
                    276:        } else if (IS_ULTRA2(isp)) {
                    277:                static const char m[] = "bus %d is in %s Mode";
                    278:                u_int16_t l;
                    279:                sdparam *sdp = isp->isp_param;
                    280:
                    281:                isp->isp_clock = 100;
                    282:
                    283:                if (IS_1280(isp))
                    284:                        btype = "1280";
                    285:                else if (IS_1080(isp))
                    286:                        btype = "1080";
                    287:                else if (IS_10160(isp))
                    288:                        btype = "10160";
                    289:                else if (IS_12160(isp))
                    290:                        btype = "12160";
                    291:                else
                    292:                        btype = "<UNKLVD>";
                    293:
                    294:                l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
                    295:                switch (l) {
                    296:                case ISP1080_LVD_MODE:
                    297:                        sdp->isp_lvdmode = 1;
                    298:                        isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
                    299:                        break;
                    300:                case ISP1080_HVD_MODE:
                    301:                        sdp->isp_diffmode = 1;
                    302:                        isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
                    303:                        break;
                    304:                case ISP1080_SE_MODE:
                    305:                        sdp->isp_ultramode = 1;
                    306:                        isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
                    307:                        break;
                    308:                default:
                    309:                        isp_prt(isp, ISP_LOGERR,
                    310:                            "unknown mode on bus %d (0x%x)", 0, l);
                    311:                        break;
                    312:                }
                    313:
                    314:                if (IS_DUALBUS(isp)) {
                    315:                        sdp++;
                    316:                        l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
                    317:                        l &= ISP1080_MODE_MASK;
                    318:                        switch(l) {
                    319:                        case ISP1080_LVD_MODE:
                    320:                                sdp->isp_lvdmode = 1;
                    321:                                isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
                    322:                                break;
                    323:                        case ISP1080_HVD_MODE:
                    324:                                sdp->isp_diffmode = 1;
                    325:                                isp_prt(isp, ISP_LOGCONFIG,
                    326:                                    m, 1, "Differential");
                    327:                                break;
                    328:                        case ISP1080_SE_MODE:
                    329:                                sdp->isp_ultramode = 1;
                    330:                                isp_prt(isp, ISP_LOGCONFIG,
                    331:                                    m, 1, "Single-Ended");
                    332:                                break;
                    333:                        default:
                    334:                                isp_prt(isp, ISP_LOGERR,
                    335:                                    "unknown mode on bus %d (0x%x)", 1, l);
                    336:                                break;
                    337:                        }
                    338:                }
                    339:        } else {
                    340:                sdparam *sdp = isp->isp_param;
                    341:                i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
                    342:                switch (i) {
                    343:                default:
                    344:                        isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
                    345:                        /* FALLTHROUGH */
                    346:                case 1:
                    347:                        btype = "1020";
                    348:                        isp->isp_type = ISP_HA_SCSI_1020;
                    349:                        isp->isp_clock = 40;
                    350:                        break;
                    351:                case 2:
                    352:                        /*
                    353:                         * Some 1020A chips are Ultra Capable, but don't
                    354:                         * run the clock rate up for that unless told to
                    355:                         * do so by the Ultra Capable bits being set.
                    356:                         */
                    357:                        btype = "1020A";
                    358:                        isp->isp_type = ISP_HA_SCSI_1020A;
                    359:                        isp->isp_clock = 40;
                    360:                        break;
                    361:                case 3:
                    362:                        btype = "1040";
                    363:                        isp->isp_type = ISP_HA_SCSI_1040;
                    364:                        isp->isp_clock = 60;
                    365:                        break;
                    366:                case 4:
                    367:                        btype = "1040A";
                    368:                        isp->isp_type = ISP_HA_SCSI_1040A;
                    369:                        isp->isp_clock = 60;
                    370:                        break;
                    371:                case 5:
                    372:                        btype = "1040B";
                    373:                        isp->isp_type = ISP_HA_SCSI_1040B;
                    374:                        isp->isp_clock = 60;
                    375:                        break;
                    376:                case 6:
                    377:                        btype = "1040C";
                    378:                        isp->isp_type = ISP_HA_SCSI_1040C;
                    379:                        isp->isp_clock = 60;
                    380:                         break;
                    381:                }
                    382:                /*
                    383:                 * Now, while we're at it, gather info about ultra
                    384:                 * and/or differential mode.
                    385:                 */
                    386:                if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
                    387:                        isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
                    388:                        sdp->isp_diffmode = 1;
                    389:                } else {
                    390:                        sdp->isp_diffmode = 0;
                    391:                }
                    392:                i = ISP_READ(isp, RISC_PSR);
                    393:                if (isp->isp_bustype == ISP_BT_SBUS) {
                    394:                        i &= RISC_PSR_SBUS_ULTRA;
                    395:                } else {
                    396:                        i &= RISC_PSR_PCI_ULTRA;
                    397:                }
                    398:                if (i != 0) {
                    399:                        isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
                    400:                        sdp->isp_ultramode = 1;
                    401:                        /*
                    402:                         * If we're in Ultra Mode, we have to be 60MHz clock-
                    403:                         * even for the SBus version.
                    404:                         */
                    405:                        isp->isp_clock = 60;
                    406:                } else {
                    407:                        sdp->isp_ultramode = 0;
                    408:                        /*
                    409:                         * Clock is known. Gronk.
                    410:                         */
                    411:                }
                    412:
                    413:                /*
                    414:                 * Machine dependent clock (if set) overrides
                    415:                 * our generic determinations.
                    416:                 */
                    417:                if (isp->isp_mdvec->dv_clock) {
                    418:                        if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
                    419:                                isp->isp_clock = isp->isp_mdvec->dv_clock;
                    420:                        }
                    421:                }
                    422:
                    423:        }
                    424:
                    425:        /*
                    426:         * Clear instrumentation
                    427:         */
                    428:        isp->isp_intcnt = isp->isp_intbogus = 0;
                    429:
                    430:        /*
                    431:         * Do MD specific pre initialization
                    432:         */
                    433:        ISP_RESET0(isp);
                    434:
                    435: again:
                    436:
                    437:        /*
                    438:         * Hit the chip over the head with hammer,
                    439:         * and give the ISP a chance to recover.
                    440:         */
                    441:
                    442:        if (IS_SCSI(isp)) {
                    443:                ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
                    444:                /*
                    445:                 * A slight delay...
                    446:                 */
                    447:                USEC_DELAY(100);
                    448:
                    449:                /*
                    450:                 * Clear data && control DMA engines.
                    451:                 */
                    452:                ISP_WRITE(isp, CDMA_CONTROL,
                    453:                    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
                    454:                ISP_WRITE(isp, DDMA_CONTROL,
                    455:                    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
                    456:
                    457:
                    458:        } else {
                    459:                ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
                    460:                /*
                    461:                 * A slight delay...
                    462:                 */
                    463:                USEC_DELAY(100);
                    464:
                    465:                /*
                    466:                 * Clear data && control DMA engines.
                    467:                 */
                    468:                ISP_WRITE(isp, CDMA2100_CONTROL,
                    469:                        DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
                    470:                ISP_WRITE(isp, TDMA2100_CONTROL,
                    471:                        DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
                    472:                ISP_WRITE(isp, RDMA2100_CONTROL,
                    473:                        DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
                    474:        }
                    475:
                    476:        /*
                    477:         * Wait for ISP to be ready to go...
                    478:         */
                    479:        loops = MBOX_DELAY_COUNT;
                    480:        for (;;) {
                    481:                if (IS_SCSI(isp)) {
                    482:                        if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET))
                    483:                                break;
                    484:                } else {
                    485:                        if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
                    486:                                break;
                    487:                }
                    488:                USEC_DELAY(100);
                    489:                if (--loops < 0) {
                    490:                        ISP_DUMPREGS(isp, "chip reset timed out");
                    491:                        return;
                    492:                }
                    493:        }
                    494:
                    495:        /*
                    496:         * After we've fired this chip up, zero out the conf1 register
                    497:         * for SCSI adapters and other settings for the 2100.
                    498:         */
                    499:
                    500:        if (IS_SCSI(isp)) {
                    501:                ISP_WRITE(isp, BIU_CONF1, 0);
                    502:        } else {
                    503:                ISP_WRITE(isp, BIU2100_CSR, 0);
                    504:        }
                    505:
                    506:        /*
                    507:         * Reset RISC Processor
                    508:         */
                    509:        ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
                    510:        USEC_DELAY(100);
                    511:        /* Clear semaphore register (just to be sure) */
                    512:        ISP_WRITE(isp, BIU_SEMA, 0);
                    513:
                    514:        /*
                    515:         * Establish some initial burst rate stuff.
                    516:         * (only for the 1XX0 boards). This really should
                    517:         * be done later after fetching from NVRAM.
                    518:         */
                    519:        if (IS_SCSI(isp)) {
                    520:                u_int16_t tmp = isp->isp_mdvec->dv_conf1;
                    521:                /*
                    522:                 * Busted FIFO. Turn off all but burst enables.
                    523:                 */
                    524:                if (isp->isp_type == ISP_HA_SCSI_1040A) {
                    525:                        tmp &= BIU_BURST_ENABLE;
                    526:                }
                    527:                ISP_SETBITS(isp, BIU_CONF1, tmp);
                    528:                if (tmp & BIU_BURST_ENABLE) {
                    529:                        ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
                    530:                        ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
                    531:                }
                    532: #ifdef PTI_CARDS
                    533:                if (((sdparam *) isp->isp_param)->isp_ultramode) {
                    534:                        while (ISP_READ(isp, RISC_MTR) != 0x1313) {
                    535:                                ISP_WRITE(isp, RISC_MTR, 0x1313);
                    536:                                ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
                    537:                        }
                    538:                } else {
                    539:                        ISP_WRITE(isp, RISC_MTR, 0x1212);
                    540:                }
                    541:                /*
                    542:                 * PTI specific register
                    543:                 */
                    544:                ISP_WRITE(isp, RISC_EMB, DUAL_BANK)
                    545: #else
                    546:                ISP_WRITE(isp, RISC_MTR, 0x1212);
                    547: #endif
                    548:        } else {
                    549:                ISP_WRITE(isp, RISC_MTR2100, 0x1212);
                    550:                if (IS_2200(isp) || IS_23XX(isp)) {
                    551:                        ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
                    552:                }
                    553:        }
                    554:
                    555:        ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); /* release paused processor */
                    556:
                    557:        /*
                    558:         * Do MD specific post initialization
                    559:         */
                    560:        ISP_RESET1(isp);
                    561:
                    562:        /*
                    563:         * Wait for everything to finish firing up.
                    564:         *
                    565:         * Avoid doing this on the 2312 because you can generate a PCI
                    566:         * parity error (chip breakage).
                    567:         */
                    568:        if (IS_23XX(isp)) {
                    569:                USEC_DELAY(5);
                    570:        } else {
                    571:                loops = MBOX_DELAY_COUNT;
                    572:                while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
                    573:                        USEC_DELAY(100);
                    574:                        if (--loops < 0) {
                    575:                                isp_prt(isp, ISP_LOGERR,
                    576:                                    "MBOX_BUSY never cleared on reset");
                    577:                                return;
                    578:                        }
                    579:                }
                    580:        }
                    581:
                    582:        /*
                    583:         * Up until this point we've done everything by just reading or
                    584:         * setting registers. From this point on we rely on at least *some*
                    585:         * kind of firmware running in the card.
                    586:         */
                    587:
                    588:        /*
                    589:         * Do some sanity checking.
                    590:         */
                    591:        mbs.param[0] = MBOX_NO_OP;
                    592:        isp_mboxcmd(isp, &mbs, MBLOGALL);
                    593:        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    594:                return;
                    595:        }
                    596:
                    597:        if (IS_SCSI(isp)) {
                    598:                mbs.param[0] = MBOX_MAILBOX_REG_TEST;
                    599:                mbs.param[1] = 0xdead;
                    600:                mbs.param[2] = 0xbeef;
                    601:                mbs.param[3] = 0xffff;
                    602:                mbs.param[4] = 0x1111;
                    603:                mbs.param[5] = 0xa5a5;
                    604:                isp_mboxcmd(isp, &mbs, MBLOGALL);
                    605:                if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    606:                        return;
                    607:                }
                    608:                if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
                    609:                    mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
                    610:                    mbs.param[5] != 0xa5a5) {
                    611:                        isp_prt(isp, ISP_LOGERR,
                    612:                            "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)",
                    613:                            mbs.param[1], mbs.param[2], mbs.param[3],
                    614:                            mbs.param[4], mbs.param[5]);
                    615:                        return;
                    616:                }
                    617:
                    618:        }
                    619:
                    620:        /*
                    621:         * Download new Firmware, unless requested not to do so.
                    622:         * This is made slightly trickier in some cases where the
                    623:         * firmware of the ROM revision is newer than the revision
                    624:         * compiled into the driver. So, where we used to compare
                    625:         * versions of our f/w and the ROM f/w, now we just see
                    626:         * whether we have f/w at all and whether a config flag
                    627:         * has disabled our download.
                    628:         */
                    629:        if ((isp->isp_mdvec->dv_ispfw == NULL) ||
                    630:            (isp->isp_confopts & ISP_CFG_NORELOAD)) {
                    631:                dodnld = 0;
                    632:        }
                    633:
                    634:        if (IS_23XX(isp))
                    635:                code_org = ISP_CODE_ORG_2300;
                    636:        else
                    637:                code_org = ISP_CODE_ORG;
                    638:
                    639:        if (dodnld) {
                    640:                isp->isp_mbxworkp = (void *) &isp->isp_mdvec->dv_ispfw[1];
                    641:                isp->isp_mbxwrk0 = isp->isp_mdvec->dv_ispfw[3] - 1;
                    642:                isp->isp_mbxwrk1 = code_org + 1;
                    643:                mbs.param[0] = MBOX_WRITE_RAM_WORD;
                    644:                mbs.param[1] = code_org;
                    645:                mbs.param[2] = isp->isp_mdvec->dv_ispfw[0];
                    646:                isp_mboxcmd(isp, &mbs, MBLOGNONE);
                    647:                if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    648:                        isp_prt(isp, ISP_LOGERR,
                    649:                            "F/W download failed at word %d",
                    650:                            isp->isp_mbxwrk1 - code_org);
                    651:                        dodnld = 0;
                    652:                        goto again;
                    653:                }
                    654:                /*
                    655:                 * Verify that it downloaded correctly.
                    656:                 */
                    657:                mbs.param[0] = MBOX_VERIFY_CHECKSUM;
                    658:                mbs.param[1] = code_org;
                    659:                isp_mboxcmd(isp, &mbs, MBLOGNONE);
                    660:                if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    661:                        isp_prt(isp, ISP_LOGERR, "Ram Checksum Failure");
                    662:                        return;
                    663:                }
                    664:                isp->isp_loaded_fw = 1;
                    665:        } else {
                    666:                isp->isp_loaded_fw = 0;
                    667:                isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
                    668:        }
                    669:
                    670:        /*
                    671:         * Now start it rolling.
                    672:         *
                    673:         * If we didn't actually download f/w,
                    674:         * we still need to (re)start it.
                    675:         */
                    676:
                    677:
                    678:        mbs.param[0] = MBOX_EXEC_FIRMWARE;
                    679:        mbs.param[1] = code_org;
                    680:        isp_mboxcmd(isp, &mbs, MBLOGNONE);
                    681:        /*
                    682:         * Give it a chance to start.
                    683:         */
                    684:        USEC_DELAY(500);
                    685:
                    686:        if (IS_SCSI(isp)) {
                    687:                /*
                    688:                 * Set CLOCK RATE, but only if asked to.
                    689:                 */
                    690:                if (isp->isp_clock) {
                    691:                        mbs.param[0] = MBOX_SET_CLOCK_RATE;
                    692:                        mbs.param[1] = isp->isp_clock;
                    693:                        isp_mboxcmd(isp, &mbs, MBLOGALL);
                    694:                        /* we will try not to care if this fails */
                    695:                }
                    696:        }
                    697:
                    698:        mbs.param[0] = MBOX_ABOUT_FIRMWARE;
                    699:        isp_mboxcmd(isp, &mbs, MBLOGALL);
                    700:        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    701:                return;
                    702:        }
                    703:
                    704:        /*
                    705:         * The SBus firmware that we are using apparently does not return
                    706:         * major, minor, micro revisions in the mailbox registers, which
                    707:         * is really, really, annoying.
                    708:         */
                    709:        if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
                    710:                if (dodnld) {
                    711: #ifdef ISP_TARGET_MODE
                    712:                        isp->isp_fwrev[0] = 7;
                    713:                        isp->isp_fwrev[1] = 55;
                    714: #else
                    715:                        isp->isp_fwrev[0] = 1;
                    716:                        isp->isp_fwrev[1] = 37;
                    717: #endif
                    718:                        isp->isp_fwrev[2] = 0;
                    719:                }
                    720:        } else {
                    721:                isp->isp_fwrev[0] = mbs.param[1];
                    722:                isp->isp_fwrev[1] = mbs.param[2];
                    723:                isp->isp_fwrev[2] = mbs.param[3];
                    724:        }
                    725:        isp_prt(isp, ISP_LOGCONFIG,
                    726:            "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
                    727:            btype, isp->isp_revision, dodnld? "loaded" : "resident",
                    728:            isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
                    729:
                    730:        if (IS_FC(isp)) {
                    731:                /*
                    732:                 * We do not believe firmware attributes for 2100 code less
                    733:                 * than 1.17.0, unless it's the firmware we specifically
                    734:                 * are loading.
                    735:                 *
                    736:                 * Note that all 22XX and 23XX f/w is greater than 1.X.0.
                    737:                 */
                    738:                if (!(ISP_FW_NEWER_THAN(isp, 1, 17, 0))) {
                    739: #ifdef USE_SMALLER_2100_FIRMWARE
                    740:                        FCPARAM(isp)->isp_fwattr = ISP_FW_ATTR_SCCLUN;
                    741: #else
                    742:                        FCPARAM(isp)->isp_fwattr = 0;
                    743: #endif
                    744:                } else {
                    745:                        FCPARAM(isp)->isp_fwattr = mbs.param[6];
                    746:                        isp_prt(isp, ISP_LOGDEBUG0,
                    747:                            "Firmware Attributes = 0x%x", mbs.param[6]);
                    748:                }
                    749:                if (ISP_READ(isp, BIU2100_CSR) & BIU2100_PCI64) {
                    750:                        isp_prt(isp, ISP_LOGCONFIG,
                    751:                            "Installed in 64-Bit PCI slot");
                    752:                }
                    753:        }
                    754:
                    755:        if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] ||
                    756:            isp->isp_romfw_rev[2]) {
                    757:                isp_prt(isp, ISP_LOGCONFIG, "Last F/W revision was %d.%d.%d",
                    758:                    isp->isp_romfw_rev[0], isp->isp_romfw_rev[1],
                    759:                    isp->isp_romfw_rev[2]);
                    760:        }
                    761:
                    762:        mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
                    763:        isp_mboxcmd(isp, &mbs, MBLOGALL);
                    764:        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    765:                return;
                    766:        }
                    767:        isp->isp_maxcmds = mbs.param[2];
                    768:        isp_prt(isp, ISP_LOGINFO,
                    769:            "%d max I/O commands supported", mbs.param[2]);
                    770:        isp_fw_state(isp);
                    771:
                    772:        /*
                    773:         * Set up DMA for the request and result mailboxes.
                    774:         */
                    775:        if (ISP_MBOXDMASETUP(isp) != 0) {
                    776:                isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
                    777:                return;
                    778:        }
                    779:        isp->isp_state = ISP_RESETSTATE;
                    780:
                    781:        /*
                    782:         * Okay- now that we have new firmware running, we now (re)set our
                    783:         * notion of how many luns we support. This is somewhat tricky because
                    784:         * if we haven't loaded firmware, we sometimes do not have an easy way
                    785:         * of knowing how many luns we support.
                    786:         *
                    787:         * Expanded lun firmware gives you 32 luns for SCSI cards and
                    788:         * 16384 luns for Fibre Channel cards.
                    789:         *
                    790:         * It turns out that even for QLogic 2100s with ROM 1.10 and above
                    791:         * we do get a firmware attributes word returned in mailbox register 6.
                    792:         *
                    793:         * Because the lun is in a different position in the Request Queue
                    794:         * Entry structure for Fibre Channel with expanded lun firmware, we
                    795:         * can only support one lun (lun zero) when we don't know what kind
                    796:         * of firmware we're running.
                    797:         */
                    798:        if (IS_SCSI(isp)) {
                    799:                if (dodnld) {
                    800:                        if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
                    801:                                isp->isp_maxluns = 32;
                    802:                        } else {
                    803:                                isp->isp_maxluns = 8;
                    804:                        }
                    805:                } else {
                    806:                        isp->isp_maxluns = 8;
                    807:                }
                    808:        } else {
                    809:                if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
                    810:                        isp->isp_maxluns = 16384;
                    811:                } else {
                    812:                        isp->isp_maxluns = 16;
                    813:                }
                    814:        }
                    815: }
                    816:
                    817: /*
                    818:  * Initialize Parameters of Hardware to a known state.
                    819:  *
                    820:  * Locks are held before coming here.
                    821:  */
                    822:
                    823: void
                    824: isp_init(struct ispsoftc *isp)
                    825: {
                    826:        /*
                    827:         * Must do this first to get defaults established.
                    828:         */
                    829:        isp_setdfltparm(isp, 0);
                    830:        if (IS_DUALBUS(isp)) {
                    831:                isp_setdfltparm(isp, 1);
                    832:        }
                    833:        if (IS_FC(isp)) {
                    834:                isp_fibre_init(isp);
                    835:        } else {
                    836:                isp_scsi_init(isp);
                    837:        }
                    838: }
                    839:
                    840: static void
                    841: isp_scsi_init(struct ispsoftc *isp)
                    842: {
                    843:        sdparam *sdp_chan0, *sdp_chan1;
                    844:        mbreg_t mbs;
                    845:
                    846:        sdp_chan0 = isp->isp_param;
                    847:        sdp_chan1 = sdp_chan0;
                    848:        if (IS_DUALBUS(isp)) {
                    849:                sdp_chan1++;
                    850:        }
                    851:
                    852:        /*
                    853:         * If we have no role (neither target nor initiator), return.
                    854:         */
                    855:        if (isp->isp_role == ISP_ROLE_NONE) {
                    856:                return;
                    857:        }
                    858:
                    859:        /* First do overall per-card settings. */
                    860:
                    861:        /*
                    862:         * If we have fast memory timing enabled, turn it on.
                    863:         */
                    864:        if (sdp_chan0->isp_fast_mttr) {
                    865:                ISP_WRITE(isp, RISC_MTR, 0x1313);
                    866:        }
                    867:
                    868:        /*
                    869:         * Set Retry Delay and Count.
                    870:         * You set both channels at the same time.
                    871:         */
                    872:        mbs.param[0] = MBOX_SET_RETRY_COUNT;
                    873:        mbs.param[1] = sdp_chan0->isp_retry_count;
                    874:        mbs.param[2] = sdp_chan0->isp_retry_delay;
                    875:        mbs.param[6] = sdp_chan1->isp_retry_count;
                    876:        mbs.param[7] = sdp_chan1->isp_retry_delay;
                    877:
                    878:        isp_mboxcmd(isp, &mbs, MBLOGALL);
                    879:        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    880:                return;
                    881:        }
                    882:
                    883:        /*
                    884:         * Set ASYNC DATA SETUP time. This is very important.
                    885:         */
                    886:        mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
                    887:        mbs.param[1] = sdp_chan0->isp_async_data_setup;
                    888:        mbs.param[2] = sdp_chan1->isp_async_data_setup;
                    889:        isp_mboxcmd(isp, &mbs, MBLOGALL);
                    890:        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    891:                return;
                    892:        }
                    893:
                    894:        /*
                    895:         * Set ACTIVE Negation State.
                    896:         */
                    897:        mbs.param[0] = MBOX_SET_ACT_NEG_STATE;
                    898:        mbs.param[1] =
                    899:            (sdp_chan0->isp_req_ack_active_neg << 4) |
                    900:            (sdp_chan0->isp_data_line_active_neg << 5);
                    901:        mbs.param[2] =
                    902:            (sdp_chan1->isp_req_ack_active_neg << 4) |
                    903:            (sdp_chan1->isp_data_line_active_neg << 5);
                    904:
                    905:        isp_mboxcmd(isp, &mbs, MBLOGNONE);
                    906:        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    907:                isp_prt(isp, ISP_LOGERR,
                    908:                    "failed to set active negation state (%d,%d), (%d,%d)",
                    909:                    sdp_chan0->isp_req_ack_active_neg,
                    910:                    sdp_chan0->isp_data_line_active_neg,
                    911:                    sdp_chan1->isp_req_ack_active_neg,
                    912:                    sdp_chan1->isp_data_line_active_neg);
                    913:                /*
                    914:                 * But don't return.
                    915:                 */
                    916:        }
                    917:
                    918:        /*
                    919:         * Set the Tag Aging limit
                    920:         */
                    921:        mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT;
                    922:        mbs.param[1] = sdp_chan0->isp_tag_aging;
                    923:        mbs.param[2] = sdp_chan1->isp_tag_aging;
                    924:        isp_mboxcmd(isp, &mbs, MBLOGALL);
                    925:        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    926:                isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
                    927:                    sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
                    928:                return;
                    929:        }
                    930:
                    931:        /*
                    932:         * Set selection timeout.
                    933:         */
                    934:        mbs.param[0] = MBOX_SET_SELECT_TIMEOUT;
                    935:        mbs.param[1] = sdp_chan0->isp_selection_timeout;
                    936:        mbs.param[2] = sdp_chan1->isp_selection_timeout;
                    937:        isp_mboxcmd(isp, &mbs, MBLOGALL);
                    938:        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    939:                return;
                    940:        }
                    941:
                    942:        /* now do per-channel settings */
                    943:        isp_scsi_channel_init(isp, 0);
                    944:        if (IS_DUALBUS(isp))
                    945:                isp_scsi_channel_init(isp, 1);
                    946:
                    947:        /*
                    948:         * Now enable request/response queues
                    949:         */
                    950:
                    951:        if (IS_ULTRA2(isp) || IS_1240(isp)) {
                    952:                mbs.param[0] = MBOX_INIT_RES_QUEUE_A64;
                    953:                mbs.param[1] = RESULT_QUEUE_LEN(isp);
                    954:                mbs.param[2] = DMA_WD1(isp->isp_result_dma);
                    955:                mbs.param[3] = DMA_WD0(isp->isp_result_dma);
                    956:                mbs.param[4] = 0;
                    957:                mbs.param[6] = DMA_WD3(isp->isp_result_dma);
                    958:                mbs.param[7] = DMA_WD2(isp->isp_result_dma);
                    959:                isp_mboxcmd(isp, &mbs, MBLOGALL);
                    960:                if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    961:                        return;
                    962:                }
                    963:                isp->isp_residx = mbs.param[5];
                    964:
                    965:                mbs.param[0] = MBOX_INIT_REQ_QUEUE_A64;
                    966:                mbs.param[1] = RQUEST_QUEUE_LEN(isp);
                    967:                mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
                    968:                mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
                    969:                mbs.param[5] = 0;
                    970:                mbs.param[6] = DMA_WD3(isp->isp_result_dma);
                    971:                mbs.param[7] = DMA_WD2(isp->isp_result_dma);
                    972:                isp_mboxcmd(isp, &mbs, MBLOGALL);
                    973:                if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    974:                        return;
                    975:                }
                    976:                isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
                    977:        } else {
                    978:                mbs.param[0] = MBOX_INIT_RES_QUEUE;
                    979:                mbs.param[1] = RESULT_QUEUE_LEN(isp);
                    980:                mbs.param[2] = DMA_WD1(isp->isp_result_dma);
                    981:                mbs.param[3] = DMA_WD0(isp->isp_result_dma);
                    982:                mbs.param[4] = 0;
                    983:                isp_mboxcmd(isp, &mbs, MBLOGALL);
                    984:                if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    985:                        return;
                    986:                }
                    987:                isp->isp_residx = mbs.param[5];
                    988:
                    989:                mbs.param[0] = MBOX_INIT_REQ_QUEUE;
                    990:                mbs.param[1] = RQUEST_QUEUE_LEN(isp);
                    991:                mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
                    992:                mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
                    993:                mbs.param[5] = 0;
                    994:                isp_mboxcmd(isp, &mbs, MBLOGALL);
                    995:                if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                    996:                        return;
                    997:                }
                    998:                isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
                    999:        }
                   1000:
                   1001:        /*
                   1002:         * Turn on Fast Posting, LVD transitions
                   1003:         *
                   1004:         * Ultra2 F/W always has had fast posting (and LVD transitions)
                   1005:         *
                   1006:         * Ultra and older (i.e., SBus) cards may not. It's just safer
                   1007:         * to assume not for them.
                   1008:         */
                   1009:
                   1010:        mbs.param[0] = MBOX_SET_FW_FEATURES;
                   1011:        mbs.param[1] = 0;
                   1012:        if (IS_ULTRA2(isp))
                   1013:                mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
                   1014: #ifndef        ISP_NO_RIO
                   1015:        if (IS_ULTRA2(isp) || IS_1240(isp))
                   1016:                mbs.param[1] |= FW_FEATURE_RIO_16BIT;
                   1017: #else
                   1018: #ifndef        ISP_NO_FASTPOST
                   1019:        if (IS_ULTRA2(isp) || IS_1240(isp))
                   1020:                mbs.param[1] |= FW_FEATURE_FAST_POST;
                   1021: #endif
                   1022: #endif
                   1023:        if (mbs.param[1] != 0) {
                   1024:                u_int16_t sfeat = mbs.param[1];
                   1025:                isp_mboxcmd(isp, &mbs, MBLOGALL);
                   1026:                if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
                   1027:                        isp_prt(isp, ISP_LOGINFO,
                   1028:                            "Enabled FW features (0x%x)", sfeat);
                   1029:                }
                   1030:        }
                   1031:
                   1032:        /*
                   1033:         * Let the outer layers decide whether to issue a SCSI bus reset.
                   1034:         */
                   1035:        isp->isp_state = ISP_INITSTATE;
                   1036: }
                   1037:
                   1038: static void
                   1039: isp_scsi_channel_init(struct ispsoftc *isp, int channel)
                   1040: {
                   1041:        sdparam *sdp;
                   1042:        mbreg_t mbs;
                   1043:        int tgt;
                   1044:
                   1045:        sdp = isp->isp_param;
                   1046:        sdp += channel;
                   1047:
                   1048:        /*
                   1049:         * Set (possibly new) Initiator ID.
                   1050:         */
                   1051:        mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
                   1052:        mbs.param[1] = (channel << 7) | sdp->isp_initiator_id;
                   1053:        isp_mboxcmd(isp, &mbs, MBLOGALL);
                   1054:        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                   1055:                return;
                   1056:        }
                   1057:        isp_prt(isp, ISP_LOGINFO, "Initiator ID is %d on Channel %d",
                   1058:            sdp->isp_initiator_id, channel);
                   1059:
                   1060:
                   1061:        /*
                   1062:         * Set current per-target parameters to an initial safe minimum.
                   1063:         */
                   1064:        for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
                   1065:                int lun;
                   1066:                u_int16_t sdf;
                   1067:
                   1068:                if (sdp->isp_devparam[tgt].dev_enable == 0) {
                   1069:                        continue;
                   1070:                }
                   1071: #ifndef        ISP_TARGET_MODE
                   1072:                sdf = sdp->isp_devparam[tgt].goal_flags;
                   1073:                sdf &= DPARM_SAFE_DFLT;
                   1074:                /*
                   1075:                 * It is not quite clear when this changed over so that
                   1076:                 * we could force narrow and async for 1000/1020 cards,
                   1077:                 * but assume that this is only the case for loaded
                   1078:                 * firmware.
                   1079:                 */
                   1080:                if (isp->isp_loaded_fw) {
                   1081:                        sdf |= DPARM_NARROW | DPARM_ASYNC;
                   1082:                }
                   1083: #else
                   1084:                /*
                   1085:                 * The !$*!)$!$)* f/w uses the same index into some
                   1086:                 * internal table to decide how to respond to negotiations,
                   1087:                 * so if we've said "let's be safe" for ID X, and ID X
                   1088:                 * selects *us*, the negotiations will back to 'safe'
                   1089:                 * (as in narrow/async). What the f/w *should* do is
                   1090:                 * use the initiator id settings to decide how to respond.
                   1091:                 */
                   1092:                sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
                   1093: #endif
                   1094:                mbs.param[0] = MBOX_SET_TARGET_PARAMS;
                   1095:                mbs.param[1] = (channel << 15) | (tgt << 8);
                   1096:                mbs.param[2] = sdf;
                   1097:                if ((sdf & DPARM_SYNC) == 0) {
                   1098:                        mbs.param[3] = 0;
                   1099:                } else {
                   1100:                        mbs.param[3] =
                   1101:                            (sdp->isp_devparam[tgt].goal_offset << 8) |
                   1102:                            (sdp->isp_devparam[tgt].goal_period);
                   1103:                }
                   1104:                isp_prt(isp, ISP_LOGDEBUG0,
                   1105:                    "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
                   1106:                    channel, tgt, mbs.param[2], mbs.param[3] >> 8,
                   1107:                    mbs.param[3] & 0xff);
                   1108:                isp_mboxcmd(isp, &mbs, MBLOGNONE);
                   1109:                if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                   1110:                        sdf = DPARM_SAFE_DFLT;
                   1111:                        mbs.param[0] = MBOX_SET_TARGET_PARAMS;
                   1112:                        mbs.param[1] = (tgt << 8) | (channel << 15);
                   1113:                        mbs.param[2] = sdf;
                   1114:                        mbs.param[3] = 0;
                   1115:                        isp_mboxcmd(isp, &mbs, MBLOGALL);
                   1116:                        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                   1117:                                continue;
                   1118:                        }
                   1119:                }
                   1120:
                   1121:                /*
                   1122:                 * We don't update any information directly from the f/w
                   1123:                 * because we need to run at least one command to cause a
                   1124:                 * new state to be latched up. So, we just assume that we
                   1125:                 * converge to the values we just had set.
                   1126:                 *
                   1127:                 * Ensure that we don't believe tagged queuing is enabled yet.
                   1128:                 * It turns out that sometimes the ISP just ignores our
                   1129:                 * attempts to set parameters for devices that it hasn't
                   1130:                 * seen yet.
                   1131:                 */
                   1132:                sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
                   1133:                for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
                   1134:                        mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
                   1135:                        mbs.param[1] = (channel << 15) | (tgt << 8) | lun;
                   1136:                        mbs.param[2] = sdp->isp_max_queue_depth;
                   1137:                        mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
                   1138:                        isp_mboxcmd(isp, &mbs, MBLOGALL);
                   1139:                        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                   1140:                                break;
                   1141:                        }
                   1142:                }
                   1143:        }
                   1144:        for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
                   1145:                if (sdp->isp_devparam[tgt].dev_refresh) {
                   1146:                        isp->isp_sendmarker |= (1 << channel);
                   1147:                        isp->isp_update |= (1 << channel);
                   1148:                        break;
                   1149:                }
                   1150:        }
                   1151: }
                   1152:
                   1153: /*
                   1154:  * Fibre Channel specific initialization.
                   1155:  *
                   1156:  * Locks are held before coming here.
                   1157:  */
                   1158: static void
                   1159: isp_fibre_init(struct ispsoftc *isp)
                   1160: {
                   1161:        fcparam *fcp;
                   1162:        isp_icb_t local, *icbp = &local;
                   1163:        mbreg_t mbs;
                   1164:        int loopid;
                   1165:        u_int64_t nwwn, pwwn;
                   1166:
                   1167:        fcp = isp->isp_param;
                   1168:
                   1169:        /*
                   1170:         * Do this *before* initializing the firmware.
                   1171:         */
                   1172:        isp_mark_getpdb_all(isp);
                   1173:        fcp->isp_fwstate = FW_CONFIG_WAIT;
                   1174:        fcp->isp_loopstate = LOOP_NIL;
                   1175:
                   1176:        /*
                   1177:         * If we have no role (neither target nor initiator), return.
                   1178:         */
                   1179:        if (isp->isp_role == ISP_ROLE_NONE) {
                   1180:                return;
                   1181:        }
                   1182:
                   1183:        loopid = fcp->isp_loopid;
                   1184:        MEMZERO(icbp, sizeof (*icbp));
                   1185:        icbp->icb_version = ICB_VERSION1;
                   1186:
                   1187:        /*
                   1188:         * Firmware Options are either retrieved from NVRAM or
                   1189:         * are patched elsewhere. We check them for sanity here
                   1190:         * and make changes based on board revision, but otherwise
                   1191:         * let others decide policy.
                   1192:         */
                   1193:
                   1194:        /*
                   1195:         * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
                   1196:         */
                   1197:        if ((isp->isp_type == ISP_HA_FC_2100) && isp->isp_revision < 5) {
                   1198:                fcp->isp_fwoptions &= ~ICBOPT_FAIRNESS;
                   1199:        }
                   1200:
                   1201:        /*
                   1202:         * We have to use FULL LOGIN even though it resets the loop too much
                   1203:         * because otherwise port database entries don't get updated after
                   1204:         * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
                   1205:         */
                   1206:        if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
                   1207:                fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
                   1208:        }
                   1209:
                   1210:        /*
                   1211:         * Insist on Port Database Update Async notifications
                   1212:         */
                   1213:        fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
                   1214:
                   1215:        /*
                   1216:         * Make sure that target role reflects into fwoptions.
                   1217:         */
                   1218:        if (isp->isp_role & ISP_ROLE_TARGET) {
                   1219:                fcp->isp_fwoptions |= ICBOPT_TGT_ENABLE;
                   1220:        } else {
                   1221:                fcp->isp_fwoptions &= ~ICBOPT_TGT_ENABLE;
                   1222:        }
                   1223:
                   1224:        /*
                   1225:         * Propagate all of this into the ICB structure.
                   1226:         */
                   1227:        icbp->icb_fwoptions = fcp->isp_fwoptions;
                   1228:        icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
                   1229:        if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
                   1230:            icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
                   1231:                isp_prt(isp, ISP_LOGERR,
                   1232:                    "bad frame length (%d) from NVRAM- using %d",
                   1233:                    fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN);
                   1234:                icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
                   1235:        }
                   1236:        icbp->icb_maxalloc = fcp->isp_maxalloc;
                   1237:        if (icbp->icb_maxalloc < 1) {
                   1238:                isp_prt(isp, ISP_LOGERR,
                   1239:                    "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
                   1240:                icbp->icb_maxalloc = 16;
                   1241:        }
                   1242:        icbp->icb_execthrottle = fcp->isp_execthrottle;
                   1243:        if (icbp->icb_execthrottle < 1) {
                   1244:                isp_prt(isp, ISP_LOGERR,
                   1245:                    "bad execution throttle of %d- using 16",
                   1246:                    fcp->isp_execthrottle);
                   1247:                icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
                   1248:        }
                   1249:        icbp->icb_retry_delay = fcp->isp_retry_delay;
                   1250:        icbp->icb_retry_count = fcp->isp_retry_count;
                   1251:        icbp->icb_hardaddr = loopid;
                   1252:        /*
                   1253:         * Right now we just set extended options to prefer point-to-point
                   1254:         * over loop based upon some soft config options.
                   1255:         *
                   1256:         * NB: for the 2300, ICBOPT_EXTENDED is required.
                   1257:         */
                   1258:        if (IS_2200(isp) || IS_23XX(isp)) {
                   1259:                icbp->icb_fwoptions |= ICBOPT_EXTENDED;
                   1260:                /*
                   1261:                 * Prefer or force Point-To-Point instead Loop?
                   1262:                 */
                   1263:                switch(isp->isp_confopts & ISP_CFG_PORT_PREF) {
                   1264:                case ISP_CFG_NPORT:
                   1265:                        icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
                   1266:                        break;
                   1267:                case ISP_CFG_NPORT_ONLY:
                   1268:                        icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY;
                   1269:                        break;
                   1270:                case ISP_CFG_LPORT_ONLY:
                   1271:                        icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY;
                   1272:                        break;
                   1273:                default:
                   1274:                        icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
                   1275:                        break;
                   1276:                }
                   1277:                if (IS_23XX(isp)) {
                   1278:                        /*
                   1279:                         * QLogic recommends that FAST Posting be turned
                   1280:                         * off for 23XX cards and instead allow the HBA
                   1281:                         * to write response queue entries and interrupt
                   1282:                         * after a delay (ZIO).
                   1283:                         *
                   1284:                         * If we set ZIO, it will disable fast posting,
                   1285:                         * so we don't need to clear it in fwoptions.
                   1286:                         */
                   1287:                        icbp->icb_xfwoptions |= ICBXOPT_ZIO;
                   1288: #if    0
                   1289:                        /*
                   1290:                         * Values, in 100us increments. The default
                   1291:                         * is 2 (200us) if a value 0 (default) is
                   1292:                         * selected.
                   1293:                         */
                   1294:                        icbp->icb_idelaytimer = 2;
                   1295: #endif
                   1296:
                   1297:                        if (isp->isp_confopts & ISP_CFG_ONEGB) {
                   1298:                                icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
                   1299:                        } else if (isp->isp_confopts & ISP_CFG_TWOGB) {
                   1300:                                icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB;
                   1301:                        } else {
                   1302:                                icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
                   1303:                        }
                   1304:                }
                   1305:        }
                   1306:
                   1307: #ifndef        ISP_NO_RIO_FC
                   1308:        /*
                   1309:         * RIO seems to be enabled in 2100s for fw >= 1.17.0.
                   1310:         *
                   1311:         * I've had some questionable problems with RIO on 2200.
                   1312:         * More specifically, on a 2204 I had problems with RIO
                   1313:         * on a Linux system where I was dropping commands right
                   1314:         * and left. It's not clear to me what the actual problem
                   1315:         * was.
                   1316:         *
                   1317:         * 23XX Cards do not support RIO. Instead they support ZIO.
                   1318:         */
                   1319: #if    0
                   1320:        if (!IS_23XX(isp) && ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
                   1321:                icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
                   1322:                icbp->icb_racctimer = 4;
                   1323:                icbp->icb_idelaytimer = 8;
                   1324:        }
                   1325: #endif
                   1326: #endif
                   1327:
                   1328:        /*
                   1329:         * For 22XX > 2.1.26 && 23XX, set someoptions.
                   1330:         * XXX: Probably okay for newer 2100 f/w too.
                   1331:         */
                   1332:        if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
                   1333:                /*
                   1334:                 * Turn on LIP F8 async event (1)
                   1335:                 * Turn on generate AE 8013 on all LIP Resets (2)
                   1336:                 * Disable LIP F7 switching (8)
                   1337:                 */
                   1338:                mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS;
                   1339:                mbs.param[1] = 0xb;
                   1340:                mbs.param[2] = 0;
                   1341:                mbs.param[3] = 0;
                   1342:                isp_mboxcmd(isp, &mbs, MBLOGALL);
                   1343:        }
                   1344:        icbp->icb_logintime = 30;       /* 30 second login timeout */
                   1345:
                   1346:        if (IS_23XX(isp)) {
                   1347:                ISP_WRITE(isp, isp->isp_rqstinrp, 0);
                   1348:                ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
                   1349:                ISP_WRITE(isp, isp->isp_respinrp, 0);
                   1350:                ISP_WRITE(isp, isp->isp_respoutrp, 0);
                   1351:        }
                   1352:
                   1353:        nwwn = ISP_NODEWWN(isp);
                   1354:        pwwn = ISP_PORTWWN(isp);
                   1355:        if (nwwn && pwwn) {
                   1356:                icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
                   1357:                MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn);
                   1358:                MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
                   1359:                isp_prt(isp, ISP_LOGDEBUG1,
                   1360:                    "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
                   1361:                    ((u_int32_t) (nwwn >> 32)),
                   1362:                    ((u_int32_t) (nwwn & 0xffffffff)),
                   1363:                    ((u_int32_t) (pwwn >> 32)),
                   1364:                    ((u_int32_t) (pwwn & 0xffffffff)));
                   1365:        } else {
                   1366:                isp_prt(isp, ISP_LOGDEBUG1, "Not using any WWNs");
                   1367:                icbp->icb_fwoptions &= ~(ICBOPT_BOTH_WWNS|ICBOPT_FULL_LOGIN);
                   1368:        }
                   1369:        icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
                   1370:        icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
                   1371:        icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
                   1372:        icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
                   1373:        icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
                   1374:        icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
                   1375:        icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
                   1376:        icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
                   1377:        icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
                   1378:        icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
                   1379:        isp_prt(isp, ISP_LOGDEBUG0,
                   1380:            "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
                   1381:            icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
                   1382:
                   1383:        FC_SCRATCH_ACQUIRE(isp);
                   1384:        isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
                   1385:
                   1386:        /*
                   1387:         * Init the firmware
                   1388:         */
                   1389:        mbs.param[0] = MBOX_INIT_FIRMWARE;
                   1390:        mbs.param[1] = 0;
                   1391:        mbs.param[2] = DMA_WD1(fcp->isp_scdma);
                   1392:        mbs.param[3] = DMA_WD0(fcp->isp_scdma);
                   1393:        mbs.param[4] = 0;
                   1394:        mbs.param[5] = 0;
                   1395:        mbs.param[6] = DMA_WD3(fcp->isp_scdma);
                   1396:        mbs.param[7] = DMA_WD2(fcp->isp_scdma);
                   1397:        isp_mboxcmd(isp, &mbs, MBLOGALL);
                   1398:        FC_SCRATCH_RELEASE(isp);
                   1399:        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                   1400:                return;
                   1401:        }
                   1402:        isp->isp_reqidx = isp->isp_reqodx = 0;
                   1403:        isp->isp_residx = 0;
                   1404:        isp->isp_sendmarker = 1;
                   1405:
                   1406:        /*
                   1407:         * Whatever happens, we're now committed to being here.
                   1408:         */
                   1409:        isp->isp_state = ISP_INITSTATE;
                   1410: }
                   1411:
                   1412: /*
                   1413:  * Fibre Channel Support- get the port database for the id.
                   1414:  *
                   1415:  * Locks are held before coming here. Return 0 if success,
                   1416:  * else failure.
                   1417:  */
                   1418:
                   1419: static int
                   1420: isp_getmap(struct ispsoftc *isp, fcpos_map_t *map)
                   1421: {
                   1422:        fcparam *fcp = (fcparam *) isp->isp_param;
                   1423:        mbreg_t mbs;
                   1424:
                   1425:        mbs.param[0] = MBOX_GET_FC_AL_POSITION_MAP;
                   1426:        mbs.param[1] = 0;
                   1427:        mbs.param[2] = DMA_WD1(fcp->isp_scdma);
                   1428:        mbs.param[3] = DMA_WD0(fcp->isp_scdma);
                   1429:        /*
                   1430:         * Unneeded. For the 2100, except for initializing f/w, registers
                   1431:         * 4/5 have to not be written to.
                   1432:         *      mbs.param[4] = 0;
                   1433:         *      mbs.param[5] = 0;
                   1434:         *
                   1435:         */
                   1436:        mbs.param[6] = 0;
                   1437:        mbs.param[7] = 0;
                   1438:        FC_SCRATCH_ACQUIRE(isp);
                   1439:        isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
                   1440:        if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
                   1441:                MEMCPY(map, fcp->isp_scratch, sizeof (fcpos_map_t));
                   1442:                map->fwmap = mbs.param[1] != 0;
                   1443:                FC_SCRATCH_RELEASE(isp);
                   1444:                return (0);
                   1445:        }
                   1446:        FC_SCRATCH_RELEASE(isp);
                   1447:        return (-1);
                   1448: }
                   1449:
                   1450: static void
                   1451: isp_mark_getpdb_all(struct ispsoftc *isp)
                   1452: {
                   1453:        fcparam *fcp = (fcparam *) isp->isp_param;
                   1454:        int i;
                   1455:        for (i = 0; i < MAX_FC_TARG; i++) {
                   1456:                fcp->portdb[i].valid = fcp->portdb[i].fabric_dev = 0;
                   1457:        }
                   1458: }
                   1459:
                   1460: static int
                   1461: isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp)
                   1462: {
                   1463:        fcparam *fcp = (fcparam *) isp->isp_param;
                   1464:        mbreg_t mbs;
                   1465:
                   1466:        mbs.param[0] = MBOX_GET_PORT_DB;
                   1467:        mbs.param[1] = id << 8;
                   1468:        mbs.param[2] = DMA_WD1(fcp->isp_scdma);
                   1469:        mbs.param[3] = DMA_WD0(fcp->isp_scdma);
                   1470:        /*
                   1471:         * Unneeded. For the 2100, except for initializing f/w, registers
                   1472:         * 4/5 have to not be written to.
                   1473:         *      mbs.param[4] = 0;
                   1474:         *      mbs.param[5] = 0;
                   1475:         *
                   1476:         */
                   1477:        mbs.param[6] = DMA_WD3(fcp->isp_scdma);
                   1478:        mbs.param[7] = DMA_WD2(fcp->isp_scdma);
                   1479:        FC_SCRATCH_ACQUIRE(isp);
                   1480:        isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
                   1481:        if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
                   1482:                isp_get_pdb(isp, (isp_pdb_t *)fcp->isp_scratch, pdbp);
                   1483:                FC_SCRATCH_RELEASE(isp);
                   1484:                return (0);
                   1485:        }
                   1486:        FC_SCRATCH_RELEASE(isp);
                   1487:        return (-1);
                   1488: }
                   1489:
                   1490: static u_int64_t
                   1491: isp_get_portname(struct ispsoftc *isp, int loopid, int nodename)
                   1492: {
                   1493:        u_int64_t wwn = 0;
                   1494:        mbreg_t mbs;
                   1495:
                   1496:        mbs.param[0] = MBOX_GET_PORT_NAME;
                   1497:        mbs.param[1] = loopid << 8;
                   1498:        if (nodename)
                   1499:                mbs.param[1] |= 1;
                   1500:        isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
                   1501:        if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
                   1502:                wwn =
                   1503:                    (((u_int64_t)(mbs.param[2] & 0xff)) << 56) |
                   1504:                    (((u_int64_t)(mbs.param[2] >> 8))   << 48) |
                   1505:                    (((u_int64_t)(mbs.param[3] & 0xff)) << 40) |
                   1506:                    (((u_int64_t)(mbs.param[3] >> 8))   << 32) |
                   1507:                    (((u_int64_t)(mbs.param[6] & 0xff)) << 24) |
                   1508:                    (((u_int64_t)(mbs.param[6] >> 8))   << 16) |
                   1509:                    (((u_int64_t)(mbs.param[7] & 0xff)) <<  8) |
                   1510:                    (((u_int64_t)(mbs.param[7] >> 8)));
                   1511:        }
                   1512:        return (wwn);
                   1513: }
                   1514:
                   1515: /*
                   1516:  * Make sure we have good FC link and know our Loop ID.
                   1517:  */
                   1518:
                   1519: static int
                   1520: isp_fclink_test(struct ispsoftc *isp, int usdelay)
                   1521: {
                   1522:        static char *toponames[] = {
                   1523:                "Private Loop",
                   1524:                "FL Port",
                   1525:                "N-Port to N-Port",
                   1526:                "F Port",
                   1527:                "F Port (no FLOGI_ACC response)"
                   1528:        };
                   1529:        mbreg_t mbs;
                   1530:        int count, check_for_fabric;
                   1531:        u_int8_t lwfs;
                   1532:        fcparam *fcp;
                   1533:        struct lportdb *lp;
                   1534:        isp_pdb_t pdb;
                   1535:
                   1536:        fcp = isp->isp_param;
                   1537:
                   1538:        /*
                   1539:         * XXX: Here is where we would start a 'loop dead' timeout
                   1540:         */
                   1541:
                   1542:        /*
                   1543:         * Wait up to N microseconds for F/W to go to a ready state.
                   1544:         */
                   1545:        lwfs = FW_CONFIG_WAIT;
                   1546:        count = 0;
                   1547:        while (count < usdelay) {
                   1548:                u_int64_t enano;
                   1549:                u_int32_t wrk;
                   1550:                NANOTIME_T hra, hrb;
                   1551:
                   1552:                GET_NANOTIME(&hra);
                   1553:                isp_fw_state(isp);
                   1554:                if (lwfs != fcp->isp_fwstate) {
                   1555:                        isp_prt(isp, ISP_LOGINFO, "Firmware State <%s->%s>",
                   1556:                            isp2100_fw_statename((int)lwfs),
                   1557:                            isp2100_fw_statename((int)fcp->isp_fwstate));
                   1558:                        lwfs = fcp->isp_fwstate;
                   1559:                }
                   1560:                if (fcp->isp_fwstate == FW_READY) {
                   1561:                        break;
                   1562:                }
                   1563:                GET_NANOTIME(&hrb);
                   1564:
                   1565:                /*
                   1566:                 * Get the elapsed time in nanoseconds.
                   1567:                 * Always guaranteed to be non-zero.
                   1568:                 */
                   1569:                enano = NANOTIME_SUB(&hrb, &hra);
                   1570:
                   1571:                isp_prt(isp, ISP_LOGDEBUG1,
                   1572:                    "usec%d: 0x%lx->0x%lx enano 0x%x%08x",
                   1573:                    count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb),
                   1574:                    (u_int32_t)(enano >> 32), (u_int32_t)(enano & 0xffffffff));
                   1575:
                   1576:                /*
                   1577:                 * If the elapsed time is less than 1 millisecond,
                   1578:                 * delay a period of time up to that millisecond of
                   1579:                 * waiting.
                   1580:                 *
                   1581:                 * This peculiar code is an attempt to try and avoid
                   1582:                 * invoking u_int64_t math support functions for some
                   1583:                 * platforms where linkage is a problem.
                   1584:                 */
                   1585:                if (enano < (1000 * 1000)) {
                   1586:                        count += 1000;
                   1587:                        enano = (1000 * 1000) - enano;
                   1588:                        while (enano > (u_int64_t) 4000000000U) {
                   1589:                                USEC_SLEEP(isp, 4000000);
                   1590:                                enano -= (u_int64_t) 4000000000U;
                   1591:                        }
                   1592:                        wrk = enano;
                   1593:                        wrk /= 1000;
                   1594:                        USEC_SLEEP(isp, wrk);
                   1595:                } else {
                   1596:                        while (enano > (u_int64_t) 4000000000U) {
                   1597:                                count += 4000000;
                   1598:                                enano -= (u_int64_t) 4000000000U;
                   1599:                        }
                   1600:                        wrk = enano;
                   1601:                        count += (wrk / 1000);
                   1602:                }
                   1603:        }
                   1604:
                   1605:        /*
                   1606:         * If we haven't gone to 'ready' state, return.
                   1607:         */
                   1608:        if (fcp->isp_fwstate != FW_READY) {
                   1609:                return (-1);
                   1610:        }
                   1611:
                   1612:        /*
                   1613:         * Get our Loop ID (if possible). We really need to have it.
                   1614:         */
                   1615:        mbs.param[0] = MBOX_GET_LOOP_ID;
                   1616:        isp_mboxcmd(isp, &mbs, MBLOGALL);
                   1617:        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                   1618:                return (-1);
                   1619:        }
                   1620:        fcp->isp_loopid = mbs.param[1];
                   1621:        if (IS_2200(isp) || IS_23XX(isp)) {
                   1622:                int topo = (int) mbs.param[6];
                   1623:                if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
                   1624:                        topo = TOPO_PTP_STUB;
                   1625:                fcp->isp_topo = topo;
                   1626:        } else {
                   1627:                fcp->isp_topo = TOPO_NL_PORT;
                   1628:        }
                   1629:        fcp->isp_portid = fcp->isp_alpa = mbs.param[2] & 0xff;
                   1630:
                   1631:        /*
                   1632:         * Check to see if we're on a fabric by trying to see if we
                   1633:         * can talk to the fabric name server. This can be a bit
                   1634:         * tricky because if we're a 2100, we should check always
                   1635:         * (in case we're connected to a server doing aliasing).
                   1636:         */
                   1637:        fcp->isp_onfabric = 0;
                   1638:
                   1639:        if (IS_2100(isp)) {
                   1640:                /*
                   1641:                 * Don't bother with fabric if we are using really old
                   1642:                 * 2100 firmware. It's just not worth it.
                   1643:                 */
                   1644:                if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) {
                   1645:                        check_for_fabric = 1;
                   1646:                } else {
                   1647:                        check_for_fabric = 0;
                   1648:                }
                   1649:        } else if (fcp->isp_topo == TOPO_FL_PORT ||
                   1650:            fcp->isp_topo == TOPO_F_PORT) {
                   1651:                check_for_fabric = 1;
                   1652:        } else
                   1653:                check_for_fabric = 0;
                   1654:
                   1655:        if (check_for_fabric && isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
                   1656:                int loopid = FL_PORT_ID;
                   1657:                if (IS_2100(isp)) {
                   1658:                        fcp->isp_topo = TOPO_FL_PORT;
                   1659:                }
                   1660:
                   1661:                if (BITS2WORD(pdb.pdb_portid_bits) == 0) {
                   1662:                        /*
                   1663:                         * Crock.
                   1664:                         */
                   1665:                        fcp->isp_topo = TOPO_NL_PORT;
                   1666:                        goto not_on_fabric;
                   1667:                }
                   1668:                fcp->isp_portid = mbs.param[2] | ((int) mbs.param[3] << 16);
                   1669:
                   1670:                /*
                   1671:                 * Save the Fabric controller's port database entry.
                   1672:                 */
                   1673:                lp = &fcp->portdb[loopid];
                   1674:                lp->node_wwn =
                   1675:                    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
                   1676:                    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
                   1677:                    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
                   1678:                    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
                   1679:                    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
                   1680:                    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
                   1681:                    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
                   1682:                    (((u_int64_t)pdb.pdb_nodename[7]));
                   1683:                lp->port_wwn =
                   1684:                    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
                   1685:                    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
                   1686:                    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
                   1687:                    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
                   1688:                    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
                   1689:                    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
                   1690:                    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
                   1691:                    (((u_int64_t)pdb.pdb_portname[7]));
                   1692:                lp->roles =
                   1693:                    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
                   1694:                lp->portid = BITS2WORD(pdb.pdb_portid_bits);
                   1695:                lp->loopid = pdb.pdb_loopid;
                   1696:                lp->loggedin = lp->valid = 1;
                   1697:                fcp->isp_onfabric = 1;
                   1698:                (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
                   1699:                isp_register_fc4_type(isp);
                   1700:        } else {
                   1701: not_on_fabric:
                   1702:                fcp->isp_onfabric = 0;
                   1703:                fcp->portdb[FL_PORT_ID].valid = 0;
                   1704:        }
                   1705:
                   1706:        fcp->isp_gbspeed = 1;
                   1707:        if (IS_23XX(isp)) {
                   1708:                mbs.param[0] = MBOX_GET_SET_DATA_RATE;
                   1709:                mbs.param[1] = MBGSD_GET_RATE;
                   1710:                /* mbs.param[2] undefined if we're just getting rate */
                   1711:                isp_mboxcmd(isp, &mbs, MBLOGALL);
                   1712:                if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
                   1713:                        if (mbs.param[1] == MBGSD_TWOGB) {
                   1714:                                isp_prt(isp, ISP_LOGINFO, "2Gb link speed/s");
                   1715:                                fcp->isp_gbspeed = 2;
                   1716:                        }
                   1717:                }
                   1718:        }
                   1719:
                   1720:        isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_loopid, fcp->isp_alpa,
                   1721:            fcp->isp_portid, fcp->isp_loopstate, toponames[fcp->isp_topo]);
                   1722:
                   1723:        /*
                   1724:         * Announce ourselves, too. This involves synthesizing an entry.
                   1725:         */
                   1726:        if (fcp->isp_iid_set == 0) {
                   1727:                fcp->isp_iid_set = 1;
                   1728:                fcp->isp_iid = fcp->isp_loopid;
                   1729:                lp = &fcp->portdb[fcp->isp_iid];
                   1730:        } else {
                   1731:                lp = &fcp->portdb[fcp->isp_iid];
                   1732:                if (fcp->isp_portid != lp->portid ||
                   1733:                    fcp->isp_loopid != lp->loopid ||
                   1734:                    fcp->isp_nodewwn != ISP_NODEWWN(isp) ||
                   1735:                    fcp->isp_portwwn != ISP_PORTWWN(isp)) {
                   1736:                        lp->valid = 0;
                   1737:                        count = fcp->isp_iid;
                   1738:                        (void) isp_async(isp, ISPASYNC_PROMENADE, &count);
                   1739:                }
                   1740:        }
                   1741:        lp->loopid = fcp->isp_loopid;
                   1742:        lp->portid = fcp->isp_portid;
                   1743:        lp->node_wwn = ISP_NODEWWN(isp);
                   1744:        lp->port_wwn = ISP_PORTWWN(isp);
                   1745:        switch (isp->isp_role) {
                   1746:        case ISP_ROLE_NONE:
                   1747:                lp->roles = 0;
                   1748:                break;
                   1749:        case ISP_ROLE_TARGET:
                   1750:                lp->roles = SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT;
                   1751:                break;
                   1752:        case ISP_ROLE_INITIATOR:
                   1753:                lp->roles = SVC3_INI_ROLE >> SVC3_ROLE_SHIFT;
                   1754:                break;
                   1755:        case ISP_ROLE_BOTH:
                   1756:                lp->roles = (SVC3_INI_ROLE|SVC3_TGT_ROLE) >> SVC3_ROLE_SHIFT;
                   1757:                break;
                   1758:        }
                   1759:        lp->loggedin = lp->valid = 1;
                   1760:        count = fcp->isp_iid;
                   1761:        (void) isp_async(isp, ISPASYNC_PROMENADE, &count);
                   1762:        return (0);
                   1763: }
                   1764:
                   1765: static char *
                   1766: isp2100_fw_statename(int state)
                   1767: {
                   1768:        switch(state) {
                   1769:        case FW_CONFIG_WAIT:    return "Config Wait";
                   1770:        case FW_WAIT_AL_PA:     return "Waiting for AL_PA";
                   1771:        case FW_WAIT_LOGIN:     return "Wait Login";
                   1772:        case FW_READY:          return "Ready";
                   1773:        case FW_LOSS_OF_SYNC:   return "Loss Of Sync";
                   1774:        case FW_ERROR:          return "Error";
                   1775:        case FW_REINIT:         return "Re-Init";
                   1776:        case FW_NON_PART:       return "Nonparticipating";
                   1777:        default:                return "?????";
                   1778:        }
                   1779: }
                   1780:
                   1781: /*
                   1782:  * Synchronize our soft copy of the port database with what the f/w thinks
                   1783:  * (with a view toward possibly for a specific target....)
                   1784:  */
                   1785:
                   1786: static int
                   1787: isp_pdb_sync(struct ispsoftc *isp)
                   1788: {
                   1789:        struct lportdb *lp;
                   1790:        fcparam *fcp = isp->isp_param;
                   1791:        isp_pdb_t pdb;
                   1792:        int loopid, base, lim;
                   1793:
                   1794:        /*
                   1795:         * Make sure we're okay for doing this right now.
                   1796:         */
                   1797:        if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
                   1798:            fcp->isp_loopstate != LOOP_FSCAN_DONE &&
                   1799:            fcp->isp_loopstate != LOOP_LSCAN_DONE) {
                   1800:                return (-1);
                   1801:        }
                   1802:
                   1803:        if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT ||
                   1804:            fcp->isp_topo == TOPO_N_PORT) {
                   1805:                if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
                   1806:                        if (isp_scan_loop(isp) != 0) {
                   1807:                                return (-1);
                   1808:                        }
                   1809:                }
                   1810:        }
                   1811:        fcp->isp_loopstate = LOOP_SYNCING_PDB;
                   1812:
                   1813:        /*
                   1814:         * If we get this far, we've settled our differences with the f/w
                   1815:         * (for local loop device) and we can say that the loop state is ready.
                   1816:         */
                   1817:
                   1818:        if (fcp->isp_topo == TOPO_NL_PORT) {
                   1819:                fcp->loop_seen_once = 1;
                   1820:                fcp->isp_loopstate = LOOP_READY;
                   1821:                return (0);
                   1822:        }
                   1823:
                   1824:        /*
                   1825:         * Find all Fabric Entities that didn't make it from one scan to the
                   1826:         * next and let the world know they went away. Scan the whole database.
                   1827:         */
                   1828:        for (lp = &fcp->portdb[0]; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
                   1829:                if (lp->was_fabric_dev && lp->fabric_dev == 0) {
                   1830:                        loopid = lp - fcp->portdb;
                   1831:                        lp->valid = 0;  /* should already be set */
                   1832:                        (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
                   1833:                        MEMZERO((void *) lp, sizeof (*lp));
                   1834:                        continue;
                   1835:                }
                   1836:                lp->was_fabric_dev = lp->fabric_dev;
                   1837:        }
                   1838:
                   1839:        if (fcp->isp_topo == TOPO_FL_PORT)
                   1840:                base = FC_SNS_ID+1;
                   1841:        else
                   1842:                base = 0;
                   1843:
                   1844:        if (fcp->isp_topo == TOPO_N_PORT)
                   1845:                lim = 1;
                   1846:        else
                   1847:                lim = MAX_FC_TARG;
                   1848:
                   1849:        /*
                   1850:         * Now log in any fabric devices that the outer layer has
                   1851:         * left for us to see. This seems the most sane policy
                   1852:         * for the moment.
                   1853:         */
                   1854:        for (lp = &fcp->portdb[base]; lp < &fcp->portdb[lim]; lp++) {
                   1855:                u_int32_t portid;
                   1856:                mbreg_t mbs;
                   1857:
                   1858:                loopid = lp - fcp->portdb;
                   1859:                if (loopid >= FL_PORT_ID && loopid <= FC_SNS_ID) {
                   1860:                        continue;
                   1861:                }
                   1862:
                   1863:                /*
                   1864:                 * Anything here?
                   1865:                 */
                   1866:                if (lp->port_wwn == 0) {
                   1867:                        continue;
                   1868:                }
                   1869:
                   1870:                /*
                   1871:                 * Don't try to log into yourself.
                   1872:                 */
                   1873:                if ((portid = lp->portid) == fcp->isp_portid) {
                   1874:                        continue;
                   1875:                }
                   1876:
                   1877:
                   1878:                /*
                   1879:                 * If we'd been logged in- see if we still are and we haven't
                   1880:                 * changed. If so, no need to log ourselves out, etc..
                   1881:                 *
                   1882:                 * Unfortunately, our charming Qlogic f/w has decided to
                   1883:                 * return a valid port database entry for a fabric device
                   1884:                 * that has, in fact, gone away. And it hangs trying to
                   1885:                 * log it out.
                   1886:                 */
                   1887:                if (lp->loggedin && lp->force_logout == 0 &&
                   1888:                    isp_getpdb(isp, lp->loopid, &pdb) == 0) {
                   1889:                        int nrole;
                   1890:                        u_int64_t nwwnn, nwwpn;
                   1891:                        nwwnn =
                   1892:                            (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
                   1893:                            (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
                   1894:                            (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
                   1895:                            (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
                   1896:                            (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
                   1897:                            (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
                   1898:                            (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
                   1899:                            (((u_int64_t)pdb.pdb_nodename[7]));
                   1900:                        nwwpn =
                   1901:                            (((u_int64_t)pdb.pdb_portname[0]) << 56) |
                   1902:                            (((u_int64_t)pdb.pdb_portname[1]) << 48) |
                   1903:                            (((u_int64_t)pdb.pdb_portname[2]) << 40) |
                   1904:                            (((u_int64_t)pdb.pdb_portname[3]) << 32) |
                   1905:                            (((u_int64_t)pdb.pdb_portname[4]) << 24) |
                   1906:                            (((u_int64_t)pdb.pdb_portname[5]) << 16) |
                   1907:                            (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
                   1908:                            (((u_int64_t)pdb.pdb_portname[7]));
                   1909:                        nrole = (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >>
                   1910:                            SVC3_ROLE_SHIFT;
                   1911:                        if (pdb.pdb_loopid == lp->loopid && lp->portid ==
                   1912:                            (u_int32_t) BITS2WORD(pdb.pdb_portid_bits) &&
                   1913:                            nwwnn == lp->node_wwn && nwwpn == lp->port_wwn &&
                   1914:                            lp->roles == nrole && lp->force_logout == 0) {
                   1915:                                lp->loggedin = lp->valid = 1;
                   1916:                                isp_prt(isp, ISP_LOGCONFIG, lretained,
                   1917:                                    (int) (lp - fcp->portdb),
                   1918:                                    (int) lp->loopid, lp->portid);
                   1919:                                continue;
                   1920:                        }
                   1921:                }
                   1922:
                   1923:                if (fcp->isp_fwstate != FW_READY ||
                   1924:                    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
                   1925:                        return (-1);
                   1926:                }
                   1927:
                   1928:                /*
                   1929:                 * Force a logout if we were logged in.
                   1930:                 */
                   1931:                if (lp->loggedin) {
                   1932:                        if (lp->force_logout ||
                   1933:                            isp_getpdb(isp, lp->loopid, &pdb) == 0) {
                   1934:                                mbs.param[0] = MBOX_FABRIC_LOGOUT;
                   1935:                                mbs.param[1] = lp->loopid << 8;
                   1936:                                mbs.param[2] = 0;
                   1937:                                mbs.param[3] = 0;
                   1938:                                isp_mboxcmd(isp, &mbs, MBLOGNONE);
                   1939:                                isp_prt(isp, ISP_LOGINFO, plogout,
                   1940:                                    (int) (lp - fcp->portdb), lp->loopid,
                   1941:                                    lp->portid);
                   1942:                        }
                   1943:                        lp->force_logout = lp->loggedin = 0;
                   1944:                        if (fcp->isp_fwstate != FW_READY ||
                   1945:                            fcp->isp_loopstate != LOOP_SYNCING_PDB) {
                   1946:                                return (-1);
                   1947:                        }
                   1948:                }
                   1949:
                   1950:                /*
                   1951:                 * And log in....
                   1952:                 */
                   1953:                loopid = lp - fcp->portdb;
                   1954:                lp->loopid = FL_PORT_ID;
                   1955:                do {
                   1956:                        mbs.param[0] = MBOX_FABRIC_LOGIN;
                   1957:                        mbs.param[1] = loopid << 8;
                   1958:                        mbs.param[2] = portid >> 16;
                   1959:                        mbs.param[3] = portid & 0xffff;
                   1960:                        isp_mboxcmd(isp, &mbs, MBLOGALL & ~(MBOX_LOOP_ID_USED |
                   1961:                            MBOX_PORT_ID_USED | MBOX_COMMAND_ERROR));
                   1962:                        if (fcp->isp_fwstate != FW_READY ||
                   1963:                            fcp->isp_loopstate != LOOP_SYNCING_PDB) {
                   1964:                                return (-1);
                   1965:                        }
                   1966:                        switch (mbs.param[0]) {
                   1967:                        case MBOX_LOOP_ID_USED:
                   1968:                                /*
                   1969:                                 * Try the next available loop id.
                   1970:                                 */
                   1971:                                loopid++;
                   1972:                                break;
                   1973:                        case MBOX_PORT_ID_USED:
                   1974:                                /*
                   1975:                                 * This port is already logged in.
                   1976:                                 * Snaffle the loop id it's using if it's
                   1977:                                 * nonzero, otherwise we're hosed.
                   1978:                                 */
                   1979:                                if (mbs.param[1] != 0) {
                   1980:                                        loopid = mbs.param[1];
                   1981:                                        isp_prt(isp, ISP_LOGINFO, retained,
                   1982:                                            loopid, (int) (lp - fcp->portdb),
                   1983:                                            lp->portid);
                   1984:                                } else {
                   1985:                                        loopid = MAX_FC_TARG;
                   1986:                                        break;
                   1987:                                }
                   1988:                                /* FALLTHROUGH */
                   1989:                        case MBOX_COMMAND_COMPLETE:
                   1990:                                lp->loggedin = 1;
                   1991:                                lp->loopid = loopid;
                   1992:                                break;
                   1993:                        case MBOX_COMMAND_ERROR:
                   1994:                                isp_prt(isp, ISP_LOGINFO, plogierr,
                   1995:                                    portid, mbs.param[1]);
                   1996:                                /* FALLTHROUGH */
                   1997:                        case MBOX_ALL_IDS_USED: /* We're outta IDs */
                   1998:                        default:
                   1999:                                loopid = MAX_FC_TARG;
                   2000:                                break;
                   2001:                        }
                   2002:                } while (lp->loopid == FL_PORT_ID && loopid < MAX_FC_TARG);
                   2003:
                   2004:                /*
                   2005:                 * If we get here and we haven't set a Loop ID,
                   2006:                 * we failed to log into this device.
                   2007:                 */
                   2008:
                   2009:                if (lp->loopid == FL_PORT_ID) {
                   2010:                        lp->loopid = 0;
                   2011:                        continue;
                   2012:                }
                   2013:
                   2014:                /*
                   2015:                 * Make sure we can get the appropriate port information.
                   2016:                 */
                   2017:                if (isp_getpdb(isp, lp->loopid, &pdb) != 0) {
                   2018:                        isp_prt(isp, ISP_LOGWARN, nopdb, lp->portid);
                   2019:                        goto dump_em;
                   2020:                }
                   2021:
                   2022:                if (fcp->isp_fwstate != FW_READY ||
                   2023:                    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
                   2024:                        return (-1);
                   2025:                }
                   2026:
                   2027:                if (pdb.pdb_loopid != lp->loopid) {
                   2028:                        isp_prt(isp, ISP_LOGWARN, pdbmfail1,
                   2029:                            lp->portid, pdb.pdb_loopid);
                   2030:                        goto dump_em;
                   2031:                }
                   2032:
                   2033:                if (lp->portid != (u_int32_t) BITS2WORD(pdb.pdb_portid_bits)) {
                   2034:                        isp_prt(isp, ISP_LOGWARN, pdbmfail2,
                   2035:                            lp->portid, BITS2WORD(pdb.pdb_portid_bits));
                   2036:                        goto dump_em;
                   2037:                }
                   2038:
                   2039:                lp->roles =
                   2040:                    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
                   2041:                lp->node_wwn =
                   2042:                    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
                   2043:                    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
                   2044:                    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
                   2045:                    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
                   2046:                    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
                   2047:                    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
                   2048:                    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
                   2049:                    (((u_int64_t)pdb.pdb_nodename[7]));
                   2050:                lp->port_wwn =
                   2051:                    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
                   2052:                    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
                   2053:                    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
                   2054:                    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
                   2055:                    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
                   2056:                    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
                   2057:                    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
                   2058:                    (((u_int64_t)pdb.pdb_portname[7]));
                   2059:                /*
                   2060:                 * Check to make sure this all makes sense.
                   2061:                 */
                   2062:                if (lp->node_wwn && lp->port_wwn) {
                   2063:                        lp->valid = 1;
                   2064:                        loopid = lp - fcp->portdb;
                   2065:                        (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
                   2066:                        continue;
                   2067:                }
                   2068: dump_em:
                   2069:                lp->valid = 0;
                   2070:                isp_prt(isp, ISP_LOGINFO,
                   2071:                    ldumped, loopid, lp->loopid, lp->portid);
                   2072:                mbs.param[0] = MBOX_FABRIC_LOGOUT;
                   2073:                mbs.param[1] = lp->loopid << 8;
                   2074:                mbs.param[2] = 0;
                   2075:                mbs.param[3] = 0;
                   2076:                isp_mboxcmd(isp, &mbs, MBLOGNONE);
                   2077:                if (fcp->isp_fwstate != FW_READY ||
                   2078:                    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
                   2079:                        return (-1);
                   2080:                }
                   2081:        }
                   2082:        /*
                   2083:         * If we get here, we've for sure seen not only a valid loop
                   2084:         * but know what is or isn't on it, so mark this for usage
                   2085:         * in isp_start.
                   2086:         */
                   2087:        fcp->loop_seen_once = 1;
                   2088:        fcp->isp_loopstate = LOOP_READY;
                   2089:        return (0);
                   2090: }
                   2091:
                   2092: static int
                   2093: isp_scan_loop(struct ispsoftc *isp)
                   2094: {
                   2095:        struct lportdb *lp;
                   2096:        fcparam *fcp = isp->isp_param;
                   2097:        isp_pdb_t pdb;
                   2098:        int loopid, lim, hival;
                   2099:
                   2100:        switch (fcp->isp_topo) {
                   2101:        case TOPO_NL_PORT:
                   2102:                hival = FL_PORT_ID;
                   2103:                break;
                   2104:        case TOPO_N_PORT:
                   2105:                hival = 2;
                   2106:                break;
                   2107:        case TOPO_FL_PORT:
                   2108:                hival = FC_PORT_ID;
                   2109:                break;
                   2110:        default:
                   2111:                fcp->isp_loopstate = LOOP_LSCAN_DONE;
                   2112:                return (0);
                   2113:        }
                   2114:        fcp->isp_loopstate = LOOP_SCANNING_LOOP;
                   2115:
                   2116:        /*
                   2117:         * make sure the temp port database is clean...
                   2118:         */
                   2119:        MEMZERO((void *)fcp->tport, sizeof (fcp->tport));
                   2120:
                   2121:        /*
                   2122:         * Run through the local loop ports and get port database info
                   2123:         * for each loop ID.
                   2124:         *
                   2125:         * There's a somewhat unexplained situation where the f/w passes back
                   2126:         * the wrong database entity- if that happens, just restart (up to
                   2127:         * FL_PORT_ID times).
                   2128:         */
                   2129:        for (lim = loopid = 0; loopid < hival; loopid++) {
                   2130:                lp = &fcp->tport[loopid];
                   2131:
                   2132:                /*
                   2133:                 * Don't even try for ourselves...
                   2134:                 */
                   2135:                if (loopid == fcp->isp_loopid)
                   2136:                        continue;
                   2137:
                   2138:                lp->node_wwn = isp_get_portname(isp, loopid, 1);
                   2139:                if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
                   2140:                        return (-1);
                   2141:                if (lp->node_wwn == 0)
                   2142:                        continue;
                   2143:                lp->port_wwn = isp_get_portname(isp, loopid, 0);
                   2144:                if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
                   2145:                        return (-1);
                   2146:                if (lp->port_wwn == 0) {
                   2147:                        lp->node_wwn = 0;
                   2148:                        continue;
                   2149:                }
                   2150:
                   2151:                /*
                   2152:                 * Get an entry....
                   2153:                 */
                   2154:                if (isp_getpdb(isp, loopid, &pdb) != 0) {
                   2155:                        if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
                   2156:                                return (-1);
                   2157:                        continue;
                   2158:                }
                   2159:                if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
                   2160:                        return (-1);
                   2161:                }
                   2162:
                   2163:                /*
                   2164:                 * If the returned database element doesn't match what we
                   2165:                 * asked for, restart the process entirely (up to a point...).
                   2166:                 */
                   2167:                if (pdb.pdb_loopid != loopid) {
                   2168:                        loopid = 0;
                   2169:                        if (lim++ < hival) {
                   2170:                                continue;
                   2171:                        }
                   2172:                        isp_prt(isp, ISP_LOGWARN,
                   2173:                            "giving up on synchronizing the port database");
                   2174:                        return (-1);
                   2175:                }
                   2176:
                   2177:                /*
                   2178:                 * Save the pertinent info locally.
                   2179:                 */
                   2180:                lp->node_wwn =
                   2181:                    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
                   2182:                    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
                   2183:                    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
                   2184:                    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
                   2185:                    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
                   2186:                    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
                   2187:                    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
                   2188:                    (((u_int64_t)pdb.pdb_nodename[7]));
                   2189:                lp->port_wwn =
                   2190:                    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
                   2191:                    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
                   2192:                    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
                   2193:                    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
                   2194:                    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
                   2195:                    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
                   2196:                    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
                   2197:                    (((u_int64_t)pdb.pdb_portname[7]));
                   2198:                lp->roles =
                   2199:                    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
                   2200:                lp->portid = BITS2WORD(pdb.pdb_portid_bits);
                   2201:                lp->loopid = pdb.pdb_loopid;
                   2202:        }
                   2203:
                   2204:        /*
                   2205:         * Mark all of the permanent local loop database entries as invalid
                   2206:         * (except our own entry).
                   2207:         */
                   2208:        for (loopid = 0; loopid < hival; loopid++) {
                   2209:                if (loopid == fcp->isp_iid) {
                   2210:                        fcp->portdb[loopid].valid = 1;
                   2211:                        fcp->portdb[loopid].loopid = fcp->isp_loopid;
                   2212:                        continue;
                   2213:                }
                   2214:                fcp->portdb[loopid].valid = 0;
                   2215:        }
                   2216:
                   2217:        /*
                   2218:         * Now merge our local copy of the port database into our saved copy.
                   2219:         * Notify the outer layers of new devices arriving.
                   2220:         */
                   2221:        for (loopid = 0; loopid < hival; loopid++) {
                   2222:                int i;
                   2223:
                   2224:                /*
                   2225:                 * If we don't have a non-zero Port WWN, we're not here.
                   2226:                 */
                   2227:                if (fcp->tport[loopid].port_wwn == 0) {
                   2228:                        continue;
                   2229:                }
                   2230:
                   2231:                /*
                   2232:                 * Skip ourselves.
                   2233:                 */
                   2234:                if (loopid == fcp->isp_iid) {
                   2235:                        continue;
                   2236:                }
                   2237:
                   2238:                /*
                   2239:                 * For the purposes of deciding whether this is the
                   2240:                 * 'same' device or not, we only search for an identical
                   2241:                 * Port WWN. Node WWNs may or may not be the same as
                   2242:                 * the Port WWN, and there may be multiple different
                   2243:                 * Port WWNs with the same Node WWN. It would be chaos
                   2244:                 * to have multiple identical Port WWNs, so we don't
                   2245:                 * allow that.
                   2246:                 */
                   2247:
                   2248:                for (i = 0; i < hival; i++) {
                   2249:                        int j;
                   2250:                        if (fcp->portdb[i].port_wwn == 0)
                   2251:                                continue;
                   2252:                        if (fcp->portdb[i].port_wwn !=
                   2253:                            fcp->tport[loopid].port_wwn)
                   2254:                                continue;
                   2255:                        /*
                   2256:                         * We found this WWN elsewhere- it's changed
                   2257:                         * loopids then. We don't change its actual
                   2258:                         * position in our cached port database- we
                   2259:                         * just change the actual loop ID we'd use.
                   2260:                         */
                   2261:                        if (fcp->portdb[i].loopid != loopid) {
                   2262:                                isp_prt(isp, ISP_LOGINFO, portshift, i,
                   2263:                                    fcp->portdb[i].loopid,
                   2264:                                    fcp->portdb[i].portid, loopid,
                   2265:                                    fcp->tport[loopid].portid);
                   2266:                        }
                   2267:                        fcp->portdb[i].portid = fcp->tport[loopid].portid;
                   2268:                        fcp->portdb[i].loopid = loopid;
                   2269:                        fcp->portdb[i].valid = 1;
                   2270:                        fcp->portdb[i].roles = fcp->tport[loopid].roles;
                   2271:
                   2272:                        /*
                   2273:                         * Now make sure this Port WWN doesn't exist elsewhere
                   2274:                         * in the port database.
                   2275:                         */
                   2276:                        for (j = i+1; j < hival; j++) {
                   2277:                                if (fcp->portdb[i].port_wwn !=
                   2278:                                    fcp->portdb[j].port_wwn) {
                   2279:                                        continue;
                   2280:                                }
                   2281:                                isp_prt(isp, ISP_LOGWARN, portdup, j, i);
                   2282:                                /*
                   2283:                                 * Invalidate the 'old' *and* 'new' ones.
                   2284:                                 * This is really harsh and not quite right,
                   2285:                                 * but if this happens, we really don't know
                   2286:                                 * who is what at this point.
                   2287:                                 */
                   2288:                                fcp->portdb[i].valid = 0;
                   2289:                                fcp->portdb[j].valid = 0;
                   2290:                        }
                   2291:                        break;
                   2292:                }
                   2293:
                   2294:                /*
                   2295:                 * If we didn't traverse the entire port database,
                   2296:                 * then we found (and remapped) an existing entry.
                   2297:                 * No need to notify anyone- go for the next one.
                   2298:                 */
                   2299:                if (i < hival) {
                   2300:                        isp_prt(isp, ISP_LOGINFO, retained,
                   2301:                            fcp->portdb[i].loopid, i, fcp->portdb[i].portid);
                   2302:                        continue;
                   2303:                }
                   2304:
                   2305:                /*
                   2306:                 * We've not found this Port WWN anywhere. It's a new entry.
                   2307:                 * See if we can leave it where it is (with target == loopid).
                   2308:                 */
                   2309:                if (fcp->portdb[loopid].port_wwn != 0) {
                   2310:                        for (lim = 0; lim < hival; lim++) {
                   2311:                                if (fcp->portdb[lim].port_wwn == 0)
                   2312:                                        break;
                   2313:                        }
                   2314:                        /* "Cannot Happen" */
                   2315:                        if (lim == hival) {
                   2316:                                isp_prt(isp, ISP_LOGWARN, "Remap Overflow");
                   2317:                                continue;
                   2318:                        }
                   2319:                        i = lim;
                   2320:                } else {
                   2321:                        i = loopid;
                   2322:                }
                   2323:
                   2324:                /*
                   2325:                 * NB:  The actual loopid we use here is loopid- we may
                   2326:                 *      in fact be at a completely different index (target).
                   2327:                 */
                   2328:                fcp->portdb[i].loopid = loopid;
                   2329:                fcp->portdb[i].port_wwn = fcp->tport[loopid].port_wwn;
                   2330:                fcp->portdb[i].node_wwn = fcp->tport[loopid].node_wwn;
                   2331:                fcp->portdb[i].roles = fcp->tport[loopid].roles;
                   2332:                fcp->portdb[i].portid = fcp->tport[loopid].portid;
                   2333:                fcp->portdb[i].valid = 1;
                   2334:
                   2335:                /*
                   2336:                 * Tell the outside world we've arrived.
                   2337:                 */
                   2338:                (void) isp_async(isp, ISPASYNC_PROMENADE, &i);
                   2339:        }
                   2340:
                   2341:        /*
                   2342:         * Now find all previously used targets that are now invalid and
                   2343:         * notify the outer layers that they're gone.
                   2344:         */
                   2345:        for (lp = &fcp->portdb[0]; lp < &fcp->portdb[hival]; lp++) {
                   2346:                if (lp->valid || lp->port_wwn == 0) {
                   2347:                        continue;
                   2348:                }
                   2349:
                   2350:                /*
                   2351:                 * Tell the outside world we've gone
                   2352:                 * away and erase our pdb entry.
                   2353:                 *
                   2354:                 */
                   2355:                loopid = lp - fcp->portdb;
                   2356:                (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
                   2357:                MEMZERO((void *) lp, sizeof (*lp));
                   2358:        }
                   2359:        fcp->isp_loopstate = LOOP_LSCAN_DONE;
                   2360:        return (0);
                   2361: }
                   2362:
                   2363:
                   2364: static int
                   2365: isp_fabric_mbox_cmd(struct ispsoftc *isp, mbreg_t *mbp)
                   2366: {
                   2367:        isp_mboxcmd(isp, mbp, MBLOGNONE);
                   2368:        if (mbp->param[0] != MBOX_COMMAND_COMPLETE) {
                   2369:                if (FCPARAM(isp)->isp_loopstate == LOOP_SCANNING_FABRIC) {
                   2370:                        FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
                   2371:                }
                   2372:                if (mbp->param[0] == MBOX_COMMAND_ERROR) {
                   2373:                        char tbuf[16];
                   2374:                        char *m;
                   2375:                        switch (mbp->param[1]) {
                   2376:                        case 1:
                   2377:                                m = "No Loop";
                   2378:                                break;
                   2379:                        case 2:
                   2380:                                m = "Failed to allocate IOCB buffer";
                   2381:                                break;
                   2382:                        case 3:
                   2383:                                m = "Failed to allocate XCB buffer";
                   2384:                                break;
                   2385:                        case 4:
                   2386:                                m = "timeout or transmit failed";
                   2387:                                break;
                   2388:                        case 5:
                   2389:                                m = "no fabric loop";
                   2390:                                break;
                   2391:                        case 6:
                   2392:                                m = "remote device not a target";
                   2393:                                break;
                   2394:                        default:
                   2395:                                SNPRINTF(tbuf, sizeof tbuf, "%x",
                   2396:                                    mbp->param[1]);
                   2397:                                m = tbuf;
                   2398:                                break;
                   2399:                        }
                   2400:                        isp_prt(isp, ISP_LOGERR, "SNS Failed- %s", m);
                   2401:                }
                   2402:                return (-1);
                   2403:        }
                   2404:
                   2405:        if (FCPARAM(isp)->isp_fwstate != FW_READY ||
                   2406:            FCPARAM(isp)->isp_loopstate < LOOP_SCANNING_FABRIC) {
                   2407:                return (-1);
                   2408:        }
                   2409:        return(0);
                   2410: }
                   2411:
                   2412: #ifdef ISP_USE_GA_NXT
                   2413: static int
                   2414: isp_scan_fabric(struct ispsoftc *isp, int ftype)
                   2415: {
                   2416:        fcparam *fcp = isp->isp_param;
                   2417:        u_int32_t portid, first_portid, last_portid;
                   2418:        int hicap, last_port_same;
                   2419:
                   2420:        if (fcp->isp_onfabric == 0) {
                   2421:                fcp->isp_loopstate = LOOP_FSCAN_DONE;
                   2422:                return (0);
                   2423:        }
                   2424:
                   2425:        FC_SCRATCH_ACQUIRE(isp);
                   2426:
                   2427:        /*
                   2428:         * Since Port IDs are 24 bits, we can check against having seen
                   2429:         * anything yet with this value.
                   2430:         */
                   2431:        last_port_same = 0;
                   2432:        last_portid = 0xffffffff;       /* not a port */
                   2433:        first_portid = portid = fcp->isp_portid;
                   2434:        fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
                   2435:
                   2436:        for (hicap = 0; hicap < GA_NXT_MAX; hicap++) {
                   2437:                mbreg_t mbs;
                   2438:                sns_screq_t *rq;
                   2439:                sns_ga_nxt_rsp_t *rs0, *rs1;
                   2440:                struct lportdb lcl;
                   2441:                u_int8_t sc[SNS_GA_NXT_RESP_SIZE];
                   2442:
                   2443:                rq = (sns_screq_t *)sc;
                   2444:                MEMZERO((void *) rq, SNS_GA_NXT_REQ_SIZE);
                   2445:                rq->snscb_rblen = SNS_GA_NXT_RESP_SIZE >> 1;
                   2446:                rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+0x100);
                   2447:                rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+0x100);
                   2448:                rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+0x100);
                   2449:                rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+0x100);
                   2450:                rq->snscb_sblen = 6;
                   2451:                rq->snscb_data[0] = SNS_GA_NXT;
                   2452:                rq->snscb_data[4] = portid & 0xffff;
                   2453:                rq->snscb_data[5] = (portid >> 16) & 0xff;
                   2454:                isp_put_sns_request(isp, rq, (sns_screq_t *) fcp->isp_scratch);
                   2455:                MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GA_NXT_REQ_SIZE);
                   2456:                mbs.param[0] = MBOX_SEND_SNS;
                   2457:                mbs.param[1] = SNS_GA_NXT_REQ_SIZE >> 1;
                   2458:                mbs.param[2] = DMA_WD1(fcp->isp_scdma);
                   2459:                mbs.param[3] = DMA_WD0(fcp->isp_scdma);
                   2460:                /*
                   2461:                 * Leave 4 and 5 alone
                   2462:                 */
                   2463:                mbs.param[6] = DMA_WD3(fcp->isp_scdma);
                   2464:                mbs.param[7] = DMA_WD2(fcp->isp_scdma);
                   2465:                if (isp_fabric_mbox_cmd(isp, &mbs)) {
                   2466:                        if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
                   2467:                                fcp->isp_loopstate = LOOP_PDB_RCVD;
                   2468:                        }
                   2469:                        FC_SCRATCH_RELEASE(isp);
                   2470:                        return (-1);
                   2471:                }
                   2472:                MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GA_NXT_RESP_SIZE);
                   2473:                rs1 = (sns_ga_nxt_rsp_t *) sc;
                   2474:                rs0 = (sns_ga_nxt_rsp_t *) ((u_int8_t *)fcp->isp_scratch+0x100);
                   2475:                isp_get_ga_nxt_response(isp, rs0, rs1);
                   2476:                if (rs1->snscb_cthdr.ct_response != FS_ACC) {
                   2477:                        int level;
                   2478:                        if (rs1->snscb_cthdr.ct_reason == 9 &&
                   2479:                            rs1->snscb_cthdr.ct_explanation == 7)
                   2480:                                level = ISP_LOGDEBUG0;
                   2481:                        else
                   2482:                                level = ISP_LOGWARN;
                   2483:                        isp_prt(isp, level, swrej, "GA_NXT",
                   2484:                            rs1->snscb_cthdr.ct_reason,
                   2485:                            rs1->snscb_cthdr.ct_explanation, portid);
                   2486:                        FC_SCRATCH_RELEASE(isp);
                   2487:                        fcp->isp_loopstate = LOOP_FSCAN_DONE;
                   2488:                        return (0);
                   2489:                }
                   2490:                portid =
                   2491:                    (((u_int32_t) rs1->snscb_port_id[0]) << 16) |
                   2492:                    (((u_int32_t) rs1->snscb_port_id[1]) << 8) |
                   2493:                    (((u_int32_t) rs1->snscb_port_id[2]));
                   2494:
                   2495:                /*
                   2496:                 * XXX: We should check to make sure that this entry
                   2497:                 * XXX: supports the type(s) we are interested in.
                   2498:                 */
                   2499:                /*
                   2500:                 * Okay, we now have information about a fabric object.
                   2501:                 * If it is the type we're interested in, tell the outer layers
                   2502:                 * about it. The outer layer needs to  know: Port ID, WWNN,
                   2503:                 * WWPN, FC4 type, and port type.
                   2504:                 *
                   2505:                 * The lportdb structure is adequate for this.
                   2506:                 */
                   2507:                MEMZERO(&lcl, sizeof (lcl));
                   2508:                lcl.port_type = rs1->snscb_port_type;
                   2509:                lcl.fc4_type = ftype;
                   2510:                lcl.portid = portid;
                   2511:                lcl.node_wwn =
                   2512:                    (((u_int64_t)rs1->snscb_nodename[0]) << 56) |
                   2513:                    (((u_int64_t)rs1->snscb_nodename[1]) << 48) |
                   2514:                    (((u_int64_t)rs1->snscb_nodename[2]) << 40) |
                   2515:                    (((u_int64_t)rs1->snscb_nodename[3]) << 32) |
                   2516:                    (((u_int64_t)rs1->snscb_nodename[4]) << 24) |
                   2517:                    (((u_int64_t)rs1->snscb_nodename[5]) << 16) |
                   2518:                    (((u_int64_t)rs1->snscb_nodename[6]) <<  8) |
                   2519:                    (((u_int64_t)rs1->snscb_nodename[7]));
                   2520:                lcl.port_wwn =
                   2521:                    (((u_int64_t)rs1->snscb_portname[0]) << 56) |
                   2522:                    (((u_int64_t)rs1->snscb_portname[1]) << 48) |
                   2523:                    (((u_int64_t)rs1->snscb_portname[2]) << 40) |
                   2524:                    (((u_int64_t)rs1->snscb_portname[3]) << 32) |
                   2525:                    (((u_int64_t)rs1->snscb_portname[4]) << 24) |
                   2526:                    (((u_int64_t)rs1->snscb_portname[5]) << 16) |
                   2527:                    (((u_int64_t)rs1->snscb_portname[6]) <<  8) |
                   2528:                    (((u_int64_t)rs1->snscb_portname[7]));
                   2529:
                   2530:                /*
                   2531:                 * Does this fabric object support the type we want?
                   2532:                 * If not, skip it.
                   2533:                 */
                   2534:                if (rs1->snscb_fc4_types[ftype >> 5] & (1 << (ftype & 0x1f))) {
                   2535:                        if (first_portid == portid) {
                   2536:                                lcl.last_fabric_dev = 1;
                   2537:                        } else {
                   2538:                                lcl.last_fabric_dev = 0;
                   2539:                        }
                   2540:                        (void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
                   2541:                } else {
                   2542:                        isp_prt(isp, ISP_LOGDEBUG0,
                   2543:                            "PortID 0x%x doesn't support FC4 type 0x%x",
                   2544:                            portid, ftype);
                   2545:                }
                   2546:                if (first_portid == portid) {
                   2547:                        fcp->isp_loopstate = LOOP_FSCAN_DONE;
                   2548:                        FC_SCRATCH_RELEASE(isp);
                   2549:                        return (0);
                   2550:                }
                   2551:                if (portid == last_portid) {
                   2552:                        if (last_port_same++ > 20) {
                   2553:                                isp_prt(isp, ISP_LOGWARN,
                   2554:                                    "tangled fabric database detected");
                   2555:                                break;
                   2556:                        }
                   2557:                } else {
                   2558:                        last_port_same = 0 ;
                   2559:                        last_portid = portid;
                   2560:                }
                   2561:        }
                   2562:        FC_SCRATCH_RELEASE(isp);
                   2563:        if (hicap >= GA_NXT_MAX) {
                   2564:                isp_prt(isp, ISP_LOGWARN, "fabric too big (> %d)", GA_NXT_MAX);
                   2565:        }
                   2566:        fcp->isp_loopstate = LOOP_FSCAN_DONE;
                   2567:        return (0);
                   2568: }
                   2569: #else
                   2570: #define        GIDLEN  ((ISP2100_SCRLEN >> 1) + 16)
                   2571: #define        NGENT   ((GIDLEN - 16) >> 2)
                   2572:
                   2573: #define        IGPOFF  (ISP2100_SCRLEN - GIDLEN)
                   2574: #define        GXOFF   (256)
                   2575:
                   2576: static int
                   2577: isp_scan_fabric(struct ispsoftc *isp, int ftype)
                   2578: {
                   2579:        fcparam *fcp = FCPARAM(isp);
                   2580:        mbreg_t mbs;
                   2581:        int i;
                   2582:        sns_gid_ft_req_t *rq;
                   2583:        sns_gid_ft_rsp_t *rs0, *rs1;
                   2584:
                   2585:        if (fcp->isp_onfabric == 0) {
                   2586:                fcp->isp_loopstate = LOOP_FSCAN_DONE;
                   2587:                return (0);
                   2588:        }
                   2589:
                   2590:        FC_SCRATCH_ACQUIRE(isp);
                   2591:        fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
                   2592:
                   2593:        rq = (sns_gid_ft_req_t *)fcp->tport;
                   2594:        MEMZERO((void *) rq, SNS_GID_FT_REQ_SIZE);
                   2595:        rq->snscb_rblen = GIDLEN >> 1;
                   2596:        rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+IGPOFF);
                   2597:        rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+IGPOFF);
                   2598:        rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+IGPOFF);
                   2599:        rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+IGPOFF);
                   2600:        rq->snscb_sblen = 6;
                   2601:        rq->snscb_cmd = SNS_GID_FT;
                   2602:        rq->snscb_mword_div_2 = NGENT;
                   2603:        rq->snscb_fc4_type = ftype;
                   2604:        isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *) fcp->isp_scratch);
                   2605:        MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
                   2606:        mbs.param[0] = MBOX_SEND_SNS;
                   2607:        mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
                   2608:        mbs.param[2] = DMA_WD1(fcp->isp_scdma);
                   2609:        mbs.param[3] = DMA_WD0(fcp->isp_scdma);
                   2610:
                   2611:        /*
                   2612:         * Leave 4 and 5 alone
                   2613:         */
                   2614:        mbs.param[6] = DMA_WD3(fcp->isp_scdma);
                   2615:        mbs.param[7] = DMA_WD2(fcp->isp_scdma);
                   2616:        if (isp_fabric_mbox_cmd(isp, &mbs)) {
                   2617:                if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
                   2618:                        fcp->isp_loopstate = LOOP_PDB_RCVD;
                   2619:                }
                   2620:                FC_SCRATCH_RELEASE(isp);
                   2621:                return (-1);
                   2622:        }
                   2623:        if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
                   2624:                FC_SCRATCH_RELEASE(isp);
                   2625:                return (-1);
                   2626:        }
                   2627:        MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
                   2628:        rs1 = (sns_gid_ft_rsp_t *) fcp->tport;
                   2629:        rs0 = (sns_gid_ft_rsp_t *) ((u_int8_t *)fcp->isp_scratch+IGPOFF);
                   2630:        isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
                   2631:        if (rs1->snscb_cthdr.ct_response != FS_ACC) {
                   2632:                int level;
                   2633:                if (rs1->snscb_cthdr.ct_reason == 9 &&
                   2634:                    rs1->snscb_cthdr.ct_explanation == 7)
                   2635:                        level = ISP_LOGDEBUG0;
                   2636:                else
                   2637:                        level = ISP_LOGWARN;
                   2638:                isp_prt(isp, level, swrej, "GID_FT",
                   2639:                    rs1->snscb_cthdr.ct_reason,
                   2640:                    rs1->snscb_cthdr.ct_explanation, 0);
                   2641:                FC_SCRATCH_RELEASE(isp);
                   2642:                fcp->isp_loopstate = LOOP_FSCAN_DONE;
                   2643:                return (0);
                   2644:        }
                   2645:
                   2646:        /*
                   2647:         * Okay, we now have a list of Port IDs for this class of device.
                   2648:         * Go through the list and for each one get the WWPN/WWNN for it
                   2649:         * and tell the outer layers about it. The outer layer needs to
                   2650:         * know: Port ID, WWNN, WWPN, FC4 type, and (possibly) port type.
                   2651:         *
                   2652:         * The lportdb structure is adequate for this.
                   2653:         */
                   2654:        i = -1;
                   2655:        do {
                   2656:                sns_gxn_id_req_t grqbuf, *gq = &grqbuf;
                   2657:                sns_gxn_id_rsp_t *gs0, grsbuf, *gs1 = &grsbuf;
                   2658:                struct lportdb lcl;
                   2659: #if    0
                   2660:                sns_gff_id_rsp_t *fs0, ffsbuf, *fs1 = &ffsbuf;
                   2661: #endif
                   2662:
                   2663:                i++;
                   2664:                MEMZERO(&lcl, sizeof (lcl));
                   2665:                lcl.fc4_type = ftype;
                   2666:                lcl.portid =
                   2667:                    (((u_int32_t) rs1->snscb_ports[i].portid[0]) << 16) |
                   2668:                    (((u_int32_t) rs1->snscb_ports[i].portid[1]) << 8) |
                   2669:                    (((u_int32_t) rs1->snscb_ports[i].portid[2]));
                   2670:
                   2671:                MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
                   2672:                gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
                   2673:                gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
                   2674:                gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
                   2675:                gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
                   2676:                gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
                   2677:                gq->snscb_sblen = 6;
                   2678:                gq->snscb_cmd = SNS_GPN_ID;
                   2679:                gq->snscb_portid = lcl.portid;
                   2680:                isp_put_gxn_id_request(isp, gq,
                   2681:                    (sns_gxn_id_req_t *) fcp->isp_scratch);
                   2682:                MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
                   2683:                mbs.param[0] = MBOX_SEND_SNS;
                   2684:                mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
                   2685:                mbs.param[2] = DMA_WD1(fcp->isp_scdma);
                   2686:                mbs.param[3] = DMA_WD0(fcp->isp_scdma);
                   2687:                /*
                   2688:                 * Leave 4 and 5 alone
                   2689:                 */
                   2690:                mbs.param[6] = DMA_WD3(fcp->isp_scdma);
                   2691:                mbs.param[7] = DMA_WD2(fcp->isp_scdma);
                   2692:                if (isp_fabric_mbox_cmd(isp, &mbs)) {
                   2693:                        if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
                   2694:                                fcp->isp_loopstate = LOOP_PDB_RCVD;
                   2695:                        }
                   2696:                        FC_SCRATCH_RELEASE(isp);
                   2697:                        return (-1);
                   2698:                }
                   2699:                if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
                   2700:                        FC_SCRATCH_RELEASE(isp);
                   2701:                        return (-1);
                   2702:                }
                   2703:                MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
                   2704:                gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
                   2705:                isp_get_gxn_id_response(isp, gs0, gs1);
                   2706:                if (gs1->snscb_cthdr.ct_response != FS_ACC) {
                   2707:                        isp_prt(isp, ISP_LOGWARN, swrej, "GPN_ID",
                   2708:                            gs1->snscb_cthdr.ct_reason,
                   2709:                            gs1->snscb_cthdr.ct_explanation, lcl.portid);
                   2710:                        if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
                   2711:                                FC_SCRATCH_RELEASE(isp);
                   2712:                                return (-1);
                   2713:                        }
                   2714:                        continue;
                   2715:                }
                   2716:                lcl.port_wwn =
                   2717:                    (((u_int64_t)gs1->snscb_wwn[0]) << 56) |
                   2718:                    (((u_int64_t)gs1->snscb_wwn[1]) << 48) |
                   2719:                    (((u_int64_t)gs1->snscb_wwn[2]) << 40) |
                   2720:                    (((u_int64_t)gs1->snscb_wwn[3]) << 32) |
                   2721:                    (((u_int64_t)gs1->snscb_wwn[4]) << 24) |
                   2722:                    (((u_int64_t)gs1->snscb_wwn[5]) << 16) |
                   2723:                    (((u_int64_t)gs1->snscb_wwn[6]) <<  8) |
                   2724:                    (((u_int64_t)gs1->snscb_wwn[7]));
                   2725:
                   2726:                MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
                   2727:                gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
                   2728:                gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
                   2729:                gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
                   2730:                gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
                   2731:                gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
                   2732:                gq->snscb_sblen = 6;
                   2733:                gq->snscb_cmd = SNS_GNN_ID;
                   2734:                gq->snscb_portid = lcl.portid;
                   2735:                isp_put_gxn_id_request(isp, gq,
                   2736:                    (sns_gxn_id_req_t *) fcp->isp_scratch);
                   2737:                MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
                   2738:                mbs.param[0] = MBOX_SEND_SNS;
                   2739:                mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
                   2740:                mbs.param[2] = DMA_WD1(fcp->isp_scdma);
                   2741:                mbs.param[3] = DMA_WD0(fcp->isp_scdma);
                   2742:                /*
                   2743:                 * Leave 4 and 5 alone
                   2744:                 */
                   2745:                mbs.param[6] = DMA_WD3(fcp->isp_scdma);
                   2746:                mbs.param[7] = DMA_WD2(fcp->isp_scdma);
                   2747:                if (isp_fabric_mbox_cmd(isp, &mbs)) {
                   2748:                        if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
                   2749:                                fcp->isp_loopstate = LOOP_PDB_RCVD;
                   2750:                        }
                   2751:                        FC_SCRATCH_RELEASE(isp);
                   2752:                        return (-1);
                   2753:                }
                   2754:                if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
                   2755:                        FC_SCRATCH_RELEASE(isp);
                   2756:                        return (-1);
                   2757:                }
                   2758:                MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
                   2759:                gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
                   2760:                isp_get_gxn_id_response(isp, gs0, gs1);
                   2761:                if (gs1->snscb_cthdr.ct_response != FS_ACC) {
                   2762:                        isp_prt(isp, ISP_LOGWARN, swrej, "GNN_ID",
                   2763:                            gs1->snscb_cthdr.ct_reason,
                   2764:                            gs1->snscb_cthdr.ct_explanation, lcl.portid);
                   2765:                        if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
                   2766:                                FC_SCRATCH_RELEASE(isp);
                   2767:                                return (-1);
                   2768:                        }
                   2769:                        continue;
                   2770:                }
                   2771:                lcl.node_wwn =
                   2772:                    (((u_int64_t)gs1->snscb_wwn[0]) << 56) |
                   2773:                    (((u_int64_t)gs1->snscb_wwn[1]) << 48) |
                   2774:                    (((u_int64_t)gs1->snscb_wwn[2]) << 40) |
                   2775:                    (((u_int64_t)gs1->snscb_wwn[3]) << 32) |
                   2776:                    (((u_int64_t)gs1->snscb_wwn[4]) << 24) |
                   2777:                    (((u_int64_t)gs1->snscb_wwn[5]) << 16) |
                   2778:                    (((u_int64_t)gs1->snscb_wwn[6]) <<  8) |
                   2779:                    (((u_int64_t)gs1->snscb_wwn[7]));
                   2780:
                   2781:                /*
                   2782:                 * The QLogic f/w is bouncing this with a parameter error.
                   2783:                 */
                   2784: #if    0
                   2785:                /*
                   2786:                 * Try and get FC4 Features (FC-GS-3 only).
                   2787:                 * We can use the sns_gxn_id_req_t for this request.
                   2788:                 */
                   2789:                MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
                   2790:                gq->snscb_rblen = SNS_GFF_ID_RESP_SIZE >> 1;
                   2791:                gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
                   2792:                gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
                   2793:                gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
                   2794:                gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
                   2795:                gq->snscb_sblen = 6;
                   2796:                gq->snscb_cmd = SNS_GFF_ID;
                   2797:                gq->snscb_portid = lcl.portid;
                   2798:                isp_put_gxn_id_request(isp, gq,
                   2799:                    (sns_gxn_id_req_t *) fcp->isp_scratch);
                   2800:                MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
                   2801:                mbs.param[0] = MBOX_SEND_SNS;
                   2802:                mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
                   2803:                mbs.param[2] = DMA_WD1(fcp->isp_scdma);
                   2804:                mbs.param[3] = DMA_WD0(fcp->isp_scdma);
                   2805:                /*
                   2806:                 * Leave 4 and 5 alone
                   2807:                 */
                   2808:                mbs.param[6] = DMA_WD3(fcp->isp_scdma);
                   2809:                mbs.param[7] = DMA_WD2(fcp->isp_scdma);
                   2810:                if (isp_fabric_mbox_cmd(isp, &mbs)) {
                   2811:                        if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
                   2812:                                fcp->isp_loopstate = LOOP_PDB_RCVD;
                   2813:                        }
                   2814:                        FC_SCRATCH_RELEASE(isp);
                   2815:                        return (-1);
                   2816:                }
                   2817:                if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
                   2818:                        FC_SCRATCH_RELEASE(isp);
                   2819:                        return (-1);
                   2820:                }
                   2821:                MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GFF_ID_RESP_SIZE);
                   2822:                fs0 = (sns_gff_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
                   2823:                isp_get_gff_id_response(isp, fs0, fs1);
                   2824:                if (fs1->snscb_cthdr.ct_response != FS_ACC) {
                   2825:                        isp_prt(isp, /* ISP_LOGDEBUG0 */ ISP_LOGWARN,
                   2826:                            swrej, "GFF_ID",
                   2827:                            fs1->snscb_cthdr.ct_reason,
                   2828:                            fs1->snscb_cthdr.ct_explanation, lcl.portid);
                   2829:                        if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
                   2830:                                FC_SCRATCH_RELEASE(isp);
                   2831:                                return (-1);
                   2832:                        }
                   2833:                } else {
                   2834:                        int index = (ftype >> 3);
                   2835:                        int bshft = (ftype & 0x7) * 4;
                   2836:                        int fc4_fval =
                   2837:                            (fs1->snscb_fc4_features[index] >> bshft) & 0xf;
                   2838:                        if (fc4_fval & 0x1) {
                   2839:                                lcl.roles |=
                   2840:                                    (SVC3_INI_ROLE >> SVC3_ROLE_SHIFT);
                   2841:                        }
                   2842:                        if (fc4_fval & 0x2) {
                   2843:                                lcl.roles |=
                   2844:                                    (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
                   2845:                        }
                   2846:                }
                   2847: #endif
                   2848:
                   2849:                /*
                   2850:                 * If we really want to know what kind of port type this is,
                   2851:                 * we have to run another CT command. Otherwise, we'll leave
                   2852:                 * it as undefined.
                   2853:                 *
                   2854:                lcl.port_type = 0;
                   2855:                 */
                   2856:                if (rs1->snscb_ports[i].control & 0x80) {
                   2857:                        lcl.last_fabric_dev = 1;
                   2858:                } else {
                   2859:                        lcl.last_fabric_dev = 0;
                   2860:                }
                   2861:                (void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
                   2862:
                   2863:        } while ((rs1->snscb_ports[i].control & 0x80) == 0 && i < NGENT-1);
                   2864:
                   2865:        /*
                   2866:         * If we're not at the last entry, our list isn't big enough.
                   2867:         */
                   2868:        if ((rs1->snscb_ports[i].control & 0x80) == 0) {
                   2869:                isp_prt(isp, ISP_LOGWARN, "fabric too big for scratch area");
                   2870:        }
                   2871:
                   2872:        FC_SCRATCH_RELEASE(isp);
                   2873:        fcp->isp_loopstate = LOOP_FSCAN_DONE;
                   2874:        return (0);
                   2875: }
                   2876: #endif
                   2877:
                   2878: static void
                   2879: isp_register_fc4_type(struct ispsoftc *isp)
                   2880: {
                   2881:        fcparam *fcp = isp->isp_param;
                   2882:        u_int8_t local[SNS_RFT_ID_REQ_SIZE];
                   2883:        sns_screq_t *reqp = (sns_screq_t *) local;
                   2884:        mbreg_t mbs;
                   2885:
                   2886:        MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
                   2887:        reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
                   2888:        reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
                   2889:        reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
                   2890:        reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
                   2891:        reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
                   2892:        reqp->snscb_sblen = 22;
                   2893:        reqp->snscb_data[0] = SNS_RFT_ID;
                   2894:        reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
                   2895:        reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
                   2896:        reqp->snscb_data[6] = (1 << FC4_SCSI);
                   2897: #if    0
                   2898:        reqp->snscb_data[6] |= (1 << FC4_IP);   /* ISO/IEC 8802-2 LLC/SNAP */
                   2899: #endif
                   2900:        FC_SCRATCH_ACQUIRE(isp);
                   2901:        isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
                   2902:        mbs.param[0] = MBOX_SEND_SNS;
                   2903:        mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
                   2904:        mbs.param[2] = DMA_WD1(fcp->isp_scdma);
                   2905:        mbs.param[3] = DMA_WD0(fcp->isp_scdma);
                   2906:        /*
                   2907:         * Leave 4 and 5 alone
                   2908:         */
                   2909:        mbs.param[6] = DMA_WD3(fcp->isp_scdma);
                   2910:        mbs.param[7] = DMA_WD2(fcp->isp_scdma);
                   2911:        isp_mboxcmd(isp, &mbs, MBLOGALL);
                   2912:        FC_SCRATCH_RELEASE(isp);
                   2913:        if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
                   2914:                isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 types succeeded");
                   2915:        }
                   2916: }
                   2917:
                   2918: /*
                   2919:  * Start a command. Locking is assumed done in the caller.
                   2920:  */
                   2921:
                   2922: int
                   2923: isp_start(XS_T *xs)
                   2924: {
                   2925:        struct ispsoftc *isp;
                   2926:        u_int16_t nxti, optr, handle;
                   2927:        u_int8_t local[QENTRY_LEN];
                   2928:        ispreq_t *reqp, *qep;
                   2929:        int target, i;
                   2930:
                   2931:        XS_INITERR(xs);
                   2932:        isp = XS_ISP(xs);
                   2933:
                   2934:        /*
                   2935:         * Check to make sure we're supporting initiator role.
                   2936:         */
                   2937:        if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
                   2938:                XS_SETERR(xs, HBA_SELTIMEOUT);
                   2939:                return (CMD_COMPLETE);
                   2940:        }
                   2941:
                   2942:        /*
                   2943:         * Now make sure we're running.
                   2944:         */
                   2945:
                   2946:        if (isp->isp_state != ISP_RUNSTATE) {
                   2947:                isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
                   2948:                XS_SETERR(xs, HBA_BOTCH);
                   2949:                return (CMD_COMPLETE);
                   2950:        }
                   2951:
                   2952:        /*
                   2953:         * Check command CDB length, etc.. We really are limited to 16 bytes
                   2954:         * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
                   2955:         * but probably only if we're running fairly new firmware (we'll
                   2956:         * let the old f/w choke on an extended command queue entry).
                   2957:         */
                   2958:
                   2959:        if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
                   2960:                isp_prt(isp, ISP_LOGERR,
                   2961:                    "unsupported cdb length (%d, CDB[0]=0x%x)",
                   2962:                    XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
                   2963:                XS_SETERR(xs, HBA_BOTCH);
                   2964:                return (CMD_COMPLETE);
                   2965:        }
                   2966:
                   2967:        /*
                   2968:         * Check to see whether we have good firmware state still or
                   2969:         * need to refresh our port database for this target.
                   2970:         */
                   2971:        target = XS_TGT(xs);
                   2972:        if (IS_FC(isp)) {
                   2973:                fcparam *fcp = isp->isp_param;
                   2974:                struct lportdb *lp;
                   2975: #ifdef HANDLE_LOOPSTATE_IN_OUTER_LAYERS
                   2976:                if (fcp->isp_fwstate != FW_READY ||
                   2977:                    fcp->isp_loopstate != LOOP_READY) {
                   2978:                        return (CMD_RQLATER);
                   2979:                }
                   2980:
                   2981:                /*
                   2982:                 * If we're not on a Fabric, we can't have a target
                   2983:                 * above FL_PORT_ID-1.
                   2984:                 *
                   2985:                 * If we're on a fabric and *not* connected as an F-port,
                   2986:                 * we can't have a target less than FC_SNS_ID+1. This
                   2987:                 * keeps us from having to sort out the difference between
                   2988:                 * local public loop devices and those which we might get
                   2989:                 * from a switch's database.
                   2990:                 */
                   2991:                if (fcp->isp_onfabric == 0) {
                   2992:                        if (target >= FL_PORT_ID) {
                   2993:                                XS_SETERR(xs, HBA_SELTIMEOUT);
                   2994:                                return (CMD_COMPLETE);
                   2995:                        }
                   2996:                } else {
                   2997:                        if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
                   2998:                                XS_SETERR(xs, HBA_SELTIMEOUT);
                   2999:                                return (CMD_COMPLETE);
                   3000:                        }
                   3001:                        /*
                   3002:                         * We used to exclude having local loop ports
                   3003:                         * at the same time that we have fabric ports.
                   3004:                         * That is, we used to exclude having ports
                   3005:                         * at < FL_PORT_ID if we're FL-port.
                   3006:                         *
                   3007:                         * That's wrong. The only thing that could be
                   3008:                         * dicey is if the switch you're connected to
                   3009:                         * has these local loop ports appear on the
                   3010:                         * fabric and we somehow attach them twice.
                   3011:                         */
                   3012:                }
                   3013: #else
                   3014:                /*
                   3015:                 * Check for f/w being in ready state. If the f/w
                   3016:                 * isn't in ready state, then we don't know our
                   3017:                 * loop ID and the f/w hasn't completed logging
                   3018:                 * into all targets on the loop. If this is the
                   3019:                 * case, then bounce the command. We pretend this is
                   3020:                 * a SELECTION TIMEOUT error if we've never gone to
                   3021:                 * FW_READY state at all- in this case we may not
                   3022:                 * be hooked to a loop at all and we shouldn't hang
                   3023:                 * the machine for this. Otherwise, defer this command
                   3024:                 * until later.
                   3025:                 */
                   3026:                if (fcp->isp_fwstate != FW_READY) {
                   3027:                        /*
                   3028:                         * Give ourselves at most a 250ms delay.
                   3029:                         */
                   3030:                        if (isp_fclink_test(isp, 250000)) {
                   3031:                                XS_SETERR(xs, HBA_SELTIMEOUT);
                   3032:                                if (fcp->loop_seen_once) {
                   3033:                                        return (CMD_RQLATER);
                   3034:                                } else {
                   3035:                                        return (CMD_COMPLETE);
                   3036:                                }
                   3037:                        }
                   3038:                }
                   3039:
                   3040:                /*
                   3041:                 * If we're not on a Fabric, we can't have a target
                   3042:                 * above FL_PORT_ID-1.
                   3043:                 *
                   3044:                 * If we're on a fabric and *not* connected as an F-port,
                   3045:                 * we can't have a target less than FC_SNS_ID+1. This
                   3046:                 * keeps us from having to sort out the difference between
                   3047:                 * local public loop devices and those which we might get
                   3048:                 * from a switch's database.
                   3049:                 */
                   3050:                if (fcp->isp_onfabric == 0) {
                   3051:                        if (target >= FL_PORT_ID) {
                   3052:                                XS_SETERR(xs, HBA_SELTIMEOUT);
                   3053:                                return (CMD_COMPLETE);
                   3054:                        }
                   3055:                } else {
                   3056:                        if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
                   3057:                                XS_SETERR(xs, HBA_SELTIMEOUT);
                   3058:                                return (CMD_COMPLETE);
                   3059:                        }
                   3060:                        if (fcp->isp_topo != TOPO_F_PORT &&
                   3061:                            target < FL_PORT_ID) {
                   3062:                                XS_SETERR(xs, HBA_SELTIMEOUT);
                   3063:                                return (CMD_COMPLETE);
                   3064:                        }
                   3065:                }
                   3066:
                   3067:                /*
                   3068:                 * If our loop state is such that we haven't yet received
                   3069:                 * a "Port Database Changed" notification (after a LIP or
                   3070:                 * a Loop Reset or firmware initialization), then defer
                   3071:                 * sending commands for a little while, but only if we've
                   3072:                 * seen a valid loop at one point (otherwise we can get
                   3073:                 * stuck at initialization time).
                   3074:                 */
                   3075:                if (fcp->isp_loopstate < LOOP_PDB_RCVD) {
                   3076:                        XS_SETERR(xs, HBA_SELTIMEOUT);
                   3077:                        if (fcp->loop_seen_once) {
                   3078:                                return (CMD_RQLATER);
                   3079:                        } else {
                   3080:                                return (CMD_COMPLETE);
                   3081:                        }
                   3082:                }
                   3083:
                   3084:                /*
                   3085:                 * If we're in the middle of loop or fabric scanning
                   3086:                 * or merging the port databases, retry this command later.
                   3087:                 */
                   3088:                if (fcp->isp_loopstate == LOOP_SCANNING_FABRIC ||
                   3089:                    fcp->isp_loopstate == LOOP_SCANNING_LOOP ||
                   3090:                    fcp->isp_loopstate == LOOP_SYNCING_PDB) {
                   3091:                        return (CMD_RQLATER);
                   3092:                }
                   3093:
                   3094:                /*
                   3095:                 * If our loop state is now such that we've just now
                   3096:                 * received a Port Database Change notification, then
                   3097:                 * we have to go off and (re)scan the fabric. We back
                   3098:                 * out and try again later if this doesn't work.
                   3099:                 */
                   3100:                if (fcp->isp_loopstate == LOOP_PDB_RCVD && fcp->isp_onfabric) {
                   3101:                        if (isp_scan_fabric(isp, FC4_SCSI)) {
                   3102:                                return (CMD_RQLATER);
                   3103:                        }
                   3104:                        if (fcp->isp_fwstate != FW_READY ||
                   3105:                            fcp->isp_loopstate < LOOP_FSCAN_DONE) {
                   3106:                                return (CMD_RQLATER);
                   3107:                        }
                   3108:                }
                   3109:
                   3110:                /*
                   3111:                 * If our loop state is now such that we've just now
                   3112:                 * received a Port Database Change notification, then
                   3113:                 * we have to go off and (re)synchronize our port
                   3114:                 * database.
                   3115:                 */
                   3116:                if (fcp->isp_loopstate < LOOP_READY) {
                   3117:                        if (isp_pdb_sync(isp)) {
                   3118:                                return (CMD_RQLATER);
                   3119:                        }
                   3120:                        if (fcp->isp_fwstate != FW_READY ||
                   3121:                            fcp->isp_loopstate != LOOP_READY) {
                   3122:                                return (CMD_RQLATER);
                   3123:                        }
                   3124:                }
                   3125:
                   3126:                /*
                   3127:                 * XXX: Here's were we would cancel any loop_dead flag
                   3128:                 * XXX: also cancel in dead_loop timeout that's running
                   3129:                 */
                   3130: #endif
                   3131:
                   3132:                /*
                   3133:                 * Now check whether we should even think about pursuing this.
                   3134:                 */
                   3135:                lp = &fcp->portdb[target];
                   3136:                if (lp->valid == 0) {
                   3137:                        XS_SETERR(xs, HBA_SELTIMEOUT);
                   3138:                        return (CMD_COMPLETE);
                   3139:                }
                   3140:                if ((lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) == 0) {
                   3141:                        isp_prt(isp, ISP_LOGDEBUG2,
                   3142:                            "Target %d does not have target service", target);
                   3143:                        XS_SETERR(xs, HBA_SELTIMEOUT);
                   3144:                        return (CMD_COMPLETE);
                   3145:                }
                   3146:                /*
                   3147:                 * Now turn target into what the actual Loop ID is.
                   3148:                 */
                   3149:                target = lp->loopid;
                   3150:                xs->sc_link->node_wwn = lp->node_wwn;
                   3151:                xs->sc_link->port_wwn = lp->port_wwn;
                   3152:
                   3153:        }
                   3154:
                   3155:        /*
                   3156:         * Next check to see if any HBA or Device
                   3157:         * parameters need to be updated.
                   3158:         */
                   3159:        if (isp->isp_update != 0) {
                   3160:                isp_update(isp);
                   3161:        }
                   3162:
                   3163:        if (isp_getrqentry(isp, &nxti, &optr, (void *)&qep)) {
                   3164:                isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
                   3165:                XS_SETERR(xs, HBA_BOTCH);
                   3166:                return (CMD_EAGAIN);
                   3167:        }
                   3168:
                   3169:        /*
                   3170:         * Now see if we need to synchronize the ISP with respect to anything.
                   3171:         * We do dual duty here (cough) for synchronizing for busses other
                   3172:         * than which we got here to send a command to.
                   3173:         */
                   3174:        reqp = (ispreq_t *) local;
                   3175:        if (isp->isp_sendmarker) {
                   3176:                u_int8_t n = (IS_DUALBUS(isp)? 2: 1);
                   3177:                /*
                   3178:                 * Check ports to send markers for...
                   3179:                 */
                   3180:                for (i = 0; i < n; i++) {
                   3181:                        if ((isp->isp_sendmarker & (1 << i)) == 0) {
                   3182:                                continue;
                   3183:                        }
                   3184:                        MEMZERO((void *) reqp, QENTRY_LEN);
                   3185:                        reqp->req_header.rqs_entry_count = 1;
                   3186:                        reqp->req_header.rqs_entry_type = RQSTYPE_MARKER;
                   3187:                        reqp->req_modifier = SYNC_ALL;
                   3188:                        reqp->req_target = i << 7;      /* insert bus number */
                   3189:                        isp_put_request(isp, reqp, qep);
                   3190:                        ISP_ADD_REQUEST(isp, nxti);
                   3191:                        isp->isp_sendmarker &= ~(1 << i);
                   3192:                        if (isp_getrqentry(isp, &nxti, &optr, (void *) &qep)) {
                   3193:                                isp_prt(isp, ISP_LOGDEBUG0,
                   3194:                                    "Request Queue Overflow+");
                   3195:                                XS_SETERR(xs, HBA_BOTCH);
                   3196:                                return (CMD_EAGAIN);
                   3197:                        }
                   3198:                }
                   3199:        }
                   3200:
                   3201:        MEMZERO((void *)reqp, QENTRY_LEN);
                   3202:        reqp->req_header.rqs_entry_count = 1;
                   3203:        if (IS_FC(isp)) {
                   3204:                reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
                   3205:        } else {
                   3206:                if (XS_CDBLEN(xs) > 12)
                   3207:                        reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
                   3208:                else
                   3209:                        reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
                   3210:        }
                   3211:        /* reqp->req_header.rqs_flags = 0; */
                   3212:        /* reqp->req_header.rqs_seqno = 0; */
                   3213:        if (IS_FC(isp)) {
                   3214:                /*
                   3215:                 * See comment in isp_intr
                   3216:                 */
                   3217:                /* XS_RESID(xs) = 0; */
                   3218:
                   3219:                /*
                   3220:                 * Fibre Channel always requires some kind of tag.
                   3221:                 * The Qlogic drivers seem be happy not to use a tag,
                   3222:                 * but this breaks for some devices (IBM drives).
                   3223:                 */
                   3224:                if (XS_TAG_P(xs)) {
                   3225:                        ((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
                   3226:                } else {
                   3227:                        /*
                   3228:                         * If we don't know what tag to use, use HEAD OF QUEUE
                   3229:                         * for Request Sense or Simple.
                   3230:                         */
                   3231:                        if (XS_CDBP(xs)[0] == 0x3)      /* REQUEST SENSE */
                   3232:                                ((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
                   3233:                        else
                   3234:                                ((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
                   3235:                }
                   3236:        } else {
                   3237:                sdparam *sdp = (sdparam *)isp->isp_param;
                   3238:                sdp += XS_CHANNEL(xs);
                   3239:                if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) &&
                   3240:                    XS_TAG_P(xs)) {
                   3241:                        reqp->req_flags = XS_TAG_TYPE(xs);
                   3242:                }
                   3243:        }
                   3244:        reqp->req_target = target | (XS_CHANNEL(xs) << 7);
                   3245:        if (IS_SCSI(isp)) {
                   3246:                reqp->req_lun_trn = XS_LUN(xs);
                   3247:                reqp->req_cdblen = XS_CDBLEN(xs);
                   3248:        } else {
                   3249:                if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)
                   3250:                        ((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
                   3251:                else
                   3252:                        ((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
                   3253:        }
                   3254:        MEMCPY(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs));
                   3255:
                   3256:        reqp->req_time = XS_TIME(xs) / 1000;
                   3257:        if (reqp->req_time == 0 && XS_TIME(xs)) {
                   3258:                reqp->req_time = 1;
                   3259:        }
                   3260:
                   3261:        if (isp_save_xs(isp, xs, &handle)) {
                   3262:                isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
                   3263:                XS_SETERR(xs, HBA_BOTCH);
                   3264:                return (CMD_EAGAIN);
                   3265:        }
                   3266:        reqp->req_handle = handle;
                   3267:
                   3268:        /*
                   3269:         * Set up DMA and/or do any bus swizzling of the request entry
                   3270:         * so that the Qlogic F/W understands what is being asked of it.
                   3271:         */
                   3272:        i = ISP_DMASETUP(isp, xs, reqp, &nxti, optr);
                   3273:        if (i != CMD_QUEUED) {
                   3274:                isp_destroy_handle(isp, handle);
                   3275:                /*
                   3276:                 * dmasetup sets actual error in packet, and
                   3277:                 * return what we were given to return.
                   3278:                 */
                   3279:                return (i);
                   3280:        }
                   3281:        XS_SETERR(xs, HBA_NOERROR);
                   3282:        isp_prt(isp, ISP_LOGDEBUG2,
                   3283:            "START cmd for %d.%d.%d cmd 0x%x datalen %ld",
                   3284:            XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0],
                   3285:            (long) XS_XFRLEN(xs));
                   3286:        ISP_ADD_REQUEST(isp, nxti);
                   3287:        isp->isp_nactive++;
                   3288:        return (CMD_QUEUED);
                   3289: }
                   3290:
                   3291: /*
                   3292:  * isp control
                   3293:  * Locks (ints blocked) assumed held.
                   3294:  */
                   3295:
                   3296: int
                   3297: isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
                   3298: {
                   3299:        XS_T *xs;
                   3300:        mbreg_t mbs;
                   3301:        int bus, tgt;
                   3302:        u_int16_t handle;
                   3303:
                   3304:        switch (ctl) {
                   3305:        default:
                   3306:                isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
                   3307:                break;
                   3308:
                   3309:        case ISPCTL_RESET_BUS:
                   3310:                /*
                   3311:                 * Issue a bus reset.
                   3312:                 */
                   3313:                mbs.param[0] = MBOX_BUS_RESET;
                   3314:                mbs.param[2] = 0;
                   3315:                if (IS_SCSI(isp)) {
                   3316:                        mbs.param[1] =
                   3317:                            ((sdparam *) isp->isp_param)->isp_bus_reset_delay;
                   3318:                        if (mbs.param[1] < 2)
                   3319:                                mbs.param[1] = 2;
                   3320:                        bus = *((int *) arg);
                   3321:                        if (IS_DUALBUS(isp))
                   3322:                                mbs.param[2] = bus;
                   3323:                } else {
                   3324:                        mbs.param[1] = 10;
                   3325:                        bus = 0;
                   3326:                }
                   3327:                isp->isp_sendmarker |= (1 << bus);
                   3328:                isp_mboxcmd(isp, &mbs, MBLOGALL);
                   3329:                if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                   3330:                        break;
                   3331:                }
                   3332:                isp_prt(isp, ISP_LOGINFO,
                   3333:                    "driver initiated bus reset of bus %d", bus);
                   3334:                return (0);
                   3335:
                   3336:        case ISPCTL_RESET_DEV:
                   3337:                tgt = (*((int *) arg)) & 0xffff;
                   3338:                bus = (*((int *) arg)) >> 16;
                   3339:                mbs.param[0] = MBOX_ABORT_TARGET;
                   3340:                mbs.param[1] = (tgt << 8) | (bus << 15);
                   3341:                mbs.param[2] = 3;       /* 'delay', in seconds */
                   3342:                isp_mboxcmd(isp, &mbs, MBLOGALL);
                   3343:                if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                   3344:                        break;
                   3345:                }
                   3346:                isp_prt(isp, ISP_LOGINFO,
                   3347:                    "Target %d on Bus %d Reset Succeeded", tgt, bus);
                   3348:                isp->isp_sendmarker |= (1 << bus);
                   3349:                return (0);
                   3350:
                   3351:        case ISPCTL_ABORT_CMD:
                   3352:                xs = (XS_T *) arg;
                   3353:                tgt = XS_TGT(xs);
                   3354:                handle = isp_find_handle(isp, xs);
                   3355:                if (handle == 0) {
                   3356:                        isp_prt(isp, ISP_LOGWARN,
                   3357:                            "cannot find handle for command to abort");
                   3358:                        break;
                   3359:                }
                   3360:                bus = XS_CHANNEL(xs);
                   3361:                mbs.param[0] = MBOX_ABORT;
                   3362:                if (IS_FC(isp)) {
                   3363:                        if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)  {
                   3364:                                mbs.param[1] = tgt << 8;
                   3365:                                mbs.param[4] = 0;
                   3366:                                mbs.param[5] = 0;
                   3367:                                mbs.param[6] = XS_LUN(xs);
                   3368:                        } else {
                   3369:                                mbs.param[1] = tgt << 8 | XS_LUN(xs);
                   3370:                        }
                   3371:                } else {
                   3372:                        mbs.param[1] =
                   3373:                            (bus << 15) | (XS_TGT(xs) << 8) | XS_LUN(xs);
                   3374:                }
                   3375:                mbs.param[3] = 0;
                   3376:                mbs.param[2] = handle;
                   3377:                isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_ERROR);
                   3378:                if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
                   3379:                        return (0);
                   3380:                }
                   3381:                /*
                   3382:                 * XXX: Look for command in the REQUEST QUEUE. That is,
                   3383:                 * XXX: It hasn't been picked up by firmware yet.
                   3384:                 */
                   3385:                break;
                   3386:
                   3387:        case ISPCTL_UPDATE_PARAMS:
                   3388:
                   3389:                isp_update(isp);
                   3390:                return (0);
                   3391:
                   3392:        case ISPCTL_FCLINK_TEST:
                   3393:
                   3394:                if (IS_FC(isp)) {
                   3395:                        int usdelay = (arg)? *((int *) arg) : 250000;
                   3396:                        return (isp_fclink_test(isp, usdelay));
                   3397:                }
                   3398:                break;
                   3399:
                   3400:        case ISPCTL_SCAN_FABRIC:
                   3401:
                   3402:                if (IS_FC(isp)) {
                   3403:                        int ftype = (arg)? *((int *) arg) : FC4_SCSI;
                   3404:                        return (isp_scan_fabric(isp, ftype));
                   3405:                }
                   3406:                break;
                   3407:
                   3408:        case ISPCTL_SCAN_LOOP:
                   3409:
                   3410:                if (IS_FC(isp)) {
                   3411:                        return (isp_scan_loop(isp));
                   3412:                }
                   3413:                break;
                   3414:
                   3415:        case ISPCTL_PDB_SYNC:
                   3416:
                   3417:                if (IS_FC(isp)) {
                   3418:                        return (isp_pdb_sync(isp));
                   3419:                }
                   3420:                break;
                   3421:
                   3422:        case ISPCTL_SEND_LIP:
                   3423:
                   3424:                if (IS_FC(isp)) {
                   3425:                        mbs.param[0] = MBOX_INIT_LIP;
                   3426:                        isp_mboxcmd(isp, &mbs, MBLOGALL);
                   3427:                        if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
                   3428:                                return (0);
                   3429:                        }
                   3430:                }
                   3431:                break;
                   3432:
                   3433:        case ISPCTL_GET_POSMAP:
                   3434:
                   3435:                if (IS_FC(isp) && arg) {
                   3436:                        return (isp_getmap(isp, arg));
                   3437:                }
                   3438:                break;
                   3439:
                   3440:        case ISPCTL_RUN_MBOXCMD:
                   3441:
                   3442:                isp_mboxcmd(isp, arg, MBLOGALL);
                   3443:                return(0);
                   3444:
                   3445: #ifdef ISP_TARGET_MODE
                   3446:        case ISPCTL_TOGGLE_TMODE:
                   3447:        {
                   3448:
                   3449:                /*
                   3450:                 * We don't check/set against role here- that's the
                   3451:                 * responsibility for the outer layer to coordinate.
                   3452:                 */
                   3453:                if (IS_SCSI(isp)) {
                   3454:                        int param = *(int *)arg;
                   3455:                        mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
                   3456:                        mbs.param[1] = param & 0xffff;
                   3457:                        mbs.param[2] = param >> 16;
                   3458:                        isp_mboxcmd(isp, &mbs, MBLOGALL);
                   3459:                        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                   3460:                                break;
                   3461:                        }
                   3462:                }
                   3463:                return (0);
                   3464:        }
                   3465: #endif
                   3466:        }
                   3467:        return (-1);
                   3468: }
                   3469:
                   3470: /*
                   3471:  * Interrupt Service Routine(s).
                   3472:  *
                   3473:  * External (OS) framework has done the appropriate locking,
                   3474:  * and the locking will be held throughout this function.
                   3475:  */
                   3476:
                   3477: /*
                   3478:  * Limit our stack depth by sticking with the max likely number
                   3479:  * of completions on a request queue at any one time.
                   3480:  */
                   3481: #ifndef        MAX_REQUESTQ_COMPLETIONS
                   3482: #define        MAX_REQUESTQ_COMPLETIONS        64
                   3483: #endif
                   3484:
                   3485: void
                   3486: isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
                   3487: {
                   3488:        XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
                   3489:        u_int16_t iptr, optr, junk;
                   3490:        int i, nlooked = 0, ndone = 0;
                   3491:
                   3492: again:
                   3493:        /*
                   3494:         * Is this a mailbox related interrupt?
                   3495:         * The mailbox semaphore will be nonzero if so.
                   3496:         */
                   3497:        if (sema) {
                   3498:                if (mbox & 0x4000) {
                   3499:                        isp->isp_intmboxc++;
                   3500:                        if (isp->isp_mboxbsy) {
                   3501:                                int i = 0, obits = isp->isp_obits;
                   3502:                                isp->isp_mboxtmp[i++] = mbox;
                   3503:                                for (i = 1; i < MAX_MAILBOX; i++) {
                   3504:                                        if ((obits & (1 << i)) == 0) {
                   3505:                                                continue;
                   3506:                                        }
                   3507:                                        isp->isp_mboxtmp[i] =
                   3508:                                            ISP_READ(isp, MBOX_OFF(i));
                   3509:                                }
                   3510:                                if (isp->isp_mbxwrk0) {
                   3511:                                        if (isp_mbox_continue(isp) == 0) {
                   3512:                                                return;
                   3513:                                        }
                   3514:                                }
                   3515:                                MBOX_NOTIFY_COMPLETE(isp);
                   3516:                        } else {
                   3517:                                isp_prt(isp, ISP_LOGWARN,
                   3518:                                    "Mbox Command Async (0x%x) with no waiters",
                   3519:                                    mbox);
                   3520:                        }
                   3521:                } else if (isp_parse_async(isp, mbox) < 0) {
                   3522:                        return;
                   3523:                }
                   3524:                if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) ||
                   3525:                    isp->isp_state != ISP_RUNSTATE) {
                   3526:                        ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
                   3527:                        ISP_WRITE(isp, BIU_SEMA, 0);
                   3528:                        return;
                   3529:                }
                   3530:        }
                   3531:
                   3532:        /*
                   3533:         * We can't be getting this now.
                   3534:         */
                   3535:        if (isp->isp_state != ISP_RUNSTATE) {
                   3536:                isp_prt(isp, ISP_LOGWARN,
                   3537:                    "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
                   3538:                /*
                   3539:                 * Thank you very much!  *Burrrp*!
                   3540:                 */
                   3541:                WRITE_RESPONSE_QUEUE_OUT_POINTER(isp,
                   3542:                    READ_RESPONSE_QUEUE_IN_POINTER(isp));
                   3543:
                   3544:                ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
                   3545:                ISP_WRITE(isp, BIU_SEMA, 0);
                   3546:                return;
                   3547:        }
                   3548:
                   3549:        /*
                   3550:         * Get the current Response Queue Out Pointer.
                   3551:         *
                   3552:         * If we're a 2300, we can ask what hardware what it thinks.
                   3553:         */
                   3554:        if (IS_23XX(isp)) {
                   3555:                optr = ISP_READ(isp, isp->isp_respoutrp);
                   3556:                /*
                   3557:                 * Debug: to be taken out eventually
                   3558:                 */
                   3559:                if (isp->isp_residx != optr) {
                   3560:                        isp_prt(isp, ISP_LOGWARN, "optr %x soft optr %x",
                   3561:                            optr, isp->isp_residx);
                   3562:                }
                   3563:        } else {
                   3564:                optr = isp->isp_residx;
                   3565:        }
                   3566:
                   3567:        /*
                   3568:         * You *must* read the Response Queue In Pointer
                   3569:         * prior to clearing the RISC interrupt.
                   3570:         *
                   3571:         * Debounce the 2300 if revision less than 2.
                   3572:         */
                   3573:        if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
                   3574:                i = 0;
                   3575:                do {
                   3576:                        iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
                   3577:                        junk = READ_RESPONSE_QUEUE_IN_POINTER(isp);
                   3578:                } while (junk != iptr && ++i < 1000);
                   3579:
                   3580:                if (iptr != junk) {
                   3581:                        ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
                   3582:                        isp_prt(isp, ISP_LOGWARN,
                   3583:                            "Response Queue Out Pointer Unstable (%x, %x)",
                   3584:                            iptr, junk);
                   3585:                        return;
                   3586:                }
                   3587:        } else {
                   3588:                iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
                   3589:        }
                   3590:        isp->isp_resodx = iptr;
                   3591:
                   3592:
                   3593:        if (optr == iptr && sema == 0) {
                   3594:                /*
                   3595:                 * There are a lot of these- reasons unknown- mostly on
                   3596:                 * faster Alpha machines.
                   3597:                 *
                   3598:                 * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
                   3599:                 * make sure the old interrupt went away (to avoid 'ringing'
                   3600:                 * effects), but that didn't stop this from occurring.
                   3601:                 */
                   3602:                if (IS_23XX(isp)) {
                   3603:                        USEC_DELAY(100);
                   3604:                        iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
                   3605:                        junk = ISP_READ(isp, BIU_R2HSTSLO);
                   3606:                } else {
                   3607:                        junk = ISP_READ(isp, BIU_ISR);
                   3608:                }
                   3609:                if (optr == iptr) {
                   3610:                        if (IS_23XX(isp)) {
                   3611:                                ;
                   3612:                        } else {
                   3613:                                sema = ISP_READ(isp, BIU_SEMA);
                   3614:                                mbox = ISP_READ(isp, OUTMAILBOX0);
                   3615:                                if ((sema & 0x3) && (mbox & 0x8000)) {
                   3616:                                        goto again;
                   3617:                                }
                   3618:                        }
                   3619:                        isp->isp_intbogus++;
                   3620:                        isp_prt(isp, ISP_LOGDEBUG1,
                   3621:                            "bogus intr- isr %x (%x) iptr %x optr %x",
                   3622:                            isr, junk, iptr, optr);
                   3623:                }
                   3624:        }
                   3625:        isp->isp_resodx = iptr;
                   3626:        ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
                   3627:        ISP_WRITE(isp, BIU_SEMA, 0);
                   3628:
                   3629:        if (isp->isp_rspbsy) {
                   3630:                return;
                   3631:        }
                   3632:        isp->isp_rspbsy = 1;
                   3633:
                   3634:        while (optr != iptr) {
                   3635:                ispstatusreq_t local, *sp = &local;
                   3636:                isphdr_t *hp;
                   3637:                int type;
                   3638:                u_int16_t oop;
                   3639:                int buddaboom = 0;
                   3640:
                   3641:                hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
                   3642:                oop = optr;
                   3643:                optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
                   3644:                nlooked++;
                   3645:                /*
                   3646:                 * Synchronize our view of this response queue entry.
                   3647:                 */
                   3648:                MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN);
                   3649:
                   3650:                type = isp_get_response_type(isp, hp);
                   3651:
                   3652:                if (type == RQSTYPE_RESPONSE) {
                   3653:                        isp_get_response(isp, (ispstatusreq_t *) hp, sp);
                   3654:                } else if (type == RQSTYPE_RIO2) {
                   3655:                        isp_rio2_t rio;
                   3656:                        isp_get_rio2(isp, (isp_rio2_t *) hp, &rio);
                   3657:                        for (i = 0; i < rio.req_header.rqs_seqno; i++) {
                   3658:                                isp_fastpost_complete(isp, rio.req_handles[i]);
                   3659:                        }
                   3660:                        if (isp->isp_fpcchiwater < rio.req_header.rqs_seqno)
                   3661:                                isp->isp_fpcchiwater = rio.req_header.rqs_seqno;
                   3662:                        MEMZERO(hp, QENTRY_LEN);        /* PERF */
                   3663:                        continue;
                   3664:                } else {
                   3665:                        /*
                   3666:                         * Somebody reachable via isp_handle_other_response
                   3667:                         * may have updated the response queue pointers for
                   3668:                         * us, so we reload our goal index.
                   3669:                         */
                   3670:                        if (isp_handle_other_response(isp, type, hp, &optr)) {
                   3671:                                iptr = isp->isp_resodx;
                   3672:                                MEMZERO(hp, QENTRY_LEN);        /* PERF */
                   3673:                                continue;
                   3674:                        }
                   3675:
                   3676:                        /*
                   3677:                         * After this point, we'll just look at the header as
                   3678:                         * we don't know how to deal with the rest of the
                   3679:                         * response.
                   3680:                         */
                   3681:                        isp_get_response(isp, (ispstatusreq_t *) hp, sp);
                   3682:
                   3683:                        /*
                   3684:                         * It really has to be a bounced request just copied
                   3685:                         * from the request queue to the response queue. If
                   3686:                         * not, something bad has happened.
                   3687:                         */
                   3688:                        if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) {
                   3689:                                isp_prt(isp, ISP_LOGERR, notresp,
                   3690:                                    sp->req_header.rqs_entry_type, oop, optr,
                   3691:                                    nlooked);
                   3692:                                if (isp->isp_dblev & ISP_LOGDEBUG0) {
                   3693:                                        isp_print_bytes(isp, "Queue Entry",
                   3694:                                            QENTRY_LEN, sp);
                   3695:                                }
                   3696:                                MEMZERO(hp, QENTRY_LEN);        /* PERF */
                   3697:                                continue;
                   3698:                        }
                   3699:                        buddaboom = 1;
                   3700:                }
                   3701:
                   3702:                if (sp->req_header.rqs_flags & 0xf) {
                   3703: #define        _RQS_OFLAGS     \
                   3704:        ~(RQSFLAG_CONTINUATION|RQSFLAG_FULL|RQSFLAG_BADHEADER|RQSFLAG_BADPACKET)
                   3705:                        if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
                   3706:                                isp_prt(isp, ISP_LOGWARN,
                   3707:                                    "continuation segment");
                   3708:                                WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
                   3709:                                continue;
                   3710:                        }
                   3711:                        if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
                   3712:                                isp_prt(isp, ISP_LOGDEBUG1,
                   3713:                                    "internal queues full");
                   3714:                                /*
                   3715:                                 * We'll synthesize a QUEUE FULL message below.
                   3716:                                 */
                   3717:                        }
                   3718:                        if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
                   3719:                                isp_prt(isp, ISP_LOGERR,  "bad header flag");
                   3720:                                buddaboom++;
                   3721:                        }
                   3722:                        if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
                   3723:                                isp_prt(isp, ISP_LOGERR, "bad request packet");
                   3724:                                buddaboom++;
                   3725:                        }
                   3726:                        if (sp->req_header.rqs_flags & _RQS_OFLAGS) {
                   3727:                                isp_prt(isp, ISP_LOGERR,
                   3728:                                    "unknown flags (0x%x) in response",
                   3729:                                    sp->req_header.rqs_flags);
                   3730:                                buddaboom++;
                   3731:                        }
                   3732: #undef _RQS_OFLAGS
                   3733:                }
                   3734:                if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) {
                   3735:                        MEMZERO(hp, QENTRY_LEN);        /* PERF */
                   3736:                        isp_prt(isp, ISP_LOGERR,
                   3737:                            "bad request handle %d (type 0x%x, flags 0x%x)",
                   3738:                            sp->req_handle, sp->req_header.rqs_entry_type,
                   3739:                            sp->req_header.rqs_flags);
                   3740:                        WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
                   3741:                        continue;
                   3742:                }
                   3743:                xs = isp_find_xs(isp, sp->req_handle);
                   3744:                if (xs == NULL) {
                   3745:                        u_int8_t ts = sp->req_completion_status & 0xff;
                   3746:                        MEMZERO(hp, QENTRY_LEN);        /* PERF */
                   3747:                        /*
                   3748:                         * Only whine if this isn't the expected fallout of
                   3749:                         * aborting the command.
                   3750:                         */
                   3751:                        if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
                   3752:                                isp_prt(isp, ISP_LOGERR,
                   3753:                                    "cannot find handle 0x%x (type 0x%x)",
                   3754:                                    sp->req_handle,
                   3755:                                    sp->req_header.rqs_entry_type);
                   3756:                        } else if (ts != RQCS_ABORTED) {
                   3757:                                isp_prt(isp, ISP_LOGERR,
                   3758:                                    "cannot find handle 0x%x (status 0x%x)",
                   3759:                                    sp->req_handle, ts);
                   3760:                        }
                   3761:                        WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
                   3762:                        continue;
                   3763:                }
                   3764:                isp_destroy_handle(isp, sp->req_handle);
                   3765:                if (sp->req_status_flags & RQSTF_BUS_RESET) {
                   3766:                        XS_SETERR(xs, HBA_BUSRESET);
                   3767:                        isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
                   3768:                }
                   3769:                if (buddaboom) {
                   3770:                        XS_SETERR(xs, HBA_BOTCH);
                   3771:                }
                   3772:
                   3773:                if (IS_FC(isp) && (sp->req_scsi_status & RQCS_SV)) {
                   3774:                        /*
                   3775:                         * Fibre Channel F/W doesn't say we got status
                   3776:                         * if there's Sense Data instead. I guess they
                   3777:                         * think it goes w/o saying.
                   3778:                         */
                   3779:                        sp->req_state_flags |= RQSF_GOT_STATUS;
                   3780:                }
                   3781:                if (sp->req_state_flags & RQSF_GOT_STATUS) {
                   3782:                        *XS_STSP(xs) = sp->req_scsi_status & 0xff;
                   3783:                }
                   3784:
                   3785:                switch (sp->req_header.rqs_entry_type) {
                   3786:                case RQSTYPE_RESPONSE:
                   3787:                        XS_SET_STATE_STAT(isp, xs, sp);
                   3788:                        isp_parse_status(isp, sp, xs);
                   3789:                        if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) &&
                   3790:                            (*XS_STSP(xs) == SCSI_BUSY)) {
                   3791:                                XS_SETERR(xs, HBA_TGTBSY);
                   3792:                        }
                   3793:                        if (IS_SCSI(isp)) {
                   3794:                                XS_RESID(xs) = sp->req_resid;
                   3795:                                if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
                   3796:                                    (*XS_STSP(xs) == SCSI_CHECK) &&
                   3797:                                    (sp->req_state_flags & RQSF_GOT_SENSE)) {
                   3798:                                        XS_SAVE_SENSE(xs, sp);
                   3799:                                }
                   3800:                                /*
                   3801:                                 * A new synchronous rate was negotiated for
                   3802:                                 * this target. Mark state such that we'll go
                   3803:                                 * look up that which has changed later.
                   3804:                                 */
                   3805:                                if (sp->req_status_flags & RQSTF_NEGOTIATION) {
                   3806:                                        int t = XS_TGT(xs);
                   3807:                                        sdparam *sdp = isp->isp_param;
                   3808:                                        sdp += XS_CHANNEL(xs);
                   3809:                                        sdp->isp_devparam[t].dev_refresh = 1;
                   3810:                                        isp->isp_update |=
                   3811:                                            (1 << XS_CHANNEL(xs));
                   3812:                                }
                   3813:                        } else {
                   3814:                                if (sp->req_status_flags & RQSF_XFER_COMPLETE) {
                   3815:                                        XS_RESID(xs) = 0;
                   3816:                                } else if (sp->req_scsi_status & RQCS_RESID) {
                   3817:                                        XS_RESID(xs) = sp->req_resid;
                   3818:                                } else {
                   3819:                                        XS_RESID(xs) = 0;
                   3820:                                }
                   3821:                                if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
                   3822:                                    (*XS_STSP(xs) == SCSI_CHECK) &&
                   3823:                                    (sp->req_scsi_status & RQCS_SV)) {
                   3824:                                        XS_SAVE_SENSE(xs, sp);
                   3825:                                        /* solely for the benefit of debug */
                   3826:                                        sp->req_state_flags |= RQSF_GOT_SENSE;
                   3827:                                }
                   3828:                        }
                   3829:                        isp_prt(isp, ISP_LOGDEBUG2,
                   3830:                           "asked for %ld got resid %ld", (long) XS_XFRLEN(xs),
                   3831:                           (long) sp->req_resid);
                   3832:                        break;
                   3833:                case RQSTYPE_REQUEST:
                   3834:                        if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
                   3835:                                /*
                   3836:                                 * Force Queue Full status.
                   3837:                                 */
                   3838:                                *XS_STSP(xs) = SCSI_QFULL;
                   3839:                                XS_SETERR(xs, HBA_NOERROR);
                   3840:                        } else if (XS_NOERR(xs)) {
                   3841:                                /*
                   3842:                                 * ????
                   3843:                                 */
                   3844:                                isp_prt(isp, ISP_LOGDEBUG0,
                   3845:                                    "Request Queue Entry bounced back");
                   3846:                                XS_SETERR(xs, HBA_BOTCH);
                   3847:                        }
                   3848:                        XS_RESID(xs) = XS_XFRLEN(xs);
                   3849:                        break;
                   3850:                default:
                   3851:                        isp_prt(isp, ISP_LOGWARN,
                   3852:                            "unhandled response queue type 0x%x",
                   3853:                            sp->req_header.rqs_entry_type);
                   3854:                        if (XS_NOERR(xs)) {
                   3855:                                XS_SETERR(xs, HBA_BOTCH);
                   3856:                        }
                   3857:                        break;
                   3858:                }
                   3859:
                   3860:                /*
                   3861:                 * Free any dma resources. As a side effect, this may
                   3862:                 * also do any cache flushing necessary for data coherence.                      */
                   3863:                if (XS_XFRLEN(xs)) {
                   3864:                        ISP_DMAFREE(isp, xs, sp->req_handle);
                   3865:                }
                   3866:
                   3867:                if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
                   3868:                    ((isp->isp_dblev & ISP_LOGDEBUG1) && ((!XS_NOERR(xs)) ||
                   3869:                    (*XS_STSP(xs) != SCSI_GOOD)))) {
                   3870:                        char skey;
                   3871:                        if (sp->req_state_flags & RQSF_GOT_SENSE) {
                   3872:                                skey = XS_SNSKEY(xs) & 0xf;
                   3873:                                if (skey < 10)
                   3874:                                        skey += '0';
                   3875:                                else
                   3876:                                        skey += 'a' - 10;
                   3877:                        } else if (*XS_STSP(xs) == SCSI_CHECK) {
                   3878:                                skey = '?';
                   3879:                        } else {
                   3880:                                skey = '.';
                   3881:                        }
                   3882:                        isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs),
                   3883:                            XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs),
                   3884:                            (ulong)XS_RESID(xs),
                   3885:                            *XS_STSP(xs), skey, XS_ERR(xs));
                   3886:                }
                   3887:
                   3888:                if (isp->isp_nactive > 0)
                   3889:                    isp->isp_nactive--;
                   3890:                complist[ndone++] = xs; /* defer completion call until later */
                   3891:                MEMZERO(hp, QENTRY_LEN);        /* PERF */
                   3892:                if (ndone == MAX_REQUESTQ_COMPLETIONS) {
                   3893:                        break;
                   3894:                }
                   3895:        }
                   3896:
                   3897:        /*
                   3898:         * If we looked at any commands, then it's valid to find out
                   3899:         * what the outpointer is. It also is a trigger to update the
                   3900:         * ISP's notion of what we've seen so far.
                   3901:         */
                   3902:        if (nlooked) {
                   3903:                WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
                   3904:                /*
                   3905:                 * While we're at it, read the request queue out pointer.
                   3906:                 */
                   3907:                isp->isp_reqodx = READ_REQUEST_QUEUE_OUT_POINTER(isp);
                   3908:                if (isp->isp_rscchiwater < ndone)
                   3909:                        isp->isp_rscchiwater = ndone;
                   3910:        }
                   3911:
                   3912:        isp->isp_residx = optr;
                   3913:        isp->isp_rspbsy = 0;
                   3914:        for (i = 0; i < ndone; i++) {
                   3915:                xs = complist[i];
                   3916:                if (xs) {
                   3917:                        isp->isp_rsltccmplt++;
                   3918:                        isp_done(xs);
                   3919:                }
                   3920:        }
                   3921: }
                   3922:
                   3923: /*
                   3924:  * Support routines.
                   3925:  */
                   3926:
                   3927: static int
                   3928: isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
                   3929: {
                   3930:        int rval = 0;
                   3931:        int bus;
                   3932:
                   3933:        if (IS_DUALBUS(isp)) {
                   3934:                bus = ISP_READ(isp, OUTMAILBOX6);
                   3935:        } else {
                   3936:                bus = 0;
                   3937:        }
                   3938:        isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
                   3939:
                   3940:        switch (mbox) {
                   3941:        case ASYNC_BUS_RESET:
                   3942:                isp->isp_sendmarker |= (1 << bus);
                   3943: #ifdef ISP_TARGET_MODE
                   3944:                if (isp_target_async(isp, bus, mbox))
                   3945:                        rval = -1;
                   3946: #endif
                   3947:                isp_async(isp, ISPASYNC_BUS_RESET, &bus);
                   3948:                break;
                   3949:        case ASYNC_SYSTEM_ERROR:
                   3950: #ifdef ISP_FW_CRASH_DUMP
                   3951:                /*
                   3952:                 * If we have crash dumps enabled, it's up to the handler
                   3953:                 * for isp_async to reinit stuff and restart the firmware
                   3954:                 * after performing the crash dump. The reason we do things
                   3955:                 * this way is that we may need to activate a kernel thread
                   3956:                 * to do all the crash dump goop.
                   3957:                 */
                   3958:                isp_async(isp, ISPASYNC_FW_CRASH, NULL);
                   3959: #else
                   3960:                isp_async(isp, ISPASYNC_FW_CRASH, NULL);
                   3961:                isp_reinit(isp);
                   3962:                isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
                   3963: #endif
                   3964:                rval = -1;
                   3965:                break;
                   3966:
                   3967:        case ASYNC_RQS_XFER_ERR:
                   3968:                isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
                   3969:                break;
                   3970:
                   3971:        case ASYNC_RSP_XFER_ERR:
                   3972:                isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
                   3973:                break;
                   3974:
                   3975:        case ASYNC_QWAKEUP:
                   3976:                /*
                   3977:                 * We've just been notified that the Queue has woken up.
                   3978:                 * We don't need to be chatty about this- just unlatch things
                   3979:                 * and move on.
                   3980:                 */
                   3981:                mbox = READ_REQUEST_QUEUE_OUT_POINTER(isp);
                   3982:                break;
                   3983:
                   3984:        case ASYNC_TIMEOUT_RESET:
                   3985:                isp_prt(isp, ISP_LOGWARN,
                   3986:                    "timeout initiated SCSI bus reset of bus %d", bus);
                   3987:                isp->isp_sendmarker |= (1 << bus);
                   3988: #ifdef ISP_TARGET_MODE
                   3989:                if (isp_target_async(isp, bus, mbox))
                   3990:                        rval = -1;
                   3991: #endif
                   3992:                break;
                   3993:
                   3994:        case ASYNC_DEVICE_RESET:
                   3995:                isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus);
                   3996:                isp->isp_sendmarker |= (1 << bus);
                   3997: #ifdef ISP_TARGET_MODE
                   3998:                if (isp_target_async(isp, bus, mbox))
                   3999:                        rval = -1;
                   4000: #endif
                   4001:                break;
                   4002:
                   4003:        case ASYNC_EXTMSG_UNDERRUN:
                   4004:                isp_prt(isp, ISP_LOGWARN, "extended message underrun");
                   4005:                break;
                   4006:
                   4007:        case ASYNC_SCAM_INT:
                   4008:                isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
                   4009:                break;
                   4010:
                   4011:        case ASYNC_HUNG_SCSI:
                   4012:                isp_prt(isp, ISP_LOGERR,
                   4013:                    "stalled SCSI Bus after DATA Overrun");
                   4014:                /* XXX: Need to issue SCSI reset at this point */
                   4015:                break;
                   4016:
                   4017:        case ASYNC_KILLED_BUS:
                   4018:                isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
                   4019:                break;
                   4020:
                   4021:        case ASYNC_BUS_TRANSIT:
                   4022:                mbox = ISP_READ(isp, OUTMAILBOX2);
                   4023:                switch (mbox & 0x1c00) {
                   4024:                case SXP_PINS_LVD_MODE:
                   4025:                        isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
                   4026:                        SDPARAM(isp)->isp_diffmode = 0;
                   4027:                        SDPARAM(isp)->isp_ultramode = 0;
                   4028:                        SDPARAM(isp)->isp_lvdmode = 1;
                   4029:                        break;
                   4030:                case SXP_PINS_HVD_MODE:
                   4031:                        isp_prt(isp, ISP_LOGINFO,
                   4032:                            "Transition to Differential mode");
                   4033:                        SDPARAM(isp)->isp_diffmode = 1;
                   4034:                        SDPARAM(isp)->isp_ultramode = 0;
                   4035:                        SDPARAM(isp)->isp_lvdmode = 0;
                   4036:                        break;
                   4037:                case SXP_PINS_SE_MODE:
                   4038:                        isp_prt(isp, ISP_LOGINFO,
                   4039:                            "Transition to Single Ended mode");
                   4040:                        SDPARAM(isp)->isp_diffmode = 0;
                   4041:                        SDPARAM(isp)->isp_ultramode = 1;
                   4042:                        SDPARAM(isp)->isp_lvdmode = 0;
                   4043:                        break;
                   4044:                default:
                   4045:                        isp_prt(isp, ISP_LOGWARN,
                   4046:                            "Transition to Unknown Mode 0x%x", mbox);
                   4047:                        break;
                   4048:                }
                   4049:                /*
                   4050:                 * XXX: Set up to renegotiate again!
                   4051:                 */
                   4052:                /* Can only be for a 1080... */
                   4053:                isp->isp_sendmarker |= (1 << bus);
                   4054:                break;
                   4055:
                   4056:        /*
                   4057:         * We can use bus, which will always be zero for FC cards,
                   4058:         * as a mailbox pattern accumulator to be checked below.
                   4059:         */
                   4060:        case ASYNC_RIO5:
                   4061:                bus = 0x1ce;    /* outgoing mailbox regs 1-3, 6-7 */
                   4062:                break;
                   4063:
                   4064:        case ASYNC_RIO4:
                   4065:                bus = 0x14e;    /* outgoing mailbox regs 1-3, 6 */
                   4066:                break;
                   4067:
                   4068:        case ASYNC_RIO3:
                   4069:                bus = 0x10e;    /* outgoing mailbox regs 1-3 */
                   4070:                break;
                   4071:
                   4072:        case ASYNC_RIO2:
                   4073:                bus = 0x106;    /* outgoing mailbox regs 1-2 */
                   4074:                break;
                   4075:
                   4076:        case ASYNC_RIO1:
                   4077:        case ASYNC_CMD_CMPLT:
                   4078:                bus = 0x102;    /* outgoing mailbox regs 1 */
                   4079:                break;
                   4080:
                   4081:        case ASYNC_RIO_RESP:
                   4082:                return (rval);
                   4083:
                   4084:        case ASYNC_CTIO_DONE:
                   4085:        {
                   4086: #ifdef ISP_TARGET_MODE
                   4087:                int handle =
                   4088:                    (ISP_READ(isp, OUTMAILBOX2) << 16) |
                   4089:                    (ISP_READ(isp, OUTMAILBOX1));
                   4090:                if (isp_target_async(isp, handle, mbox))
                   4091:                        rval = -1;
                   4092: #else
                   4093:                isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
                   4094: #endif
                   4095:                isp->isp_fphccmplt++;   /* count it as a fast posting intr */
                   4096:                break;
                   4097:        }
                   4098:        case ASYNC_LIP_F8:
                   4099:        case ASYNC_LIP_OCCURRED:
                   4100:                FCPARAM(isp)->isp_lipseq =
                   4101:                    ISP_READ(isp, OUTMAILBOX1);
                   4102:                FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
                   4103:                FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
                   4104:                isp->isp_sendmarker = 1;
                   4105:                isp_mark_getpdb_all(isp);
                   4106:                isp_async(isp, ISPASYNC_LIP, NULL);
                   4107: #ifdef ISP_TARGET_MODE
                   4108:                if (isp_target_async(isp, bus, mbox))
                   4109:                        rval = -1;
                   4110: #endif
                   4111:                /*
                   4112:                 * We've had problems with data corruption occurring on
                   4113:                 * commands that complete (with no apparent error) after
                   4114:                 * we receive a LIP. This has been observed mostly on
                   4115:                 * Local Loop topologies. To be safe, let's just mark
                   4116:                 * all active commands as dead.
                   4117:                 */
                   4118:                if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
                   4119:                    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
                   4120:                        int i, j;
                   4121:                        for (i = j = 0; i < isp->isp_maxcmds; i++) {
                   4122:                                XS_T *xs;
                   4123:                                xs = isp->isp_xflist[i];
                   4124:                                if (xs != NULL) {
                   4125:                                        j++;
                   4126:                                        XS_SETERR(xs, HBA_BUSRESET);
                   4127:                                }
                   4128:                        }
                   4129:                        if (j) {
                   4130:                                isp_prt(isp, ISP_LOGERR,
                   4131:                                    "LIP destroyed %d active commands", j);
                   4132:                        }
                   4133:                }
                   4134:                break;
                   4135:
                   4136:        case ASYNC_LOOP_UP:
                   4137:                isp->isp_sendmarker = 1;
                   4138:                FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
                   4139:                FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
                   4140:                isp_mark_getpdb_all(isp);
                   4141:                isp_async(isp, ISPASYNC_LOOP_UP, NULL);
                   4142: #ifdef ISP_TARGET_MODE
                   4143:                if (isp_target_async(isp, bus, mbox))
                   4144:                        rval = -1;
                   4145: #endif
                   4146:                break;
                   4147:
                   4148:        case ASYNC_LOOP_DOWN:
                   4149:                isp->isp_sendmarker = 1;
                   4150:                FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
                   4151:                FCPARAM(isp)->isp_loopstate = LOOP_NIL;
                   4152:                isp_mark_getpdb_all(isp);
                   4153:                isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
                   4154: #ifdef ISP_TARGET_MODE
                   4155:                if (isp_target_async(isp, bus, mbox))
                   4156:                        rval = -1;
                   4157: #endif
                   4158:                break;
                   4159:
                   4160:        case ASYNC_LOOP_RESET:
                   4161:                isp->isp_sendmarker = 1;
                   4162:                FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
                   4163:                FCPARAM(isp)->isp_loopstate = LOOP_NIL;
                   4164:                isp_mark_getpdb_all(isp);
                   4165:                isp_async(isp, ISPASYNC_LOOP_RESET, NULL);
                   4166: #ifdef ISP_TARGET_MODE
                   4167:                if (isp_target_async(isp, bus, mbox))
                   4168:                        rval = -1;
                   4169: #endif
                   4170:                break;
                   4171:
                   4172:        case ASYNC_PDB_CHANGED:
                   4173:                isp->isp_sendmarker = 1;
                   4174:                FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
                   4175:                isp_mark_getpdb_all(isp);
                   4176:                isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_PDB);
                   4177:                break;
                   4178:
                   4179:        case ASYNC_CHANGE_NOTIFY:
                   4180:                /*
                   4181:                 * Not correct, but it will force us to rescan the loop.
                   4182:                 */
                   4183:                FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
                   4184:                isp_mark_getpdb_all(isp);
                   4185:                isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_SNS);
                   4186:                break;
                   4187:
                   4188:        case ASYNC_PTPMODE:
                   4189:                if (FCPARAM(isp)->isp_onfabric)
                   4190:                        FCPARAM(isp)->isp_topo = TOPO_F_PORT;
                   4191:                else
                   4192:                        FCPARAM(isp)->isp_topo = TOPO_N_PORT;
                   4193:                isp_mark_getpdb_all(isp);
                   4194:                isp->isp_sendmarker = 1;
                   4195:                FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
                   4196:                FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
                   4197:                isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
                   4198: #ifdef ISP_TARGET_MODE
                   4199:                if (isp_target_async(isp, bus, mbox))
                   4200:                        rval = -1;
                   4201: #endif
                   4202:                isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode");
                   4203:                break;
                   4204:
                   4205:        case ASYNC_CONNMODE:
                   4206:                mbox = ISP_READ(isp, OUTMAILBOX1);
                   4207:                isp_mark_getpdb_all(isp);
                   4208:                switch (mbox) {
                   4209:                case ISP_CONN_LOOP:
                   4210:                        isp_prt(isp, ISP_LOGINFO,
                   4211:                            "Point-to-Point -> Loop mode");
                   4212:                        break;
                   4213:                case ISP_CONN_PTP:
                   4214:                        isp_prt(isp, ISP_LOGINFO,
                   4215:                            "Loop -> Point-to-Point mode");
                   4216:                        break;
                   4217:                case ISP_CONN_BADLIP:
                   4218:                        isp_prt(isp, ISP_LOGWARN,
                   4219:                            "Point-to-Point -> Loop mode (BAD LIP)");
                   4220:                        break;
                   4221:                case ISP_CONN_FATAL:
                   4222:                        isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
                   4223: #ifdef ISP_FW_CRASH_DUMP
                   4224:                        isp_async(isp, ISPASYNC_FW_CRASH, NULL);
                   4225: #else
                   4226:                        isp_async(isp, ISPASYNC_FW_CRASH, NULL);
                   4227:                        isp_reinit(isp);
                   4228:                        isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
                   4229: #endif
                   4230:                        return (-1);
                   4231:                case ISP_CONN_LOOPBACK:
                   4232:                        isp_prt(isp, ISP_LOGWARN,
                   4233:                            "Looped Back in Point-to-Point mode");
                   4234:                        break;
                   4235:                default:
                   4236:                        isp_prt(isp, ISP_LOGWARN,
                   4237:                            "Unknown connection mode (0x%x)", mbox);
                   4238:                        break;
                   4239:                }
                   4240:                isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
                   4241:                isp->isp_sendmarker = 1;
                   4242:                FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
                   4243:                FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
                   4244:                break;
                   4245:
                   4246:        default:
                   4247:                isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
                   4248:                break;
                   4249:        }
                   4250:
                   4251:        if (bus & 0x100) {
                   4252:                int i, nh;
                   4253:                u_int16_t handles[5];
                   4254:
                   4255:                for (nh = 0, i = 1; i < MAX_MAILBOX; i++) {
                   4256:                        if ((bus & (1 << i)) == 0) {
                   4257:                                continue;
                   4258:                        }
                   4259:                        handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
                   4260:                }
                   4261:                for (i = 0; i < nh; i++) {
                   4262:                        isp_fastpost_complete(isp, handles[i]);
                   4263:                        isp_prt(isp,  ISP_LOGDEBUG3,
                   4264:                            "fast post completion of %u", handles[i]);
                   4265:                }
                   4266:                if (isp->isp_fpcchiwater < nh)
                   4267:                        isp->isp_fpcchiwater = nh;
                   4268:        } else {
                   4269:                isp->isp_intoasync++;
                   4270:        }
                   4271:        return (rval);
                   4272: }
                   4273:
                   4274: /*
                   4275:  * Handle other response entries. A pointer to the request queue output
                   4276:  * index is here in case we want to eat several entries at once, although
                   4277:  * this is not used currently.
                   4278:  */
                   4279:
                   4280: static int
                   4281: isp_handle_other_response(struct ispsoftc *isp, int type,
                   4282:     isphdr_t *hp, u_int16_t *optrp)
                   4283: {
                   4284:        switch (type) {
                   4285:        case RQSTYPE_STATUS_CONT:
                   4286:                isp_prt(isp, ISP_LOGINFO, "Ignored Continuation Response");
                   4287:                return (1);
                   4288:        case RQSTYPE_ATIO:
                   4289:        case RQSTYPE_CTIO:
                   4290:        case RQSTYPE_ENABLE_LUN:
                   4291:        case RQSTYPE_MODIFY_LUN:
                   4292:        case RQSTYPE_NOTIFY:
                   4293:        case RQSTYPE_NOTIFY_ACK:
                   4294:        case RQSTYPE_CTIO1:
                   4295:        case RQSTYPE_ATIO2:
                   4296:        case RQSTYPE_CTIO2:
                   4297:        case RQSTYPE_CTIO3:
                   4298:                isp->isp_rsltccmplt++;  /* count as a response completion */
                   4299: #ifdef ISP_TARGET_MODE
                   4300:                if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
                   4301:                        return (1);
                   4302:                }
                   4303: #endif
                   4304:                /* FALLTHROUGH */
                   4305:        case RQSTYPE_REQUEST:
                   4306:        default:
                   4307:                if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) {
                   4308:                        return (1);
                   4309:                }
                   4310:                isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
                   4311:                    isp_get_response_type(isp, hp));
                   4312:                return (0);
                   4313:        }
                   4314: }
                   4315:
                   4316: static void
                   4317: isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
                   4318: {
                   4319:        switch (sp->req_completion_status & 0xff) {
                   4320:        case RQCS_COMPLETE:
                   4321:                if (XS_NOERR(xs)) {
                   4322:                        XS_SETERR(xs, HBA_NOERROR);
                   4323:                }
                   4324:                return;
                   4325:
                   4326:        case RQCS_INCOMPLETE:
                   4327:                if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
                   4328:                        isp_prt(isp, ISP_LOGDEBUG1,
                   4329:                            "Selection Timeout for %d.%d.%d",
                   4330:                            XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4331:                        if (XS_NOERR(xs)) {
                   4332:                                XS_SETERR(xs, HBA_SELTIMEOUT);
                   4333:                        }
                   4334:                        return;
                   4335:                }
                   4336:                isp_prt(isp, ISP_LOGERR,
                   4337:                    "command incomplete for %d.%d.%d, state 0x%x",
                   4338:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
                   4339:                    sp->req_state_flags);
                   4340:                break;
                   4341:
                   4342:        case RQCS_DMA_ERROR:
                   4343:                isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
                   4344:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4345:                break;
                   4346:
                   4347:        case RQCS_TRANSPORT_ERROR:
                   4348:        {
                   4349:                char buf[172];
                   4350:                SNPRINTF(buf, sizeof (buf), "states=>");
                   4351:                if (sp->req_state_flags & RQSF_GOT_BUS) {
                   4352:                        SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
                   4353:                }
                   4354:                if (sp->req_state_flags & RQSF_GOT_TARGET) {
                   4355:                        SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
                   4356:                }
                   4357:                if (sp->req_state_flags & RQSF_SENT_CDB) {
                   4358:                        SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
                   4359:                }
                   4360:                if (sp->req_state_flags & RQSF_XFRD_DATA) {
                   4361:                        SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
                   4362:                }
                   4363:                if (sp->req_state_flags & RQSF_GOT_STATUS) {
                   4364:                        SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
                   4365:                }
                   4366:                if (sp->req_state_flags & RQSF_GOT_SENSE) {
                   4367:                        SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
                   4368:                }
                   4369:                if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
                   4370:                        SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
                   4371:                }
                   4372:                SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
                   4373:                if (sp->req_status_flags & RQSTF_DISCONNECT) {
                   4374:                        SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
                   4375:                }
                   4376:                if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
                   4377:                        SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
                   4378:                }
                   4379:                if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
                   4380:                        SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
                   4381:                }
                   4382:                if (sp->req_status_flags & RQSTF_BUS_RESET) {
                   4383:                        SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
                   4384:                }
                   4385:                if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
                   4386:                        SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
                   4387:                }
                   4388:                if (sp->req_status_flags & RQSTF_ABORTED) {
                   4389:                        SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
                   4390:                }
                   4391:                if (sp->req_status_flags & RQSTF_TIMEOUT) {
                   4392:                        SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
                   4393:                }
                   4394:                if (sp->req_status_flags & RQSTF_NEGOTIATION) {
                   4395:                        SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
                   4396:                }
                   4397:                isp_prt(isp, ISP_LOGERR, "%s", buf);
                   4398:                isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
                   4399:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
                   4400:                break;
                   4401:        }
                   4402:        case RQCS_RESET_OCCURRED:
                   4403:                isp_prt(isp, ISP_LOGWARN,
                   4404:                    "bus reset destroyed command for %d.%d.%d",
                   4405:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4406:                isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
                   4407:                if (XS_NOERR(xs)) {
                   4408:                        XS_SETERR(xs, HBA_BUSRESET);
                   4409:                }
                   4410:                return;
                   4411:
                   4412:        case RQCS_ABORTED:
                   4413:                isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
                   4414:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4415:                isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
                   4416:                if (XS_NOERR(xs)) {
                   4417:                        XS_SETERR(xs, HBA_ABORTED);
                   4418:                }
                   4419:                return;
                   4420:
                   4421:        case RQCS_TIMEOUT:
                   4422:                isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
                   4423:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4424:                /*
                   4425:                 * Check to see if we logged out the device.
                   4426:                 */
                   4427:                if (IS_FC(isp)) {
                   4428:                        if ((sp->req_completion_status & RQSTF_LOGOUT) &&
                   4429:                            FCPARAM(isp)->portdb[XS_TGT(xs)].valid &&
                   4430:                            FCPARAM(isp)->portdb[XS_TGT(xs)].fabric_dev) {
                   4431:                                FCPARAM(isp)->portdb[XS_TGT(xs)].relogin = 1;
                   4432:                        }
                   4433:                }
                   4434:                if (XS_NOERR(xs)) {
                   4435:                        XS_SETERR(xs, HBA_CMDTIMEOUT);
                   4436:                }
                   4437:                return;
                   4438:
                   4439:        case RQCS_DATA_OVERRUN:
                   4440:                XS_RESID(xs) = sp->req_resid;
                   4441:                isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d",
                   4442:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4443:                if (XS_NOERR(xs)) {
                   4444:                        XS_SETERR(xs, HBA_DATAOVR);
                   4445:                }
                   4446:                return;
                   4447:
                   4448:        case RQCS_COMMAND_OVERRUN:
                   4449:                isp_prt(isp, ISP_LOGERR,
                   4450:                    "command overrun for command on %d.%d.%d",
                   4451:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4452:                break;
                   4453:
                   4454:        case RQCS_STATUS_OVERRUN:
                   4455:                isp_prt(isp, ISP_LOGERR,
                   4456:                    "status overrun for command on %d.%d.%d",
                   4457:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4458:                break;
                   4459:
                   4460:        case RQCS_BAD_MESSAGE:
                   4461:                isp_prt(isp, ISP_LOGERR,
                   4462:                    "msg not COMMAND COMPLETE after status %d.%d.%d",
                   4463:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4464:                break;
                   4465:
                   4466:        case RQCS_NO_MESSAGE_OUT:
                   4467:                isp_prt(isp, ISP_LOGERR,
                   4468:                    "No MESSAGE OUT phase after selection on %d.%d.%d",
                   4469:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4470:                break;
                   4471:
                   4472:        case RQCS_EXT_ID_FAILED:
                   4473:                isp_prt(isp, ISP_LOGERR, "EXTENDED IDENTIFY failed %d.%d.%d",
                   4474:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4475:                break;
                   4476:
                   4477:        case RQCS_IDE_MSG_FAILED:
                   4478:                isp_prt(isp, ISP_LOGERR,
                   4479:                    "INITIATOR DETECTED ERROR rejected by %d.%d.%d",
                   4480:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4481:                break;
                   4482:
                   4483:        case RQCS_ABORT_MSG_FAILED:
                   4484:                isp_prt(isp, ISP_LOGERR, "ABORT OPERATION rejected by %d.%d.%d",
                   4485:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4486:                break;
                   4487:
                   4488:        case RQCS_REJECT_MSG_FAILED:
                   4489:                isp_prt(isp, ISP_LOGERR, "MESSAGE REJECT rejected by %d.%d.%d",
                   4490:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4491:                break;
                   4492:
                   4493:        case RQCS_NOP_MSG_FAILED:
                   4494:                isp_prt(isp, ISP_LOGERR, "NOP rejected by %d.%d.%d",
                   4495:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4496:                break;
                   4497:
                   4498:        case RQCS_PARITY_ERROR_MSG_FAILED:
                   4499:                isp_prt(isp, ISP_LOGERR,
                   4500:                    "MESSAGE PARITY ERROR rejected by %d.%d.%d",
                   4501:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4502:                break;
                   4503:
                   4504:        case RQCS_DEVICE_RESET_MSG_FAILED:
                   4505:                isp_prt(isp, ISP_LOGWARN,
                   4506:                    "BUS DEVICE RESET rejected by %d.%d.%d",
                   4507:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4508:                break;
                   4509:
                   4510:        case RQCS_ID_MSG_FAILED:
                   4511:                isp_prt(isp, ISP_LOGERR, "IDENTIFY rejected by %d.%d.%d",
                   4512:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4513:                break;
                   4514:
                   4515:        case RQCS_UNEXP_BUS_FREE:
                   4516:                isp_prt(isp, ISP_LOGERR, "%d.%d.%d had an unexpected bus free",
                   4517:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4518:                break;
                   4519:
                   4520:        case RQCS_DATA_UNDERRUN:
                   4521:        {
                   4522:                if (IS_FC(isp)) {
                   4523:                        int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
                   4524:                        if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
                   4525:                                isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
                   4526:                                    XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
                   4527:                                    (ru_marked)? "marked" : "not marked");
                   4528:                                if (XS_NOERR(xs)) {
                   4529:                                        XS_SETERR(xs, HBA_BOTCH);
                   4530:                                }
                   4531:                                return;
                   4532:                        }
                   4533:                }
                   4534:                XS_RESID(xs) = sp->req_resid;
                   4535:                if (XS_NOERR(xs)) {
                   4536:                        XS_SETERR(xs, HBA_NOERROR);
                   4537:                }
                   4538:                return;
                   4539:        }
                   4540:
                   4541:        case RQCS_XACT_ERR1:
                   4542:                isp_prt(isp, ISP_LOGERR, xact1, XS_CHANNEL(xs),
                   4543:                    XS_TGT(xs), XS_LUN(xs));
                   4544:                break;
                   4545:
                   4546:        case RQCS_XACT_ERR2:
                   4547:                isp_prt(isp, ISP_LOGERR, xact2,
                   4548:                    XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs));
                   4549:                break;
                   4550:
                   4551:        case RQCS_XACT_ERR3:
                   4552:                isp_prt(isp, ISP_LOGERR, xact3,
                   4553:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4554:                break;
                   4555:
                   4556:        case RQCS_BAD_ENTRY:
                   4557:                isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
                   4558:                break;
                   4559:
                   4560:        case RQCS_QUEUE_FULL:
                   4561:                isp_prt(isp, ISP_LOGDEBUG0,
                   4562:                    "internal queues full for %d.%d.%d status 0x%x",
                   4563:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), *XS_STSP(xs));
                   4564:
                   4565:                /*
                   4566:                 * If QFULL or some other status byte is set, then this
                   4567:                 * isn't an error, per se.
                   4568:                 *
                   4569:                 * Unfortunately, some QLogic f/w writers have, in
                   4570:                 * some cases, ommitted to *set* status to QFULL.
                   4571:                 *
                   4572:
                   4573:                if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
                   4574:                        XS_SETERR(xs, HBA_NOERROR);
                   4575:                        return;
                   4576:                }
                   4577:
                   4578:                 *
                   4579:                 *
                   4580:                 */
                   4581:
                   4582:                *XS_STSP(xs) = SCSI_QFULL;
                   4583:                XS_SETERR(xs, HBA_NOERROR);
                   4584:                return;
                   4585:
                   4586:        case RQCS_PHASE_SKIPPED:
                   4587:                isp_prt(isp, ISP_LOGERR, pskip, XS_CHANNEL(xs),
                   4588:                    XS_TGT(xs), XS_LUN(xs));
                   4589:                break;
                   4590:
                   4591:        case RQCS_ARQS_FAILED:
                   4592:                isp_prt(isp, ISP_LOGERR,
                   4593:                    "Auto Request Sense failed for %d.%d.%d",
                   4594:                    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
                   4595:                if (XS_NOERR(xs)) {
                   4596:                        XS_SETERR(xs, HBA_ARQFAIL);
                   4597:                }
                   4598:                return;
                   4599:
                   4600:        case RQCS_WIDE_FAILED:
                   4601:                isp_prt(isp, ISP_LOGERR,
                   4602:                    "Wide Negotiation failed for %d.%d.%d",
                   4603:                    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
                   4604:                if (IS_SCSI(isp)) {
                   4605:                        sdparam *sdp = isp->isp_param;
                   4606:                        sdp += XS_CHANNEL(xs);
                   4607:                        sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
                   4608:                        sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
                   4609:                        isp->isp_update |= (1 << XS_CHANNEL(xs));
                   4610:                }
                   4611:                if (XS_NOERR(xs)) {
                   4612:                        XS_SETERR(xs, HBA_NOERROR);
                   4613:                }
                   4614:                return;
                   4615:
                   4616:        case RQCS_SYNCXFER_FAILED:
                   4617:                isp_prt(isp, ISP_LOGERR,
                   4618:                    "SDTR Message failed for target %d.%d.%d",
                   4619:                    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
                   4620:                if (IS_SCSI(isp)) {
                   4621:                        sdparam *sdp = isp->isp_param;
                   4622:                        sdp += XS_CHANNEL(xs);
                   4623:                        sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
                   4624:                        sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
                   4625:                        isp->isp_update |= (1 << XS_CHANNEL(xs));
                   4626:                }
                   4627:                break;
                   4628:
                   4629:        case RQCS_LVD_BUSERR:
                   4630:                isp_prt(isp, ISP_LOGERR,
                   4631:                    "Bad LVD condition while talking to %d.%d.%d",
                   4632:                    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
                   4633:                break;
                   4634:
                   4635:        case RQCS_PORT_UNAVAILABLE:
                   4636:                /*
                   4637:                 * No such port on the loop. Moral equivalent of SELTIMEO
                   4638:                 */
                   4639:        case RQCS_PORT_LOGGED_OUT:
                   4640:                /*
                   4641:                 * It was there (maybe)- treat as a selection timeout.
                   4642:                 */
                   4643:                if ((sp->req_completion_status & 0xff) == RQCS_PORT_UNAVAILABLE)
                   4644:                        isp_prt(isp, ISP_LOGINFO,
                   4645:                            "port unavailable for target %d", XS_TGT(xs));
                   4646:                else
                   4647:                        isp_prt(isp, ISP_LOGINFO,
                   4648:                            "port logout for target %d", XS_TGT(xs));
                   4649:                /*
                   4650:                 * If we're on a local loop, force a LIP (which is overkill)
                   4651:                 * to force a re-login of this unit. If we're on fabric,
                   4652:                 * then we'll have to relogin as a matter of course.
                   4653:                 */
                   4654:                if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
                   4655:                    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
                   4656:                        mbreg_t mbs;
                   4657:                        mbs.param[0] = MBOX_INIT_LIP;
                   4658:                        isp_mboxcmd_qnw(isp, &mbs, 1);
                   4659:                }
                   4660:
                   4661:                /*
                   4662:                 * Probably overkill.
                   4663:                 */
                   4664:                isp->isp_sendmarker = 1;
                   4665:                FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
                   4666:                isp_mark_getpdb_all(isp);
                   4667:                isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
                   4668:                if (XS_NOERR(xs)) {
                   4669:                        XS_SETERR(xs, HBA_SELTIMEOUT);
                   4670:                }
                   4671:                return;
                   4672:
                   4673:        case RQCS_PORT_CHANGED:
                   4674:                isp_prt(isp, ISP_LOGWARN,
                   4675:                    "port changed for target %d", XS_TGT(xs));
                   4676:                if (XS_NOERR(xs)) {
                   4677:                        XS_SETERR(xs, HBA_SELTIMEOUT);
                   4678:                }
                   4679:                return;
                   4680:
                   4681:        case RQCS_PORT_BUSY:
                   4682:                isp_prt(isp, ISP_LOGWARN,
                   4683:                    "port busy for target %d", XS_TGT(xs));
                   4684:                if (XS_NOERR(xs)) {
                   4685:                        XS_SETERR(xs, HBA_TGTBSY);
                   4686:                }
                   4687:                return;
                   4688:
                   4689:        default:
                   4690:                isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
                   4691:                    sp->req_completion_status);
                   4692:                break;
                   4693:        }
                   4694:        if (XS_NOERR(xs)) {
                   4695:                XS_SETERR(xs, HBA_BOTCH);
                   4696:        }
                   4697: }
                   4698:
                   4699: static void
                   4700: isp_fastpost_complete(struct ispsoftc *isp, u_int16_t fph)
                   4701: {
                   4702:        XS_T *xs;
                   4703:
                   4704:        if (fph == 0) {
                   4705:                return;
                   4706:        }
                   4707:        xs = isp_find_xs(isp, fph);
                   4708:        if (xs == NULL) {
                   4709:                isp_prt(isp, ISP_LOGWARN,
                   4710:                    "Command for fast post handle 0x%x not found", fph);
                   4711:                return;
                   4712:        }
                   4713:        isp_destroy_handle(isp, fph);
                   4714:
                   4715:        /*
                   4716:         * Since we don't have a result queue entry item,
                   4717:         * we must believe that SCSI status is zero and
                   4718:         * that all data transferred.
                   4719:         */
                   4720:        XS_SET_STATE_STAT(isp, xs, NULL);
                   4721:        XS_RESID(xs) = 0;
                   4722:        *XS_STSP(xs) = SCSI_GOOD;
                   4723:        if (XS_XFRLEN(xs)) {
                   4724:                ISP_DMAFREE(isp, xs, fph);
                   4725:        }
                   4726:        if (isp->isp_nactive)
                   4727:                isp->isp_nactive--;
                   4728:        isp->isp_fphccmplt++;
                   4729:        isp_done(xs);
                   4730: }
                   4731:
                   4732: static int
                   4733: isp_mbox_continue(struct ispsoftc *isp)
                   4734: {
                   4735:        mbreg_t mbs;
                   4736:        u_int16_t *ptr;
                   4737:
                   4738:        switch (isp->isp_lastmbxcmd) {
                   4739:        case MBOX_WRITE_RAM_WORD:
                   4740:        case MBOX_READ_RAM_WORD:
                   4741:        case MBOX_READ_RAM_WORD_EXTENDED:
                   4742:                break;
                   4743:        default:
                   4744:                return (1);
                   4745:        }
                   4746:        if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
                   4747:                isp->isp_mbxwrk0 = 0;
                   4748:                return (-1);
                   4749:        }
                   4750:
                   4751:
                   4752:        /*
                   4753:         * Clear the previous interrupt.
                   4754:         */
                   4755:        ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
                   4756:        ISP_WRITE(isp, BIU_SEMA, 0);
                   4757:
                   4758:        /*
                   4759:         * Continue with next word.
                   4760:         */
                   4761:        ptr = isp->isp_mbxworkp;
                   4762:        switch (isp->isp_lastmbxcmd) {
                   4763:        case MBOX_WRITE_RAM_WORD:
                   4764:                mbs.param[2] = *ptr++;
                   4765:                mbs.param[1] = isp->isp_mbxwrk1++;
                   4766:                break;
                   4767:        case MBOX_READ_RAM_WORD:
                   4768:        case MBOX_READ_RAM_WORD_EXTENDED:
                   4769:                *ptr++ = isp->isp_mboxtmp[2];
                   4770:                mbs.param[1] = isp->isp_mbxwrk1++;
                   4771:                break;
                   4772:        }
                   4773:        isp->isp_mbxworkp = ptr;
                   4774:        mbs.param[0] = isp->isp_lastmbxcmd;
                   4775:        isp->isp_mbxwrk0 -= 1;
                   4776:        isp_mboxcmd_qnw(isp, &mbs, 0);
                   4777:        return (0);
                   4778: }
                   4779:
                   4780:
                   4781: #define        HIBYT(x)                        ((x) >> 0x8)
                   4782: #define        LOBYT(x)                        ((x)  & 0xff)
                   4783: #define        ISPOPMAP(a, b)                  (((a) << 8) | (b))
                   4784: static const u_int16_t mbpscsi[] = {
                   4785:        ISPOPMAP(0x01, 0x01),   /* 0x00: MBOX_NO_OP */
                   4786:        ISPOPMAP(0x1f, 0x01),   /* 0x01: MBOX_LOAD_RAM */
                   4787:        ISPOPMAP(0x03, 0x01),   /* 0x02: MBOX_EXEC_FIRMWARE */
                   4788:        ISPOPMAP(0x1f, 0x01),   /* 0x03: MBOX_DUMP_RAM */
                   4789:        ISPOPMAP(0x07, 0x07),   /* 0x04: MBOX_WRITE_RAM_WORD */
                   4790:        ISPOPMAP(0x03, 0x07),   /* 0x05: MBOX_READ_RAM_WORD */
                   4791:        ISPOPMAP(0x3f, 0x3f),   /* 0x06: MBOX_MAILBOX_REG_TEST */
                   4792:        ISPOPMAP(0x03, 0x07),   /* 0x07: MBOX_VERIFY_CHECKSUM   */
                   4793:        ISPOPMAP(0x01, 0x0f),   /* 0x08: MBOX_ABOUT_FIRMWARE */
                   4794:        ISPOPMAP(0x00, 0x00),   /* 0x09: */
                   4795:        ISPOPMAP(0x00, 0x00),   /* 0x0a: */
                   4796:        ISPOPMAP(0x00, 0x00),   /* 0x0b: */
                   4797:        ISPOPMAP(0x00, 0x00),   /* 0x0c: */
                   4798:        ISPOPMAP(0x00, 0x00),   /* 0x0d: */
                   4799:        ISPOPMAP(0x01, 0x05),   /* 0x0e: MBOX_CHECK_FIRMWARE */
                   4800:        ISPOPMAP(0x00, 0x00),   /* 0x0f: */
                   4801:        ISPOPMAP(0x1f, 0x1f),   /* 0x10: MBOX_INIT_REQ_QUEUE */
                   4802:        ISPOPMAP(0x3f, 0x3f),   /* 0x11: MBOX_INIT_RES_QUEUE */
                   4803:        ISPOPMAP(0x0f, 0x0f),   /* 0x12: MBOX_EXECUTE_IOCB */
                   4804:        ISPOPMAP(0x03, 0x03),   /* 0x13: MBOX_WAKE_UP   */
                   4805:        ISPOPMAP(0x01, 0x3f),   /* 0x14: MBOX_STOP_FIRMWARE */
                   4806:        ISPOPMAP(0x0f, 0x0f),   /* 0x15: MBOX_ABORT */
                   4807:        ISPOPMAP(0x03, 0x03),   /* 0x16: MBOX_ABORT_DEVICE */
                   4808:        ISPOPMAP(0x07, 0x07),   /* 0x17: MBOX_ABORT_TARGET */
                   4809:        ISPOPMAP(0x07, 0x07),   /* 0x18: MBOX_BUS_RESET */
                   4810:        ISPOPMAP(0x03, 0x07),   /* 0x19: MBOX_STOP_QUEUE */
                   4811:        ISPOPMAP(0x03, 0x07),   /* 0x1a: MBOX_START_QUEUE */
                   4812:        ISPOPMAP(0x03, 0x07),   /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
                   4813:        ISPOPMAP(0x03, 0x07),   /* 0x1c: MBOX_ABORT_QUEUE */
                   4814:        ISPOPMAP(0x03, 0x4f),   /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
                   4815:        ISPOPMAP(0x00, 0x00),   /* 0x1e: */
                   4816:        ISPOPMAP(0x01, 0x07),   /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
                   4817:        ISPOPMAP(0x01, 0x07),   /* 0x20: MBOX_GET_INIT_SCSI_ID */
                   4818:        ISPOPMAP(0x01, 0x07),   /* 0x21: MBOX_GET_SELECT_TIMEOUT */
                   4819:        ISPOPMAP(0x01, 0xc7),   /* 0x22: MBOX_GET_RETRY_COUNT   */
                   4820:        ISPOPMAP(0x01, 0x07),   /* 0x23: MBOX_GET_TAG_AGE_LIMIT */
                   4821:        ISPOPMAP(0x01, 0x03),   /* 0x24: MBOX_GET_CLOCK_RATE */
                   4822:        ISPOPMAP(0x01, 0x07),   /* 0x25: MBOX_GET_ACT_NEG_STATE */
                   4823:        ISPOPMAP(0x01, 0x07),   /* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
                   4824:        ISPOPMAP(0x01, 0x07),   /* 0x27: MBOX_GET_PCI_PARAMS */
                   4825:        ISPOPMAP(0x03, 0x4f),   /* 0x28: MBOX_GET_TARGET_PARAMS */
                   4826:        ISPOPMAP(0x03, 0x0f),   /* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
                   4827:        ISPOPMAP(0x01, 0x07),   /* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
                   4828:        ISPOPMAP(0x00, 0x00),   /* 0x2b: */
                   4829:        ISPOPMAP(0x00, 0x00),   /* 0x2c: */
                   4830:        ISPOPMAP(0x00, 0x00),   /* 0x2d: */
                   4831:        ISPOPMAP(0x00, 0x00),   /* 0x2e: */
                   4832:        ISPOPMAP(0x00, 0x00),   /* 0x2f: */
                   4833:        ISPOPMAP(0x03, 0x03),   /* 0x30: MBOX_SET_INIT_SCSI_ID */
                   4834:        ISPOPMAP(0x07, 0x07),   /* 0x31: MBOX_SET_SELECT_TIMEOUT */
                   4835:        ISPOPMAP(0xc7, 0xc7),   /* 0x32: MBOX_SET_RETRY_COUNT   */
                   4836:        ISPOPMAP(0x07, 0x07),   /* 0x33: MBOX_SET_TAG_AGE_LIMIT */
                   4837:        ISPOPMAP(0x03, 0x03),   /* 0x34: MBOX_SET_CLOCK_RATE */
                   4838:        ISPOPMAP(0x07, 0x07),   /* 0x35: MBOX_SET_ACT_NEG_STATE */
                   4839:        ISPOPMAP(0x07, 0x07),   /* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
                   4840:        ISPOPMAP(0x07, 0x07),   /* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
                   4841:        ISPOPMAP(0x4f, 0x4f),   /* 0x38: MBOX_SET_TARGET_PARAMS */
                   4842:        ISPOPMAP(0x0f, 0x0f),   /* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
                   4843:        ISPOPMAP(0x07, 0x07),   /* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
                   4844:        ISPOPMAP(0x00, 0x00),   /* 0x3b: */
                   4845:        ISPOPMAP(0x00, 0x00),   /* 0x3c: */
                   4846:        ISPOPMAP(0x00, 0x00),   /* 0x3d: */
                   4847:        ISPOPMAP(0x00, 0x00),   /* 0x3e: */
                   4848:        ISPOPMAP(0x00, 0x00),   /* 0x3f: */
                   4849:        ISPOPMAP(0x01, 0x03),   /* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
                   4850:        ISPOPMAP(0x3f, 0x01),   /* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
                   4851:        ISPOPMAP(0x03, 0x07),   /* 0x42: MBOX_EXEC_BIOS_IOCB */
                   4852:        ISPOPMAP(0x00, 0x00),   /* 0x43: */
                   4853:        ISPOPMAP(0x00, 0x00),   /* 0x44: */
                   4854:        ISPOPMAP(0x03, 0x03),   /* 0x45: SET SYSTEM PARAMETER */
                   4855:        ISPOPMAP(0x01, 0x03),   /* 0x46: GET SYSTEM PARAMETER */
                   4856:        ISPOPMAP(0x00, 0x00),   /* 0x47: */
                   4857:        ISPOPMAP(0x01, 0xcf),   /* 0x48: GET SCAM CONFIGURATION */
                   4858:        ISPOPMAP(0xcf, 0xcf),   /* 0x49: SET SCAM CONFIGURATION */
                   4859:        ISPOPMAP(0x03, 0x03),   /* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
                   4860:        ISPOPMAP(0x01, 0x03),   /* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
                   4861:        ISPOPMAP(0x00, 0x00),   /* 0x4c: */
                   4862:        ISPOPMAP(0x00, 0x00),   /* 0x4d: */
                   4863:        ISPOPMAP(0x00, 0x00),   /* 0x4e: */
                   4864:        ISPOPMAP(0x00, 0x00),   /* 0x4f: */
                   4865:        ISPOPMAP(0xdf, 0xdf),   /* 0x50: LOAD RAM A64 */
                   4866:        ISPOPMAP(0xdf, 0xdf),   /* 0x51: DUMP RAM A64 */
                   4867:        ISPOPMAP(0xdf, 0xff),   /* 0x52: INITIALIZE REQUEST QUEUE A64 */
                   4868:        ISPOPMAP(0xef, 0xff),   /* 0x53: INITIALIZE RESPONSE QUEUE A64 */
                   4869:        ISPOPMAP(0xcf, 0x01),   /* 0x54: EXECUTE IOCB A64 */
                   4870:        ISPOPMAP(0x07, 0x01),   /* 0x55: ENABLE TARGET MODE */
                   4871:        ISPOPMAP(0x03, 0x0f),   /* 0x56: GET TARGET STATUS */
                   4872:        ISPOPMAP(0x00, 0x00),   /* 0x57: */
                   4873:        ISPOPMAP(0x00, 0x00),   /* 0x58: */
                   4874:        ISPOPMAP(0x00, 0x00),   /* 0x59: */
                   4875:        ISPOPMAP(0x03, 0x03),   /* 0x5a: SET DATA OVERRUN RECOVERY MODE */
                   4876:        ISPOPMAP(0x01, 0x03),   /* 0x5b: GET DATA OVERRUN RECOVERY MODE */
                   4877:        ISPOPMAP(0x0f, 0x0f),   /* 0x5c: SET HOST DATA */
                   4878:        ISPOPMAP(0x01, 0x01)    /* 0x5d: GET NOST DATA */
                   4879: };
                   4880:
                   4881: #ifdef SMALL_KERNEL
                   4882: #define ISP_STRIPPED
                   4883: #endif
                   4884:
                   4885: #ifndef        ISP_STRIPPED
                   4886: static char *scsi_mbcmd_names[] = {
                   4887:        "NO-OP",
                   4888:        "LOAD RAM",
                   4889:        "EXEC FIRMWARE",
                   4890:        "DUMP RAM",
                   4891:        "WRITE RAM WORD",
                   4892:        "READ RAM WORD",
                   4893:        "MAILBOX REG TEST",
                   4894:        "VERIFY CHECKSUM",
                   4895:        "ABOUT FIRMWARE",
                   4896:        NULL,
                   4897:        NULL,
                   4898:        NULL,
                   4899:        NULL,
                   4900:        NULL,
                   4901:        "CHECK FIRMWARE",
                   4902:        NULL,
                   4903:        "INIT REQUEST QUEUE",
                   4904:        "INIT RESULT QUEUE",
                   4905:        "EXECUTE IOCB",
                   4906:        "WAKE UP",
                   4907:        "STOP FIRMWARE",
                   4908:        "ABORT",
                   4909:        "ABORT DEVICE",
                   4910:        "ABORT TARGET",
                   4911:        "BUS RESET",
                   4912:        "STOP QUEUE",
                   4913:        "START QUEUE",
                   4914:        "SINGLE STEP QUEUE",
                   4915:        "ABORT QUEUE",
                   4916:        "GET DEV QUEUE STATUS",
                   4917:        NULL,
                   4918:        "GET FIRMWARE STATUS",
                   4919:        "GET INIT SCSI ID",
                   4920:        "GET SELECT TIMEOUT",
                   4921:        "GET RETRY COUNT",
                   4922:        "GET TAG AGE LIMIT",
                   4923:        "GET CLOCK RATE",
                   4924:        "GET ACT NEG STATE",
                   4925:        "GET ASYNC DATA SETUP TIME",
                   4926:        "GET PCI PARAMS",
                   4927:        "GET TARGET PARAMS",
                   4928:        "GET DEV QUEUE PARAMS",
                   4929:        "GET RESET DELAY PARAMS",
                   4930:        NULL,
                   4931:        NULL,
                   4932:        NULL,
                   4933:        NULL,
                   4934:        NULL,
                   4935:        "SET INIT SCSI ID",
                   4936:        "SET SELECT TIMEOUT",
                   4937:        "SET RETRY COUNT",
                   4938:        "SET TAG AGE LIMIT",
                   4939:        "SET CLOCK RATE",
                   4940:        "SET ACT NEG STATE",
                   4941:        "SET ASYNC DATA SETUP TIME",
                   4942:        "SET PCI CONTROL PARAMS",
                   4943:        "SET TARGET PARAMS",
                   4944:        "SET DEV QUEUE PARAMS",
                   4945:        "SET RESET DELAY PARAMS",
                   4946:        NULL,
                   4947:        NULL,
                   4948:        NULL,
                   4949:        NULL,
                   4950:        NULL,
                   4951:        "RETURN BIOS BLOCK ADDR",
                   4952:        "WRITE FOUR RAM WORDS",
                   4953:        "EXEC BIOS IOCB",
                   4954:        NULL,
                   4955:        NULL,
                   4956:        "SET SYSTEM PARAMETER",
                   4957:        "GET SYSTEM PARAMETER",
                   4958:        NULL,
                   4959:        "GET SCAM CONFIGURATION",
                   4960:        "SET SCAM CONFIGURATION",
                   4961:        "SET FIRMWARE FEATURES",
                   4962:        "GET FIRMWARE FEATURES",
                   4963:        NULL,
                   4964:        NULL,
                   4965:        NULL,
                   4966:        NULL,
                   4967:        "LOAD RAM A64",
                   4968:        "DUMP RAM A64",
                   4969:        "INITIALIZE REQUEST QUEUE A64",
                   4970:        "INITIALIZE RESPONSE QUEUE A64",
                   4971:        "EXECUTE IOCB A64",
                   4972:        "ENABLE TARGET MODE",
                   4973:        "GET TARGET MODE STATE",
                   4974:        NULL,
                   4975:        NULL,
                   4976:        NULL,
                   4977:        "SET DATA OVERRUN RECOVERY MODE",
                   4978:        "GET DATA OVERRUN RECOVERY MODE",
                   4979:        "SET HOST DATA",
                   4980:        "GET NOST DATA",
                   4981: };
                   4982: #endif
                   4983:
                   4984: static const u_int16_t mbpfc[] = {
                   4985:        ISPOPMAP(0x01, 0x01),   /* 0x00: MBOX_NO_OP */
                   4986:        ISPOPMAP(0x1f, 0x01),   /* 0x01: MBOX_LOAD_RAM */
                   4987:        ISPOPMAP(0x03, 0x01),   /* 0x02: MBOX_EXEC_FIRMWARE */
                   4988:        ISPOPMAP(0xdf, 0x01),   /* 0x03: MBOX_DUMP_RAM */
                   4989:        ISPOPMAP(0x07, 0x07),   /* 0x04: MBOX_WRITE_RAM_WORD */
                   4990:        ISPOPMAP(0x03, 0x07),   /* 0x05: MBOX_READ_RAM_WORD */
                   4991:        ISPOPMAP(0xff, 0xff),   /* 0x06: MBOX_MAILBOX_REG_TEST */
                   4992:        ISPOPMAP(0x03, 0x05),   /* 0x07: MBOX_VERIFY_CHECKSUM   */
                   4993:        ISPOPMAP(0x01, 0x4f),   /* 0x08: MBOX_ABOUT_FIRMWARE */
                   4994:        ISPOPMAP(0xdf, 0x01),   /* 0x09: LOAD RAM */
                   4995:        ISPOPMAP(0xdf, 0x01),   /* 0x0a: DUMP RAM */
                   4996:        ISPOPMAP(0x00, 0x00),   /* 0x0b: */
                   4997:        ISPOPMAP(0x00, 0x00),   /* 0x0c: */
                   4998:        ISPOPMAP(0x00, 0x00),   /* 0x0d: */
                   4999:        ISPOPMAP(0x01, 0x05),   /* 0x0e: MBOX_CHECK_FIRMWARE */
                   5000:        ISPOPMAP(0x03, 0x07),   /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED(1) */
                   5001:        ISPOPMAP(0x1f, 0x11),   /* 0x10: MBOX_INIT_REQ_QUEUE */
                   5002:        ISPOPMAP(0x2f, 0x21),   /* 0x11: MBOX_INIT_RES_QUEUE */
                   5003:        ISPOPMAP(0x0f, 0x01),   /* 0x12: MBOX_EXECUTE_IOCB */
                   5004:        ISPOPMAP(0x03, 0x03),   /* 0x13: MBOX_WAKE_UP   */
                   5005:        ISPOPMAP(0x01, 0xff),   /* 0x14: MBOX_STOP_FIRMWARE */
                   5006:        ISPOPMAP(0x4f, 0x01),   /* 0x15: MBOX_ABORT */
                   5007:        ISPOPMAP(0x07, 0x01),   /* 0x16: MBOX_ABORT_DEVICE */
                   5008:        ISPOPMAP(0x07, 0x01),   /* 0x17: MBOX_ABORT_TARGET */
                   5009:        ISPOPMAP(0x03, 0x03),   /* 0x18: MBOX_BUS_RESET */
                   5010:        ISPOPMAP(0x07, 0x05),   /* 0x19: MBOX_STOP_QUEUE */
                   5011:        ISPOPMAP(0x07, 0x05),   /* 0x1a: MBOX_START_QUEUE */
                   5012:        ISPOPMAP(0x07, 0x05),   /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
                   5013:        ISPOPMAP(0x07, 0x05),   /* 0x1c: MBOX_ABORT_QUEUE */
                   5014:        ISPOPMAP(0x07, 0x03),   /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
                   5015:        ISPOPMAP(0x00, 0x00),   /* 0x1e: */
                   5016:        ISPOPMAP(0x01, 0x07),   /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
                   5017:        ISPOPMAP(0x01, 0x4f),   /* 0x20: MBOX_GET_LOOP_ID */
                   5018:        ISPOPMAP(0x00, 0x00),   /* 0x21: */
                   5019:        ISPOPMAP(0x01, 0x07),   /* 0x22: MBOX_GET_RETRY_COUNT   */
                   5020:        ISPOPMAP(0x00, 0x00),   /* 0x23: */
                   5021:        ISPOPMAP(0x00, 0x00),   /* 0x24: */
                   5022:        ISPOPMAP(0x00, 0x00),   /* 0x25: */
                   5023:        ISPOPMAP(0x00, 0x00),   /* 0x26: */
                   5024:        ISPOPMAP(0x00, 0x00),   /* 0x27: */
                   5025:        ISPOPMAP(0x01, 0x03),   /* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
                   5026:        ISPOPMAP(0x03, 0x07),   /* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
                   5027:        ISPOPMAP(0x00, 0x00),   /* 0x2a: */
                   5028:        ISPOPMAP(0x00, 0x00),   /* 0x2b: */
                   5029:        ISPOPMAP(0x00, 0x00),   /* 0x2c: */
                   5030:        ISPOPMAP(0x00, 0x00),   /* 0x2d: */
                   5031:        ISPOPMAP(0x00, 0x00),   /* 0x2e: */
                   5032:        ISPOPMAP(0x00, 0x00),   /* 0x2f: */
                   5033:        ISPOPMAP(0x00, 0x00),   /* 0x30: */
                   5034:        ISPOPMAP(0x00, 0x00),   /* 0x31: */
                   5035:        ISPOPMAP(0x07, 0x07),   /* 0x32: MBOX_SET_RETRY_COUNT   */
                   5036:        ISPOPMAP(0x00, 0x00),   /* 0x33: */
                   5037:        ISPOPMAP(0x00, 0x00),   /* 0x34: */
                   5038:        ISPOPMAP(0x00, 0x00),   /* 0x35: */
                   5039:        ISPOPMAP(0x00, 0x00),   /* 0x36: */
                   5040:        ISPOPMAP(0x00, 0x00),   /* 0x37: */
                   5041:        ISPOPMAP(0x0f, 0x01),   /* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
                   5042:        ISPOPMAP(0x0f, 0x07),   /* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
                   5043:        ISPOPMAP(0x00, 0x00),   /* 0x3a: */
                   5044:        ISPOPMAP(0x00, 0x00),   /* 0x3b: */
                   5045:        ISPOPMAP(0x00, 0x00),   /* 0x3c: */
                   5046:        ISPOPMAP(0x00, 0x00),   /* 0x3d: */
                   5047:        ISPOPMAP(0x00, 0x00),   /* 0x3e: */
                   5048:        ISPOPMAP(0x00, 0x00),   /* 0x3f: */
                   5049:        ISPOPMAP(0x03, 0x01),   /* 0x40: MBOX_LOOP_PORT_BYPASS */
                   5050:        ISPOPMAP(0x03, 0x01),   /* 0x41: MBOX_LOOP_PORT_ENABLE */
                   5051:        ISPOPMAP(0x03, 0x07),   /* 0x42: MBOX_GET_RESOURCE_COUNTS */
                   5052:        ISPOPMAP(0x01, 0x01),   /* 0x43: MBOX_REQUEST_NON_PARTICIPATING_MODE */
                   5053:        ISPOPMAP(0x00, 0x00),   /* 0x44: */
                   5054:        ISPOPMAP(0x00, 0x00),   /* 0x45: */
                   5055:        ISPOPMAP(0x00, 0x00),   /* 0x46: */
                   5056:        ISPOPMAP(0xcf, 0x03),   /* 0x47: GET PORT_DATABASE ENHANCED */
                   5057:        ISPOPMAP(0x00, 0x00),   /* 0x48: */
                   5058:        ISPOPMAP(0x00, 0x00),   /* 0x49: */
                   5059:        ISPOPMAP(0x00, 0x00),   /* 0x4a: */
                   5060:        ISPOPMAP(0x00, 0x00),   /* 0x4b: */
                   5061:        ISPOPMAP(0x00, 0x00),   /* 0x4c: */
                   5062:        ISPOPMAP(0x00, 0x00),   /* 0x4d: */
                   5063:        ISPOPMAP(0x00, 0x00),   /* 0x4e: */
                   5064:        ISPOPMAP(0x00, 0x00),   /* 0x4f: */
                   5065:        ISPOPMAP(0x00, 0x00),   /* 0x50: */
                   5066:        ISPOPMAP(0x00, 0x00),   /* 0x51: */
                   5067:        ISPOPMAP(0x00, 0x00),   /* 0x52: */
                   5068:        ISPOPMAP(0x00, 0x00),   /* 0x53: */
                   5069:        ISPOPMAP(0xcf, 0x01),   /* 0x54: EXECUTE IOCB A64 */
                   5070:        ISPOPMAP(0x00, 0x00),   /* 0x55: */
                   5071:        ISPOPMAP(0x00, 0x00),   /* 0x56: */
                   5072:        ISPOPMAP(0x00, 0x00),   /* 0x57: */
                   5073:        ISPOPMAP(0x00, 0x00),   /* 0x58: */
                   5074:        ISPOPMAP(0x00, 0x00),   /* 0x59: */
                   5075:        ISPOPMAP(0x00, 0x00),   /* 0x5a: */
                   5076:        ISPOPMAP(0x03, 0x01),   /* 0x5b: MBOX_DRIVER_HEARTBEAT */
                   5077:        ISPOPMAP(0xcf, 0x01),   /* 0x5c: MBOX_FW_HEARTBEAT */
                   5078:        ISPOPMAP(0x07, 0x03),   /* 0x5d: MBOX_GET_SET_DATA_RATE */
                   5079:        ISPOPMAP(0x00, 0x00),   /* 0x5e: */
                   5080:        ISPOPMAP(0x00, 0x00),   /* 0x5f: */
                   5081:        ISPOPMAP(0xfd, 0x31),   /* 0x60: MBOX_INIT_FIRMWARE */
                   5082:        ISPOPMAP(0x00, 0x00),   /* 0x61: */
                   5083:        ISPOPMAP(0x01, 0x01),   /* 0x62: MBOX_INIT_LIP */
                   5084:        ISPOPMAP(0xcd, 0x03),   /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
                   5085:        ISPOPMAP(0xcf, 0x01),   /* 0x64: MBOX_GET_PORT_DB */
                   5086:        ISPOPMAP(0x07, 0x01),   /* 0x65: MBOX_CLEAR_ACA */
                   5087:        ISPOPMAP(0x07, 0x01),   /* 0x66: MBOX_TARGET_RESET */
                   5088:        ISPOPMAP(0x07, 0x01),   /* 0x67: MBOX_CLEAR_TASK_SET */
                   5089:        ISPOPMAP(0x07, 0x01),   /* 0x68: MBOX_ABORT_TASK_SET */
                   5090:        ISPOPMAP(0x01, 0x07),   /* 0x69: MBOX_GET_FW_STATE */
                   5091:        ISPOPMAP(0x03, 0xcf),   /* 0x6a: MBOX_GET_PORT_NAME */
                   5092:        ISPOPMAP(0xcf, 0x01),   /* 0x6b: MBOX_GET_LINK_STATUS */
                   5093:        ISPOPMAP(0x0f, 0x01),   /* 0x6c: MBOX_INIT_LIP_RESET */
                   5094:        ISPOPMAP(0x00, 0x00),   /* 0x6d: */
                   5095:        ISPOPMAP(0xcf, 0x03),   /* 0x6e: MBOX_SEND_SNS */
                   5096:        ISPOPMAP(0x0f, 0x07),   /* 0x6f: MBOX_FABRIC_LOGIN */
                   5097:        ISPOPMAP(0x03, 0x01),   /* 0x70: MBOX_SEND_CHANGE_REQUEST */
                   5098:        ISPOPMAP(0x03, 0x03),   /* 0x71: MBOX_FABRIC_LOGOUT */
                   5099:        ISPOPMAP(0x0f, 0x0f),   /* 0x72: MBOX_INIT_LIP_LOGIN */
                   5100:        ISPOPMAP(0x00, 0x00),   /* 0x73: */
                   5101:        ISPOPMAP(0x07, 0x01),   /* 0x74: LOGIN LOOP PORT */
                   5102:        ISPOPMAP(0xcf, 0x03),   /* 0x75: GET PORT/NODE NAME LIST */
                   5103:        ISPOPMAP(0x4f, 0x01),   /* 0x76: SET VENDOR ID */
                   5104:        ISPOPMAP(0xcd, 0x01),   /* 0x77: INITIALIZE IP MAILBOX */
                   5105:        ISPOPMAP(0x00, 0x00),   /* 0x78: */
                   5106:        ISPOPMAP(0x00, 0x00),   /* 0x79: */
                   5107:        ISPOPMAP(0x00, 0x00),   /* 0x7a: */
                   5108:        ISPOPMAP(0x00, 0x00),   /* 0x7b: */
                   5109:        ISPOPMAP(0x4f, 0x03),   /* 0x7c: Get ID List */
                   5110:        ISPOPMAP(0xcf, 0x01),   /* 0x7d: SEND LFA */
                   5111:        ISPOPMAP(0x07, 0x01)    /* 0x7e: Lun RESET */
                   5112: };
                   5113: /*
                   5114:  * Footnotes
                   5115:  *
                   5116:  * (1): this sets bits 21..16 in mailbox register #8, which we nominally
                   5117:  *     do not access at this time in the core driver. The caller is
                   5118:  *     responsible for setting this register first (Gross!).
                   5119:  */
                   5120:
                   5121: #ifndef        ISP_STRIPPED
                   5122: static char *fc_mbcmd_names[] = {
                   5123:        "NO-OP",
                   5124:        "LOAD RAM",
                   5125:        "EXEC FIRMWARE",
                   5126:        "DUMP RAM",
                   5127:        "WRITE RAM WORD",
                   5128:        "READ RAM WORD",
                   5129:        "MAILBOX REG TEST",
                   5130:        "VERIFY CHECKSUM",
                   5131:        "ABOUT FIRMWARE",
                   5132:        "LOAD RAM",
                   5133:        "DUMP RAM",
                   5134:        NULL,
                   5135:        NULL,
                   5136:        "READ RAM WORD EXTENDED",
                   5137:        "CHECK FIRMWARE",
                   5138:        NULL,
                   5139:        "INIT REQUEST QUEUE",
                   5140:        "INIT RESULT QUEUE",
                   5141:        "EXECUTE IOCB",
                   5142:        "WAKE UP",
                   5143:        "STOP FIRMWARE",
                   5144:        "ABORT",
                   5145:        "ABORT DEVICE",
                   5146:        "ABORT TARGET",
                   5147:        "BUS RESET",
                   5148:        "STOP QUEUE",
                   5149:        "START QUEUE",
                   5150:        "SINGLE STEP QUEUE",
                   5151:        "ABORT QUEUE",
                   5152:        "GET DEV QUEUE STATUS",
                   5153:        NULL,
                   5154:        "GET FIRMWARE STATUS",
                   5155:        "GET LOOP ID",
                   5156:        NULL,
                   5157:        "GET RETRY COUNT",
                   5158:        NULL,
                   5159:        NULL,
                   5160:        NULL,
                   5161:        NULL,
                   5162:        NULL,
                   5163:        "GET FIRMWARE OPTIONS",
                   5164:        "GET PORT QUEUE PARAMS",
                   5165:        NULL,
                   5166:        NULL,
                   5167:        NULL,
                   5168:        NULL,
                   5169:        NULL,
                   5170:        NULL,
                   5171:        NULL,
                   5172:        NULL,
                   5173:        "SET RETRY COUNT",
                   5174:        NULL,
                   5175:        NULL,
                   5176:        NULL,
                   5177:        NULL,
                   5178:        NULL,
                   5179:        "SET FIRMWARE OPTIONS",
                   5180:        "SET PORT QUEUE PARAMS",
                   5181:        NULL,
                   5182:        NULL,
                   5183:        NULL,
                   5184:        NULL,
                   5185:        NULL,
                   5186:        NULL,
                   5187:        "LOOP PORT BYPASS",
                   5188:        "LOOP PORT ENABLE",
                   5189:        "GET RESOURCE COUNTS",
                   5190:        "REQUEST NON PARTICIPATING MODE",
                   5191:        NULL,
                   5192:        NULL,
                   5193:        NULL,
                   5194:        "GET PORT DATABASE,, ENHANCED",
                   5195:        NULL,
                   5196:        NULL,
                   5197:        NULL,
                   5198:        NULL,
                   5199:        NULL,
                   5200:        NULL,
                   5201:        NULL,
                   5202:        NULL,
                   5203:        NULL,
                   5204:        NULL,
                   5205:        NULL,
                   5206:        NULL,
                   5207:        "EXECUTE IOCB A64",
                   5208:        NULL,
                   5209:        NULL,
                   5210:        NULL,
                   5211:        NULL,
                   5212:        NULL,
                   5213:        NULL,
                   5214:        "DRIVER HEARTBEAT",
                   5215:        NULL,
                   5216:        "GET/SET DATA RATE",
                   5217:        NULL,
                   5218:        NULL,
                   5219:        "INIT FIRMWARE",
                   5220:        NULL,
                   5221:        "INIT LIP",
                   5222:        "GET FC-AL POSITION MAP",
                   5223:        "GET PORT DATABASE",
                   5224:        "CLEAR ACA",
                   5225:        "TARGET RESET",
                   5226:        "CLEAR TASK SET",
                   5227:        "ABORT TASK SET",
                   5228:        "GET FW STATE",
                   5229:        "GET PORT NAME",
                   5230:        "GET LINK STATUS",
                   5231:        "INIT LIP RESET",
                   5232:        NULL,
                   5233:        "SEND SNS",
                   5234:        "FABRIC LOGIN",
                   5235:        "SEND CHANGE REQUEST",
                   5236:        "FABRIC LOGOUT",
                   5237:        "INIT LIP LOGIN",
                   5238:        NULL,
                   5239:        "LOGIN LOOP PORT",
                   5240:        "GET PORT/NODE NAME LIST",
                   5241:        "SET VENDOR ID",
                   5242:        "INITIALIZE IP MAILBOX",
                   5243:        NULL,
                   5244:        NULL,
                   5245:        NULL,
                   5246:        NULL,
                   5247:        "Get ID List",
                   5248:        "SEND LFA",
                   5249:        "Lun RESET"
                   5250: };
                   5251: #endif
                   5252:
                   5253: static void
                   5254: isp_mboxcmd_qnw(struct ispsoftc *isp, mbreg_t *mbp, int nodelay)
                   5255: {
                   5256:        unsigned int lim, ibits, obits, box, opcode;
                   5257:        const u_int16_t *mcp;
                   5258:
                   5259:        if (IS_FC(isp)) {
                   5260:                mcp = mbpfc;
                   5261:                lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
                   5262:        } else {
                   5263:                mcp = mbpscsi;
                   5264:                lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
                   5265:        }
                   5266:        opcode = mbp->param[0];
                   5267:        ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
                   5268:        obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
                   5269:        for (box = 0; box < MAX_MAILBOX; box++) {
                   5270:                if (ibits & (1 << box)) {
                   5271:                        ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
                   5272:                }
                   5273:                if (nodelay == 0) {
                   5274:                        isp->isp_mboxtmp[box] = mbp->param[box] = 0;
                   5275:                }
                   5276:        }
                   5277:        if (nodelay == 0) {
                   5278:                isp->isp_lastmbxcmd = opcode;
                   5279:                isp->isp_obits = obits;
                   5280:                isp->isp_mboxbsy = 1;
                   5281:        }
                   5282:        ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
                   5283:        /*
                   5284:         * Oddly enough, if we're not delaying for an answer,
                   5285:         * delay a bit to give the f/w a chance to pick up the
                   5286:         * command.
                   5287:         */
                   5288:        if (nodelay) {
                   5289:                USEC_DELAY(1000);
                   5290:        }
                   5291: }
                   5292:
                   5293: static void
                   5294: isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
                   5295: {
                   5296:        char *cname, *xname, tname[16], mname[16];
                   5297:        unsigned int lim, ibits, obits, box, opcode;
                   5298:        const u_int16_t *mcp;
                   5299:
                   5300:        if (IS_FC(isp)) {
                   5301:                mcp = mbpfc;
                   5302:                lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
                   5303:        } else {
                   5304:                mcp = mbpscsi;
                   5305:                lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
                   5306:        }
                   5307:
                   5308:        if ((opcode = mbp->param[0]) >= lim) {
                   5309:                mbp->param[0] = MBOX_INVALID_COMMAND;
                   5310:                isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
                   5311:                return;
                   5312:        }
                   5313:
                   5314:        ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
                   5315:        obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
                   5316:
                   5317:        if (ibits == 0 && obits == 0) {
                   5318:                mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
                   5319:                isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
                   5320:                return;
                   5321:        }
                   5322:
                   5323:        /*
                   5324:         * Get exclusive usage of mailbox registers.
                   5325:         */
                   5326:        MBOX_ACQUIRE(isp);
                   5327:
                   5328:        for (box = 0; box < MAX_MAILBOX; box++) {
                   5329:                if (ibits & (1 << box)) {
                   5330:                        ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
                   5331:                }
                   5332:                isp->isp_mboxtmp[box] = mbp->param[box] = 0;
                   5333:        }
                   5334:
                   5335:        isp->isp_lastmbxcmd = opcode;
                   5336:
                   5337:        /*
                   5338:         * We assume that we can't overwrite a previous command.
                   5339:         */
                   5340:        isp->isp_obits = obits;
                   5341:        isp->isp_mboxbsy = 1;
                   5342:
                   5343:        /*
                   5344:         * Set Host Interrupt condition so that RISC will pick up mailbox regs.
                   5345:         */
                   5346:        ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
                   5347:
                   5348:        /*
                   5349:         * While we haven't finished the command, spin our wheels here.
                   5350:         */
                   5351:        MBOX_WAIT_COMPLETE(isp);
                   5352:
                   5353:        if (isp->isp_mboxbsy) {
                   5354:                /*
                   5355:                 * Command timed out.
                   5356:                 */
                   5357:                isp->isp_mboxbsy = 0;
                   5358:                MBOX_RELEASE(isp);
                   5359:                return;
                   5360:        }
                   5361:
                   5362:        /*
                   5363:         * Copy back output registers.
                   5364:         */
                   5365:        for (box = 0; box < MAX_MAILBOX; box++) {
                   5366:                if (obits & (1 << box)) {
                   5367:                        mbp->param[box] = isp->isp_mboxtmp[box];
                   5368:                }
                   5369:        }
                   5370:
                   5371:        MBOX_RELEASE(isp);
                   5372:
                   5373:        if (logmask == 0 || opcode == MBOX_EXEC_FIRMWARE) {
                   5374:                return;
                   5375:        }
                   5376: #ifdef ISP_STRIPPED
                   5377:        cname = NULL;
                   5378: #else
                   5379:        cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
                   5380: #endif
                   5381:        if (cname == NULL) {
                   5382:                cname = tname;
                   5383:                SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
                   5384:        }
                   5385:
                   5386:        /*
                   5387:         * Just to be chatty here...
                   5388:         */
                   5389:        xname = NULL;
                   5390:        switch (mbp->param[0]) {
                   5391:        case MBOX_COMMAND_COMPLETE:
                   5392:                break;
                   5393:        case MBOX_INVALID_COMMAND:
                   5394:                if (logmask & MBLOGMASK(MBOX_COMMAND_COMPLETE))
                   5395:                        xname = "INVALID COMMAND";
                   5396:                break;
                   5397:        case MBOX_HOST_INTERFACE_ERROR:
                   5398:                if (logmask & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR))
                   5399:                        xname = "HOST INTERFACE ERROR";
                   5400:                break;
                   5401:        case MBOX_TEST_FAILED:
                   5402:                if (logmask & MBLOGMASK(MBOX_TEST_FAILED))
                   5403:                        xname = "TEST FAILED";
                   5404:                break;
                   5405:        case MBOX_COMMAND_ERROR:
                   5406:                if (logmask & MBLOGMASK(MBOX_COMMAND_ERROR))
                   5407:                        xname = "COMMAND ERROR";
                   5408:                break;
                   5409:        case MBOX_COMMAND_PARAM_ERROR:
                   5410:                if (logmask & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR))
                   5411:                        xname = "COMMAND PARAMETER ERROR";
                   5412:                break;
                   5413:        case MBOX_LOOP_ID_USED:
                   5414:                if (logmask & MBLOGMASK(MBOX_LOOP_ID_USED))
                   5415:                        xname = "LOOP ID ALREADY IN USE";
                   5416:                break;
                   5417:        case MBOX_PORT_ID_USED:
                   5418:                if (logmask & MBLOGMASK(MBOX_PORT_ID_USED))
                   5419:                        xname = "PORT ID ALREADY IN USE";
                   5420:                break;
                   5421:        case MBOX_ALL_IDS_USED:
                   5422:                if (logmask & MBLOGMASK(MBOX_ALL_IDS_USED))
                   5423:                        xname = "ALL LOOP IDS IN USE";
                   5424:                break;
                   5425:        case 0:         /* special case */
                   5426:                xname = "TIMEOUT";
                   5427:                break;
                   5428:        default:
                   5429:                SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
                   5430:                xname = mname;
                   5431:                break;
                   5432:        }
                   5433:        if (xname)
                   5434:                isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
                   5435:                    cname, xname);
                   5436: }
                   5437:
                   5438: static void
                   5439: isp_fw_state(struct ispsoftc *isp)
                   5440: {
                   5441:        if (IS_FC(isp)) {
                   5442:                mbreg_t mbs;
                   5443:                fcparam *fcp = isp->isp_param;
                   5444:
                   5445:                mbs.param[0] = MBOX_GET_FW_STATE;
                   5446:                isp_mboxcmd(isp, &mbs, MBLOGALL);
                   5447:                if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
                   5448:                        fcp->isp_fwstate = mbs.param[1];
                   5449:                }
                   5450:        }
                   5451: }
                   5452:
                   5453: static void
                   5454: isp_update(struct ispsoftc *isp)
                   5455: {
                   5456:        int bus, upmask;
                   5457:
                   5458:        for (bus = 0, upmask = isp->isp_update; upmask != 0; bus++) {
                   5459:                if (upmask & (1 << bus)) {
                   5460:                        isp_update_bus(isp, bus);
                   5461:                }
                   5462:                upmask &= ~(1 << bus);
                   5463:        }
                   5464: }
                   5465:
                   5466: static void
                   5467: isp_update_bus(struct ispsoftc *isp, int bus)
                   5468: {
                   5469:        int tgt;
                   5470:        mbreg_t mbs;
                   5471:        sdparam *sdp;
                   5472:
                   5473:        isp->isp_update &= ~(1 << bus);
                   5474:        if (IS_FC(isp)) {
                   5475:                /*
                   5476:                 * There are no 'per-bus' settings for Fibre Channel.
                   5477:                 */
                   5478:                return;
                   5479:        }
                   5480:        sdp = isp->isp_param;
                   5481:        sdp += bus;
                   5482:
                   5483:        for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
                   5484:                u_int16_t flags, period, offset;
                   5485:                int get;
                   5486:
                   5487:                if (sdp->isp_devparam[tgt].dev_enable == 0) {
                   5488:                        sdp->isp_devparam[tgt].dev_update = 0;
                   5489:                        sdp->isp_devparam[tgt].dev_refresh = 0;
                   5490:                        isp_prt(isp, ISP_LOGDEBUG0,
                   5491:                            "skipping target %d bus %d update", tgt, bus);
                   5492:                        continue;
                   5493:                }
                   5494:                /*
                   5495:                 * If the goal is to update the status of the device,
                   5496:                 * take what's in goal_flags and try and set the device
                   5497:                 * toward that. Otherwise, if we're just refreshing the
                   5498:                 * current device state, get the current parameters.
                   5499:                 */
                   5500:
                   5501:                /*
                   5502:                 * Refresh overrides set
                   5503:                 */
                   5504:                if (sdp->isp_devparam[tgt].dev_refresh) {
                   5505:                        mbs.param[0] = MBOX_GET_TARGET_PARAMS;
                   5506:                        sdp->isp_devparam[tgt].dev_refresh = 0;
                   5507:                        get = 1;
                   5508:                } else if (sdp->isp_devparam[tgt].dev_update) {
                   5509:                        mbs.param[0] = MBOX_SET_TARGET_PARAMS;
                   5510:                        /*
                   5511:                         * Make sure goal_flags has "Renegotiate on Error"
                   5512:                         * on and "Freeze Queue on Error" off.
                   5513:                         */
                   5514:                        sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
                   5515:                        sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
                   5516:
                   5517:                        mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
                   5518:
                   5519:                        /*
                   5520:                         * Insist that PARITY must be enabled
                   5521:                         * if SYNC or WIDE is enabled.
                   5522:                         */
                   5523:                        if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
                   5524:                                mbs.param[2] |= DPARM_PARITY;
                   5525:                        }
                   5526:
                   5527:                        if ((mbs.param[2] & DPARM_SYNC) == 0) {
                   5528:                                mbs.param[3] = 0;
                   5529:                        } else {
                   5530:                                mbs.param[3] =
                   5531:                                    (sdp->isp_devparam[tgt].goal_offset << 8) |
                   5532:                                    (sdp->isp_devparam[tgt].goal_period);
                   5533:                        }
                   5534:                        /*
                   5535:                         * A command completion later that has
                   5536:                         * RQSTF_NEGOTIATION set can cause
                   5537:                         * the dev_refresh/announce cycle also.
                   5538:                         *
                   5539:                         * Note: It is really important to update our current
                   5540:                         * flags with at least the state of TAG capabilities-
                   5541:                         * otherwise we might try and send a tagged command
                   5542:                         * when we have it all turned off. So change it here
                   5543:                         * to say that current already matches goal.
                   5544:                         */
                   5545:                        sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
                   5546:                        sdp->isp_devparam[tgt].actv_flags |=
                   5547:                            (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
                   5548:                        isp_prt(isp, ISP_LOGDEBUG0,
                   5549:                            "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
                   5550:                            bus, tgt, mbs.param[2], mbs.param[3] >> 8,
                   5551:                            mbs.param[3] & 0xff);
                   5552:                        sdp->isp_devparam[tgt].dev_update = 0;
                   5553:                        sdp->isp_devparam[tgt].dev_refresh = 1;
                   5554:                        get = 0;
                   5555:                } else {
                   5556:                        continue;
                   5557:                }
                   5558:                mbs.param[1] = (bus << 15) | (tgt << 8);
                   5559:                isp_mboxcmd(isp, &mbs, MBLOGALL);
                   5560:                if (get == 0) {
                   5561:                        isp->isp_sendmarker |= (1 << bus);
                   5562:                        continue;
                   5563:                }
                   5564:                flags = mbs.param[2];
                   5565:                period = mbs.param[3] & 0xff;
                   5566:                offset = mbs.param[3] >> 8;
                   5567:                sdp->isp_devparam[tgt].actv_flags = flags;
                   5568:                sdp->isp_devparam[tgt].actv_period = period;
                   5569:                sdp->isp_devparam[tgt].actv_offset = offset;
                   5570:                get = (bus << 16) | tgt;
                   5571:                (void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get);
                   5572:        }
                   5573:
                   5574:        for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
                   5575:                if (sdp->isp_devparam[tgt].dev_update ||
                   5576:                    sdp->isp_devparam[tgt].dev_refresh) {
                   5577:                        isp->isp_update |= (1 << bus);
                   5578:                        break;
                   5579:                }
                   5580:        }
                   5581: }
                   5582:
                   5583: #ifndef        DEFAULT_FRAMESIZE
                   5584: #define        DEFAULT_FRAMESIZE(isp)          ICB_DFLT_FRMLEN
                   5585: #endif
                   5586: #ifndef        DEFAULT_EXEC_THROTTLE
                   5587: #define        DEFAULT_EXEC_THROTTLE(isp)      ISP_EXEC_THROTTLE
                   5588: #endif
                   5589:
                   5590: static void
                   5591: isp_setdfltparm(struct ispsoftc *isp, int channel)
                   5592: {
                   5593:        int tgt;
                   5594:        mbreg_t mbs;
                   5595:        sdparam *sdp;
                   5596:
                   5597:        if (IS_FC(isp)) {
                   5598:                fcparam *fcp = (fcparam *) isp->isp_param;
                   5599:                int nvfail;
                   5600:
                   5601:                fcp += channel;
                   5602:                if (fcp->isp_gotdparms) {
                   5603:                        return;
                   5604:                }
                   5605:                fcp->isp_gotdparms = 1;
                   5606:                fcp->isp_maxfrmlen = DEFAULT_FRAMESIZE(isp);
                   5607:                fcp->isp_maxalloc = ICB_DFLT_ALLOC;
                   5608:                fcp->isp_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
                   5609:                fcp->isp_retry_delay = ICB_DFLT_RDELAY;
                   5610:                fcp->isp_retry_count = ICB_DFLT_RCOUNT;
                   5611:                /* Platform specific.... */
                   5612:                fcp->isp_loopid = DEFAULT_LOOPID(isp);
                   5613:                fcp->isp_nodewwn = DEFAULT_NODEWWN(isp);
                   5614:                fcp->isp_portwwn = DEFAULT_PORTWWN(isp);
                   5615:                fcp->isp_fwoptions = 0;
                   5616:                fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
                   5617:                fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
                   5618:                fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
                   5619: #ifndef        ISP_NO_FASTPOST_FC
                   5620:                fcp->isp_fwoptions |= ICBOPT_FAST_POST;
                   5621: #endif
                   5622:                if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
                   5623:                        fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
                   5624:
                   5625:                /*
                   5626:                 * Make sure this is turned off now until we get
                   5627:                 * extended options from NVRAM
                   5628:                 */
                   5629:                fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
                   5630:
                   5631:                /*
                   5632:                 * Now try and read NVRAM unless told to not do so.
                   5633:                 * This will set fcparam's isp_nodewwn && isp_portwwn.
                   5634:                 */
                   5635:                if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
                   5636:                        nvfail = isp_read_nvram(isp);
                   5637:                        if (nvfail)
                   5638:                                isp->isp_confopts |= ISP_CFG_NONVRAM;
                   5639:                } else {
                   5640:                        nvfail = 1;
                   5641:                }
                   5642:                /*
                   5643:                 * Set node && port to override platform set defaults
                   5644:                 * unless the nvram read failed (or none was done),
                   5645:                 * or the platform code wants to use what had been
                   5646:                 * set in the defaults.
                   5647:                 */
                   5648:                if (nvfail) {
                   5649:                        isp->isp_confopts |= ISP_CFG_OWNWWPN|ISP_CFG_OWNWWNN;
                   5650:                }
                   5651:                if (isp->isp_confopts & ISP_CFG_OWNWWNN) {
                   5652:                        isp_prt(isp, ISP_LOGCONFIG, "Using Node WWN 0x%08x%08x",
                   5653:                            (u_int32_t) (DEFAULT_NODEWWN(isp) >> 32),
                   5654:                            (u_int32_t) (DEFAULT_NODEWWN(isp) & 0xffffffff));
                   5655:                        ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
                   5656:                } else {
                   5657:                        /*
                   5658:                         * We always start out with values derived
                   5659:                         * from NVRAM or our platform default.
                   5660:                         */
                   5661:                        ISP_NODEWWN(isp) = fcp->isp_nodewwn;
                   5662:                }
                   5663:                if (isp->isp_confopts & ISP_CFG_OWNWWPN) {
                   5664:                        isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x",
                   5665:                            (u_int32_t) (DEFAULT_PORTWWN(isp) >> 32),
                   5666:                            (u_int32_t) (DEFAULT_PORTWWN(isp) & 0xffffffff));
                   5667:                        ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
                   5668:                } else {
                   5669:                        /*
                   5670:                         * We always start out with values derived
                   5671:                         * from NVRAM or our platform default.
                   5672:                         */
                   5673:                        ISP_PORTWWN(isp) = fcp->isp_portwwn;
                   5674:                }
                   5675:                return;
                   5676:        }
                   5677:
                   5678:        sdp = (sdparam *) isp->isp_param;
                   5679:        sdp += channel;
                   5680:
                   5681:        /*
                   5682:         * Been there, done that, got the T-shirt...
                   5683:         */
                   5684:        if (sdp->isp_gotdparms) {
                   5685:                return;
                   5686:        }
                   5687:        sdp->isp_gotdparms = 1;
                   5688:
                   5689:        /*
                   5690:         * Establish some default parameters.
                   5691:         */
                   5692:        sdp->isp_cmd_dma_burst_enable = 0;
                   5693:        sdp->isp_data_dma_burst_enabl = 1;
                   5694:        sdp->isp_fifo_threshold = 0;
                   5695:        sdp->isp_initiator_id = DEFAULT_IID(isp);
                   5696:        if (isp->isp_type >= ISP_HA_SCSI_1040) {
                   5697:                sdp->isp_async_data_setup = 9;
                   5698:        } else {
                   5699:                sdp->isp_async_data_setup = 6;
                   5700:        }
                   5701:        sdp->isp_selection_timeout = 250;
                   5702:        sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
                   5703:        sdp->isp_tag_aging = 8;
                   5704:        sdp->isp_bus_reset_delay = 5;
                   5705:        /*
                   5706:         * Don't retry selection, busy or queue full automatically- reflect
                   5707:         * these back to us.
                   5708:         */
                   5709:        sdp->isp_retry_count = 0;
                   5710:        sdp->isp_retry_delay = 0;
                   5711:
                   5712:        for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
                   5713:                sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
                   5714:                sdp->isp_devparam[tgt].dev_enable = 1;
                   5715:        }
                   5716:
                   5717:        /*
                   5718:         * If we've not been told to avoid reading NVRAM, try and read it.
                   5719:         * If we're successful reading it, we can then return because NVRAM
                   5720:         * will tell us what the desired settings are. Otherwise, we establish
                   5721:         * some reasonable 'fake' nvram and goal defaults.
                   5722:         */
                   5723:
                   5724:        if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
                   5725:                if (isp_read_nvram(isp) == 0) {
                   5726:                        return;
                   5727:                }
                   5728:        }
                   5729:
                   5730:        /*
                   5731:         * Now try and see whether we have specific values for them.
                   5732:         */
                   5733:        if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
                   5734:                mbs.param[0] = MBOX_GET_ACT_NEG_STATE;
                   5735:                isp_mboxcmd(isp, &mbs, MBLOGNONE);
                   5736:                if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                   5737:                        sdp->isp_req_ack_active_neg = 1;
                   5738:                        sdp->isp_data_line_active_neg = 1;
                   5739:                } else {
                   5740:                        sdp->isp_req_ack_active_neg =
                   5741:                            (mbs.param[1+channel] >> 4) & 0x1;
                   5742:                        sdp->isp_data_line_active_neg =
                   5743:                            (mbs.param[1+channel] >> 5) & 0x1;
                   5744:                }
                   5745:        }
                   5746:
                   5747:        isp_prt(isp, ISP_LOGDEBUG0, sc0, sc3,
                   5748:            0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
                   5749:            sdp->isp_bus_reset_delay, sdp->isp_retry_count,
                   5750:            sdp->isp_retry_delay, sdp->isp_async_data_setup);
                   5751:        isp_prt(isp, ISP_LOGDEBUG0, sc1, sc3,
                   5752:            sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
                   5753:            sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
                   5754:            sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
                   5755:
                   5756:        /*
                   5757:         * The trick here is to establish a default for the default (honk!)
                   5758:         * state (goal_flags). Then try and get the current status from
                   5759:         * the card to fill in the current state. We don't, in fact, set
                   5760:         * the default to the SAFE default state- that's not the goal state.
                   5761:         */
                   5762:        for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
                   5763:                u_int8_t off, per;
                   5764:                sdp->isp_devparam[tgt].actv_offset = 0;
                   5765:                sdp->isp_devparam[tgt].actv_period = 0;
                   5766:                sdp->isp_devparam[tgt].actv_flags = 0;
                   5767:
                   5768:                sdp->isp_devparam[tgt].goal_flags =
                   5769:                    sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
                   5770:
                   5771:                /*
                   5772:                 * We default to Wide/Fast for versions less than a 1040
                   5773:                 * (unless its SBus).
                   5774:                 */
                   5775:                if (IS_ULTRA3(isp)) {
                   5776:                        off = ISP_80M_SYNCPARMS >> 8;
                   5777:                        per = ISP_80M_SYNCPARMS & 0xff;
                   5778:                } else if (IS_ULTRA2(isp)) {
                   5779:                        off = ISP_40M_SYNCPARMS >> 8;
                   5780:                        per = ISP_40M_SYNCPARMS & 0xff;
                   5781:                } else if (IS_1240(isp)) {
                   5782:                        off = ISP_20M_SYNCPARMS >> 8;
                   5783:                        per = ISP_20M_SYNCPARMS & 0xff;
                   5784:                } else if ((isp->isp_bustype == ISP_BT_SBUS &&
                   5785:                    isp->isp_type < ISP_HA_SCSI_1020A) ||
                   5786:                    (isp->isp_bustype == ISP_BT_PCI &&
                   5787:                    isp->isp_type < ISP_HA_SCSI_1040) ||
                   5788:                    (isp->isp_clock && isp->isp_clock < 60) ||
                   5789:                    (sdp->isp_ultramode == 0)) {
                   5790:                        off = ISP_10M_SYNCPARMS >> 8;
                   5791:                        per = ISP_10M_SYNCPARMS & 0xff;
                   5792:                } else {
                   5793:                        off = ISP_20M_SYNCPARMS_1040 >> 8;
                   5794:                        per = ISP_20M_SYNCPARMS_1040 & 0xff;
                   5795:                }
                   5796:                sdp->isp_devparam[tgt].goal_offset =
                   5797:                    sdp->isp_devparam[tgt].nvrm_offset = off;
                   5798:                sdp->isp_devparam[tgt].goal_period =
                   5799:                    sdp->isp_devparam[tgt].nvrm_period = per;
                   5800:
                   5801:                isp_prt(isp, ISP_LOGDEBUG0, sc2, sc3,
                   5802:                    channel, tgt, sdp->isp_devparam[tgt].nvrm_flags,
                   5803:                    sdp->isp_devparam[tgt].nvrm_offset,
                   5804:                    sdp->isp_devparam[tgt].nvrm_period);
                   5805:        }
                   5806: }
                   5807:
                   5808: /*
                   5809:  * Re-initialize the ISP and complete all orphaned commands
                   5810:  * with a 'botched' notice. The reset/init routines should
                   5811:  * not disturb an already active list of commands.
                   5812:  *
                   5813:  * Locks held prior to coming here.
                   5814:  */
                   5815:
                   5816: void
                   5817: isp_reinit(struct ispsoftc *isp)
                   5818: {
                   5819:        XS_T *xs;
                   5820:        u_int16_t handle;
                   5821:
                   5822:        isp_reset(isp);
                   5823:        if (isp->isp_state != ISP_RESETSTATE) {
                   5824:                isp_prt(isp, ISP_LOGERR, "isp_reinit cannot reset card");
                   5825:        } else if (isp->isp_role != ISP_ROLE_NONE) {
                   5826:                isp_init(isp);
                   5827:                if (isp->isp_state == ISP_INITSTATE) {
                   5828:                        isp->isp_state = ISP_RUNSTATE;
                   5829:                }
                   5830:                if (isp->isp_state != ISP_RUNSTATE) {
                   5831:                        isp_prt(isp, ISP_LOGERR,
                   5832:                            "isp_reinit cannot restart card");
                   5833:                }
                   5834:        }
                   5835:        isp->isp_nactive = 0;
                   5836:
                   5837:        for (handle = 1; (int) handle <= isp->isp_maxcmds; handle++) {
                   5838:                xs = isp_find_xs(isp, handle);
                   5839:                if (xs == NULL) {
                   5840:                        continue;
                   5841:                }
                   5842:                isp_destroy_handle(isp, handle);
                   5843:                if (XS_XFRLEN(xs)) {
                   5844:                        ISP_DMAFREE(isp, xs, handle);
                   5845:                        XS_RESID(xs) = XS_XFRLEN(xs);
                   5846:                } else {
                   5847:                        XS_RESID(xs) = 0;
                   5848:                }
                   5849:                XS_SETERR(xs, HBA_BUSRESET);
                   5850:                isp_done(xs);
                   5851:        }
                   5852: }
                   5853:
                   5854: /*
                   5855:  * NVRAM Routines
                   5856:  */
                   5857: static int
                   5858: isp_read_nvram(struct ispsoftc *isp)
                   5859: {
                   5860:        int i, amt;
                   5861:        u_int8_t csum, minversion;
                   5862:        union {
                   5863:                u_int8_t _x[ISP2100_NVRAM_SIZE];
                   5864:                u_int16_t _s[ISP2100_NVRAM_SIZE>>1];
                   5865:        } _n;
                   5866: #define        nvram_data      _n._x
                   5867: #define        nvram_words     _n._s
                   5868:
                   5869:        if (IS_FC(isp)) {
                   5870:                amt = ISP2100_NVRAM_SIZE;
                   5871:                minversion = 1;
                   5872:        } else if (IS_ULTRA2(isp)) {
                   5873:                amt = ISP1080_NVRAM_SIZE;
                   5874:                minversion = 0;
                   5875:        } else {
                   5876:                amt = ISP_NVRAM_SIZE;
                   5877:                minversion = 2;
                   5878:        }
                   5879:
                   5880:        /*
                   5881:         * Just read the first two words first to see if we have a valid
                   5882:         * NVRAM to continue reading the rest with.
                   5883:         */
                   5884:        for (i = 0; i < 2; i++) {
                   5885:                isp_rdnvram_word(isp, i, &nvram_words[i]);
                   5886:        }
                   5887:        if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
                   5888:            nvram_data[2] != 'P') {
                   5889:                if (isp->isp_bustype != ISP_BT_SBUS) {
                   5890:                        isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
                   5891:                        isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
                   5892:                            nvram_data[0], nvram_data[1], nvram_data[2]);
                   5893:                }
                   5894:                return (-1);
                   5895:        }
                   5896:        for (i = 2; i < amt>>1; i++) {
                   5897:                isp_rdnvram_word(isp, i, &nvram_words[i]);
                   5898:        }
                   5899:        for (csum = 0, i = 0; i < amt; i++) {
                   5900:                csum += nvram_data[i];
                   5901:        }
                   5902:        if (csum != 0) {
                   5903:                isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
                   5904:                return (-1);
                   5905:        }
                   5906:        if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
                   5907:                isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
                   5908:                    ISP_NVRAM_VERSION(nvram_data));
                   5909:                return (-1);
                   5910:        }
                   5911:
                   5912:        if (IS_ULTRA3(isp)) {
                   5913:                isp_parse_nvram_12160(isp, 0, nvram_data);
                   5914:                if (IS_12160(isp))
                   5915:                        isp_parse_nvram_12160(isp, 1, nvram_data);
                   5916:        } else if (IS_1080(isp)) {
                   5917:                isp_parse_nvram_1080(isp, 0, nvram_data);
                   5918:        } else if (IS_1280(isp) || IS_1240(isp)) {
                   5919:                isp_parse_nvram_1080(isp, 0, nvram_data);
                   5920:                isp_parse_nvram_1080(isp, 1, nvram_data);
                   5921:        } else if (IS_SCSI(isp)) {
                   5922:                isp_parse_nvram_1020(isp, nvram_data);
                   5923:        } else {
                   5924:                isp_parse_nvram_2100(isp, nvram_data);
                   5925:        }
                   5926:        return (0);
                   5927: #undef nvram_data
                   5928: #undef nvram_words
                   5929: }
                   5930:
                   5931: static void
                   5932: isp_rdnvram_word(struct ispsoftc *isp, int wo, u_int16_t *rp)
                   5933: {
                   5934:        int i, cbits;
                   5935:        u_int16_t bit, rqst;
                   5936:
                   5937:        ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
                   5938:        USEC_DELAY(2);
                   5939:        ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
                   5940:        USEC_DELAY(2);
                   5941:
                   5942:        if (IS_FC(isp)) {
                   5943:                wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
                   5944:                if (IS_2312(isp) && isp->isp_port) {
                   5945:                        wo += 128;
                   5946:                }
                   5947:                rqst = (ISP_NVRAM_READ << 8) | wo;
                   5948:                cbits = 10;
                   5949:        } else if (IS_ULTRA2(isp)) {
                   5950:                wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
                   5951:                rqst = (ISP_NVRAM_READ << 8) | wo;
                   5952:                cbits = 10;
                   5953:        } else {
                   5954:                wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
                   5955:                rqst = (ISP_NVRAM_READ << 6) | wo;
                   5956:                cbits = 8;
                   5957:        }
                   5958:
                   5959:        /*
                   5960:         * Clock the word select request out...
                   5961:         */
                   5962:        for (i = cbits; i >= 0; i--) {
                   5963:                if ((rqst >> i) & 1) {
                   5964:                        bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
                   5965:                } else {
                   5966:                        bit = BIU_NVRAM_SELECT;
                   5967:                }
                   5968:                ISP_WRITE(isp, BIU_NVRAM, bit);
                   5969:                USEC_DELAY(2);
                   5970:                ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
                   5971:                USEC_DELAY(2);
                   5972:                ISP_WRITE(isp, BIU_NVRAM, bit);
                   5973:                USEC_DELAY(2);
                   5974:        }
                   5975:        /*
                   5976:         * Now read the result back in (bits come back in MSB format).
                   5977:         */
                   5978:        *rp = 0;
                   5979:        for (i = 0; i < 16; i++) {
                   5980:                u_int16_t rv;
                   5981:                *rp <<= 1;
                   5982:                ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
                   5983:                USEC_DELAY(2);
                   5984:                rv = ISP_READ(isp, BIU_NVRAM);
                   5985:                if (rv & BIU_NVRAM_DATAIN) {
                   5986:                        *rp |= 1;
                   5987:                }
                   5988:                USEC_DELAY(2);
                   5989:                ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
                   5990:                USEC_DELAY(2);
                   5991:        }
                   5992:        ISP_WRITE(isp, BIU_NVRAM, 0);
                   5993:        USEC_DELAY(2);
                   5994:        ISP_SWIZZLE_NVRAM_WORD(isp, rp);
                   5995: }
                   5996:
                   5997: static void
                   5998: isp_parse_nvram_1020(struct ispsoftc *isp, u_int8_t *nvram_data)
                   5999: {
                   6000:        sdparam *sdp = (sdparam *) isp->isp_param;
                   6001:        int tgt;
                   6002:
                   6003:        sdp->isp_fifo_threshold =
                   6004:                ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
                   6005:                (ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
                   6006:
                   6007:        if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
                   6008:                sdp->isp_initiator_id =
                   6009:                        ISP_NVRAM_INITIATOR_ID(nvram_data);
                   6010:
                   6011:        sdp->isp_bus_reset_delay =
                   6012:                ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
                   6013:
                   6014:        sdp->isp_retry_count =
                   6015:                ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
                   6016:
                   6017:        sdp->isp_retry_delay =
                   6018:                ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
                   6019:
                   6020:        sdp->isp_async_data_setup =
                   6021:                ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
                   6022:
                   6023:        if (isp->isp_type >= ISP_HA_SCSI_1040) {
                   6024:                if (sdp->isp_async_data_setup < 9) {
                   6025:                        sdp->isp_async_data_setup = 9;
                   6026:                }
                   6027:        } else {
                   6028:                if (sdp->isp_async_data_setup != 6) {
                   6029:                        sdp->isp_async_data_setup = 6;
                   6030:                }
                   6031:        }
                   6032:
                   6033:        sdp->isp_req_ack_active_neg =
                   6034:                ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
                   6035:
                   6036:        sdp->isp_data_line_active_neg =
                   6037:                ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
                   6038:
                   6039:        sdp->isp_data_dma_burst_enabl =
                   6040:                ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
                   6041:
                   6042:        sdp->isp_cmd_dma_burst_enable =
                   6043:                ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
                   6044:
                   6045:        sdp->isp_tag_aging =
                   6046:                ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
                   6047:
                   6048:        sdp->isp_selection_timeout =
                   6049:                ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
                   6050:
                   6051:        sdp->isp_max_queue_depth =
                   6052:                ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
                   6053:
                   6054:        sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
                   6055:
                   6056:        isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
                   6057:            0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
                   6058:            sdp->isp_bus_reset_delay, sdp->isp_retry_count,
                   6059:            sdp->isp_retry_delay, sdp->isp_async_data_setup);
                   6060:        isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
                   6061:            sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
                   6062:            sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
                   6063:            sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
                   6064:
                   6065:        for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
                   6066:                sdp->isp_devparam[tgt].dev_enable =
                   6067:                        ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
                   6068:                sdp->isp_devparam[tgt].exc_throttle =
                   6069:                        ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
                   6070:                sdp->isp_devparam[tgt].nvrm_offset =
                   6071:                        ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
                   6072:                sdp->isp_devparam[tgt].nvrm_period =
                   6073:                        ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
                   6074:                /*
                   6075:                 * We probably shouldn't lie about this, but it
                   6076:                 * it makes it much safer if we limit NVRAM values
                   6077:                 * to sanity.
                   6078:                 */
                   6079:                if (isp->isp_type < ISP_HA_SCSI_1040) {
                   6080:                        /*
                   6081:                         * If we're not ultra, we can't possibly
                   6082:                         * be a shorter period than this.
                   6083:                         */
                   6084:                        if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
                   6085:                                sdp->isp_devparam[tgt].nvrm_period = 0x19;
                   6086:                        }
                   6087:                        if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
                   6088:                                sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
                   6089:                        }
                   6090:                } else {
                   6091:                        if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
                   6092:                                sdp->isp_devparam[tgt].nvrm_offset = 0x8;
                   6093:                        }
                   6094:                }
                   6095:                sdp->isp_devparam[tgt].nvrm_flags = 0;
                   6096:                if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
                   6097:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
                   6098:                sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
                   6099:                if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
                   6100:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
                   6101:                if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
                   6102:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
                   6103:                if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
                   6104:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
                   6105:                if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
                   6106:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
                   6107:                if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
                   6108:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
                   6109:                sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
                   6110:                isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
                   6111:                    0, tgt, sdp->isp_devparam[tgt].nvrm_flags,
                   6112:                    sdp->isp_devparam[tgt].nvrm_offset,
                   6113:                    sdp->isp_devparam[tgt].nvrm_period);
                   6114:                sdp->isp_devparam[tgt].goal_offset =
                   6115:                    sdp->isp_devparam[tgt].nvrm_offset;
                   6116:                sdp->isp_devparam[tgt].goal_period =
                   6117:                    sdp->isp_devparam[tgt].nvrm_period;
                   6118:                sdp->isp_devparam[tgt].goal_flags =
                   6119:                    sdp->isp_devparam[tgt].nvrm_flags;
                   6120:        }
                   6121: }
                   6122:
                   6123: static void
                   6124: isp_parse_nvram_1080(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
                   6125: {
                   6126:        sdparam *sdp = (sdparam *) isp->isp_param;
                   6127:        int tgt;
                   6128:
                   6129:        sdp += bus;
                   6130:
                   6131:        sdp->isp_fifo_threshold =
                   6132:            ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
                   6133:
                   6134:        if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
                   6135:                sdp->isp_initiator_id =
                   6136:                    ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
                   6137:
                   6138:        sdp->isp_bus_reset_delay =
                   6139:            ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
                   6140:
                   6141:        sdp->isp_retry_count =
                   6142:            ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
                   6143:
                   6144:        sdp->isp_retry_delay =
                   6145:            ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
                   6146:
                   6147:        sdp->isp_async_data_setup =
                   6148:            ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
                   6149:
                   6150:        sdp->isp_req_ack_active_neg =
                   6151:            ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
                   6152:
                   6153:        sdp->isp_data_line_active_neg =
                   6154:            ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
                   6155:
                   6156:        sdp->isp_data_dma_burst_enabl =
                   6157:            ISP1080_NVRAM_BURST_ENABLE(nvram_data);
                   6158:
                   6159:        sdp->isp_cmd_dma_burst_enable =
                   6160:            ISP1080_NVRAM_BURST_ENABLE(nvram_data);
                   6161:
                   6162:        sdp->isp_selection_timeout =
                   6163:            ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
                   6164:
                   6165:        sdp->isp_max_queue_depth =
                   6166:             ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
                   6167:
                   6168:        isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
                   6169:            bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
                   6170:            sdp->isp_bus_reset_delay, sdp->isp_retry_count,
                   6171:            sdp->isp_retry_delay, sdp->isp_async_data_setup);
                   6172:        isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
                   6173:            sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
                   6174:            sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
                   6175:            sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
                   6176:
                   6177:
                   6178:        for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
                   6179:                sdp->isp_devparam[tgt].dev_enable =
                   6180:                    ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
                   6181:                sdp->isp_devparam[tgt].exc_throttle =
                   6182:                        ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
                   6183:                sdp->isp_devparam[tgt].nvrm_offset =
                   6184:                        ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
                   6185:                sdp->isp_devparam[tgt].nvrm_period =
                   6186:                        ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
                   6187:                sdp->isp_devparam[tgt].nvrm_flags = 0;
                   6188:                if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
                   6189:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
                   6190:                sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
                   6191:                if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
                   6192:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
                   6193:                if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
                   6194:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
                   6195:                if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
                   6196:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
                   6197:                if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
                   6198:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
                   6199:                if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
                   6200:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
                   6201:                sdp->isp_devparam[tgt].actv_flags = 0;
                   6202:                isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
                   6203:                    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
                   6204:                    sdp->isp_devparam[tgt].nvrm_offset,
                   6205:                    sdp->isp_devparam[tgt].nvrm_period);
                   6206:                sdp->isp_devparam[tgt].goal_offset =
                   6207:                    sdp->isp_devparam[tgt].nvrm_offset;
                   6208:                sdp->isp_devparam[tgt].goal_period =
                   6209:                    sdp->isp_devparam[tgt].nvrm_period;
                   6210:                sdp->isp_devparam[tgt].goal_flags =
                   6211:                    sdp->isp_devparam[tgt].nvrm_flags;
                   6212:        }
                   6213: }
                   6214:
                   6215: static void
                   6216: isp_parse_nvram_12160(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
                   6217: {
                   6218:        sdparam *sdp = (sdparam *) isp->isp_param;
                   6219:        int tgt;
                   6220:
                   6221:        sdp += bus;
                   6222:
                   6223:        sdp->isp_fifo_threshold =
                   6224:            ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
                   6225:
                   6226:        if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
                   6227:                sdp->isp_initiator_id =
                   6228:                    ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
                   6229:
                   6230:        sdp->isp_bus_reset_delay =
                   6231:            ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
                   6232:
                   6233:        sdp->isp_retry_count =
                   6234:            ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
                   6235:
                   6236:        sdp->isp_retry_delay =
                   6237:            ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
                   6238:
                   6239:        sdp->isp_async_data_setup =
                   6240:            ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
                   6241:
                   6242:        sdp->isp_req_ack_active_neg =
                   6243:            ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
                   6244:
                   6245:        sdp->isp_data_line_active_neg =
                   6246:            ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
                   6247:
                   6248:        sdp->isp_data_dma_burst_enabl =
                   6249:            ISP12160_NVRAM_BURST_ENABLE(nvram_data);
                   6250:
                   6251:        sdp->isp_cmd_dma_burst_enable =
                   6252:            ISP12160_NVRAM_BURST_ENABLE(nvram_data);
                   6253:
                   6254:        sdp->isp_selection_timeout =
                   6255:            ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
                   6256:
                   6257:        sdp->isp_max_queue_depth =
                   6258:             ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
                   6259:
                   6260:        isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
                   6261:            bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
                   6262:            sdp->isp_bus_reset_delay, sdp->isp_retry_count,
                   6263:            sdp->isp_retry_delay, sdp->isp_async_data_setup);
                   6264:        isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
                   6265:            sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
                   6266:            sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
                   6267:            sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
                   6268:
                   6269:        for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
                   6270:                sdp->isp_devparam[tgt].dev_enable =
                   6271:                    ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
                   6272:                sdp->isp_devparam[tgt].exc_throttle =
                   6273:                        ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
                   6274:                sdp->isp_devparam[tgt].nvrm_offset =
                   6275:                        ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
                   6276:                sdp->isp_devparam[tgt].nvrm_period =
                   6277:                        ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
                   6278:                sdp->isp_devparam[tgt].nvrm_flags = 0;
                   6279:                if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
                   6280:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
                   6281:                sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
                   6282:                if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
                   6283:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
                   6284:                if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
                   6285:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
                   6286:                if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
                   6287:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
                   6288:                if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
                   6289:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
                   6290:                if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
                   6291:                        sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
                   6292:                sdp->isp_devparam[tgt].actv_flags = 0;
                   6293:                isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
                   6294:                    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
                   6295:                    sdp->isp_devparam[tgt].nvrm_offset,
                   6296:                    sdp->isp_devparam[tgt].nvrm_period);
                   6297:                sdp->isp_devparam[tgt].goal_offset =
                   6298:                    sdp->isp_devparam[tgt].nvrm_offset;
                   6299:                sdp->isp_devparam[tgt].goal_period =
                   6300:                    sdp->isp_devparam[tgt].nvrm_period;
                   6301:                sdp->isp_devparam[tgt].goal_flags =
                   6302:                    sdp->isp_devparam[tgt].nvrm_flags;
                   6303:        }
                   6304: }
                   6305:
                   6306: static void
                   6307: isp_parse_nvram_2100(struct ispsoftc *isp, u_int8_t *nvram_data)
                   6308: {
                   6309:        fcparam *fcp = (fcparam *) isp->isp_param;
                   6310:        u_int64_t wwn;
                   6311:
                   6312:        /*
                   6313:         * There is NVRAM storage for both Port and Node entities-
                   6314:         * but the Node entity appears to be unused on all the cards
                   6315:         * I can find. However, we should account for this being set
                   6316:         * at some point in the future.
                   6317:         *
                   6318:         * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
                   6319:         * bits 48..60. In the case of the 2202, it appears that they do
                   6320:         * use bit 48 to distinguish between the two instances on the card.
                   6321:         * The 2204, which I've never seen, *probably* extends this method.
                   6322:         */
                   6323:        wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
                   6324:        if (wwn) {
                   6325:                isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
                   6326:                    (u_int32_t) (wwn >> 32), (u_int32_t) (wwn & 0xffffffff));
                   6327:                if ((wwn >> 60) == 0) {
                   6328:                        wwn |= (((u_int64_t) 2)<< 60);
                   6329:                }
                   6330:        }
                   6331:        fcp->isp_portwwn = wwn;
                   6332:        if (IS_2200(isp) || IS_23XX(isp)) {
                   6333:                wwn = ISP2200_NVRAM_NODE_NAME(nvram_data);
                   6334:                if (wwn) {
                   6335:                        isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
                   6336:                            (u_int32_t) (wwn >> 32),
                   6337:                            (u_int32_t) (wwn & 0xffffffff));
                   6338:                        if ((wwn >> 60) == 0) {
                   6339:                                wwn |= (((u_int64_t) 2)<< 60);
                   6340:                        }
                   6341:                }
                   6342:        } else {
                   6343:                wwn &= ~((u_int64_t) 0xfff << 48);
                   6344:        }
                   6345:        fcp->isp_nodewwn = wwn;
                   6346:
                   6347:        /*
                   6348:         * Make sure we have both Node and Port as non-zero values.
                   6349:         */
                   6350:        if (fcp->isp_nodewwn != 0 && fcp->isp_portwwn == 0) {
                   6351:                fcp->isp_portwwn = fcp->isp_nodewwn;
                   6352:        } else if (fcp->isp_nodewwn == 0 && fcp->isp_portwwn != 0) {
                   6353:                fcp->isp_nodewwn = fcp->isp_portwwn;
                   6354:        }
                   6355:
                   6356:        /*
                   6357:         * Make the Node and Port values sane if they're NAA == 2.
                   6358:         * This means to clear bits 48..56 for the Node WWN and
                   6359:         * make sure that there's some non-zero value in 48..56
                   6360:         * for the Port WWN.
                   6361:         */
                   6362:        if (fcp->isp_nodewwn && fcp->isp_portwwn) {
                   6363:                if ((fcp->isp_nodewwn & (((u_int64_t) 0xfff) << 48)) != 0 &&
                   6364:                    (fcp->isp_nodewwn >> 60) == 2) {
                   6365:                        fcp->isp_nodewwn &= ~((u_int64_t) 0xfff << 48);
                   6366:                }
                   6367:                if ((fcp->isp_portwwn & (((u_int64_t) 0xfff) << 48)) == 0 &&
                   6368:                    (fcp->isp_portwwn >> 60) == 2) {
                   6369:                        fcp->isp_portwwn |= ((u_int64_t) 1 << 56);
                   6370:                }
                   6371:        }
                   6372:
                   6373:        isp_prt(isp, ISP_LOGDEBUG0,
                   6374:            "NVRAM: maxfrmlen %d execthrottle %d fwoptions 0x%x loopid %x",
                   6375:            ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data),
                   6376:            ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
                   6377:            ISP2100_NVRAM_OPTIONS(nvram_data),
                   6378:            ISP2100_NVRAM_HARDLOOPID(nvram_data));
                   6379:
                   6380:        fcp->isp_maxalloc =
                   6381:                ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
                   6382:        if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0)
                   6383:                fcp->isp_maxfrmlen =
                   6384:                        ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
                   6385:        fcp->isp_retry_delay =
                   6386:                ISP2100_NVRAM_RETRY_DELAY(nvram_data);
                   6387:        fcp->isp_retry_count =
                   6388:                ISP2100_NVRAM_RETRY_COUNT(nvram_data);
                   6389:        if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
                   6390:                fcp->isp_loopid =
                   6391:                        ISP2100_NVRAM_HARDLOOPID(nvram_data);
                   6392:        if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0)
                   6393:                fcp->isp_execthrottle =
                   6394:                        ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
                   6395:        fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
                   6396: }
                   6397:
                   6398: #ifdef ISP_FW_CRASH_DUMP
                   6399: static void isp2200_fw_dump(struct ispsoftc *);
                   6400: static void isp2300_fw_dump(struct ispsoftc *);
                   6401:
                   6402: static void
                   6403: isp2200_fw_dump(struct ispsoftc *isp)
                   6404: {
                   6405:        int i, j;
                   6406:        mbreg_t mbs;
                   6407:        u_int16_t *ptr;
                   6408:
                   6409:        ptr = FCPARAM(isp)->isp_dump_data;
                   6410:        if (ptr == NULL) {
                   6411:                isp_prt(isp, ISP_LOGERR,
                   6412:                   "No place to dump RISC registers and SRAM");
                   6413:                return;
                   6414:        }
                   6415:        if (*ptr++) {
                   6416:                isp_prt(isp, ISP_LOGERR,
                   6417:                   "dump area for RISC registers and SRAM already used");
                   6418:                return;
                   6419:        }
                   6420:        ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
                   6421:        for (i = 0; i < 100; i++) {
                   6422:                USEC_DELAY(100);
                   6423:                if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
                   6424:                        break;
                   6425:                }
                   6426:        }
                   6427:        if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
                   6428:                /*
                   6429:                 * PBIU Registers
                   6430:                 */
                   6431:                for (i = 0; i < 8; i++) {
                   6432:                        *ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
                   6433:                }
                   6434:
                   6435:                /*
                   6436:                 * Mailbox Registers
                   6437:                 */
                   6438:                for (i = 0; i < 8; i++) {
                   6439:                        *ptr++ = ISP_READ(isp, MBOX_BLOCK + (i << 1));
                   6440:                }
                   6441:
                   6442:                /*
                   6443:                 * DMA Registers
                   6444:                 */
                   6445:                for (i = 0; i < 48; i++) {
                   6446:                        *ptr++ = ISP_READ(isp, DMA_BLOCK + 0x20 + (i << 1));
                   6447:                }
                   6448:
                   6449:                /*
                   6450:                 * RISC H/W Registers
                   6451:                 */
                   6452:                ISP_WRITE(isp, BIU2100_CSR, 0);
                   6453:                for (i = 0; i < 16; i++) {
                   6454:                        *ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
                   6455:                }
                   6456:
                   6457:                /*
                   6458:                 * RISC GP Registers
                   6459:                 */
                   6460:                for (j = 0; j < 8; j++) {
                   6461:                        ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 8));
                   6462:                        for (i = 0; i < 16; i++) {
                   6463:                                *ptr++ =
                   6464:                                    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
                   6465:                        }
                   6466:                }
                   6467:
                   6468:                /*
                   6469:                 * Frame Buffer Hardware Registers
                   6470:                 */
                   6471:                ISP_WRITE(isp, BIU2100_CSR, 0x10);
                   6472:                for (i = 0; i < 16; i++) {
                   6473:                        *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
                   6474:                }
                   6475:
                   6476:                /*
                   6477:                 * Fibre Protocol Module 0 Hardware Registers
                   6478:                 */
                   6479:                ISP_WRITE(isp, BIU2100_CSR, 0x20);
                   6480:                for (i = 0; i < 64; i++) {
                   6481:                        *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
                   6482:                }
                   6483:
                   6484:                /*
                   6485:                 * Fibre Protocol Module 1 Hardware Registers
                   6486:                 */
                   6487:                ISP_WRITE(isp, BIU2100_CSR, 0x30);
                   6488:                for (i = 0; i < 64; i++) {
                   6489:                        *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
                   6490:                }
                   6491:        } else {
                   6492:                isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
                   6493:                return;
                   6494:        }
                   6495:        isp_prt(isp, ISP_LOGALL,
                   6496:           "isp_fw_dump: RISC registers dumped successfully");
                   6497:        ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
                   6498:        for (i = 0; i < 100; i++) {
                   6499:                USEC_DELAY(100);
                   6500:                if (ISP_READ(isp, OUTMAILBOX0) == 0) {
                   6501:                        break;
                   6502:                }
                   6503:        }
                   6504:        if (ISP_READ(isp, OUTMAILBOX0) != 0) {
                   6505:                isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
                   6506:                return;
                   6507:        }
                   6508:        ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
                   6509:        for (i = 0; i < 100; i++) {
                   6510:                USEC_DELAY(100);
                   6511:                if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
                   6512:                        break;
                   6513:                }
                   6514:        }
                   6515:        if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
                   6516:                isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause After Reset");
                   6517:                return;
                   6518:        }
                   6519:        ISP_WRITE(isp, RISC_EMB, 0xf2);
                   6520:        ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
                   6521:        for (i = 0; i < 100; i++) {
                   6522:                USEC_DELAY(100);
                   6523:                if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
                   6524:                        break;
                   6525:                }
                   6526:        }
                   6527:        ENABLE_INTS(isp);
                   6528:        mbs.param[0] = MBOX_READ_RAM_WORD;
                   6529:        mbs.param[1] = 0x1000;
                   6530:        isp->isp_mbxworkp = (void *) ptr;
                   6531:        isp->isp_mbxwrk0 = 0xefff;      /* continuation count */
                   6532:        isp->isp_mbxwrk1 = 0x1001;      /* next SRAM address */
                   6533:        isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
                   6534:        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                   6535:                isp_prt(isp, ISP_LOGWARN,
                   6536:                    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
                   6537:                return;
                   6538:        }
                   6539:        ptr = isp->isp_mbxworkp;        /* finish fetch of final word */
                   6540:        *ptr++ = isp->isp_mboxtmp[2];
                   6541:        isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped successfully");
                   6542:        FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
                   6543:        (void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
                   6544: }
                   6545:
                   6546: static void
                   6547: isp2300_fw_dump(struct ispsoftc *isp)
                   6548: {
                   6549:        int i, j;
                   6550:        mbreg_t mbs;
                   6551:        u_int16_t *ptr;
                   6552:
                   6553:        ptr = FCPARAM(isp)->isp_dump_data;
                   6554:        if (ptr == NULL) {
                   6555:                isp_prt(isp, ISP_LOGERR,
                   6556:                   "No place to dump RISC registers and SRAM");
                   6557:                return;
                   6558:        }
                   6559:        if (*ptr++) {
                   6560:                isp_prt(isp, ISP_LOGERR,
                   6561:                   "dump area for RISC registers and SRAM already used");
                   6562:                return;
                   6563:        }
                   6564:        ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
                   6565:        for (i = 0; i < 100; i++) {
                   6566:                USEC_DELAY(100);
                   6567:                if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
                   6568:                        break;
                   6569:                }
                   6570:        }
                   6571:        if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
                   6572:                /*
                   6573:                 * PBIU registers
                   6574:                 */
                   6575:                for (i = 0; i < 8; i++) {
                   6576:                        *ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
                   6577:                }
                   6578:
                   6579:                /*
                   6580:                 * ReqQ-RspQ-Risc2Host Status registers
                   6581:                 */
                   6582:                for (i = 0; i < 8; i++) {
                   6583:                        *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x10 + (i << 1));
                   6584:                }
                   6585:
                   6586:                /*
                   6587:                 * Mailbox Registers
                   6588:                 */
                   6589:                for (i = 0; i < 32; i++) {
                   6590:                        *ptr++ =
                   6591:                            ISP_READ(isp, PCI_MBOX_REGS2300_OFF + (i << 1));
                   6592:                }
                   6593:
                   6594:                /*
                   6595:                 * Auto Request Response DMA registers
                   6596:                 */
                   6597:                ISP_WRITE(isp, BIU2100_CSR, 0x40);
                   6598:                for (i = 0; i < 32; i++) {
                   6599:                        *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
                   6600:                }
                   6601:
                   6602:                /*
                   6603:                 * DMA registers
                   6604:                 */
                   6605:                ISP_WRITE(isp, BIU2100_CSR, 0x50);
                   6606:                for (i = 0; i < 48; i++) {
                   6607:                        *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
                   6608:                }
                   6609:
                   6610:                /*
                   6611:                 * RISC hardware registers
                   6612:                 */
                   6613:                ISP_WRITE(isp, BIU2100_CSR, 0);
                   6614:                for (i = 0; i < 16; i++) {
                   6615:                        *ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
                   6616:                }
                   6617:
                   6618:                /*
                   6619:                 * RISC GP? registers
                   6620:                 */
                   6621:                for (j = 0; j < 8; j++) {
                   6622:                        ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 9));
                   6623:                        for (i = 0; i < 16; i++) {
                   6624:                                *ptr++ =
                   6625:                                    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
                   6626:                        }
                   6627:                }
                   6628:
                   6629:                /*
                   6630:                 * frame buffer hardware registers
                   6631:                 */
                   6632:                ISP_WRITE(isp, BIU2100_CSR, 0x10);
                   6633:                for (i = 0; i < 64; i++) {
                   6634:                        *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
                   6635:                }
                   6636:
                   6637:                /*
                   6638:                 * FPM B0 hardware registers
                   6639:                 */
                   6640:                ISP_WRITE(isp, BIU2100_CSR, 0x20);
                   6641:                for (i = 0; i < 64; i++) {
                   6642:                        *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
                   6643:                }
                   6644:
                   6645:                /*
                   6646:                 * FPM B1 hardware registers
                   6647:                 */
                   6648:                ISP_WRITE(isp, BIU2100_CSR, 0x30);
                   6649:                for (i = 0; i < 64; i++) {
                   6650:                        *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
                   6651:                }
                   6652:        } else {
                   6653:                isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
                   6654:                return;
                   6655:        }
                   6656:        isp_prt(isp, ISP_LOGALL,
                   6657:           "isp_fw_dump: RISC registers dumped successfully");
                   6658:        ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
                   6659:        for (i = 0; i < 100; i++) {
                   6660:                USEC_DELAY(100);
                   6661:                if (ISP_READ(isp, OUTMAILBOX0) == 0) {
                   6662:                        break;
                   6663:                }
                   6664:        }
                   6665:        if (ISP_READ(isp, OUTMAILBOX0) != 0) {
                   6666:                isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
                   6667:                return;
                   6668:        }
                   6669:        ENABLE_INTS(isp);
                   6670:        mbs.param[0] = MBOX_READ_RAM_WORD;
                   6671:        mbs.param[1] = 0x800;
                   6672:        isp->isp_mbxworkp = (void *) ptr;
                   6673:        isp->isp_mbxwrk0 = 0xf7ff;      /* continuation count */
                   6674:        isp->isp_mbxwrk1 = 0x801;       /* next SRAM address */
                   6675:        isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
                   6676:        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                   6677:                isp_prt(isp, ISP_LOGWARN,
                   6678:                    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
                   6679:                return;
                   6680:        }
                   6681:        ptr = isp->isp_mbxworkp;        /* finish fetch of final word */
                   6682:        *ptr++ = isp->isp_mboxtmp[2];
                   6683:
                   6684:        /*
                   6685:         * We don't have access to mailbox registers 8.. onward
                   6686:         * in our 'common' device model- so we have to set it
                   6687:         * here and hope it stays the same!
                   6688:         */
                   6689:        ISP_WRITE(isp, PCI_MBOX_REGS2300_OFF + (8 << 1), 0x1);
                   6690:
                   6691:        mbs.param[0] = MBOX_READ_RAM_WORD_EXTENDED;
                   6692:        mbs.param[1] = 0;
                   6693:        isp->isp_mbxworkp = (void *) ptr;
                   6694:        isp->isp_mbxwrk0 = 0xffff;      /* continuation count */
                   6695:        isp->isp_mbxwrk1 = 0x1;         /* next SRAM address */
                   6696:        isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
                   6697:        if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
                   6698:                isp_prt(isp, ISP_LOGWARN,
                   6699:                    "RAM DUMP FAILED @ WORD %x", 0x10000 + isp->isp_mbxwrk1);
                   6700:                return;
                   6701:        }
                   6702:        ptr = isp->isp_mbxworkp;        /* finish final word */
                   6703:        *ptr++ = mbs.param[2];
                   6704:        isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped successfully");
                   6705:        FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
                   6706:        (void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
                   6707: }
                   6708:
                   6709: void
                   6710: isp_fw_dump(struct ispsoftc *isp)
                   6711: {
                   6712:        if (IS_2200(isp))
                   6713:                isp2200_fw_dump(isp);
                   6714:        else if (IS_23XX(isp))
                   6715:                isp2300_fw_dump(isp);
                   6716: }
                   6717: #endif

CVSweb