The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/isp.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: isp.c,v 1.115 2008/05/11 02:08:11 mjacob 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 National Aeronautics & Space Administration
    7  * All rights reserved.
    8  *
    9  * Additional Copyright (C) 2000-2007 by Matthew Jacob
   10  * All rights reserved.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 
   22  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  */
   34 
   35 /*
   36  * Inspiration and ideas about this driver are from Erik Moe's Linux driver
   37  * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
   38  * ideas dredged from the Solaris driver.
   39  */
   40 
   41 /*
   42  * Include header file appropriate for platform we're building on.
   43  */
   44 #ifdef  __NetBSD__
   45 #include <sys/cdefs.h>
   46 __KERNEL_RCSID(0, "$NetBSD: isp.c,v 1.115 2008/05/11 02:08:11 mjacob Exp $");
   47 #include <dev/ic/isp_netbsd.h>
   48 #endif
   49 #ifdef  __FreeBSD__
   50 #include <sys/cdefs.h>
   51 __FBSDID("$FreeBSD$");
   52 #include <dev/isp/isp_freebsd.h>
   53 #endif
   54 #ifdef  __OpenBSD__
   55 #include <dev/ic/isp_openbsd.h>
   56 #endif
   57 #ifdef  __linux__
   58 #include "isp_linux.h"
   59 #endif
   60 #ifdef  __svr4__
   61 #include "isp_solaris.h"
   62 #endif
   63 
   64 /*
   65  * General defines
   66  */
   67 
   68 #define MBOX_DELAY_COUNT        1000000 / 100
   69 #define ISP_MARK_PORTDB(a, b, c)                                \
   70     isp_prt(isp, ISP_LOGSANCFG,                                 \
   71         "Chan %d ISP_MARK_PORTDB@LINE %d", b, __LINE__);        \
   72     isp_mark_portdb(a, b, c)
   73 
   74 /*
   75  * Local static data
   76  */
   77 static const char fconf[] =
   78     "Chan %d PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)"
   79     "\n database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)";
   80 static const char notresp[] =
   81   "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
   82 static const char xact1[] =
   83     "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
   84 static const char xact2[] =
   85     "HBA attempted queued transaction to target routine %d on target %d bus %d";
   86 static const char xact3[] =
   87     "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
   88 static const char pskip[] =
   89     "SCSI phase skipped for target %d.%d.%d";
   90 static const char topology[] =
   91     "Chan %d WWPN 0x%08x%08x PortID 0x%06x N-Port Handle %d, Connection '%s'";
   92 static const char finmsg[] =
   93     "%d.%d.%d: FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x";
   94 static const char sc4[] = "NVRAM";
   95 static const char bun[] =
   96     "bad underrun for %d.%d (count %d, resid %d, status %s)";
   97 static const char lipd[] =
   98     "Chan %d LIP destroyed %d active commands";
   99 static const char sacq[] =
  100     "unable to acquire scratch area";
  101 
  102 static const uint8_t alpa_map[] = {
  103         0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda,
  104         0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce,
  105         0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5,
  106         0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3,
  107         0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
  108         0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b,
  109         0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81,
  110         0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73,
  111         0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69,
  112         0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
  113         0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c,
  114         0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c,
  115         0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
  116         0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26,
  117         0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
  118         0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00
  119 };
  120 
  121 /*
  122  * Local function prototypes.
  123  */
  124 static int isp_parse_async(ispsoftc_t *, uint16_t);
  125 static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *,
  126     uint32_t *);
  127 static void
  128 isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *);
  129 static void
  130 isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *);
  131 static void isp_fastpost_complete(ispsoftc_t *, uint16_t);
  132 static int isp_mbox_continue(ispsoftc_t *);
  133 static void isp_scsi_init(ispsoftc_t *);
  134 static void isp_scsi_channel_init(ispsoftc_t *, int);
  135 static void isp_fibre_init(ispsoftc_t *);
  136 static void isp_fibre_init_2400(ispsoftc_t *);
  137 static void isp_mark_portdb(ispsoftc_t *, int, int);
  138 static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int, int);
  139 static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t);
  140 static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t);
  141 static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *, int);
  142 static void isp_dump_chip_portdb(ispsoftc_t *, int, int);
  143 static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
  144 static int isp_fclink_test(ispsoftc_t *, int, int);
  145 static const char *ispfc_fw_statename(int);
  146 static int isp_pdb_sync(ispsoftc_t *, int);
  147 static int isp_scan_loop(ispsoftc_t *, int);
  148 static int isp_gid_ft_sns(ispsoftc_t *, int);
  149 static int isp_gid_ft_ct_passthru(ispsoftc_t *, int);
  150 static int isp_scan_fabric(ispsoftc_t *, int);
  151 static int
  152 isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *);
  153 static int isp_register_fc4_type(ispsoftc_t *, int);
  154 static int isp_register_fc4_type_24xx(ispsoftc_t *, int);
  155 static uint16_t isp_nxt_handle(ispsoftc_t *, int, uint16_t);
  156 static void isp_fw_state(ispsoftc_t *, int);
  157 static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int);
  158 static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
  159 
  160 static void isp_spi_update(ispsoftc_t *, int);
  161 static void isp_setdfltsdparm(ispsoftc_t *);
  162 static void isp_setdfltfcparm(ispsoftc_t *, int);
  163 static int isp_read_nvram(ispsoftc_t *, int);
  164 static int isp_read_nvram_2400(ispsoftc_t *, uint8_t *);
  165 static void isp_rdnvram_word(ispsoftc_t *, int, uint16_t *);
  166 static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *);
  167 static void isp_parse_nvram_1020(ispsoftc_t *, uint8_t *);
  168 static void isp_parse_nvram_1080(ispsoftc_t *, int, uint8_t *);
  169 static void isp_parse_nvram_12160(ispsoftc_t *, int, uint8_t *);
  170 static void isp_parse_nvram_2100(ispsoftc_t *, uint8_t *);
  171 static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
  172 
  173 /*
  174  * Reset Hardware.
  175  *
  176  * Hit the chip over the head, download new f/w if available and set it running.
  177  *
  178  * Locking done elsewhere.
  179  */
  180 
  181 void
  182 isp_reset(ispsoftc_t *isp)
  183 {
  184         mbreg_t mbs;
  185         uint32_t code_org, val;
  186         int loops, i, dodnld = 1;
  187         static const char *btype = "????";
  188         static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
  189 
  190         isp->isp_state = ISP_NILSTATE;
  191         if (isp->isp_dead) {
  192                 isp_shutdown(isp);
  193                 ISP_DISABLE_INTS(isp);
  194                 return;
  195         }
  196 
  197         /*
  198          * Basic types (SCSI, FibreChannel and PCI or SBus)
  199          * have been set in the MD code. We figure out more
  200          * here. Possibly more refined types based upon PCI
  201          * identification. Chip revision has been gathered.
  202          *
  203          * After we've fired this chip up, zero out the conf1 register
  204          * for SCSI adapters and do other settings for the 2100.
  205          */
  206 
  207         ISP_DISABLE_INTS(isp);
  208 
  209 
  210         /*
  211          * Pick an initial maxcmds value which will be used
  212          * to allocate xflist pointer space. It may be changed
  213          * later by the firmware.
  214          */
  215         if (IS_24XX(isp)) {
  216                 isp->isp_maxcmds = 4096;
  217         } else if (IS_2322(isp)) {
  218                 isp->isp_maxcmds = 2048;
  219         } else if (IS_23XX(isp) || IS_2200(isp)) {
  220                 isp->isp_maxcmds = 1024;
  221         } else {
  222                 isp->isp_maxcmds = 512;
  223         }
  224 
  225         /*
  226          * Set up DMA for the request and response queues.
  227          *
  228          * We do this now so we can use the request queue
  229          * for dma to load firmware from.
  230          */
  231         if (ISP_MBOXDMASETUP(isp) != 0) {
  232                 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
  233                 return;
  234         }
  235 
  236         /*
  237          * Set up default request/response queue in-pointer/out-pointer
  238          * register indices.
  239          */
  240         if (IS_24XX(isp)) {
  241                 isp->isp_rqstinrp = BIU2400_REQINP;
  242                 isp->isp_rqstoutrp = BIU2400_REQOUTP;
  243                 isp->isp_respinrp = BIU2400_RSPINP;
  244                 isp->isp_respoutrp = BIU2400_RSPOUTP;
  245         } else if (IS_23XX(isp)) {
  246                 isp->isp_rqstinrp = BIU_REQINP;
  247                 isp->isp_rqstoutrp = BIU_REQOUTP;
  248                 isp->isp_respinrp = BIU_RSPINP;
  249                 isp->isp_respoutrp = BIU_RSPOUTP;
  250         } else {
  251                 isp->isp_rqstinrp = INMAILBOX4;
  252                 isp->isp_rqstoutrp = OUTMAILBOX4;
  253                 isp->isp_respinrp = OUTMAILBOX5;
  254                 isp->isp_respoutrp = INMAILBOX5;
  255         }
  256 
  257         /*
  258          * Put the board into PAUSE mode (so we can read the SXP registers
  259          * or write FPM/FBM registers).
  260          */
  261         if (IS_24XX(isp)) {
  262                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT);
  263                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
  264                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
  265         } else {
  266                 ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
  267         }
  268 
  269         if (IS_FC(isp)) {
  270                 switch (isp->isp_type) {
  271                 case ISP_HA_FC_2100:
  272                         btype = "2100";
  273                         break;
  274                 case ISP_HA_FC_2200:
  275                         btype = "2200";
  276                         break;
  277                 case ISP_HA_FC_2300:
  278                         btype = "2300";
  279                         break;
  280                 case ISP_HA_FC_2312:
  281                         btype = "2312";
  282                         break;
  283                 case ISP_HA_FC_2322:
  284                         btype = "2322";
  285                         break;
  286                 case ISP_HA_FC_2400:
  287                         btype = "2422";
  288                         break;
  289                 default:
  290                         break;
  291                 }
  292 
  293                 if (!IS_24XX(isp)) {
  294                         /*
  295                          * While we're paused, reset the FPM module and FBM
  296                          * fifos.
  297                          */
  298                         ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
  299                         ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
  300                         ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
  301                         ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
  302                         ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
  303                 }
  304         } else if (IS_1240(isp)) {
  305                 sdparam *sdp;
  306 
  307                 btype = "1240";
  308                 isp->isp_clock = 60;
  309                 sdp = SDPARAM(isp, 0);
  310                 sdp->isp_ultramode = 1;
  311                 sdp = SDPARAM(isp, 1);
  312                 sdp->isp_ultramode = 1;
  313                 /*
  314                  * XXX: Should probably do some bus sensing.
  315                  */
  316         } else if (IS_ULTRA2(isp)) {
  317                 static const char m[] = "bus %d is in %s Mode";
  318                 uint16_t l;
  319                 sdparam *sdp = SDPARAM(isp, 0);
  320 
  321                 isp->isp_clock = 100;
  322 
  323                 if (IS_1280(isp))
  324                         btype = "1280";
  325                 else if (IS_1080(isp))
  326                         btype = "1080";
  327                 else if (IS_10160(isp))
  328                         btype = "10160";
  329                 else if (IS_12160(isp))
  330                         btype = "12160";
  331                 else
  332                         btype = "<UNKLVD>";
  333 
  334                 l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
  335                 switch (l) {
  336                 case ISP1080_LVD_MODE:
  337                         sdp->isp_lvdmode = 1;
  338                         isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
  339                         break;
  340                 case ISP1080_HVD_MODE:
  341                         sdp->isp_diffmode = 1;
  342                         isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
  343                         break;
  344                 case ISP1080_SE_MODE:
  345                         sdp->isp_ultramode = 1;
  346                         isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
  347                         break;
  348                 default:
  349                         isp_prt(isp, ISP_LOGERR,
  350                             "unknown mode on bus %d (0x%x)", 0, l);
  351                         break;
  352                 }
  353 
  354                 if (IS_DUALBUS(isp)) {
  355                         sdp = SDPARAM(isp, 1);
  356                         l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
  357                         l &= ISP1080_MODE_MASK;
  358                         switch(l) {
  359                         case ISP1080_LVD_MODE:
  360                                 sdp->isp_lvdmode = 1;
  361                                 isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
  362                                 break;
  363                         case ISP1080_HVD_MODE:
  364                                 sdp->isp_diffmode = 1;
  365                                 isp_prt(isp, ISP_LOGCONFIG,
  366                                     m, 1, "Differential");
  367                                 break;
  368                         case ISP1080_SE_MODE:
  369                                 sdp->isp_ultramode = 1;
  370                                 isp_prt(isp, ISP_LOGCONFIG,
  371                                     m, 1, "Single-Ended");
  372                                 break;
  373                         default:
  374                                 isp_prt(isp, ISP_LOGERR,
  375                                     "unknown mode on bus %d (0x%x)", 1, l);
  376                                 break;
  377                         }
  378                 }
  379         } else {
  380                 sdparam *sdp = SDPARAM(isp, 0);
  381                 i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
  382                 switch (i) {
  383                 default:
  384                         isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
  385                         /* FALLTHROUGH */
  386                 case 1:
  387                         btype = "1020";
  388                         isp->isp_type = ISP_HA_SCSI_1020;
  389                         isp->isp_clock = 40;
  390                         break;
  391                 case 2:
  392                         /*
  393                          * Some 1020A chips are Ultra Capable, but don't
  394                          * run the clock rate up for that unless told to
  395                          * do so by the Ultra Capable bits being set.
  396                          */
  397                         btype = "1020A";
  398                         isp->isp_type = ISP_HA_SCSI_1020A;
  399                         isp->isp_clock = 40;
  400                         break;
  401                 case 3:
  402                         btype = "1040";
  403                         isp->isp_type = ISP_HA_SCSI_1040;
  404                         isp->isp_clock = 60;
  405                         break;
  406                 case 4:
  407                         btype = "1040A";
  408                         isp->isp_type = ISP_HA_SCSI_1040A;
  409                         isp->isp_clock = 60;
  410                         break;
  411                 case 5:
  412                         btype = "1040B";
  413                         isp->isp_type = ISP_HA_SCSI_1040B;
  414                         isp->isp_clock = 60;
  415                         break;
  416                 case 6:
  417                         btype = "1040C";
  418                         isp->isp_type = ISP_HA_SCSI_1040C;
  419                         isp->isp_clock = 60;
  420                         break;
  421                 }
  422                 /*
  423                  * Now, while we're at it, gather info about ultra
  424                  * and/or differential mode.
  425                  */
  426                 if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
  427                         isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
  428                         sdp->isp_diffmode = 1;
  429                 } else {
  430                         sdp->isp_diffmode = 0;
  431                 }
  432                 i = ISP_READ(isp, RISC_PSR);
  433                 if (isp->isp_bustype == ISP_BT_SBUS) {
  434                         i &= RISC_PSR_SBUS_ULTRA;
  435                 } else {
  436                         i &= RISC_PSR_PCI_ULTRA;
  437                 }
  438                 if (i != 0) {
  439                         isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
  440                         sdp->isp_ultramode = 1;
  441                         /*
  442                          * If we're in Ultra Mode, we have to be 60MHz clock-
  443                          * even for the SBus version.
  444                          */
  445                         isp->isp_clock = 60;
  446                 } else {
  447                         sdp->isp_ultramode = 0;
  448                         /*
  449                          * Clock is known. Gronk.
  450                          */
  451                 }
  452 
  453                 /*
  454                  * Machine dependent clock (if set) overrides
  455                  * our generic determinations.
  456                  */
  457                 if (isp->isp_mdvec->dv_clock) {
  458                         if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
  459                                 isp->isp_clock = isp->isp_mdvec->dv_clock;
  460                         }
  461                 }
  462 
  463         }
  464 
  465         /*
  466          * Clear instrumentation
  467          */
  468         isp->isp_intcnt = isp->isp_intbogus = 0;
  469 
  470         /*
  471          * Do MD specific pre initialization
  472          */
  473         ISP_RESET0(isp);
  474 
  475         /*
  476          * Hit the chip over the head with hammer,
  477          * and give the ISP a chance to recover.
  478          */
  479 
  480         if (IS_SCSI(isp)) {
  481                 ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
  482                 /*
  483                  * A slight delay...
  484                  */
  485                 USEC_DELAY(100);
  486 
  487                 /*
  488                  * Clear data && control DMA engines.
  489                  */
  490                 ISP_WRITE(isp, CDMA_CONTROL,
  491                     DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
  492                 ISP_WRITE(isp, DDMA_CONTROL,
  493                     DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
  494 
  495 
  496         } else if (IS_24XX(isp)) {
  497                 /*
  498                  * Stop DMA and wait for it to stop.
  499                  */
  500                 ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
  501                 for (val = loops = 0; loops < 30000; loops++) {
  502                         USEC_DELAY(10);
  503                         val = ISP_READ(isp, BIU2400_CSR);
  504                         if ((val & BIU2400_DMA_ACTIVE) == 0) {
  505                                 break;
  506                         }
  507                 } 
  508                 if (val & BIU2400_DMA_ACTIVE) {
  509                         ISP_RESET0(isp);
  510                         isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
  511                         return;
  512                 }
  513                 /*
  514                  * Hold it in SOFT_RESET and STOP state for 100us.
  515                  */
  516                 ISP_WRITE(isp, BIU2400_CSR,
  517                     BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
  518                 USEC_DELAY(100);
  519                 for (loops = 0; loops < 10000; loops++) {
  520                         USEC_DELAY(5);
  521                         val = ISP_READ(isp, OUTMAILBOX0);
  522                 }
  523                 for (val = loops = 0; loops < 500000; loops ++) {
  524                         val = ISP_READ(isp, BIU2400_CSR);
  525                         if ((val & BIU2400_SOFT_RESET) == 0) {
  526                                 break;
  527                         }
  528                 }
  529                 if (val & BIU2400_SOFT_RESET) {
  530                         ISP_RESET0(isp);
  531                         isp_prt(isp, ISP_LOGERR, "Failed to come out of reset");
  532                         return;
  533                 }
  534         } else {
  535                 ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
  536                 /*
  537                  * A slight delay...
  538                  */
  539                 USEC_DELAY(100);
  540 
  541                 /*
  542                  * Clear data && control DMA engines.
  543                  */
  544                 ISP_WRITE(isp, CDMA2100_CONTROL,
  545                         DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
  546                 ISP_WRITE(isp, TDMA2100_CONTROL,
  547                         DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
  548                 ISP_WRITE(isp, RDMA2100_CONTROL,
  549                         DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
  550         }
  551 
  552         /*
  553          * Wait for ISP to be ready to go...
  554          */
  555         loops = MBOX_DELAY_COUNT;
  556         for (;;) {
  557                 if (IS_SCSI(isp)) {
  558                         if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET)) {
  559                                 break;
  560                         }
  561                 } else if (IS_24XX(isp)) {
  562                         if (ISP_READ(isp, OUTMAILBOX0) == 0) {
  563                                 break;
  564                         }
  565                 } else {
  566                         if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
  567                                 break;
  568                 }
  569                 USEC_DELAY(100);
  570                 if (--loops < 0) {
  571                         ISP_DUMPREGS(isp, "chip reset timed out");
  572                         ISP_RESET0(isp);
  573                         return;
  574                 }
  575         }
  576 
  577         /*
  578          * After we've fired this chip up, zero out the conf1 register
  579          * for SCSI adapters and other settings for the 2100.
  580          */
  581 
  582         if (IS_SCSI(isp)) {
  583                 ISP_WRITE(isp, BIU_CONF1, 0);
  584         } else if (!IS_24XX(isp)) {
  585                 ISP_WRITE(isp, BIU2100_CSR, 0);
  586         }
  587 
  588         /*
  589          * Reset RISC Processor
  590          */
  591         if (IS_24XX(isp)) {
  592                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
  593                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
  594                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
  595         } else {
  596                 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
  597                 USEC_DELAY(100);
  598                 ISP_WRITE(isp, BIU_SEMA, 0);
  599         }
  600 
  601         
  602         /*
  603          * Post-RISC Reset stuff.
  604          */
  605         if (IS_24XX(isp)) {
  606                 for (val = loops = 0; loops < 5000000; loops++) {
  607                         USEC_DELAY(5);
  608                         val = ISP_READ(isp, OUTMAILBOX0);
  609                         if (val == 0) {
  610                                 break;
  611                         }
  612                 }
  613                 if (val != 0) {
  614                         ISP_RESET0(isp);
  615                         isp_prt(isp, ISP_LOGERR, "reset didn't clear");
  616                         return;
  617                 }
  618         } else if (IS_SCSI(isp)) {
  619                 uint16_t tmp = isp->isp_mdvec->dv_conf1;
  620                 /*
  621                  * Busted FIFO. Turn off all but burst enables.
  622                  */
  623                 if (isp->isp_type == ISP_HA_SCSI_1040A) {
  624                         tmp &= BIU_BURST_ENABLE;
  625                 }
  626                 ISP_SETBITS(isp, BIU_CONF1, tmp);
  627                 if (tmp & BIU_BURST_ENABLE) {
  628                         ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
  629                         ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
  630                 }
  631                 if (SDPARAM(isp, 0)->isp_ptisp) {
  632                         if (SDPARAM(isp, 0)->isp_ultramode) {
  633                                 while (ISP_READ(isp, RISC_MTR) != 0x1313) {
  634                                         ISP_WRITE(isp, RISC_MTR, 0x1313);
  635                                         ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
  636                                 }
  637                         } else {
  638                                 ISP_WRITE(isp, RISC_MTR, 0x1212);
  639                         }
  640                         /*
  641                          * PTI specific register
  642                          */
  643                         ISP_WRITE(isp, RISC_EMB, DUAL_BANK);
  644                 } else {
  645                         ISP_WRITE(isp, RISC_MTR, 0x1212);
  646                 }
  647                 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
  648         } else {
  649                 ISP_WRITE(isp, RISC_MTR2100, 0x1212);
  650                 if (IS_2200(isp) || IS_23XX(isp)) {
  651                         ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
  652                 }
  653                 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
  654         }
  655 
  656         ISP_WRITE(isp, isp->isp_rqstinrp, 0);
  657         ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
  658         ISP_WRITE(isp, isp->isp_respinrp, 0);
  659         ISP_WRITE(isp, isp->isp_respoutrp, 0);
  660         if (IS_24XX(isp)) {
  661                 ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
  662                 ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
  663                 ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
  664                 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
  665         }
  666 
  667         /*
  668          * Do MD specific post initialization
  669          */
  670         ISP_RESET1(isp);
  671 
  672         /*
  673          * Wait for everything to finish firing up.
  674          *
  675          * Avoid doing this on early 2312s because you can generate a PCI
  676          * parity error (chip breakage).
  677          */
  678         if (IS_2312(isp) && isp->isp_revision < 2) {
  679                 USEC_DELAY(100);
  680         } else {
  681                 loops = MBOX_DELAY_COUNT;
  682                 while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
  683                         USEC_DELAY(100);
  684                         if (--loops < 0) {
  685                                 ISP_RESET0(isp);
  686                                 isp_prt(isp, ISP_LOGERR,
  687                                     "MBOX_BUSY never cleared on reset");
  688                                 return;
  689                         }
  690                 }
  691         }
  692 
  693         /*
  694          * Up until this point we've done everything by just reading or
  695          * setting registers. From this point on we rely on at least *some*
  696          * kind of firmware running in the card.
  697          */
  698 
  699         /*
  700          * Do some sanity checking.
  701          */
  702         MEMZERO(&mbs, sizeof (mbs));
  703         mbs.param[0] = MBOX_NO_OP;
  704         mbs.logval = MBLOGALL;
  705         isp_mboxcmd(isp, &mbs);
  706         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  707                 ISP_RESET0(isp);
  708                 return;
  709         }
  710 
  711         if (IS_SCSI(isp) || IS_24XX(isp)) {
  712                 MEMZERO(&mbs, sizeof (mbs));
  713                 mbs.param[0] = MBOX_MAILBOX_REG_TEST;
  714                 mbs.param[1] = 0xdead;
  715                 mbs.param[2] = 0xbeef;
  716                 mbs.param[3] = 0xffff;
  717                 mbs.param[4] = 0x1111;
  718                 mbs.param[5] = 0xa5a5;
  719                 mbs.param[6] = 0x0000;
  720                 mbs.param[7] = 0x0000;
  721                 mbs.logval = MBLOGALL;
  722                 isp_mboxcmd(isp, &mbs);
  723                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  724                         ISP_RESET0(isp);
  725                         return;
  726                 }
  727                 if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
  728                     mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
  729                     mbs.param[5] != 0xa5a5) {
  730                         ISP_RESET0(isp);
  731                         isp_prt(isp, ISP_LOGERR,
  732                             "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)",
  733                             mbs.param[1], mbs.param[2], mbs.param[3],
  734                             mbs.param[4], mbs.param[5]);
  735                         return;
  736                 }
  737 
  738         }
  739 
  740         /*
  741          * Download new Firmware, unless requested not to do so.
  742          * This is made slightly trickier in some cases where the
  743          * firmware of the ROM revision is newer than the revision
  744          * compiled into the driver. So, where we used to compare
  745          * versions of our f/w and the ROM f/w, now we just see
  746          * whether we have f/w at all and whether a config flag
  747          * has disabled our download.
  748          */
  749         if ((isp->isp_mdvec->dv_ispfw == NULL) ||
  750             (isp->isp_confopts & ISP_CFG_NORELOAD)) {
  751                 dodnld = 0;
  752         }
  753 
  754         if (IS_24XX(isp)) {
  755                 code_org = ISP_CODE_ORG_2400;
  756         } else if (IS_23XX(isp)) {
  757                 code_org = ISP_CODE_ORG_2300;
  758         } else {
  759                 code_org = ISP_CODE_ORG;
  760         }
  761 
  762         if (dodnld && IS_24XX(isp)) {
  763                 const uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
  764 
  765                 /*
  766                  * NB: Whatever you do do, do *not* issue the VERIFY FIRMWARE
  767                  * NB: command to the 2400 while loading new firmware. This
  768                  * NB: causes the new f/w to start and immediately crash back
  769                  * NB: to the ROM.
  770                  */
  771 
  772                 /*
  773                  * Keep loading until we run out of f/w.
  774                  */
  775                 code_org = ptr[2];      /* 1st load address is our start addr */
  776 
  777                 for (;;) {
  778                         uint32_t la, wi, wl;
  779 
  780                         isp_prt(isp, ISP_LOGDEBUG0,
  781                             "load 0x%x words of code at load address 0x%x",
  782                             ptr[3], ptr[2]);
  783 
  784                         wi = 0;
  785                         la = ptr[2];
  786                         wl = ptr[3];
  787 
  788                         while (wi < ptr[3]) {
  789                                 uint32_t *cp;
  790                                 uint32_t nw;
  791 
  792                                 nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 2;
  793                                 if (nw > wl) {
  794                                         nw = wl;
  795                                 }
  796                                 cp = isp->isp_rquest;
  797                                 for (i = 0; i < nw; i++) {
  798                                         ISP_IOXPUT_32(isp,  ptr[wi++], &cp[i]);
  799                                         wl--;
  800                                 }
  801                                 MEMORYBARRIER(isp, SYNC_REQUEST,
  802                                     0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
  803                                 MEMZERO(&mbs, sizeof (mbs));
  804                                 mbs.param[0] = MBOX_LOAD_RISC_RAM;
  805                                 mbs.param[1] = la;
  806                                 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
  807                                 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
  808                                 mbs.param[4] = nw >> 16;
  809                                 mbs.param[5] = nw;
  810                                 mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
  811                                 mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
  812                                 mbs.param[8] = la >> 16;
  813                                 mbs.logval = MBLOGALL;
  814                                 isp_mboxcmd(isp, &mbs);
  815                                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  816                                         isp_prt(isp, ISP_LOGERR,
  817                                             "F/W Risc Ram Load Failed");
  818                                         ISP_RESET0(isp);
  819                                         return;
  820                                 }
  821                                 la += nw;
  822                         }
  823 
  824                         if (ptr[1] == 0) {
  825                                 break;
  826                         }
  827                         ptr += ptr[3];
  828                 } 
  829                 isp->isp_loaded_fw = 1;
  830         } else if (dodnld && IS_23XX(isp)) {
  831                 const uint16_t *ptr = isp->isp_mdvec->dv_ispfw;
  832                 uint16_t wi, wl, segno;
  833                 uint32_t la;
  834 
  835                 la = code_org;
  836                 segno = 0;
  837 
  838                 for (;;) {
  839                         uint32_t nxtaddr;
  840 
  841                         isp_prt(isp, ISP_LOGDEBUG0,
  842                             "load 0x%x words of code at load address 0x%x",
  843                             ptr[3], la);
  844 
  845                         wi = 0;
  846                         wl = ptr[3];
  847 
  848                         while (wi < ptr[3]) {
  849                                 uint16_t *cp;
  850                                 uint32_t nw;
  851                                 
  852                                 nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 1;
  853                                 if (nw > wl) {
  854                                         nw = wl;
  855                                 }
  856                                 if (nw > (1 << 15)) {
  857                                         nw = 1 << 15;
  858                                 }
  859                                 cp = isp->isp_rquest;
  860                                 for (i = 0; i < nw; i++) {
  861                                         ISP_IOXPUT_16(isp,  ptr[wi++], &cp[i]);
  862                                         wl--;
  863                                 }
  864                                 MEMORYBARRIER(isp, SYNC_REQUEST,
  865                                     0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
  866                                 MEMZERO(&mbs, sizeof (mbs));
  867                                 mbs.param[0] = MBOX_LOAD_RISC_RAM;
  868                                 mbs.param[1] = la;
  869                                 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
  870                                 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
  871                                 mbs.param[4] = nw;
  872                                 mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
  873                                 mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
  874                                 mbs.param[8] = la >> 16;
  875                                 mbs.logval = MBLOGALL;
  876                                 isp_mboxcmd(isp, &mbs);
  877                                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  878                                         isp_prt(isp, ISP_LOGERR,
  879                                             "F/W Risc Ram Load Failed");
  880                                         ISP_RESET0(isp);
  881                                         return;
  882                                 }
  883                                 la += nw;
  884                         }
  885 
  886                         if (!IS_2322(isp)) {
  887                                 /*
  888                                  * Verify that it downloaded correctly.
  889                                  */
  890                                 MEMZERO(&mbs, sizeof (mbs));
  891                                 mbs.param[0] = MBOX_VERIFY_CHECKSUM;
  892                                 mbs.param[1] = code_org;
  893                                 mbs.logval = MBLOGNONE;
  894                                 isp_mboxcmd(isp, &mbs);
  895                                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  896                                         isp_prt(isp, ISP_LOGERR, dcrc);
  897                                         ISP_RESET0(isp);
  898                                         return;
  899                                 }
  900                                 break;
  901                         }
  902 
  903                         if (++segno == 3) {
  904                                 break;
  905                         }
  906 
  907                         /*
  908                          * If we're a 2322, the firmware actually comes in
  909                          * three chunks. We loaded the first at the code_org
  910                          * address. The other two chunks, which follow right
  911                          * after each other in memory here, get loaded at
  912                          * addresses specfied at offset 0x9..0xB.
  913                          */
  914 
  915                         nxtaddr = ptr[3];
  916                         ptr = &ptr[nxtaddr];
  917                         la = ptr[5] | ((ptr[4] & 0x3f) << 16);
  918                 }
  919                 isp->isp_loaded_fw = 1;
  920         } else if (dodnld) {
  921                 union {
  922                         const uint16_t *cp;
  923                         uint16_t *np;
  924                 } ucd;
  925                 ucd.cp = isp->isp_mdvec->dv_ispfw;
  926                 isp->isp_mbxworkp = &ucd.np[1];
  927                 isp->isp_mbxwrk0 = ucd.np[3] - 1;
  928                 isp->isp_mbxwrk1 = code_org + 1;
  929                 MEMZERO(&mbs, sizeof (mbs));
  930                 mbs.param[0] = MBOX_WRITE_RAM_WORD;
  931                 mbs.param[1] = code_org;
  932                 mbs.param[2] = ucd.np[0];
  933                 mbs.logval = MBLOGNONE;
  934                 isp_mboxcmd(isp, &mbs);
  935                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  936                         isp_prt(isp, ISP_LOGERR,
  937                             "F/W download failed at word %d",
  938                             isp->isp_mbxwrk1 - code_org);
  939                         ISP_RESET0(isp);
  940                         return;
  941                 }
  942                 /*
  943                  * Verify that it downloaded correctly.
  944                  */
  945                 MEMZERO(&mbs, sizeof (mbs));
  946                 mbs.param[0] = MBOX_VERIFY_CHECKSUM;
  947                 mbs.param[1] = code_org;
  948                 mbs.logval = MBLOGNONE;
  949                 isp_mboxcmd(isp, &mbs);
  950                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  951                         isp_prt(isp, ISP_LOGERR, dcrc);
  952                         ISP_RESET0(isp);
  953                         return;
  954                 }
  955                 isp->isp_loaded_fw = 1;
  956         } else {
  957                 isp->isp_loaded_fw = 0;
  958                 isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
  959         }
  960 
  961         /*
  962          * Now start it rolling.
  963          *
  964          * If we didn't actually download f/w,
  965          * we still need to (re)start it.
  966          */
  967 
  968 
  969         MEMZERO(&mbs, sizeof (mbs));
  970         mbs.timeout = 1000000;
  971         mbs.param[0] = MBOX_EXEC_FIRMWARE;
  972         if (IS_24XX(isp)) {
  973                 mbs.param[1] = code_org >> 16;
  974                 mbs.param[2] = code_org;
  975                 if (isp->isp_loaded_fw) {
  976                         mbs.param[3] = 0;
  977                 } else {
  978                         mbs.param[3] = 1;
  979                 }
  980         } else if (IS_2322(isp)) {
  981                 mbs.param[1] = code_org;
  982                 if (isp->isp_loaded_fw) {
  983                         mbs.param[2] = 0;
  984                 } else {
  985                         mbs.param[2] = 1;
  986                 }
  987         } else {
  988                 mbs.param[1] = code_org;
  989         }
  990 
  991         mbs.logval = MBLOGALL;
  992         isp_mboxcmd(isp, &mbs);
  993         if (IS_2322(isp) || IS_24XX(isp)) {
  994                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  995                         ISP_RESET0(isp);
  996                         return;
  997                 }
  998         }
  999 
 1000         /*
 1001          * Give it a chance to finish starting up.
 1002          */
 1003         USEC_DELAY(250000);
 1004 
 1005         if (IS_SCSI(isp)) {
 1006                 /*
 1007                  * Set CLOCK RATE, but only if asked to.
 1008                  */
 1009                 if (isp->isp_clock) {
 1010                         mbs.param[0] = MBOX_SET_CLOCK_RATE;
 1011                         mbs.param[1] = isp->isp_clock;
 1012                         mbs.logval = MBLOGNONE;
 1013                         isp_mboxcmd(isp, &mbs);
 1014                         /* we will try not to care if this fails */
 1015                 }
 1016         }
 1017 
 1018         MEMZERO(&mbs, sizeof (mbs));
 1019         mbs.param[0] = MBOX_ABOUT_FIRMWARE;
 1020         mbs.logval = MBLOGALL;
 1021         isp_mboxcmd(isp, &mbs);
 1022         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1023                 ISP_RESET0(isp);
 1024                 return;
 1025         }
 1026 
 1027         if (IS_24XX(isp) && mbs.param[1] == 0xdead) {
 1028                 isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start");
 1029                 ISP_RESET0(isp);
 1030                 return;
 1031         }
 1032 
 1033         /*
 1034          * The SBus firmware that we are using apparently does not return
 1035          * major, minor, micro revisions in the mailbox registers, which
 1036          * is really, really, annoying.
 1037          */
 1038         if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
 1039                 if (dodnld) {
 1040 #ifdef  ISP_TARGET_MODE
 1041                         isp->isp_fwrev[0] = 7;
 1042                         isp->isp_fwrev[1] = 55;
 1043 #else
 1044                         isp->isp_fwrev[0] = 1;
 1045                         isp->isp_fwrev[1] = 37;
 1046 #endif
 1047                         isp->isp_fwrev[2] = 0;
 1048                 } 
 1049         } else {
 1050                 isp->isp_fwrev[0] = mbs.param[1];
 1051                 isp->isp_fwrev[1] = mbs.param[2];
 1052                 isp->isp_fwrev[2] = mbs.param[3];
 1053         }
 1054 
 1055         isp_prt(isp, ISP_LOGCONFIG,
 1056             "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
 1057             btype, isp->isp_revision, dodnld? "loaded" : "resident",
 1058             isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
 1059 
 1060         if (IS_FC(isp)) {
 1061                 /*
 1062                  * We do not believe firmware attributes for 2100 code less
 1063                  * than 1.17.0, unless it's the firmware we specifically
 1064                  * are loading.
 1065                  *
 1066                  * Note that all 22XX and later f/w is greater than 1.X.0.
 1067                  */
 1068                 if ((ISP_FW_OLDER_THAN(isp, 1, 17, 1))) {
 1069 #ifdef  USE_SMALLER_2100_FIRMWARE
 1070                         isp->isp_fwattr = ISP_FW_ATTR_SCCLUN;
 1071 #else
 1072                         isp->isp_fwattr = 0;
 1073 #endif
 1074                 } else {
 1075                         isp->isp_fwattr = mbs.param[6];
 1076                         isp_prt(isp, ISP_LOGDEBUG0,
 1077                             "Firmware Attributes = 0x%x", mbs.param[6]);
 1078                 }
 1079         } else {
 1080 #ifndef ISP_TARGET_MODE
 1081                 isp->isp_fwattr = ISP_FW_ATTR_TMODE;
 1082 #else
 1083                 isp->isp_fwattr = 0;
 1084 #endif
 1085         }
 1086 
 1087         if (!IS_24XX(isp)) {
 1088                 MEMZERO(&mbs, sizeof (mbs));
 1089                 mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
 1090                 mbs.logval = MBLOGALL;
 1091                 isp_mboxcmd(isp, &mbs);
 1092                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1093                         ISP_RESET0(isp);
 1094                         return;
 1095                 }
 1096                 if (isp->isp_maxcmds >= mbs.param[2]) {
 1097                         isp->isp_maxcmds = mbs.param[2];
 1098                 }
 1099         }
 1100         isp_prt(isp, ISP_LOGCONFIG,
 1101             "%d max I/O command limit set", isp->isp_maxcmds);
 1102         for (i = 0; i < isp->isp_nchan; i++) {
 1103                 isp_fw_state(isp, i);
 1104         }
 1105         if (isp->isp_dead) {
 1106                 isp_shutdown(isp);
 1107                 ISP_DISABLE_INTS(isp);
 1108                 return;
 1109         }
 1110 
 1111         isp->isp_state = ISP_RESETSTATE;
 1112 
 1113         /*
 1114          * Okay- now that we have new firmware running, we now (re)set our
 1115          * notion of how many luns we support. This is somewhat tricky because
 1116          * if we haven't loaded firmware, we sometimes do not have an easy way
 1117          * of knowing how many luns we support.
 1118          *
 1119          * Expanded lun firmware gives you 32 luns for SCSI cards and
 1120          * 16384 luns for Fibre Channel cards.
 1121          *
 1122          * It turns out that even for QLogic 2100s with ROM 1.10 and above
 1123          * we do get a firmware attributes word returned in mailbox register 6.
 1124          *
 1125          * Because the lun is in a different position in the Request Queue
 1126          * Entry structure for Fibre Channel with expanded lun firmware, we
 1127          * can only support one lun (lun zero) when we don't know what kind
 1128          * of firmware we're running.
 1129          */
 1130         if (IS_SCSI(isp)) {
 1131                 if (dodnld) {
 1132                         if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
 1133                                 isp->isp_maxluns = 32;
 1134                         } else {
 1135                                 isp->isp_maxluns = 8;
 1136                         }
 1137                 } else {
 1138                         isp->isp_maxluns = 8;
 1139                 }
 1140         } else {
 1141                 if (ISP_CAP_SCCFW(isp)) {
 1142                         isp->isp_maxluns = 16384;
 1143                 } else {
 1144                         isp->isp_maxluns = 16;
 1145                 }
 1146         }
 1147 
 1148         /*
 1149          * We get some default values established. As a side
 1150          * effect, NVRAM is read here (unless overriden by
 1151          * a configuration flag).
 1152          */
 1153         if (IS_SCSI(isp)) {
 1154                 isp_setdfltsdparm(isp);
 1155         } else {
 1156                 for (i = 0; i < isp->isp_nchan; i++) {
 1157                         isp_setdfltfcparm(isp, i);
 1158                 }
 1159         }
 1160 
 1161 }
 1162 
 1163 /*
 1164  * Initialize Parameters of Hardware to a known state.
 1165  *
 1166  * Locks are held before coming here.
 1167  */
 1168 
 1169 void
 1170 isp_init(ispsoftc_t *isp)
 1171 {
 1172         if (IS_FC(isp)) {
 1173                 if (IS_24XX(isp)) {
 1174                         isp_fibre_init_2400(isp);
 1175                 } else {
 1176                         isp_fibre_init(isp);
 1177                 }
 1178         } else {
 1179                 isp_scsi_init(isp);
 1180         }
 1181 }
 1182 
 1183 static void
 1184 isp_scsi_init(ispsoftc_t *isp)
 1185 {
 1186         sdparam *sdp_chan0, *sdp_chan1;
 1187         mbreg_t mbs;
 1188 
 1189         sdp_chan0 = SDPARAM(isp, 0);
 1190         sdp_chan1 = sdp_chan0;
 1191         if (IS_DUALBUS(isp)) {
 1192                 sdp_chan1 = SDPARAM(isp, 1);
 1193         }
 1194 
 1195         /* First do overall per-card settings. */
 1196 
 1197         /*
 1198          * If we have fast memory timing enabled, turn it on.
 1199          */
 1200         if (sdp_chan0->isp_fast_mttr) {
 1201                 ISP_WRITE(isp, RISC_MTR, 0x1313);
 1202         }
 1203 
 1204         /*
 1205          * Set Retry Delay and Count.
 1206          * You set both channels at the same time.
 1207          */
 1208         MEMZERO(&mbs, sizeof (mbs));
 1209         mbs.param[0] = MBOX_SET_RETRY_COUNT;
 1210         mbs.param[1] = sdp_chan0->isp_retry_count;
 1211         mbs.param[2] = sdp_chan0->isp_retry_delay;
 1212         mbs.param[6] = sdp_chan1->isp_retry_count;
 1213         mbs.param[7] = sdp_chan1->isp_retry_delay;
 1214         mbs.logval = MBLOGALL;
 1215         isp_mboxcmd(isp, &mbs);
 1216         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1217                 return;
 1218         }
 1219 
 1220         /*
 1221          * Set ASYNC DATA SETUP time. This is very important.
 1222          */
 1223         MEMZERO(&mbs, sizeof (mbs));
 1224         mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
 1225         mbs.param[1] = sdp_chan0->isp_async_data_setup;
 1226         mbs.param[2] = sdp_chan1->isp_async_data_setup;
 1227         mbs.logval = MBLOGALL;
 1228         isp_mboxcmd(isp, &mbs);
 1229         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1230                 return;
 1231         }
 1232 
 1233         /*
 1234          * Set ACTIVE Negation State.
 1235          */
 1236         MEMZERO(&mbs, sizeof (mbs));
 1237         mbs.param[0] = MBOX_SET_ACT_NEG_STATE;
 1238         mbs.param[1] =
 1239             (sdp_chan0->isp_req_ack_active_neg << 4) |
 1240             (sdp_chan0->isp_data_line_active_neg << 5);
 1241         mbs.param[2] =
 1242             (sdp_chan1->isp_req_ack_active_neg << 4) |
 1243             (sdp_chan1->isp_data_line_active_neg << 5);
 1244         mbs.logval = MBLOGNONE;
 1245         isp_mboxcmd(isp, &mbs);
 1246         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1247                 isp_prt(isp, ISP_LOGERR,
 1248                     "failed to set active negation state (%d,%d), (%d,%d)",
 1249                     sdp_chan0->isp_req_ack_active_neg,
 1250                     sdp_chan0->isp_data_line_active_neg,
 1251                     sdp_chan1->isp_req_ack_active_neg,
 1252                     sdp_chan1->isp_data_line_active_neg);
 1253                 /*
 1254                  * But don't return.
 1255                  */
 1256         }
 1257 
 1258         /*
 1259          * Set the Tag Aging limit
 1260          */
 1261         MEMZERO(&mbs, sizeof (mbs));
 1262         mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT;
 1263         mbs.param[1] = sdp_chan0->isp_tag_aging;
 1264         mbs.param[2] = sdp_chan1->isp_tag_aging;
 1265         mbs.logval = MBLOGALL;
 1266         isp_mboxcmd(isp, &mbs);
 1267         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1268                 isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
 1269                     sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
 1270                 return;
 1271         }
 1272 
 1273         /*
 1274          * Set selection timeout.
 1275          */
 1276         MEMZERO(&mbs, sizeof (mbs));
 1277         mbs.param[0] = MBOX_SET_SELECT_TIMEOUT;
 1278         mbs.param[1] = sdp_chan0->isp_selection_timeout;
 1279         mbs.param[2] = sdp_chan1->isp_selection_timeout;
 1280         mbs.logval = MBLOGALL;
 1281         isp_mboxcmd(isp, &mbs);
 1282         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1283                 return;
 1284         }
 1285 
 1286         /* now do per-channel settings */
 1287         isp_scsi_channel_init(isp, 0);
 1288         if (IS_DUALBUS(isp))
 1289                 isp_scsi_channel_init(isp, 1);
 1290 
 1291         /*
 1292          * Now enable request/response queues
 1293          */
 1294 
 1295         if (IS_ULTRA2(isp) || IS_1240(isp)) {
 1296                 MEMZERO(&mbs, sizeof (mbs));
 1297                 mbs.param[0] = MBOX_INIT_RES_QUEUE_A64;
 1298                 mbs.param[1] = RESULT_QUEUE_LEN(isp);
 1299                 mbs.param[2] = DMA_WD1(isp->isp_result_dma);
 1300                 mbs.param[3] = DMA_WD0(isp->isp_result_dma);
 1301                 mbs.param[4] = 0;
 1302                 mbs.param[6] = DMA_WD3(isp->isp_result_dma);
 1303                 mbs.param[7] = DMA_WD2(isp->isp_result_dma);
 1304                 mbs.logval = MBLOGALL;
 1305                 isp_mboxcmd(isp, &mbs);
 1306                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1307                         return;
 1308                 }
 1309                 isp->isp_residx = mbs.param[5];
 1310 
 1311                 MEMZERO(&mbs, sizeof (mbs));
 1312                 mbs.param[0] = MBOX_INIT_REQ_QUEUE_A64;
 1313                 mbs.param[1] = RQUEST_QUEUE_LEN(isp);
 1314                 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
 1315                 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
 1316                 mbs.param[5] = 0;
 1317                 mbs.param[6] = DMA_WD3(isp->isp_result_dma);
 1318                 mbs.param[7] = DMA_WD2(isp->isp_result_dma);
 1319                 mbs.logval = MBLOGALL;
 1320                 isp_mboxcmd(isp, &mbs);
 1321                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1322                         return;
 1323                 }
 1324                 isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
 1325         } else {
 1326                 MEMZERO(&mbs, sizeof (mbs));
 1327                 mbs.param[0] = MBOX_INIT_RES_QUEUE;
 1328                 mbs.param[1] = RESULT_QUEUE_LEN(isp);
 1329                 mbs.param[2] = DMA_WD1(isp->isp_result_dma);
 1330                 mbs.param[3] = DMA_WD0(isp->isp_result_dma);
 1331                 mbs.param[4] = 0;
 1332                 mbs.logval = MBLOGALL;
 1333                 isp_mboxcmd(isp, &mbs);
 1334                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1335                         return;
 1336                 }
 1337                 isp->isp_residx = mbs.param[5];
 1338 
 1339                 MEMZERO(&mbs, sizeof (mbs));
 1340                 mbs.param[0] = MBOX_INIT_REQ_QUEUE;
 1341                 mbs.param[1] = RQUEST_QUEUE_LEN(isp);
 1342                 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
 1343                 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
 1344                 mbs.param[5] = 0;
 1345                 mbs.logval = MBLOGALL;
 1346                 isp_mboxcmd(isp, &mbs);
 1347                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1348                         return;
 1349                 }
 1350                 isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
 1351         }
 1352 
 1353         /*
 1354          * Turn on Fast Posting, LVD transitions
 1355          *
 1356          * Ultra2 F/W always has had fast posting (and LVD transitions)
 1357          *
 1358          * Ultra and older (i.e., SBus) cards may not. It's just safer
 1359          * to assume not for them.
 1360          */
 1361 
 1362         MEMZERO(&mbs, sizeof (mbs));
 1363         mbs.param[0] = MBOX_SET_FW_FEATURES;
 1364         mbs.param[1] = 0;
 1365         if (IS_ULTRA2(isp))
 1366                 mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
 1367 #ifndef ISP_NO_RIO
 1368         if (IS_ULTRA2(isp) || IS_1240(isp))
 1369                 mbs.param[1] |= FW_FEATURE_RIO_16BIT;
 1370 #else
 1371         if (IS_ULTRA2(isp) || IS_1240(isp))
 1372                 mbs.param[1] |= FW_FEATURE_FAST_POST;
 1373 #endif
 1374         if (mbs.param[1] != 0) {
 1375                 uint16_t sfeat = mbs.param[1];
 1376                 mbs.logval = MBLOGALL;
 1377                 isp_mboxcmd(isp, &mbs);
 1378                 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 1379                         isp_prt(isp, ISP_LOGINFO,
 1380                             "Enabled FW features (0x%x)", sfeat);
 1381                 }
 1382         }
 1383 
 1384         isp->isp_state = ISP_INITSTATE;
 1385 }
 1386 
 1387 static void
 1388 isp_scsi_channel_init(ispsoftc_t *isp, int chan)
 1389 {
 1390         sdparam *sdp;
 1391         mbreg_t mbs;
 1392         int tgt;
 1393 
 1394         sdp = SDPARAM(isp, chan);
 1395 
 1396         /*
 1397          * Set (possibly new) Initiator ID.
 1398          */
 1399         MEMZERO(&mbs, sizeof (mbs));
 1400         mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
 1401         mbs.param[1] = (chan << 7) | sdp->isp_initiator_id;
 1402         mbs.logval = MBLOGALL;
 1403         isp_mboxcmd(isp, &mbs);
 1404         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1405                 return;
 1406         }
 1407         isp_prt(isp, ISP_LOGINFO, "Chan %d Initiator ID is %d",
 1408             chan, sdp->isp_initiator_id);
 1409 
 1410 
 1411         /*
 1412          * Set current per-target parameters to an initial safe minimum.
 1413          */
 1414         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 1415                 int lun;
 1416                 uint16_t sdf;
 1417 
 1418                 if (sdp->isp_devparam[tgt].dev_enable == 0) {
 1419                         continue;
 1420                 }
 1421 #ifndef ISP_TARGET_MODE
 1422                 sdf = sdp->isp_devparam[tgt].goal_flags;
 1423                 sdf &= DPARM_SAFE_DFLT;
 1424                 /*
 1425                  * It is not quite clear when this changed over so that
 1426                  * we could force narrow and async for 1000/1020 cards,
 1427                  * but assume that this is only the case for loaded
 1428                  * firmware.
 1429                  */
 1430                 if (isp->isp_loaded_fw) {
 1431                         sdf |= DPARM_NARROW | DPARM_ASYNC;
 1432                 }
 1433 #else
 1434                 /*
 1435                  * The !$*!)$!$)* f/w uses the same index into some
 1436                  * internal table to decide how to respond to negotiations,
 1437                  * so if we've said "let's be safe" for ID X, and ID X
 1438                  * selects *us*, the negotiations will back to 'safe'
 1439                  * (as in narrow/async). What the f/w *should* do is
 1440                  * use the initiator id settings to decide how to respond.
 1441                  */
 1442                 sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
 1443 #endif
 1444                 MEMZERO(&mbs, sizeof (mbs));
 1445                 mbs.param[0] = MBOX_SET_TARGET_PARAMS;
 1446                 mbs.param[1] = (chan << 15) | (tgt << 8);
 1447                 mbs.param[2] = sdf;
 1448                 if ((sdf & DPARM_SYNC) == 0) {
 1449                         mbs.param[3] = 0;
 1450                 } else {
 1451                         mbs.param[3] =
 1452                             (sdp->isp_devparam[tgt].goal_offset << 8) |
 1453                             (sdp->isp_devparam[tgt].goal_period);
 1454                 }
 1455                 isp_prt(isp, ISP_LOGDEBUG0,
 1456                     "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
 1457                     chan, tgt, mbs.param[2], mbs.param[3] >> 8,
 1458                     mbs.param[3] & 0xff);
 1459                 mbs.logval = MBLOGNONE;
 1460                 isp_mboxcmd(isp, &mbs);
 1461                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1462                         sdf = DPARM_SAFE_DFLT;
 1463                         MEMZERO(&mbs, sizeof (mbs));
 1464                         mbs.param[0] = MBOX_SET_TARGET_PARAMS;
 1465                         mbs.param[1] = (tgt << 8) | (chan << 15);
 1466                         mbs.param[2] = sdf;
 1467                         mbs.param[3] = 0;
 1468                         mbs.logval = MBLOGALL;
 1469                         isp_mboxcmd(isp, &mbs);
 1470                         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1471                                 continue;
 1472                         }
 1473                 }
 1474 
 1475                 /*
 1476                  * We don't update any information directly from the f/w
 1477                  * because we need to run at least one command to cause a
 1478                  * new state to be latched up. So, we just assume that we
 1479                  * converge to the values we just had set.
 1480                  *
 1481                  * Ensure that we don't believe tagged queuing is enabled yet.
 1482                  * It turns out that sometimes the ISP just ignores our
 1483                  * attempts to set parameters for devices that it hasn't
 1484                  * seen yet.
 1485                  */
 1486                 sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
 1487                 for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
 1488                         MEMZERO(&mbs, sizeof (mbs));
 1489                         mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
 1490                         mbs.param[1] = (chan << 15) | (tgt << 8) | lun;
 1491                         mbs.param[2] = sdp->isp_max_queue_depth;
 1492                         mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
 1493                         mbs.logval = MBLOGALL;
 1494                         isp_mboxcmd(isp, &mbs);
 1495                         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1496                                 break;
 1497                         }
 1498                 }
 1499         }
 1500         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 1501                 if (sdp->isp_devparam[tgt].dev_refresh) {
 1502                         sdp->sendmarker = 1;
 1503                         sdp->update = 1;
 1504                         break;
 1505                 }
 1506         }
 1507 }
 1508 
 1509 /*
 1510  * Fibre Channel specific initialization.
 1511  */
 1512 static void
 1513 isp_fibre_init(ispsoftc_t *isp)
 1514 {
 1515         fcparam *fcp;
 1516         isp_icb_t local, *icbp = &local;
 1517         mbreg_t mbs;
 1518         int ownloopid;
 1519 
 1520         /*
 1521          * We only support one channel on non-24XX cards
 1522          */
 1523         fcp = FCPARAM(isp, 0);
 1524         if (fcp->role == ISP_ROLE_NONE) {
 1525                 isp->isp_state = ISP_INITSTATE;
 1526                 return;
 1527         }
 1528 
 1529         MEMZERO(icbp, sizeof (*icbp));
 1530         icbp->icb_version = ICB_VERSION1;
 1531         icbp->icb_fwoptions = fcp->isp_fwoptions;
 1532 
 1533         /*
 1534          * Firmware Options are either retrieved from NVRAM or
 1535          * are patched elsewhere. We check them for sanity here
 1536          * and make changes based on board revision, but otherwise
 1537          * let others decide policy.
 1538          */
 1539 
 1540         /*
 1541          * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
 1542          */
 1543         if (IS_2100(isp) && isp->isp_revision < 5) {
 1544                 icbp->icb_fwoptions &= ~ICBOPT_FAIRNESS;
 1545         }
 1546 
 1547         /*
 1548          * We have to use FULL LOGIN even though it resets the loop too much
 1549          * because otherwise port database entries don't get updated after
 1550          * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
 1551          */
 1552         if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
 1553                 icbp->icb_fwoptions |= ICBOPT_FULL_LOGIN;
 1554         }
 1555 
 1556         /*
 1557          * Insist on Port Database Update Async notifications
 1558          */
 1559         icbp->icb_fwoptions |= ICBOPT_PDBCHANGE_AE;
 1560 
 1561         /*
 1562          * Make sure that target role reflects into fwoptions.
 1563          */
 1564         if (fcp->role & ISP_ROLE_TARGET) {
 1565                 icbp->icb_fwoptions |= ICBOPT_TGT_ENABLE;
 1566         } else {
 1567                 icbp->icb_fwoptions &= ~ICBOPT_TGT_ENABLE;
 1568         }
 1569 
 1570         if (fcp->role & ISP_ROLE_INITIATOR) {
 1571                 icbp->icb_fwoptions &= ~ICBOPT_INI_DISABLE;
 1572         } else {
 1573                 icbp->icb_fwoptions |= ICBOPT_INI_DISABLE;
 1574         }
 1575 
 1576         icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
 1577         if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
 1578             icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
 1579                 isp_prt(isp, ISP_LOGERR,
 1580                     "bad frame length (%d) from NVRAM- using %d",
 1581                     DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
 1582                 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
 1583         }
 1584         icbp->icb_maxalloc = fcp->isp_maxalloc;
 1585         if (icbp->icb_maxalloc < 1) {
 1586                 isp_prt(isp, ISP_LOGERR,
 1587                     "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
 1588                 icbp->icb_maxalloc = 16;
 1589         }
 1590         icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
 1591         if (icbp->icb_execthrottle < 1) {
 1592                 isp_prt(isp, ISP_LOGERR,
 1593                     "bad execution throttle of %d- using %d",
 1594                     DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
 1595                 icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
 1596         }
 1597         icbp->icb_retry_delay = fcp->isp_retry_delay;
 1598         icbp->icb_retry_count = fcp->isp_retry_count;
 1599         icbp->icb_hardaddr = fcp->isp_loopid;
 1600         ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
 1601         if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
 1602                 icbp->icb_hardaddr = 0;
 1603                 ownloopid = 0;
 1604         }
 1605 
 1606         /*
 1607          * Our life seems so much better with 2200s and later with
 1608          * the latest f/w if we set Hard Address.
 1609          */
 1610         if (ownloopid || ISP_FW_NEWER_THAN(isp, 2, 2, 5)) {
 1611                 icbp->icb_fwoptions |= ICBOPT_HARD_ADDRESS;
 1612         }
 1613 
 1614         /*
 1615          * Right now we just set extended options to prefer point-to-point
 1616          * over loop based upon some soft config options.
 1617          * 
 1618          * NB: for the 2300, ICBOPT_EXTENDED is required.
 1619          */
 1620         if (IS_2200(isp) || IS_23XX(isp)) {
 1621                 icbp->icb_fwoptions |= ICBOPT_EXTENDED;
 1622                 /*
 1623                  * Prefer or force Point-To-Point instead Loop?
 1624                  */
 1625                 switch(isp->isp_confopts & ISP_CFG_PORT_PREF) {
 1626                 case ISP_CFG_NPORT:
 1627                         icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
 1628                         break;
 1629                 case ISP_CFG_NPORT_ONLY:
 1630                         icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY;
 1631                         break;
 1632                 case ISP_CFG_LPORT_ONLY:
 1633                         icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY;
 1634                         break;
 1635                 default:
 1636                         icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
 1637                         break;
 1638                 }
 1639                 if (IS_2200(isp)) {
 1640                         /*
 1641                          * There seems to just be too much breakage here
 1642                          * with RIO and Fast Posting- it probably actually
 1643                          * works okay but this driver is messing it up.
 1644                          * This card is really ancient by now, so let's
 1645                          * just opt for safety and not use the feature.
 1646                          */
 1647 #if     0
 1648                         if (ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
 1649                                 icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
 1650                                 icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
 1651                                 icbp->icb_racctimer = 4;
 1652                                 icbp->icb_idelaytimer = 8;
 1653                         } else {
 1654                                 icbp->icb_fwoptions |= ICBOPT_FAST_POST;
 1655                         }
 1656 #else
 1657                         icbp->icb_xfwoptions &= ~ICBXOPT_RIO_16BIT;
 1658                         icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
 1659 #endif
 1660                 } else {
 1661                         /*
 1662                          * QLogic recommends that FAST Posting be turned
 1663                          * off for 23XX cards and instead allow the HBA
 1664                          * to write response queue entries and interrupt
 1665                          * after a delay (ZIO).
 1666                          */
 1667                         icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
 1668                         if ((fcp->isp_xfwoptions & ICBXOPT_TIMER_MASK) ==
 1669                             ICBXOPT_ZIO) {
 1670                                 icbp->icb_xfwoptions |= ICBXOPT_ZIO;
 1671                                 icbp->icb_idelaytimer = 10;
 1672                         }
 1673                         if (isp->isp_confopts & ISP_CFG_ONEGB) {
 1674                                 icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
 1675                         } else if (isp->isp_confopts & ISP_CFG_TWOGB) {
 1676                                 icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB;
 1677                         } else {
 1678                                 icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
 1679                         }
 1680                         if (fcp->isp_zfwoptions & ICBZOPT_50_OHM) {
 1681                                 icbp->icb_zfwoptions |= ICBZOPT_50_OHM;
 1682                         }
 1683                 }
 1684         }
 1685 
 1686 
 1687         /*
 1688          * For 22XX > 2.1.26 && 23XX, set some options.
 1689          * XXX: Probably okay for newer 2100 f/w too.
 1690          */
 1691         if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
 1692                 /*
 1693                  * Turn on LIP F8 async event (1)
 1694                  * Turn on generate AE 8013 on all LIP Resets (2)
 1695                  * Disable LIP F7 switching (8)
 1696                  */
 1697                 MEMZERO(&mbs, sizeof (mbs));
 1698                 mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS;
 1699                 mbs.param[1] = 0xb;
 1700                 mbs.param[2] = 0;
 1701                 mbs.param[3] = 0;
 1702                 mbs.logval = MBLOGALL;
 1703                 isp_mboxcmd(isp, &mbs);
 1704                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1705                         return;
 1706                 }
 1707         }
 1708         icbp->icb_logintime = ICB_LOGIN_TOV;
 1709         icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV;
 1710 
 1711         if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
 1712                 icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
 1713                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
 1714                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
 1715                 isp_prt(isp, ISP_LOGDEBUG1,
 1716                     "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
 1717                     ((uint32_t) (fcp->isp_wwnn >> 32)),
 1718                     ((uint32_t) (fcp->isp_wwnn)),
 1719                     ((uint32_t) (fcp->isp_wwpn >> 32)),
 1720                     ((uint32_t) (fcp->isp_wwpn)));
 1721         } else if (fcp->isp_wwpn) {
 1722                 icbp->icb_fwoptions &= ~ICBOPT_BOTH_WWNS;
 1723                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
 1724                 isp_prt(isp, ISP_LOGDEBUG1,
 1725                     "Setting ICB Port 0x%08x%08x",
 1726                     ((uint32_t) (fcp->isp_wwpn >> 32)),
 1727                     ((uint32_t) (fcp->isp_wwpn)));
 1728         } else {
 1729                 isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
 1730                 return;
 1731         }
 1732         icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
 1733         if (icbp->icb_rqstqlen < 1) {
 1734                 isp_prt(isp, ISP_LOGERR, "bad request queue length");
 1735         }
 1736         icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
 1737         if (icbp->icb_rsltqlen < 1) {
 1738                 isp_prt(isp, ISP_LOGERR, "bad result queue length");
 1739         }
 1740         icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
 1741         icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
 1742         icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
 1743         icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
 1744         icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
 1745         icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
 1746         icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
 1747         icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
 1748 
 1749         if (FC_SCRATCH_ACQUIRE(isp, 0)) {
 1750                 isp_prt(isp, ISP_LOGERR, sacq);
 1751                 return;
 1752         }
 1753         isp_prt(isp, ISP_LOGDEBUG0,
 1754             "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
 1755             icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
 1756 
 1757         isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
 1758 
 1759         /*
 1760          * Init the firmware
 1761          */
 1762         MEMZERO(&mbs, sizeof (mbs));
 1763         mbs.param[0] = MBOX_INIT_FIRMWARE;
 1764         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 1765         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 1766         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 1767         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 1768         mbs.logval = MBLOGALL;
 1769         mbs.timeout = 30 * 1000000;
 1770         isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %p (%08x%08x)",
 1771             fcp->isp_scratch, (uint32_t) ((uint64_t)fcp->isp_scdma >> 32),
 1772             (uint32_t) fcp->isp_scdma);
 1773         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp));
 1774         isp_mboxcmd(isp, &mbs);
 1775         FC_SCRATCH_RELEASE(isp, 0);
 1776         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1777                 isp_print_bytes(isp, "isp_fibre_init", sizeof (*icbp), icbp);
 1778                 return;
 1779         }
 1780         isp->isp_reqidx = 0;
 1781         isp->isp_reqodx = 0;
 1782         isp->isp_residx = 0;
 1783 
 1784         /*
 1785          * Whatever happens, we're now committed to being here.
 1786          */
 1787         isp->isp_state = ISP_INITSTATE;
 1788 }
 1789 
 1790 static void
 1791 isp_fibre_init_2400(ispsoftc_t *isp)
 1792 {
 1793         fcparam *fcp;
 1794         isp_icb_2400_t local, *icbp = &local;
 1795         mbreg_t mbs;
 1796         int chan, nchan;
 1797 
 1798         /*
 1799          * Check to see whether all channels have *some* kind of role
 1800          */
 1801         for (chan = 0; chan < isp->isp_nchan; chan++) {
 1802                 fcp = FCPARAM(isp, chan);
 1803                 if (fcp->role != ISP_ROLE_NONE) {
 1804                         break;
 1805                 }
 1806         }
 1807         if (chan == isp->isp_nchan) {
 1808                 isp_prt(isp, ISP_LOGDEBUG0, "all channels with role 'none'");
 1809                 isp->isp_state = ISP_INITSTATE;
 1810                 return;
 1811         }
 1812 
 1813         if (ISP_CAP_MULTI_ID(isp) == 0 && isp->isp_nchan > 1) {
 1814                 isp_prt(isp, ISP_LOGWARN,
 1815                     "non-MULTIID f/w loaded, only can enable 1 of %d channels",
 1816                     isp->isp_nchan);
 1817                 nchan = 1;
 1818         } else {
 1819                 nchan = isp->isp_nchan;
 1820         }
 1821 
 1822         /*
 1823          * Start with channel 0.
 1824          */
 1825         fcp = FCPARAM(isp, 0);
 1826 
 1827         /*
 1828          * Turn on LIP F8 async event (1)
 1829          */
 1830         MEMZERO(&mbs, sizeof (mbs));
 1831         mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS;
 1832         mbs.param[1] = 1;
 1833         mbs.logval = MBLOGALL;
 1834         isp_mboxcmd(isp, &mbs);
 1835         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1836                 return;
 1837         }
 1838 
 1839         MEMZERO(icbp, sizeof (*icbp));
 1840         icbp->icb_fwoptions1 = fcp->isp_fwoptions;
 1841         if (fcp->role & ISP_ROLE_TARGET) {
 1842                 icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
 1843         } else {
 1844                 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_TGT_ENABLE;
 1845         }
 1846 
 1847         if (fcp->role & ISP_ROLE_INITIATOR) {
 1848                 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
 1849         } else {
 1850                 icbp->icb_fwoptions1 |= ICB2400_OPT1_INI_DISABLE;
 1851         }
 1852 
 1853         icbp->icb_version = ICB_VERSION1;
 1854         icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
 1855         if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
 1856             icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
 1857                 isp_prt(isp, ISP_LOGERR,
 1858                     "bad frame length (%d) from NVRAM- using %d",
 1859                     DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
 1860                 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
 1861         }
 1862 
 1863         icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
 1864         if (icbp->icb_execthrottle < 1) {
 1865                 isp_prt(isp, ISP_LOGERR,
 1866                     "bad execution throttle of %d- using %d",
 1867                     DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
 1868                 icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
 1869         }
 1870 
 1871         if (icbp->icb_fwoptions1 & ICB2400_OPT1_TGT_ENABLE) {
 1872                 /*
 1873                  * Get current resource count
 1874                  */
 1875                 MEMZERO(&mbs, sizeof (mbs));
 1876                 mbs.param[0] = MBOX_GET_RESOURCE_COUNT;
 1877                 mbs.obits = 0x4cf;
 1878                 mbs.logval = MBLOGALL;
 1879                 isp_mboxcmd(isp, &mbs);
 1880                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1881                         return;
 1882                 }
 1883                 icbp->icb_xchgcnt = mbs.param[3];
 1884         }
 1885 
 1886 
 1887         icbp->icb_hardaddr = fcp->isp_loopid;
 1888         if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
 1889                 icbp->icb_hardaddr = 0;
 1890         }
 1891 
 1892         /*
 1893          * Force this on.
 1894          */
 1895         icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
 1896 
 1897         icbp->icb_fwoptions2 = fcp->isp_xfwoptions;
 1898         switch(isp->isp_confopts & ISP_CFG_PORT_PREF) {
 1899 #if     0
 1900         case ISP_CFG_NPORT:
 1901                 /*
 1902                  * XXX: This causes the f/w to crash.
 1903                  */
 1904                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
 1905                 icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_2_LOOP;
 1906                 break;
 1907 #endif
 1908         case ISP_CFG_NPORT_ONLY:
 1909                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
 1910                 icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY;
 1911                 break;
 1912         case ISP_CFG_LPORT_ONLY:
 1913                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
 1914                 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY;
 1915                 break;
 1916         default:
 1917                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
 1918                 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
 1919                 break;
 1920         }
 1921 
 1922         /* force this on for now */
 1923         icbp->icb_fwoptions2 |= ICB2400_OPT2_ZIO;
 1924 
 1925         switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) {
 1926         case ICB2400_OPT2_ZIO:
 1927         case ICB2400_OPT2_ZIO1:
 1928                 icbp->icb_idelaytimer = 0;
 1929                 break;
 1930         case 0:
 1931                 break;
 1932         default:
 1933                 isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field",
 1934                     icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
 1935                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK;
 1936                 break;
 1937         }
 1938 
 1939         /*
 1940          * We don't support FCTAPE, so clear it.
 1941          */
 1942         icbp->icb_fwoptions2 &= ~ICB2400_OPT2_FCTAPE;
 1943 
 1944         icbp->icb_fwoptions3 = fcp->isp_zfwoptions;
 1945         icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_AUTO;
 1946         if (isp->isp_confopts & ISP_CFG_ONEGB) {
 1947                 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_ONEGB;
 1948         } else if (isp->isp_confopts & ISP_CFG_TWOGB) {
 1949                 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_TWOGB;
 1950         } else if (isp->isp_confopts & ISP_CFG_FOURGB) {
 1951                 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_FOURGB;
 1952         } else {
 1953                 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
 1954         }
 1955 
 1956         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
 1957                 icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID;
 1958         }
 1959         icbp->icb_logintime = ICB_LOGIN_TOV;
 1960 
 1961         if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
 1962                 icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
 1963                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
 1964                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
 1965                 isp_prt(isp, ISP_LOGDEBUG1,
 1966                     "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
 1967                     ((uint32_t) (fcp->isp_wwnn >> 32)),
 1968                     ((uint32_t) (fcp->isp_wwnn)),
 1969                     ((uint32_t) (fcp->isp_wwpn >> 32)),
 1970                     ((uint32_t) (fcp->isp_wwpn)));
 1971         } else if (fcp->isp_wwpn) {
 1972                 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS;
 1973                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
 1974                 isp_prt(isp, ISP_LOGDEBUG1,
 1975                     "Setting ICB Node to be same as Port 0x%08x%08x",
 1976                     ((uint32_t) (fcp->isp_wwpn >> 32)),
 1977                     ((uint32_t) (fcp->isp_wwpn)));
 1978         } else {
 1979                 isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
 1980                 return;
 1981         }
 1982         icbp->icb_retry_count = fcp->isp_retry_count;
 1983 
 1984         icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
 1985         if (icbp->icb_rqstqlen < 8) {
 1986                 isp_prt(isp, ISP_LOGERR, "bad request queue length %d",
 1987                     icbp->icb_rqstqlen);
 1988                 return;
 1989         }
 1990         icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
 1991         if (icbp->icb_rsltqlen < 8) {
 1992                 isp_prt(isp, ISP_LOGERR, "bad result queue length %d",
 1993                     icbp->icb_rsltqlen);
 1994                 return;
 1995         }
 1996         icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
 1997         icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
 1998         icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
 1999         icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
 2000 
 2001         icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
 2002         icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
 2003         icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
 2004         icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
 2005 
 2006 #ifdef  ISP_TARGET_MODE
 2007         /* unconditionally set up the ATIO queue if we support target mode */
 2008         icbp->icb_atioqlen = RESULT_QUEUE_LEN(isp);
 2009         if (icbp->icb_atioqlen < 8) {
 2010                 isp_prt(isp, ISP_LOGERR,
 2011                     "bad ATIO queue length %d", icbp->icb_atioqlen);
 2012                 return;
 2013         }
 2014         icbp->icb_atioqaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_atioq_dma);
 2015         icbp->icb_atioqaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_atioq_dma);
 2016         icbp->icb_atioqaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_atioq_dma);
 2017         icbp->icb_atioqaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_atioq_dma);
 2018         isp_prt(isp, ISP_LOGDEBUG0,
 2019             "isp_fibre_init_2400: atioq %04x%04x%04x%04x",
 2020             DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma),
 2021             DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma));
 2022 #endif
 2023 
 2024         isp_prt(isp, ISP_LOGDEBUG0,
 2025             "isp_fibre_init_2400: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
 2026             icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3);
 2027 
 2028         isp_prt(isp, ISP_LOGDEBUG0,
 2029             "isp_fibre_init_2400: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x",
 2030             DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma),
 2031             DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma),
 2032             DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
 2033             DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
 2034 
 2035         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 2036                 isp_print_bytes(isp, "isp_fibre_init_2400", sizeof (*icbp),
 2037                     icbp);
 2038         }
 2039 
 2040         if (FC_SCRATCH_ACQUIRE(isp, 0)) {
 2041                 isp_prt(isp, ISP_LOGERR, sacq);
 2042                 return;
 2043         }
 2044         MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
 2045         isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
 2046 
 2047         /*
 2048          * Now fill in information about any additional channels
 2049          */
 2050         if (nchan > 1) {
 2051                 isp_icb_2400_vpinfo_t vpinfo, *vdst;
 2052                 vp_port_info_t pi, *pdst;
 2053                 size_t amt = 0;
 2054                 uint8_t *off;
 2055 
 2056                 vpinfo.vp_count = isp->isp_nchan - 1;
 2057                 vpinfo.vp_global_options = 0;
 2058                 off = fcp->isp_scratch;
 2059                 off += ICB2400_VPINFO_OFF;
 2060                 vdst = (isp_icb_2400_vpinfo_t *) off;
 2061                 isp_put_icb_2400_vpinfo(isp, &vpinfo, vdst);
 2062                 amt = ICB2400_VPINFO_OFF + sizeof (isp_icb_2400_vpinfo_t);
 2063                 for (chan = 1; chan < isp->isp_nchan; chan++) {
 2064                         fcparam *fcp2;
 2065 
 2066                         MEMZERO(&pi, sizeof (pi));
 2067                         fcp2 = FCPARAM(isp, chan);
 2068                         if (fcp2->role != ISP_ROLE_NONE) {
 2069                                 pi.vp_port_options = ICB2400_VPOPT_ENABLED;
 2070                                 if (fcp2->role & ISP_ROLE_INITIATOR) {
 2071                                         pi.vp_port_options |=
 2072                                             ICB2400_VPOPT_INI_ENABLE;
 2073                                 }
 2074                                 if ((fcp2->role & ISP_ROLE_TARGET) == 0) {
 2075                                         pi.vp_port_options |=
 2076                                             ICB2400_VPOPT_TGT_DISABLE;
 2077                                 }
 2078                                 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname,
 2079                                     fcp2->isp_wwpn);
 2080                                 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename,
 2081                                     fcp2->isp_wwnn);
 2082                         }
 2083                         off = fcp->isp_scratch;
 2084                         off += ICB2400_VPINFO_PORT_OFF(chan);
 2085                         pdst = (vp_port_info_t *) off;
 2086                         isp_put_vp_port_info(isp, &pi, pdst);
 2087                         amt += ICB2400_VPOPT_WRITE_SIZE;
 2088                 }
 2089         }
 2090 
 2091         /*
 2092          * Init the firmware
 2093          */
 2094         MEMZERO(&mbs, sizeof (mbs));
 2095         if (nchan > 1) {
 2096                 mbs.param[0] = MBOX_INIT_FIRMWARE_MULTI_ID;
 2097         } else {
 2098                 mbs.param[0] = MBOX_INIT_FIRMWARE;
 2099         }
 2100         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 2101         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 2102         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 2103         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 2104         mbs.logval = MBLOGALL;
 2105         mbs.timeout = 30 * 1000000;
 2106         isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %04x%04x%04x%04x",
 2107             DMA_WD3(fcp->isp_scdma), DMA_WD2(fcp->isp_scdma),
 2108             DMA_WD1(fcp->isp_scdma), DMA_WD0(fcp->isp_scdma));
 2109         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp));
 2110         isp_mboxcmd(isp, &mbs);
 2111         FC_SCRATCH_RELEASE(isp, 0);
 2112 
 2113         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 2114                 return;
 2115         }
 2116         isp->isp_reqidx = 0;
 2117         isp->isp_reqodx = 0;
 2118         isp->isp_residx = 0;
 2119 
 2120         /*
 2121          * Whatever happens, we're now committed to being here.
 2122          */
 2123         isp->isp_state = ISP_INITSTATE;
 2124 }
 2125 
 2126 static void
 2127 isp_mark_portdb(ispsoftc_t *isp, int chan, int disposition)
 2128 {
 2129         fcparam *fcp = FCPARAM(isp, chan);
 2130         int i;
 2131 
 2132         if (chan < 0 || chan >= isp->isp_nchan) {
 2133                 isp_prt(isp, ISP_LOGWARN,
 2134                     "isp_mark_portdb: bad channel %d", chan);
 2135                 return;
 2136         }
 2137         for (i = 0; i < MAX_FC_TARG; i++) {
 2138                 if (fcp->portdb[i].target_mode) {
 2139                         if (disposition < 0) {
 2140                                 isp_prt(isp, ISP_LOGTINFO,
 2141                                     "isp_mark_portdb: Chan %d zeroing handle 0x"
 2142                                     "%02x port 0x%06x", chan,
 2143                                     fcp->portdb[i].handle,
 2144                                     fcp->portdb[i].portid);
 2145                                 MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
 2146                         }
 2147                         continue;
 2148                 }
 2149                 if (disposition == 0) {
 2150                         MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
 2151                 } else {
 2152                         switch (fcp->portdb[i].state) {
 2153                         case FC_PORTDB_STATE_CHANGED:
 2154                         case FC_PORTDB_STATE_PENDING_VALID:
 2155                         case FC_PORTDB_STATE_VALID:
 2156                         case FC_PORTDB_STATE_PROBATIONAL:
 2157                                 fcp->portdb[i].state =
 2158                                         FC_PORTDB_STATE_PROBATIONAL;
 2159                                 break;
 2160                         case FC_PORTDB_STATE_ZOMBIE:
 2161                                 break;
 2162                         case FC_PORTDB_STATE_NIL:
 2163                         default:
 2164                                 MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
 2165                                 fcp->portdb[i].state = FC_PORTDB_STATE_NIL;
 2166                                 break;
 2167                         }
 2168                 }
 2169         }
 2170 }
 2171 
 2172 /*
 2173  * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards
 2174  * or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
 2175  */
 2176 static int
 2177 isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid,
 2178     int flags, int gs)
 2179 {
 2180         mbreg_t mbs;
 2181         uint8_t q[QENTRY_LEN];
 2182         isp_plogx_t *plp;
 2183         fcparam *fcp;
 2184         uint8_t *scp;
 2185         uint32_t sst, parm1;
 2186         int rval, lev;
 2187         const char *msg;
 2188         char buf[64];
 2189 
 2190         if (!IS_24XX(isp)) {
 2191                 int action = flags & PLOGX_FLG_CMD_MASK;
 2192                 if (action == PLOGX_FLG_CMD_PLOGI) {
 2193                         return (isp_port_login(isp, handle, portid));
 2194                 } else if (action == PLOGX_FLG_CMD_LOGO) {
 2195                         return (isp_port_logout(isp, handle, portid));
 2196                 } else {
 2197                         return (MBOX_INVALID_COMMAND);
 2198                 }
 2199         }
 2200 
 2201         MEMZERO(q, QENTRY_LEN);
 2202         plp = (isp_plogx_t *) q;
 2203         plp->plogx_header.rqs_entry_count = 1;
 2204         plp->plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
 2205         plp->plogx_handle = 0xffffffff;
 2206         plp->plogx_nphdl = handle;
 2207         plp->plogx_vphdl = chan;
 2208         plp->plogx_portlo = portid;
 2209         plp->plogx_rspsz_porthi = (portid >> 16) & 0xff;
 2210         plp->plogx_flags = flags;
 2211 
 2212         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 2213                 isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, plp);
 2214         }
 2215 
 2216         if (gs == 0) {
 2217                 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 2218                         isp_prt(isp, ISP_LOGERR, sacq);
 2219                         return (-1);
 2220                 }
 2221         }
 2222         fcp = FCPARAM(isp, chan);
 2223         scp = fcp->isp_scratch;
 2224         isp_put_plogx(isp, plp, (isp_plogx_t *) scp);
 2225 
 2226 
 2227         MEMZERO(&mbs, sizeof (mbs));
 2228         mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
 2229         mbs.param[1] = QENTRY_LEN;
 2230         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 2231         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 2232         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 2233         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 2234         mbs.timeout = 500000;
 2235         mbs.logval = MBLOGALL;
 2236         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN);
 2237         isp_mboxcmd(isp, &mbs);
 2238         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 2239                 rval = mbs.param[0];
 2240                 goto out;
 2241         }
 2242         MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN);
 2243         scp += QENTRY_LEN;
 2244         isp_get_plogx(isp, (isp_plogx_t *) scp, plp);
 2245         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 2246                 isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, plp);
 2247         }
 2248 
 2249         if (plp->plogx_status == PLOGX_STATUS_OK) {
 2250                 rval = 0;
 2251                 goto out;
 2252         } else if (plp->plogx_status != PLOGX_STATUS_IOCBERR) {
 2253                 isp_prt(isp, ISP_LOGWARN,
 2254                     "status 0x%x on port login IOCB chanel %d",
 2255                     plp->plogx_status, chan);
 2256                 rval = -1;
 2257                 goto out;
 2258         }
 2259 
 2260         sst = plp->plogx_ioparm[0].lo16 | (plp->plogx_ioparm[0].hi16 << 16);
 2261         parm1 = plp->plogx_ioparm[1].lo16 | (plp->plogx_ioparm[1].hi16 << 16);
 2262 
 2263         rval = -1;
 2264         lev = ISP_LOGERR;
 2265         msg = NULL;
 2266 
 2267         switch (sst) {
 2268         case PLOGX_IOCBERR_NOLINK:
 2269                 msg = "no link";
 2270                 break;
 2271         case PLOGX_IOCBERR_NOIOCB:
 2272                 msg = "no IOCB buffer";
 2273                 break;
 2274         case PLOGX_IOCBERR_NOXGHG:
 2275                 msg = "no Exchange Control Block";
 2276                 break;
 2277         case PLOGX_IOCBERR_FAILED:
 2278                 SNPRINTF(buf, sizeof (buf),
 2279                     "reason 0x%x (last LOGIN state 0x%x)",
 2280                     parm1 & 0xff, (parm1 >> 8) & 0xff);
 2281                 msg = buf;
 2282                 break;
 2283         case PLOGX_IOCBERR_NOFABRIC:
 2284                 msg = "no fabric";
 2285                 break;
 2286         case PLOGX_IOCBERR_NOTREADY:
 2287                 msg = "firmware not ready";
 2288                 break;
 2289         case PLOGX_IOCBERR_NOLOGIN:
 2290                 SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)",
 2291                     parm1);
 2292                 msg = buf;
 2293                 rval = MBOX_NOT_LOGGED_IN;
 2294                 break;
 2295         case PLOGX_IOCBERR_REJECT:
 2296                 SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1);
 2297                 msg = buf;
 2298                 break;
 2299         case PLOGX_IOCBERR_NOPCB:
 2300                 msg = "no PCB allocated";
 2301                 break;
 2302         case PLOGX_IOCBERR_EINVAL:
 2303                 SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x",
 2304                     parm1);
 2305                 msg = buf;
 2306                 break;
 2307         case PLOGX_IOCBERR_PORTUSED:
 2308                 lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;      
 2309                 SNPRINTF(buf, sizeof (buf),
 2310                     "already logged in with N-Port handle 0x%x", parm1);
 2311                 msg = buf;
 2312                 rval = MBOX_PORT_ID_USED | (parm1 << 16);
 2313                 break;
 2314         case PLOGX_IOCBERR_HNDLUSED:
 2315                 lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
 2316                 SNPRINTF(buf, sizeof (buf),
 2317                     "handle already used for PortID 0x%06x", parm1);
 2318                 msg = buf;
 2319                 rval = MBOX_LOOP_ID_USED;
 2320                 break;
 2321         case PLOGX_IOCBERR_NOHANDLE:
 2322                 msg = "no handle allocated";
 2323                 break;
 2324         case PLOGX_IOCBERR_NOFLOGI:
 2325                 msg = "no FLOGI_ACC";
 2326                 break;
 2327         default:
 2328                 SNPRINTF(buf, sizeof (buf), "status %x from %x",
 2329                     plp->plogx_status, flags);
 2330                 msg = buf;
 2331                 break;
 2332         }
 2333         if (msg) {
 2334                 isp_prt(isp, ISP_LOGERR,
 2335                     "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s",
 2336                     chan, portid, handle, msg);
 2337         }
 2338 out:
 2339         if (gs == 0) {
 2340                 FC_SCRATCH_RELEASE(isp, chan);
 2341         }
 2342         return (rval);
 2343 }
 2344 
 2345 static int
 2346 isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
 2347 {
 2348         mbreg_t mbs;
 2349 
 2350         MEMZERO(&mbs, sizeof (mbs));
 2351         mbs.param[0] = MBOX_FABRIC_LOGIN;
 2352         if (ISP_CAP_2KLOGIN(isp)) {
 2353                 mbs.param[1] = handle;
 2354                 mbs.ibits = (1 << 10);
 2355         } else {
 2356                 mbs.param[1] = handle << 8;
 2357         }
 2358         mbs.param[2] = portid >> 16;
 2359         mbs.param[3] = portid;
 2360         mbs.logval = MBLOGNONE;
 2361         mbs.timeout = 500000;
 2362         isp_mboxcmd(isp, &mbs);
 2363 
 2364         switch (mbs.param[0]) {
 2365         case MBOX_PORT_ID_USED:
 2366                 isp_prt(isp, ISP_LOGDEBUG0,
 2367                     "isp_port_login: portid 0x%06x already logged in as %u",
 2368                     portid, mbs.param[1]);
 2369                 return (MBOX_PORT_ID_USED | (mbs.param[1] << 16));
 2370 
 2371         case MBOX_LOOP_ID_USED:
 2372                 isp_prt(isp, ISP_LOGDEBUG0,
 2373                     "isp_port_login: handle %u in use for port id 0x%02xXXXX",
 2374                     handle, mbs.param[1] & 0xff);
 2375                 return (MBOX_LOOP_ID_USED);
 2376 
 2377         case MBOX_COMMAND_COMPLETE:
 2378                 return (0);
 2379 
 2380         case MBOX_COMMAND_ERROR:
 2381                 isp_prt(isp, ISP_LOGINFO,
 2382                     "isp_port_login: error 0x%x in PLOGI to port 0x%06x",
 2383                     mbs.param[1], portid);
 2384                 return (MBOX_COMMAND_ERROR);
 2385 
 2386         case MBOX_ALL_IDS_USED:
 2387                 isp_prt(isp, ISP_LOGINFO,
 2388                     "isp_port_login: all IDs used for fabric login");
 2389                 return (MBOX_ALL_IDS_USED);
 2390 
 2391         default:
 2392                 isp_prt(isp, ISP_LOGINFO,
 2393                     "isp_port_login: error 0x%x on port login of 0x%06x@0x%0x",
 2394                     mbs.param[0], portid, handle);
 2395                 return (mbs.param[0]);
 2396         }
 2397 }
 2398 
 2399 static int
 2400 isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
 2401 {
 2402         mbreg_t mbs;
 2403 
 2404         MEMZERO(&mbs, sizeof (mbs));
 2405         mbs.param[0] = MBOX_FABRIC_LOGOUT;
 2406         if (ISP_CAP_2KLOGIN(isp)) {
 2407                 mbs.param[1] = handle;
 2408                 mbs.ibits = (1 << 10);
 2409         } else {
 2410                 mbs.param[1] = handle << 8;
 2411         }
 2412         mbs.logval = MBLOGNONE;
 2413         mbs.timeout = 100000;
 2414         isp_mboxcmd(isp, &mbs);
 2415         return (mbs.param[0] == MBOX_COMMAND_COMPLETE? 0 : mbs.param[0]);
 2416 }
 2417 
 2418 static int
 2419 isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
 2420 {
 2421         fcparam *fcp = FCPARAM(isp, chan);
 2422         mbreg_t mbs;
 2423         union {
 2424                 isp_pdb_21xx_t fred;
 2425                 isp_pdb_24xx_t bill;
 2426         } un;
 2427 
 2428         MEMZERO(&mbs, sizeof (mbs));
 2429         mbs.param[0] = MBOX_GET_PORT_DB;
 2430         if (IS_24XX(isp)) {
 2431                 mbs.ibits = (1 << 9)|(1 << 10);
 2432                 mbs.param[1] = id;
 2433                 mbs.param[9] = chan;
 2434         } else if (ISP_CAP_2KLOGIN(isp)) {
 2435                 mbs.param[1] = id;
 2436         } else {
 2437                 mbs.param[1] = id << 8;
 2438         }
 2439         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 2440         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 2441         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 2442         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 2443         mbs.timeout = 250000;
 2444         mbs.logval = MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR;
 2445         if (dolock) {
 2446                 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 2447                         isp_prt(isp, ISP_LOGERR, sacq);
 2448                         return (-1);
 2449                 }
 2450         }
 2451         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (un));
 2452         isp_mboxcmd(isp, &mbs);
 2453         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 2454                 if (dolock) {
 2455                         FC_SCRATCH_RELEASE(isp, chan);
 2456                 }
 2457                 return (mbs.param[0]);
 2458         }
 2459         if (IS_24XX(isp)) {
 2460                 isp_get_pdb_24xx(isp, fcp->isp_scratch, &un.bill);
 2461                 pdb->handle = un.bill.pdb_handle;
 2462                 pdb->s3_role = un.bill.pdb_prli_svc3;
 2463                 pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
 2464                 MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
 2465                 MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
 2466                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 2467                     "Chan %d Port 0x%06x flags 0x%x curstate %x",
 2468                     chan, pdb->portid, un.bill.pdb_flags,
 2469                     un.bill.pdb_curstate);
 2470                 if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE &&
 2471                     un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) {
 2472                         mbs.param[0] = MBOX_NOT_LOGGED_IN;
 2473                         if (dolock) {
 2474                                 FC_SCRATCH_RELEASE(isp, chan);
 2475                         }
 2476                         return (mbs.param[0]);
 2477                 }
 2478         } else {
 2479                 isp_get_pdb_21xx(isp, fcp->isp_scratch, &un.fred);
 2480                 pdb->handle = un.fred.pdb_loopid;
 2481                 pdb->s3_role = un.fred.pdb_prli_svc3;
 2482                 pdb->portid = BITS2WORD(un.fred.pdb_portid_bits);
 2483                 MEMCPY(pdb->portname, un.fred.pdb_portname, 8);
 2484                 MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8);
 2485         }
 2486         if (dolock) {
 2487                 FC_SCRATCH_RELEASE(isp, chan);
 2488         }
 2489         return (0);
 2490 }
 2491 
 2492 static void
 2493 isp_dump_chip_portdb(ispsoftc_t *isp, int chan, int dolock)
 2494 {
 2495         isp_pdb_t pdb;
 2496         int lim, loopid;
 2497 
 2498         if (ISP_CAP_2KLOGIN(isp)) {
 2499                 lim = NPH_MAX_2K;
 2500         } else {
 2501                 lim = NPH_MAX;
 2502         }
 2503         for (loopid = 0; loopid != lim; loopid++) {
 2504                 if (isp_getpdb(isp, chan, loopid, &pdb, dolock)) {
 2505                         continue;
 2506                 }
 2507                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGINFO, "Chan %d Loopid 0x%04x "
 2508                     "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x",
 2509                     chan, loopid, pdb.portid, pdb.portname[0], pdb.portname[1],
 2510                     pdb.portname[2], pdb.portname[3], pdb.portname[4],
 2511                     pdb.portname[5], pdb.portname[6], pdb.portname[7]);
 2512         }
 2513 }
 2514 
 2515 static uint64_t
 2516 isp_get_wwn(ispsoftc_t *isp, int chan, int loopid, int nodename)
 2517 {
 2518         uint64_t wwn = INI_NONE;
 2519         fcparam *fcp = FCPARAM(isp, chan);
 2520         mbreg_t mbs;
 2521 
 2522         if (fcp->isp_fwstate < FW_READY ||
 2523             fcp->isp_loopstate < LOOP_PDB_RCVD) {
 2524                 return (wwn);
 2525         }
 2526         MEMZERO(&mbs, sizeof (mbs));
 2527         mbs.param[0] = MBOX_GET_PORT_NAME;
 2528         if (ISP_CAP_2KLOGIN(isp)) {
 2529                 mbs.param[1] = loopid;
 2530                 mbs.ibits = (1 << 10);
 2531                 if (nodename) {
 2532                         mbs.param[10] = 1;
 2533                 }
 2534                 if (ISP_CAP_MULTI_ID(isp)) {
 2535                         mbs.ibits |= (1 << 9);
 2536                         mbs.param[9] = chan;
 2537                 }
 2538         } else {
 2539                 mbs.param[1] = loopid << 8;
 2540                 if (nodename) {
 2541                         mbs.param[1] |= 1;
 2542                 }
 2543         }
 2544         mbs.logval = MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR;
 2545         isp_mboxcmd(isp, &mbs);
 2546         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 2547                 return (wwn);
 2548         }
 2549         if (IS_24XX(isp)) {
 2550                 wwn =
 2551                     (((uint64_t)(mbs.param[2] >> 8))    << 56) |
 2552                     (((uint64_t)(mbs.param[2] & 0xff))  << 48) |
 2553                     (((uint64_t)(mbs.param[3] >> 8))    << 40) |
 2554                     (((uint64_t)(mbs.param[3] & 0xff))  << 32) |
 2555                     (((uint64_t)(mbs.param[6] >> 8))    << 24) |
 2556                     (((uint64_t)(mbs.param[6] & 0xff))  << 16) |
 2557                     (((uint64_t)(mbs.param[7] >> 8))    <<  8) |
 2558                     (((uint64_t)(mbs.param[7] & 0xff)));
 2559         } else {
 2560                 wwn =
 2561                     (((uint64_t)(mbs.param[2] & 0xff))  << 56) |
 2562                     (((uint64_t)(mbs.param[2] >> 8))    << 48) |
 2563                     (((uint64_t)(mbs.param[3] & 0xff))  << 40) |
 2564                     (((uint64_t)(mbs.param[3] >> 8))    << 32) |
 2565                     (((uint64_t)(mbs.param[6] & 0xff))  << 24) |
 2566                     (((uint64_t)(mbs.param[6] >> 8))    << 16) |
 2567                     (((uint64_t)(mbs.param[7] & 0xff))  <<  8) |
 2568                     (((uint64_t)(mbs.param[7] >> 8)));
 2569         }
 2570         return (wwn);
 2571 }
 2572 
 2573 /*
 2574  * Make sure we have good FC link.
 2575  */
 2576 
 2577 static int
 2578 isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
 2579 {
 2580         static const char *toponames[] = {
 2581                 "Private Loop",
 2582                 "FL Port",
 2583                 "N-Port to N-Port",
 2584                 "F Port",
 2585                 "F Port (no FLOGI_ACC response)"
 2586         };
 2587         mbreg_t mbs;
 2588         int count, check_for_fabric, r;
 2589         uint8_t lwfs;
 2590         int loopid;
 2591         fcparam *fcp;
 2592         fcportdb_t *lp;
 2593         isp_pdb_t pdb;
 2594 
 2595         fcp = FCPARAM(isp, chan);
 2596 
 2597         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 2598             "Chan %d FC Link Test Entry", chan);
 2599         ISP_MARK_PORTDB(isp, chan, 1);
 2600 
 2601         /*
 2602          * Wait up to N microseconds for F/W to go to a ready state.
 2603          */
 2604         lwfs = FW_CONFIG_WAIT;
 2605         count = 0;
 2606         while (count < usdelay) {
 2607                 uint64_t enano;
 2608                 uint32_t wrk;
 2609                 NANOTIME_T hra, hrb;
 2610 
 2611                 GET_NANOTIME(&hra);
 2612                 isp_fw_state(isp, chan);
 2613                 if (lwfs != fcp->isp_fwstate) {
 2614                         isp_prt(isp, ISP_LOGCONFIG|ISP_LOGSANCFG,
 2615                             "Chan %d Firmware State <%s->%s>",
 2616                             chan, ispfc_fw_statename((int)lwfs),
 2617                             ispfc_fw_statename((int)fcp->isp_fwstate));
 2618                         lwfs = fcp->isp_fwstate;
 2619                 }
 2620                 if (fcp->isp_fwstate == FW_READY) {
 2621                         break;
 2622                 }
 2623                 GET_NANOTIME(&hrb);
 2624 
 2625                 /*
 2626                  * Get the elapsed time in nanoseconds.
 2627                  * Always guaranteed to be non-zero.
 2628                  */
 2629                 enano = NANOTIME_SUB(&hrb, &hra);
 2630 
 2631                 isp_prt(isp, ISP_LOGDEBUG1,
 2632                     "usec%d: 0x%lx->0x%lx enano 0x%x%08x",
 2633                     count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb),
 2634                     (uint32_t)(enano >> 32), (uint32_t)(enano));
 2635 
 2636                 /*
 2637                  * If the elapsed time is less than 1 millisecond,
 2638                  * delay a period of time up to that millisecond of
 2639                  * waiting.
 2640                  *
 2641                  * This peculiar code is an attempt to try and avoid
 2642                  * invoking uint64_t math support functions for some
 2643                  * platforms where linkage is a problem.
 2644                  */
 2645                 if (enano < (1000 * 1000)) {
 2646                         count += 1000;
 2647                         enano = (1000 * 1000) - enano;
 2648                         while (enano > (uint64_t) 4000000000U) {
 2649                                 USEC_SLEEP(isp, 4000000);
 2650                                 enano -= (uint64_t) 4000000000U;
 2651                         }
 2652                         wrk = enano;
 2653                         wrk /= 1000;
 2654                         USEC_SLEEP(isp, wrk);
 2655                 } else {
 2656                         while (enano > (uint64_t) 4000000000U) {
 2657                                 count += 4000000;
 2658                                 enano -= (uint64_t) 4000000000U;
 2659                         }
 2660                         wrk = enano;
 2661                         count += (wrk / 1000);
 2662                 }
 2663         }
 2664 
 2665 
 2666 
 2667         /*
 2668          * If we haven't gone to 'ready' state, return.
 2669          */
 2670         if (fcp->isp_fwstate != FW_READY) {
 2671                 isp_prt(isp, ISP_LOGSANCFG,
 2672                     "isp_fclink_test: chan %d not at FW_READY state", chan);
 2673                 return (-1);
 2674         }
 2675 
 2676         /*
 2677          * Get our Loop ID and Port ID.
 2678          */
 2679         MEMZERO(&mbs, sizeof (mbs));
 2680         mbs.param[0] = MBOX_GET_LOOP_ID;
 2681         if (ISP_CAP_MULTI_ID(isp)) {
 2682                 mbs.param[9] = chan;
 2683                 mbs.ibits = (1 << 9);
 2684                 mbs.obits = (1 << 7);
 2685         }
 2686         mbs.logval = MBLOGALL;
 2687         isp_mboxcmd(isp, &mbs);
 2688         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 2689                 return (-1);
 2690         }
 2691 
 2692         if (ISP_CAP_2KLOGIN(isp)) {
 2693                 fcp->isp_loopid = mbs.param[1];
 2694         } else {
 2695                 fcp->isp_loopid = mbs.param[1] & 0xff;
 2696         }
 2697 
 2698         if (IS_2100(isp)) {
 2699                 fcp->isp_topo = TOPO_NL_PORT;
 2700         } else {
 2701                 int topo = (int) mbs.param[6];
 2702                 if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB) {
 2703                         topo = TOPO_PTP_STUB;
 2704                 }
 2705                 fcp->isp_topo = topo;
 2706         }
 2707         fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
 2708 
 2709         if (IS_2100(isp)) {
 2710                 /*
 2711                  * Don't bother with fabric if we are using really old
 2712                  * 2100 firmware. It's just not worth it.
 2713                  */
 2714                 if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) {
 2715                         check_for_fabric = 1;
 2716                 } else {
 2717                         check_for_fabric = 0;
 2718                 }
 2719         } else if (fcp->isp_topo == TOPO_FL_PORT ||
 2720             fcp->isp_topo == TOPO_F_PORT) {
 2721                 check_for_fabric = 1;
 2722         } else {
 2723                 check_for_fabric = 0;
 2724         }
 2725 
 2726         /*
 2727          * Check to make sure we got a valid loopid
 2728          * The 24XX seems to mess this up for multiple
 2729          * channels.
 2730          */
 2731         if (fcp->isp_topo == TOPO_FL_PORT ||
 2732             fcp->isp_topo == TOPO_NL_PORT) {
 2733                 uint8_t alpa = fcp->isp_portid;
 2734 
 2735                 if (alpa == 0) {
 2736                         /* "Cannot Happen" */
 2737                         isp_prt(isp, ISP_LOGWARN,
 2738                             "Zero AL_PA for Loop Topology?");
 2739                 } else {
 2740                         int i;
 2741                         for (i = 0; alpa_map[i]; i++) {
 2742                                 if (alpa_map[i] == alpa) {
 2743                                         break;
 2744                                 }
 2745                         }
 2746                         if (alpa_map[i] && fcp->isp_loopid != i) {
 2747                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 2748                                     "Chan %d deriving loopid %d from AL_PA map "
 2749                                     " (AL_PA 0x%x) and ignoring returned value "
 2750                                     "%d (AL_PA 0x%x)", chan, i, alpa_map[i],
 2751                                     fcp->isp_loopid, alpa);
 2752                                 fcp->isp_loopid = i;
 2753                         }
 2754                 }
 2755         }
 2756 
 2757 
 2758         if (IS_24XX(isp)) { /* XXX SHOULDN'T THIS BE FOR 2K F/W? XXX */
 2759                 loopid = NPH_FL_ID;
 2760         } else {
 2761                 loopid = FL_ID;
 2762         }
 2763         if (check_for_fabric) {
 2764                 r = isp_getpdb(isp, chan, loopid, &pdb, 1);
 2765                 if (r && (fcp->isp_topo == TOPO_F_PORT ||
 2766                     fcp->isp_topo == TOPO_FL_PORT)) {
 2767                         isp_prt(isp, ISP_LOGWARN, "fabric topology but cannot "
 2768                             "get info about fabric controller (0x%x)", r);
 2769                         fcp->isp_topo = TOPO_PTP_STUB;
 2770                 }
 2771         } else {
 2772                 r = -1;
 2773         }
 2774         if (r == 0) {
 2775                 if (IS_2100(isp)) {
 2776                         fcp->isp_topo = TOPO_FL_PORT;
 2777                 }
 2778                 if (pdb.portid == 0) {
 2779                         /*
 2780                          * Crock.
 2781                          */
 2782                         fcp->isp_topo = TOPO_NL_PORT;
 2783                         goto not_on_fabric;
 2784                 }
 2785 
 2786                 /*
 2787                  * Save the Fabric controller's port database entry.
 2788                  */
 2789                 lp = &fcp->portdb[FL_ID];
 2790                 lp->state = FC_PORTDB_STATE_PENDING_VALID;
 2791                 MAKE_WWN_FROM_NODE_NAME(lp->node_wwn, pdb.nodename);
 2792                 MAKE_WWN_FROM_NODE_NAME(lp->port_wwn, pdb.portname);
 2793                 lp->roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
 2794                 lp->portid = pdb.portid;
 2795                 lp->handle = pdb.handle;
 2796                 lp->new_portid = lp->portid;
 2797                 lp->new_roles = lp->roles;
 2798                 if (IS_24XX(isp)) {
 2799                         fcp->inorder = (mbs.param[7] & ISP24XX_INORDER) != 0;
 2800                         if (ISP_FW_NEWER_THAN(isp, 4, 0, 27)) {
 2801                                 fcp->npiv_fabric =
 2802                                     (mbs.param[7] & ISP24XX_NPIV_SAN) != 0;
 2803                                 if (fcp->npiv_fabric) {
 2804                                         isp_prt(isp, ISP_LOGCONFIG,
 2805                                            "fabric supports NP-IV");
 2806                                 }
 2807                         }
 2808                         if (chan) {
 2809                                 fcp->isp_sns_hdl = NPH_SNS_HDLBASE + chan;
 2810                                 r = isp_plogx(isp, chan, fcp->isp_sns_hdl,
 2811                                     SNS_PORT_ID, PLOGX_FLG_CMD_PLOGI |
 2812                                     PLOGX_FLG_COND_PLOGI | PLOGX_FLG_SKIP_PRLI,
 2813                                     0);
 2814                                 if (r) {
 2815                                         isp_prt(isp, ISP_LOGWARN, "isp_fclink"
 2816                                             "_test: Chan %d cannot log into "
 2817                                             "SNS", chan);
 2818                                         return (-1);
 2819                                 }
 2820                         } else {
 2821                                 fcp->isp_sns_hdl = NPH_SNS_ID;
 2822                         }
 2823                         r = isp_register_fc4_type_24xx(isp, chan);
 2824                 } else {
 2825                         fcp->isp_sns_hdl = SNS_ID;
 2826                         r = isp_register_fc4_type(isp, chan);
 2827                 }
 2828                 if (r) {
 2829                         isp_prt(isp, ISP_LOGSANCFG,
 2830                             "isp_fclink_test: register fc4 type failed");
 2831                         return (-1);
 2832                 }
 2833         } else {
 2834 not_on_fabric:
 2835                 fcp->portdb[FL_ID].state = FC_PORTDB_STATE_NIL;
 2836         }
 2837 
 2838         fcp->isp_gbspeed = 1;
 2839         if (IS_23XX(isp) || IS_24XX(isp)) {
 2840                 MEMZERO(&mbs, sizeof (mbs));
 2841                 mbs.param[0] = MBOX_GET_SET_DATA_RATE;
 2842                 mbs.param[1] = MBGSD_GET_RATE;
 2843                 /* mbs.param[2] undefined if we're just getting rate */
 2844                 mbs.logval = MBLOGALL;
 2845                 mbs.timeout = 3000000;
 2846                 isp_mboxcmd(isp, &mbs);
 2847                 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 2848                         if (mbs.param[1] == MBGSD_FOURGB) {
 2849                                 isp_prt(isp, ISP_LOGINFO,
 2850                                     "Chan %d 4Gb link speed", chan);
 2851                                 fcp->isp_gbspeed = 4;
 2852                         } else if (mbs.param[1] == MBGSD_TWOGB) {
 2853                                 isp_prt(isp, ISP_LOGINFO,
 2854                                     "Chan %d 2Gb link speed", chan);
 2855                                 fcp->isp_gbspeed = 2;
 2856                         } else if (mbs.param[1] == MBGSD_ONEGB) {
 2857                                 isp_prt(isp, ISP_LOGINFO,
 2858                                     "Chan %d 1Gb link speed", chan);
 2859                                 fcp->isp_gbspeed = 1;
 2860                         }
 2861                 }
 2862         }
 2863 
 2864         /*
 2865          * Announce ourselves, too.
 2866          */
 2867         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGCONFIG, topology, chan,
 2868             (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) fcp->isp_wwpn,
 2869             fcp->isp_portid, fcp->isp_loopid, toponames[fcp->isp_topo]);
 2870         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 2871             "Chan %d FC Link Test Complete", chan);
 2872         return (0);
 2873 }
 2874 
 2875 static const char *
 2876 ispfc_fw_statename(int state)
 2877 {
 2878         switch(state) {
 2879         case FW_CONFIG_WAIT:    return "Config Wait";
 2880         case FW_WAIT_AL_PA:     return "Waiting for AL_PA";
 2881         case FW_WAIT_LOGIN:     return "Wait Login";
 2882         case FW_READY:          return "Ready";
 2883         case FW_LOSS_OF_SYNC:   return "Loss Of Sync";
 2884         case FW_ERROR:          return "Error";
 2885         case FW_REINIT:         return "Re-Init";
 2886         case FW_NON_PART:       return "Nonparticipating";
 2887         default:                return "?????";
 2888         }
 2889 }
 2890 
 2891 /*
 2892  * Complete the synchronization of our Port Database.
 2893  *
 2894  * At this point, we've scanned the local loop (if any) and the fabric
 2895  * and performed fabric logins on all new devices.
 2896  *
 2897  * Our task here is to go through our port database and remove any entities
 2898  * that are still marked probational (issuing PLOGO for ones which we had
 2899  * PLOGI'd into) or are dead.
 2900  *
 2901  * Our task here is to also check policy to decide whether devices which
 2902  * have *changed* in some way should still be kept active. For example,
 2903  * if a device has just changed PortID, we can either elect to treat it
 2904  * as an old device or as a newly arrived device (and notify the outer
 2905  * layer appropriately).
 2906  *
 2907  * We also do initiator map target id assignment here for new initiator
 2908  * devices and refresh old ones ot make sure that they point to the corret
 2909  * entities.
 2910  */
 2911 static int
 2912 isp_pdb_sync(ispsoftc_t *isp, int chan)
 2913 {
 2914         fcparam *fcp = FCPARAM(isp, chan);
 2915         fcportdb_t *lp;
 2916         uint16_t dbidx;
 2917 
 2918         if (fcp->isp_loopstate == LOOP_READY) {
 2919                 return (0);
 2920         }
 2921 
 2922         /*
 2923          * Make sure we're okay for doing this right now.
 2924          */
 2925         if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
 2926             fcp->isp_loopstate != LOOP_FSCAN_DONE &&
 2927             fcp->isp_loopstate != LOOP_LSCAN_DONE) {
 2928                 isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d",
 2929                     fcp->isp_loopstate);
 2930                 return (-1);
 2931         }
 2932 
 2933         if (fcp->isp_topo == TOPO_FL_PORT ||
 2934             fcp->isp_topo == TOPO_NL_PORT ||
 2935             fcp->isp_topo == TOPO_N_PORT) {
 2936                 if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
 2937                         if (isp_scan_loop(isp, chan) != 0) {
 2938                                 isp_prt(isp, ISP_LOGWARN,
 2939                                     "isp_pdb_sync: isp_scan_loop failed");
 2940                                 return (-1);
 2941                         }
 2942                 }
 2943         }
 2944 
 2945         if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
 2946                 if (fcp->isp_loopstate < LOOP_FSCAN_DONE) {
 2947                         if (isp_scan_fabric(isp, chan) != 0) {
 2948                                 isp_prt(isp, ISP_LOGWARN,
 2949                                     "isp_pdb_sync: isp_scan_fabric failed");
 2950                                 return (-1);
 2951                         }
 2952                 }
 2953         }
 2954 
 2955         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 2956             "Chan %d Synchronizing PDBs", chan);
 2957 
 2958         fcp->isp_loopstate = LOOP_SYNCING_PDB;
 2959 
 2960         for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
 2961                 lp = &fcp->portdb[dbidx];
 2962 
 2963                 if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode) {
 2964                         continue;
 2965                 }
 2966 
 2967                 if (lp->state == FC_PORTDB_STATE_VALID) {
 2968                         if (dbidx != FL_ID) {
 2969                                 isp_prt(isp,
 2970                                     ISP_LOGERR, "portdb idx %d already valid",
 2971                                     dbidx);
 2972                         }
 2973                         continue;
 2974                 }
 2975 
 2976                 switch (lp->state) {
 2977                 case FC_PORTDB_STATE_PROBATIONAL:
 2978                 case FC_PORTDB_STATE_DEAD:
 2979                         /*
 2980                          * It's up to the outer layers to clear isp_ini_map.
 2981                          */
 2982                         lp->state = FC_PORTDB_STATE_NIL;
 2983                         isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
 2984                         if (lp->autologin == 0) {
 2985                                 (void) isp_plogx(isp, chan, lp->handle,
 2986                                     lp->portid,
 2987                                     PLOGX_FLG_CMD_LOGO |
 2988                                     PLOGX_FLG_IMPLICIT |
 2989                                     PLOGX_FLG_FREE_NPHDL, 0);
 2990                         } else {
 2991                                 lp->autologin = 0;
 2992                         }
 2993                         lp->new_roles = 0;
 2994                         lp->new_portid = 0;
 2995                         /*
 2996                          * Note that we might come out of this with our state
 2997                          * set to FC_PORTDB_STATE_ZOMBIE.
 2998                          */
 2999                         break;
 3000                 case FC_PORTDB_STATE_NEW:
 3001                         /*
 3002                          * It's up to the outer layers to assign a virtual
 3003                          * target id in isp_ini_map (if any).
 3004                          */
 3005                         lp->portid = lp->new_portid;
 3006                         lp->roles = lp->new_roles;
 3007                         lp->state = FC_PORTDB_STATE_VALID;
 3008                         isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
 3009                         lp->new_roles = 0;
 3010                         lp->new_portid = 0;
 3011                         lp->reserved = 0;
 3012                         lp->new_reserved = 0;
 3013                         break;
 3014                 case FC_PORTDB_STATE_CHANGED:
 3015 /*
 3016  * XXXX FIX THIS
 3017  */
 3018                         lp->state = FC_PORTDB_STATE_VALID;
 3019                         isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
 3020                         lp->new_roles = 0;
 3021                         lp->new_portid = 0;
 3022                         lp->reserved = 0;
 3023                         lp->new_reserved = 0;
 3024                         break;
 3025                 case FC_PORTDB_STATE_PENDING_VALID:
 3026                         lp->portid = lp->new_portid;
 3027                         lp->roles = lp->new_roles;
 3028                         if (lp->ini_map_idx) {
 3029                                 int t = lp->ini_map_idx - 1;
 3030                                 fcp->isp_ini_map[t] = dbidx + 1;
 3031                         }
 3032                         lp->state = FC_PORTDB_STATE_VALID;
 3033                         isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
 3034                         if (dbidx != FL_ID) {
 3035                                 lp->new_roles = 0;
 3036                                 lp->new_portid = 0;
 3037                         }
 3038                         lp->reserved = 0;
 3039                         lp->new_reserved = 0;
 3040                         break;
 3041                 case FC_PORTDB_STATE_ZOMBIE:
 3042                         break;
 3043                 default:
 3044                         isp_prt(isp, ISP_LOGWARN,
 3045                             "isp_scan_loop: state %d for idx %d",
 3046                             lp->state, dbidx);
 3047                         isp_dump_portdb(isp, chan);
 3048                 }
 3049         }
 3050 
 3051         /*
 3052          * If we get here, we've for sure seen not only a valid loop
 3053          * but know what is or isn't on it, so mark this for usage
 3054          * in isp_start.
 3055          */
 3056         fcp->loop_seen_once = 1;
 3057         fcp->isp_loopstate = LOOP_READY;
 3058         return (0);
 3059 }
 3060 
 3061 /*
 3062  * Scan local loop for devices.
 3063  */
 3064 static int
 3065 isp_scan_loop(ispsoftc_t *isp, int chan)
 3066 {
 3067         fcportdb_t *lp, tmp;
 3068         fcparam *fcp = FCPARAM(isp, chan);
 3069         int i;
 3070         isp_pdb_t pdb;
 3071         uint16_t handle, lim = 0;
 3072 
 3073         if (fcp->isp_fwstate < FW_READY ||
 3074             fcp->isp_loopstate < LOOP_PDB_RCVD) {
 3075                 return (-1);
 3076         }
 3077 
 3078         if (fcp->isp_loopstate > LOOP_SCANNING_LOOP) {
 3079                 return (0);
 3080         }
 3081 
 3082         /*
 3083          * Check our connection topology.
 3084          *
 3085          * If we're a public or private loop, we scan 0..125 as handle values.
 3086          * The firmware has (typically) peformed a PLOGI for us. We skip this
 3087          * step if we're a ISP_24XX in NP-IV mode.
 3088          *
 3089          * If we're a N-port connection, we treat this is a short loop (0..1).
 3090          */
 3091         switch (fcp->isp_topo) {
 3092         case TOPO_NL_PORT:
 3093                 lim = LOCAL_LOOP_LIM;
 3094                 break;
 3095         case TOPO_FL_PORT:
 3096                 if (IS_24XX(isp) && isp->isp_nchan > 1) {
 3097                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3098                             "Chan %d Skipping Local Loop Scan", chan);
 3099                         fcp->isp_loopstate = LOOP_LSCAN_DONE;
 3100                         return (0);
 3101                 }
 3102                 lim = LOCAL_LOOP_LIM;
 3103                 break;
 3104         case TOPO_N_PORT:
 3105                 lim = 2;
 3106                 break;
 3107         default:
 3108                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3109                     "Chan %d no loop topology to scan", chan);
 3110                 fcp->isp_loopstate = LOOP_LSCAN_DONE;
 3111                 return (0);
 3112         }
 3113 
 3114         fcp->isp_loopstate = LOOP_SCANNING_LOOP;
 3115 
 3116         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3117             "Chan %d FC scan loop 0..%d", chan, lim-1);
 3118 
 3119 
 3120         /*
 3121          * Run through the list and get the port database info for each one.
 3122          */
 3123         for (handle = 0; handle < lim; handle++) {
 3124                 int r;
 3125                 /*
 3126                  * Don't scan "special" ids.
 3127                  */
 3128                 if (handle >= FL_ID && handle <= SNS_ID) {
 3129                         continue;
 3130                 }
 3131                 if (ISP_CAP_2KLOGIN(isp)) {
 3132                         if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
 3133                                 continue;
 3134                         }
 3135                 }
 3136                 /*
 3137                  * In older cards with older f/w GET_PORT_DATABASE has been
 3138                  * known to hang. This trick gets around that problem.
 3139                  */
 3140                 if (IS_2100(isp) || IS_2200(isp)) {
 3141                         uint64_t node_wwn = isp_get_wwn(isp, chan, handle, 1);
 3142                         if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
 3143                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3144                                     "Chan %d FC scan loop DONE (bad)", chan);
 3145                                 return (-1);
 3146                         }
 3147                         if (node_wwn == INI_NONE) {
 3148                                 continue;
 3149                         }
 3150                 }
 3151 
 3152                 /*
 3153                  * Get the port database entity for this index.
 3154                  */
 3155                 r = isp_getpdb(isp, chan, handle, &pdb, 1);
 3156                 if (r != 0) {
 3157                         isp_prt(isp, ISP_LOGDEBUG1,
 3158                             "Chan %d FC scan loop handle %d returned %x",
 3159                             chan, handle, r);
 3160                         if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
 3161                                 ISP_MARK_PORTDB(isp, chan, 1);
 3162                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3163                                     "Chan %d FC scan loop DONE (bad)", chan);
 3164                                 return (-1);
 3165                         }
 3166                         continue;
 3167                 }
 3168 
 3169                 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
 3170                         ISP_MARK_PORTDB(isp, chan, 1);
 3171                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3172                             "Chan %d FC scan loop DONE (bad)", chan);
 3173                         return (-1);
 3174                 }
 3175 
 3176                 /*
 3177                  * On *very* old 2100 firmware we would end up sometimes
 3178                  * with the firmware returning the port database entry
 3179                  * for something else. We used to restart this, but
 3180                  * now we just punt.
 3181                  */
 3182                 if (IS_2100(isp) && pdb.handle != handle) {
 3183                         isp_prt(isp, ISP_LOGWARN,
 3184                             "Chan %d cannot synchronize port database", chan);
 3185                         ISP_MARK_PORTDB(isp, chan, 1);
 3186                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3187                             "Chan %d FC scan loop DONE (bad)", chan);
 3188                         return (-1);
 3189                 }
 3190 
 3191                 /*
 3192                  * Save the pertinent info locally.
 3193                  */
 3194                 MAKE_WWN_FROM_NODE_NAME(tmp.node_wwn, pdb.nodename);
 3195                 MAKE_WWN_FROM_NODE_NAME(tmp.port_wwn, pdb.portname);
 3196                 tmp.roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
 3197                 tmp.portid = pdb.portid;
 3198                 tmp.handle = pdb.handle;
 3199 
 3200                 /*
 3201                  * Check to make sure it's still a valid entry. The 24XX seems
 3202                  * to return a portid but not a WWPN/WWNN or role for devices
 3203                  * which shift on a loop.
 3204                  */
 3205                 if (tmp.node_wwn == 0 || tmp.port_wwn == 0 || tmp.portid == 0) {
 3206                         int a, b, c;
 3207                         a = (tmp.node_wwn == 0);
 3208                         b = (tmp.port_wwn == 0);
 3209                         c = (tmp.portid == 0);
 3210                         if (a == 0 && b == 0) {
 3211                                 tmp.node_wwn =
 3212                                     isp_get_wwn(isp, chan, handle, 1);
 3213                                 tmp.port_wwn =
 3214                                     isp_get_wwn(isp, chan, handle, 0);
 3215                                 if (tmp.node_wwn && tmp.port_wwn) {
 3216                                         isp_prt(isp, ISP_LOGINFO, "DODGED!");
 3217                                         goto cont;
 3218                                 }
 3219                         }
 3220                         isp_prt(isp, ISP_LOGWARN,
 3221                             "Chan %d bad pdb (%1d%1d%1d) @ handle 0x%x", chan,
 3222                             a, b, c, handle);
 3223                         isp_dump_portdb(isp, chan);
 3224                         continue;
 3225                 }
 3226   cont:
 3227 
 3228                 /*
 3229                  * Now search the entire port database
 3230                  * for the same Port and Node WWN.
 3231                  */
 3232                 for (i = 0; i < MAX_FC_TARG; i++) {
 3233                         lp = &fcp->portdb[i];
 3234 
 3235                         if (lp->state == FC_PORTDB_STATE_NIL ||
 3236                             lp->target_mode) {
 3237                                 continue;
 3238                         }
 3239                         if (lp->node_wwn != tmp.node_wwn) {
 3240                                 continue;
 3241                         }
 3242                         if (lp->port_wwn != tmp.port_wwn) {
 3243                                 continue;
 3244                         }
 3245 
 3246                         /*
 3247                          * Okay- we've found a non-nil entry that matches.
 3248                          * Check to make sure it's probational or a zombie.
 3249                          */
 3250                         if (lp->state != FC_PORTDB_STATE_PROBATIONAL &&
 3251                             lp->state != FC_PORTDB_STATE_ZOMBIE) {
 3252                                 isp_prt(isp, ISP_LOGERR,
 3253                                     "Chan %d [%d] not probational/zombie (0x%x)",
 3254                                     chan, i, lp->state);
 3255                                 isp_dump_portdb(isp, chan);
 3256                                 ISP_MARK_PORTDB(isp, chan, 1);
 3257                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3258                                     "Chan %d FC scan loop DONE (bad)", chan);
 3259                                 return (-1);
 3260                         }
 3261 
 3262                         /*
 3263                          * Mark the device as something the f/w logs into
 3264                          * automatically.
 3265                          */
 3266                         lp->autologin = 1;
 3267 
 3268                         /*
 3269                          * Check to make see if really still the same
 3270                          * device. If it is, we mark it pending valid.
 3271                          */
 3272                         if (lp->portid == tmp.portid &&
 3273                             lp->handle == tmp.handle &&
 3274                             lp->roles == tmp.roles) {
 3275                                 lp->new_portid = tmp.portid;
 3276                                 lp->new_roles = tmp.roles;
 3277                                 lp->state = FC_PORTDB_STATE_PENDING_VALID;
 3278                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3279                                     "Chan %d Loop Port 0x%02x@0x%x Pending "
 3280                                     "Valid", chan, tmp.portid, tmp.handle);
 3281                                 break;
 3282                         }
 3283                 
 3284                         /*
 3285                          * We can wipe out the old handle value
 3286                          * here because it's no longer valid.
 3287                          */
 3288                         lp->handle = tmp.handle;
 3289 
 3290                         /*
 3291                          * Claim that this has changed and let somebody else
 3292                          * decide what to do.
 3293                          */
 3294                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3295                             "Chan %d Loop Port 0x%02x@0x%x changed",
 3296                             chan, tmp.portid, tmp.handle);
 3297                         lp->state = FC_PORTDB_STATE_CHANGED;
 3298                         lp->new_portid = tmp.portid;
 3299                         lp->new_roles = tmp.roles;
 3300                         break;
 3301                 }
 3302 
 3303                 /*
 3304                  * Did we find and update an old entry?
 3305                  */
 3306                 if (i < MAX_FC_TARG) {
 3307                         continue;
 3308                 }
 3309 
 3310                 /*
 3311                  * Ah. A new device entry. Find an empty slot
 3312                  * for it and save info for later disposition.
 3313                  */
 3314                 for (i = 0; i < MAX_FC_TARG; i++) {
 3315                         if (fcp->portdb[i].target_mode) {
 3316                                 continue;
 3317                         }
 3318                         if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL) {
 3319                                 break;
 3320                         }
 3321                 }
 3322                 if (i == MAX_FC_TARG) {
 3323                         isp_prt(isp, ISP_LOGERR,
 3324                             "Chan %d out of portdb entries", chan);
 3325                         continue;
 3326                 }
 3327                 lp = &fcp->portdb[i];
 3328 
 3329                 MEMZERO(lp, sizeof (fcportdb_t));
 3330                 lp->autologin = 1;
 3331                 lp->state = FC_PORTDB_STATE_NEW;
 3332                 lp->new_portid = tmp.portid;
 3333                 lp->new_roles = tmp.roles;
 3334                 lp->handle = tmp.handle;
 3335                 lp->port_wwn = tmp.port_wwn;
 3336                 lp->node_wwn = tmp.node_wwn;
 3337                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3338                     "Chan %d Loop Port 0x%02x@0x%x is New Entry",
 3339                     chan, tmp.portid, tmp.handle);
 3340         }
 3341         fcp->isp_loopstate = LOOP_LSCAN_DONE;
 3342         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3343             "Chan %d FC scan loop DONE", chan);
 3344         return (0);
 3345 }
 3346 
 3347 /*
 3348  * Scan the fabric for devices and add them to our port database.
 3349  *
 3350  * Use the GID_FT command to get all Port IDs for FC4 SCSI devices it knows.
 3351  *
 3352  * For 2100-23XX cards, we can use the SNS mailbox command to pass simple
 3353  * name server commands to the switch management server via the QLogic f/w.
 3354  *
 3355  * For the 24XX card, we have to use CT-Pass through run via the Execute IOCB
 3356  * mailbox command.
 3357  *
 3358  * The net result is to leave the list of Port IDs setting untranslated in
 3359  * offset IGPOFF of the FC scratch area, whereupon we'll canonicalize it to
 3360  * host order at OGPOFF.
 3361  */
 3362 
 3363 /*
 3364  * Take less than half of our scratch area to store Port IDs 
 3365  */
 3366 #define GIDLEN  ((ISP_FC_SCRLEN >> 1) - 16 - SNS_GID_FT_REQ_SIZE)
 3367 #define NGENT   ((GIDLEN - 16) >> 2)
 3368 
 3369 #define IGPOFF  (2 * QENTRY_LEN)
 3370 #define OGPOFF  (ISP_FC_SCRLEN >> 1)
 3371 #define ZTXOFF  (ISP_FC_SCRLEN - (1 * QENTRY_LEN))
 3372 #define CTXOFF  (ISP_FC_SCRLEN - (2 * QENTRY_LEN))
 3373 #define XTXOFF  (ISP_FC_SCRLEN - (3 * QENTRY_LEN))
 3374 
 3375 static int
 3376 isp_gid_ft_sns(ispsoftc_t *isp, int chan)
 3377 {
 3378         union {
 3379                 sns_gid_ft_req_t _x;
 3380                 uint8_t _y[SNS_GID_FT_REQ_SIZE];
 3381         } un;
 3382         fcparam *fcp = FCPARAM(isp, chan);
 3383         sns_gid_ft_req_t *rq = &un._x;
 3384         mbreg_t mbs;
 3385 
 3386         isp_prt(isp, ISP_LOGDEBUG0,
 3387             "Chan %d scanning fabric (GID_FT) via SNS", chan);
 3388 
 3389         MEMZERO(rq, SNS_GID_FT_REQ_SIZE);
 3390         rq->snscb_rblen = GIDLEN >> 1;
 3391         rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + IGPOFF);
 3392         rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + IGPOFF);
 3393         rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + IGPOFF);
 3394         rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + IGPOFF);
 3395         rq->snscb_sblen = 6;
 3396         rq->snscb_cmd = SNS_GID_FT;
 3397         rq->snscb_mword_div_2 = NGENT;
 3398         rq->snscb_fc4_type = FC4_SCSI;
 3399 
 3400         isp_put_gid_ft_request(isp, rq, fcp->isp_scratch);
 3401         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
 3402 
 3403         MEMZERO(&mbs, sizeof (mbs));
 3404         mbs.param[0] = MBOX_SEND_SNS;
 3405         mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
 3406         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 3407         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 3408         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 3409         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 3410         mbs.logval = MBLOGALL;
 3411         mbs.timeout = 10000000;
 3412         isp_mboxcmd(isp, &mbs);
 3413         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 3414                 if (mbs.param[0] == MBOX_INVALID_COMMAND) {
 3415                         return (1);
 3416                 } else {
 3417                         return (-1);
 3418                 }
 3419         }
 3420         return (0);
 3421 }
 3422 
 3423 static int
 3424 isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
 3425 {
 3426         mbreg_t mbs;
 3427         fcparam *fcp = FCPARAM(isp, chan);
 3428         union {
 3429                 isp_ct_pt_t plocal;
 3430                 ct_hdr_t clocal;
 3431                 uint8_t q[QENTRY_LEN];
 3432         } un;
 3433         isp_ct_pt_t *pt;
 3434         ct_hdr_t *ct;
 3435         uint32_t *rp;
 3436         uint8_t *scp = fcp->isp_scratch;
 3437 
 3438         isp_prt(isp, ISP_LOGDEBUG0,
 3439             "Chan %d scanning fabric (GID_FT) via CT", chan);
 3440 
 3441         if (!IS_24XX(isp)) {
 3442                 return (1);
 3443         }
 3444 
 3445         /*
 3446          * Build a Passthrough IOCB in memory.
 3447          */
 3448         pt = &un.plocal;
 3449         MEMZERO(un.q, QENTRY_LEN);
 3450         pt->ctp_header.rqs_entry_count = 1;
 3451         pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
 3452         pt->ctp_handle = 0xffffffff;
 3453         pt->ctp_nphdl = fcp->isp_sns_hdl;
 3454         pt->ctp_cmd_cnt = 1;
 3455         pt->ctp_vpidx = chan;
 3456         pt->ctp_time = 30;
 3457         pt->ctp_rsp_cnt = 1;
 3458         pt->ctp_rsp_bcnt = GIDLEN;
 3459         pt->ctp_cmd_bcnt = sizeof (*ct) + sizeof (uint32_t);
 3460         pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
 3461         pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
 3462         pt->ctp_dataseg[0].ds_count = sizeof (*ct) + sizeof (uint32_t);
 3463         pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
 3464         pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
 3465         pt->ctp_dataseg[1].ds_count = GIDLEN;
 3466         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 3467                 isp_print_bytes(isp, "ct IOCB", QENTRY_LEN, pt);
 3468         }
 3469         isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
 3470 
 3471         /*
 3472          * Build the CT header and command in memory.
 3473          *
 3474          * Note that the CT header has to end up as Big Endian format in memory.
 3475          */
 3476         ct = &un.clocal;
 3477         MEMZERO(ct, sizeof (*ct));
 3478         ct->ct_revision = CT_REVISION;
 3479         ct->ct_fcs_type = CT_FC_TYPE_FC;
 3480         ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
 3481         ct->ct_cmd_resp = SNS_GID_FT;
 3482         ct->ct_bcnt_resid = (GIDLEN - 16) >> 2;
 3483 
 3484         isp_put_ct_hdr(isp, ct, (ct_hdr_t *) &scp[XTXOFF]);
 3485         rp = (uint32_t *) &scp[XTXOFF+sizeof (*ct)];
 3486         ISP_IOZPUT_32(isp, FC4_SCSI, rp);
 3487         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 3488                 isp_print_bytes(isp, "CT HDR + payload after put",
 3489                     sizeof (*ct) + sizeof (uint32_t), &scp[XTXOFF]);
 3490         }
 3491         MEMZERO(&scp[ZTXOFF], QENTRY_LEN);
 3492         MEMZERO(&mbs, sizeof (mbs));
 3493         mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
 3494         mbs.param[1] = QENTRY_LEN;
 3495         mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
 3496         mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
 3497         mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
 3498         mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
 3499         mbs.timeout = 500000;
 3500         mbs.logval = MBLOGALL;
 3501         MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN);
 3502         isp_mboxcmd(isp, &mbs);
 3503         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 3504                 return (-1);
 3505         }
 3506         MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN);
 3507         pt = &un.plocal;
 3508         isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
 3509         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 3510                 isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
 3511         }
 3512 
 3513         if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) {
 3514                 isp_prt(isp, ISP_LOGWARN,
 3515                     "Chan %d ISP GID FT CT Passthrough returned 0x%x",
 3516                     chan, pt->ctp_status);
 3517                 return (-1);
 3518         }
 3519         MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN + 16);
 3520         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 3521                 isp_print_bytes(isp, "CT response", GIDLEN+16, &scp[IGPOFF]);
 3522         }
 3523         return (0);
 3524 }
 3525 
 3526 static int
 3527 isp_scan_fabric(ispsoftc_t *isp, int chan)
 3528 {
 3529         fcparam *fcp = FCPARAM(isp, chan);
 3530         uint32_t portid;
 3531         uint16_t handle, oldhandle, loopid;
 3532         isp_pdb_t pdb;
 3533         int portidx, portlim, r;
 3534         sns_gid_ft_rsp_t *rs0, *rs1;
 3535 
 3536         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3537             "Chan %d FC Scan Fabric", chan);
 3538         if (fcp->isp_fwstate != FW_READY ||
 3539             fcp->isp_loopstate < LOOP_LSCAN_DONE) {
 3540                 return (-1);
 3541         }
 3542         if (fcp->isp_loopstate > LOOP_SCANNING_FABRIC) {
 3543                 return (0);
 3544         }
 3545         if (fcp->isp_topo != TOPO_FL_PORT && fcp->isp_topo != TOPO_F_PORT) {
 3546                 fcp->isp_loopstate = LOOP_FSCAN_DONE;
 3547                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3548                     "Chan %d FC Scan Fabric Done (no fabric)", chan);
 3549                 return (0);
 3550         }
 3551 
 3552         fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
 3553         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 3554                 isp_prt(isp, ISP_LOGERR, sacq);
 3555                 ISP_MARK_PORTDB(isp, chan, 1);
 3556                 return (-1);
 3557         }
 3558         if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
 3559                 FC_SCRATCH_RELEASE(isp, chan);
 3560                 ISP_MARK_PORTDB(isp, chan, 1);
 3561                 return (-1);
 3562         }
 3563 
 3564         /*
 3565          * Make sure we still are logged into the fabric controller.
 3566          */
 3567         if (IS_24XX(isp)) {     /* XXX SHOULDN'T THIS BE TRUE FOR 2K F/W? XXX */
 3568                 loopid = NPH_FL_ID;
 3569         } else {
 3570                 loopid = FL_ID;
 3571         }
 3572         r = isp_getpdb(isp, chan, loopid, &pdb, 0);
 3573         if (r == MBOX_NOT_LOGGED_IN) {
 3574                 isp_dump_chip_portdb(isp, chan, 0);
 3575         }
 3576         if (r) {
 3577                 fcp->isp_loopstate = LOOP_PDB_RCVD;
 3578                 FC_SCRATCH_RELEASE(isp, chan);
 3579                 ISP_MARK_PORTDB(isp, chan, 1);
 3580                 return (-1);
 3581         }
 3582 
 3583         if (IS_24XX(isp)) {
 3584                 r = isp_gid_ft_ct_passthru(isp, chan);
 3585         } else {
 3586                 r = isp_gid_ft_sns(isp, chan);
 3587         }
 3588 
 3589         if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
 3590                 FC_SCRATCH_RELEASE(isp, chan);
 3591                 ISP_MARK_PORTDB(isp, chan, 1);
 3592                 return (-1);
 3593         }
 3594 
 3595         if (r > 0) {
 3596                 fcp->isp_loopstate = LOOP_FSCAN_DONE;
 3597                 FC_SCRATCH_RELEASE(isp, chan);
 3598                 return (0);
 3599         } else if (r < 0) {
 3600                 fcp->isp_loopstate = LOOP_PDB_RCVD;     /* try again */
 3601                 FC_SCRATCH_RELEASE(isp, chan);
 3602                 return (0);
 3603         }
 3604 
 3605         MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
 3606         rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF);
 3607         rs1 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+OGPOFF);
 3608         isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
 3609         if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
 3610                 FC_SCRATCH_RELEASE(isp, chan);
 3611                 ISP_MARK_PORTDB(isp, chan, 1);
 3612                 return (-1);
 3613         }
 3614         if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) {
 3615                 int level;
 3616                 if (rs1->snscb_cthdr.ct_reason == 9 &&
 3617                     rs1->snscb_cthdr.ct_explanation == 7) {
 3618                         level = ISP_LOGSANCFG|ISP_LOGDEBUG0;
 3619                 } else {
 3620                         level = ISP_LOGWARN;
 3621                 }
 3622                 isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_FT"
 3623                     " (Reason=0x%x Expl=0x%x)", chan,
 3624                     rs1->snscb_cthdr.ct_reason,
 3625                     rs1->snscb_cthdr.ct_explanation);
 3626                 FC_SCRATCH_RELEASE(isp, chan);
 3627                 fcp->isp_loopstate = LOOP_FSCAN_DONE;
 3628                 return (0);
 3629         }
 3630 
 3631 
 3632         /*
 3633          * If we get this far, we certainly still have the fabric controller.
 3634          */
 3635         fcp->portdb[FL_ID].state = FC_PORTDB_STATE_PENDING_VALID;
 3636 
 3637         /*
 3638          * Prime the handle we will start using.
 3639          */
 3640         oldhandle = FCPARAM(isp, 0)->isp_lasthdl;
 3641 
 3642         /*
 3643          * Go through the list and remove duplicate port ids.
 3644          */
 3645 
 3646         portlim = 0;
 3647         portidx = 0;
 3648         for (portidx = 0; portidx < NGENT-1; portidx++) {
 3649                 if (rs1->snscb_ports[portidx].control & 0x80) {
 3650                         break;
 3651                 }
 3652         }
 3653 
 3654         /*
 3655          * If we're not at the last entry, our list wasn't big enough.
 3656          */
 3657         if ((rs1->snscb_ports[portidx].control & 0x80) == 0) {
 3658                 isp_prt(isp, ISP_LOGWARN,
 3659                     "fabric too big for scratch area: increase ISP_FC_SCRLEN");
 3660         }
 3661         portlim = portidx + 1;
 3662         isp_prt(isp, ISP_LOGSANCFG,
 3663             "Chan %d got %d ports back from name server", chan, portlim);
 3664 
 3665         for (portidx = 0; portidx < portlim; portidx++) {
 3666                 int npidx;
 3667 
 3668                 portid =
 3669                     ((rs1->snscb_ports[portidx].portid[0]) << 16) |
 3670                     ((rs1->snscb_ports[portidx].portid[1]) << 8) |
 3671                     ((rs1->snscb_ports[portidx].portid[2]));
 3672 
 3673                 for (npidx = portidx + 1; npidx < portlim; npidx++) {
 3674                         uint32_t new_portid =
 3675                             ((rs1->snscb_ports[npidx].portid[0]) << 16) |
 3676                             ((rs1->snscb_ports[npidx].portid[1]) << 8) |
 3677                             ((rs1->snscb_ports[npidx].portid[2]));
 3678                         if (new_portid == portid) {
 3679                                 break;
 3680                         }
 3681                 }
 3682 
 3683                 if (npidx < portlim) {
 3684                         rs1->snscb_ports[npidx].portid[0] = 0;
 3685                         rs1->snscb_ports[npidx].portid[1] = 0;
 3686                         rs1->snscb_ports[npidx].portid[2] = 0;
 3687                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3688                             "Chan %d removing duplicate PortID 0x%06x"
 3689                             " entry from list", chan, portid);
 3690                 }
 3691         }
 3692 
 3693         /*
 3694          * We now have a list of Port IDs for all FC4 SCSI devices
 3695          * that the Fabric Name server knows about.
 3696          *
 3697          * For each entry on this list go through our port database looking
 3698          * for probational entries- if we find one, then an old entry is
 3699          * maybe still this one. We get some information to find out.
 3700          *
 3701          * Otherwise, it's a new fabric device, and we log into it
 3702          * (unconditionally). After searching the entire database
 3703          * again to make sure that we never ever ever ever have more
 3704          * than one entry that has the same PortID or the same
 3705          * WWNN/WWPN duple, we enter the device into our database.
 3706          */
 3707 
 3708         for (portidx = 0; portidx < portlim; portidx++) {
 3709                 fcportdb_t *lp;
 3710                 uint64_t wwnn, wwpn;
 3711                 int dbidx, nr;
 3712 
 3713                 portid =
 3714                     ((rs1->snscb_ports[portidx].portid[0]) << 16) |
 3715                     ((rs1->snscb_ports[portidx].portid[1]) << 8) |
 3716                     ((rs1->snscb_ports[portidx].portid[2]));
 3717 
 3718                 if (portid == 0) {
 3719                         isp_prt(isp, ISP_LOGSANCFG,
 3720                             "Chan %d skipping null PortID at idx %d",
 3721                             chan, portidx);
 3722                         continue;
 3723                 }
 3724 
 3725                 /*
 3726                  * Skip ourselves here and on other channels. If we're
 3727                  * multi-id, we can't check the portids in other FCPARAM
 3728                  * arenas because the resolutions here aren't synchronized.
 3729                  * The best way to do this is to exclude looking at portids
 3730                  * that have the same domain and area code as our own
 3731                  * portid.
 3732                  */
 3733                 if (ISP_CAP_MULTI_ID(isp)) {
 3734                         if ((portid >> 8) == (fcp->isp_portid >> 8)) {
 3735                                 isp_prt(isp, ISP_LOGSANCFG,
 3736                                     "Chan %d skip PortID 0x%06x",
 3737                                     chan, portid);
 3738                                 continue;
 3739                         }
 3740                 } else if (portid == fcp->isp_portid) {
 3741                         isp_prt(isp, ISP_LOGSANCFG,
 3742                             "Chan %d skip ourselves on @ PortID 0x%06x",
 3743                             chan, portid);
 3744                         continue;
 3745                 }
 3746 
 3747                 isp_prt(isp, ISP_LOGSANCFG,
 3748                     "Chan %d Checking Fabric Port 0x%06x", chan, portid);
 3749 
 3750                 /*
 3751                  * We now search our Port Database for any
 3752                  * probational entries with this PortID. We don't
 3753                  * look for zombies here- only probational
 3754                  * entries (we've already logged out of zombies).
 3755                  */
 3756                 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
 3757                         lp = &fcp->portdb[dbidx];
 3758 
 3759                         if (lp->state != FC_PORTDB_STATE_PROBATIONAL ||
 3760                             lp->target_mode) {
 3761                                 continue;
 3762                         }
 3763                         if (lp->portid == portid) {
 3764                                 break;
 3765                         }
 3766                 }
 3767 
 3768                 /*
 3769                  * We found a probational entry with this Port ID.
 3770                  */
 3771                 if (dbidx < MAX_FC_TARG) {
 3772                         int handle_changed = 0;
 3773 
 3774                         lp = &fcp->portdb[dbidx];
 3775 
 3776                         /*
 3777                          * See if we're still logged into it.
 3778                          *
 3779                          * If we aren't, mark it as a dead device and
 3780                          * leave the new portid in the database entry
 3781                          * for somebody further along to decide what to
 3782                          * do (policy choice).
 3783                          *
 3784                          * If we are, check to see if it's the same
 3785                          * device still (it should be). If for some
 3786                          * reason it isn't, mark it as a changed device
 3787                          * and leave the new portid and role in the
 3788                          * database entry for somebody further along to
 3789                          * decide what to do (policy choice).
 3790                          *
 3791                          */
 3792 
 3793                         r = isp_getpdb(isp, chan, lp->handle, &pdb, 0);
 3794                         if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 3795                                 FC_SCRATCH_RELEASE(isp, chan);
 3796                                 ISP_MARK_PORTDB(isp, chan, 1);
 3797                                 return (-1);
 3798                         }
 3799                         if (r != 0) {
 3800                                 lp->new_portid = portid;
 3801                                 lp->state = FC_PORTDB_STATE_DEAD;
 3802                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3803                                     "Chan %d Fabric Port 0x%06x is dead",
 3804                                     chan, portid);
 3805                                 continue;
 3806                         }
 3807 
 3808 
 3809                         /*
 3810                          * Check to make sure that handle, portid, WWPN and
 3811                          * WWNN agree. If they don't, then the association
 3812                          * between this PortID and the stated handle has been
 3813                          * broken by the firmware.
 3814                          */
 3815                         MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
 3816                         MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
 3817                         if (pdb.handle != lp->handle ||
 3818                             pdb.portid != portid ||
 3819                             wwpn != lp->port_wwn ||
 3820                             wwnn != lp->node_wwn) {
 3821                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3822                                     fconf, chan, dbidx, pdb.handle, pdb.portid,
 3823                                     (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
 3824                                     (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
 3825                                     lp->handle, portid,
 3826                                     (uint32_t) (lp->node_wwn >> 32),
 3827                                     (uint32_t) lp->node_wwn,
 3828                                     (uint32_t) (lp->port_wwn >> 32),
 3829                                     (uint32_t) lp->port_wwn);
 3830                                 /*
 3831                                  * Try to re-login to this device using a
 3832                                  * new handle. If that fails, mark it dead.
 3833                                  * 
 3834                                  * isp_login_device will check for handle and
 3835                                  * portid consistency after re-login.
 3836                                  * 
 3837                                  */
 3838                                 if (isp_login_device(isp, chan, portid, &pdb,
 3839                                     &oldhandle)) {
 3840                                         lp->new_portid = portid;
 3841                                         lp->state = FC_PORTDB_STATE_DEAD;
 3842                                         if (fcp->isp_loopstate !=
 3843                                             LOOP_SCANNING_FABRIC) {
 3844                                                 FC_SCRATCH_RELEASE(isp, chan);
 3845                                                 ISP_MARK_PORTDB(isp, chan, 1);
 3846                                                 return (-1);
 3847                                         }
 3848                                         continue;
 3849                                 }
 3850                                 if (fcp->isp_loopstate !=
 3851                                     LOOP_SCANNING_FABRIC) {
 3852                                         FC_SCRATCH_RELEASE(isp, chan);
 3853                                         ISP_MARK_PORTDB(isp, chan, 1);
 3854                                         return (-1);
 3855                                 }
 3856                                 FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
 3857                                 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
 3858                                 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
 3859                                 if (wwpn != lp->port_wwn ||
 3860                                     wwnn != lp->node_wwn) {
 3861                                         isp_prt(isp, ISP_LOGWARN, "changed WWN"
 3862                                             " after relogin");
 3863                                         lp->new_portid = portid;
 3864                                         lp->state = FC_PORTDB_STATE_DEAD;
 3865                                         continue;
 3866                                 }
 3867 
 3868                                 lp->handle = pdb.handle;
 3869                                 handle_changed++;
 3870                         }
 3871 
 3872                         nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
 3873 
 3874                         /*
 3875                          * Check to see whether the portid and roles have
 3876                          * stayed the same. If they have stayed the same,
 3877                          * we believe that this is the same device and it
 3878                          * hasn't become disconnected and reconnected, so
 3879                          * mark it as pending valid.
 3880                          *
 3881                          * If they aren't the same, mark the device as a
 3882                          * changed device and save the new port id and role
 3883                          * and let somebody else decide.
 3884                          */
 3885 
 3886                         lp->new_portid = portid;
 3887                         lp->new_roles = nr;
 3888                         if (pdb.portid != lp->portid || nr != lp->roles ||
 3889                             handle_changed) {
 3890                                 isp_prt(isp, ISP_LOGSANCFG,
 3891                                     "Chan %d Fabric Port 0x%06x changed",
 3892                                     chan, portid);
 3893                                 lp->state = FC_PORTDB_STATE_CHANGED;
 3894                         } else {
 3895                                 isp_prt(isp, ISP_LOGSANCFG,
 3896                                     "Chan %d Fabric Port 0x%06x "
 3897                                     "Now Pending Valid", chan, portid);
 3898                                 lp->state = FC_PORTDB_STATE_PENDING_VALID;
 3899                         }
 3900                         continue;
 3901                 }
 3902 
 3903                 /*
 3904                  * Ah- a new entry. Search the database again for all non-NIL
 3905                  * entries to make sure we never ever make a new database entry
 3906                  * with the same port id. While we're at it, mark where the
 3907                  * last free entry was.
 3908                  */
 3909         
 3910                 dbidx = MAX_FC_TARG;
 3911                 for (lp = fcp->portdb; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
 3912                         if (lp >= &fcp->portdb[FL_ID] &&
 3913                             lp <= &fcp->portdb[SNS_ID]) {
 3914                                 continue;
 3915                         }
 3916                         /*
 3917                          * Skip any target mode entries.
 3918                          */
 3919                         if (lp->target_mode) {
 3920                                 continue;
 3921                         }
 3922                         if (lp->state == FC_PORTDB_STATE_NIL) {
 3923                                 if (dbidx == MAX_FC_TARG) {
 3924                                         dbidx = lp - fcp->portdb;
 3925                                 }
 3926                                 continue;
 3927                         }
 3928                         if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
 3929                                 continue;
 3930                         }
 3931                         if (lp->portid == portid) {
 3932                                 break;
 3933                         }
 3934                 }
 3935 
 3936                 if (lp < &fcp->portdb[MAX_FC_TARG]) {
 3937                         isp_prt(isp, ISP_LOGWARN, "Chan %d PortID 0x%06x "
 3938                             "already at %d handle %d state %d",
 3939                             chan, portid, dbidx, lp->handle, lp->state);
 3940                         continue;
 3941                 }
 3942 
 3943                 /*
 3944                  * We should have the index of the first free entry seen.
 3945                  */
 3946                 if (dbidx == MAX_FC_TARG) {
 3947                         isp_prt(isp, ISP_LOGERR,
 3948                             "port database too small to login PortID 0x%06x"
 3949                             "- increase MAX_FC_TARG", portid);
 3950                         continue;
 3951                 }
 3952 
 3953                 /*
 3954                  * Otherwise, point to our new home.
 3955                  */
 3956                 lp = &fcp->portdb[dbidx];
 3957 
 3958                 /*
 3959                  * Try to see if we are logged into this device,
 3960                  * and maybe log into it.
 3961                  *
 3962                  * isp_login_device will check for handle and
 3963                  * portid consistency after login.
 3964                  */
 3965                 if (isp_login_device(isp, chan, portid, &pdb, &oldhandle)) {
 3966                         if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 3967                                 FC_SCRATCH_RELEASE(isp, chan);
 3968                                 ISP_MARK_PORTDB(isp, chan, 1);
 3969                                 return (-1);
 3970                         }
 3971                         continue;
 3972                 }
 3973                 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 3974                         FC_SCRATCH_RELEASE(isp, chan);
 3975                         ISP_MARK_PORTDB(isp, chan, 1);
 3976                         return (-1);
 3977                 }
 3978                 FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
 3979 
 3980                 handle = pdb.handle;
 3981                 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
 3982                 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
 3983                 nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
 3984 
 3985                 /*
 3986                  * And go through the database *one* more time to make sure
 3987                  * that we do not make more than one entry that has the same
 3988                  * WWNN/WWPN duple
 3989                  */
 3990                 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
 3991                         if (dbidx >= FL_ID && dbidx <= SNS_ID) {
 3992                                 continue;
 3993                         }
 3994                         if (fcp->portdb[dbidx].target_mode) {
 3995                                 continue;
 3996                         }
 3997                         if (fcp->portdb[dbidx].node_wwn == wwnn &&
 3998                             fcp->portdb[dbidx].port_wwn == wwpn) {
 3999                                 break;
 4000                         }
 4001                 }
 4002 
 4003                 if (dbidx == MAX_FC_TARG) {
 4004                         MEMZERO(lp, sizeof (fcportdb_t));
 4005                         lp->handle = handle;
 4006                         lp->node_wwn = wwnn;
 4007                         lp->port_wwn = wwpn;
 4008                         lp->new_portid = portid;
 4009                         lp->new_roles = nr;
 4010                         lp->state = FC_PORTDB_STATE_NEW;
 4011                         isp_prt(isp, ISP_LOGSANCFG,
 4012                             "Chan %d Fabric Port 0x%06x is a New Entry",
 4013                             chan, portid);
 4014                         continue;
 4015                 }
 4016 
 4017                 if (fcp->portdb[dbidx].state != FC_PORTDB_STATE_ZOMBIE) {
 4018                         isp_prt(isp, ISP_LOGWARN,
 4019                             "Chan %d PortID 0x%x 0x%08x%08x/0x%08x%08x %ld "
 4020                             "already at idx %d, state 0x%x", chan, portid,
 4021                             (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
 4022                             (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
 4023                             (long) (lp - fcp->portdb), dbidx,
 4024                             fcp->portdb[dbidx].state);
 4025                         continue;
 4026                 }
 4027 
 4028                 /*
 4029                  * We found a zombie entry that matches us.
 4030                  * Revive it. We know that WWN and WWPN
 4031                  * are the same. For fabric devices, we
 4032                  * don't care that handle is different
 4033                  * as we assign that. If role or portid
 4034                  * are different, it maybe a changed device.
 4035                  */
 4036                 lp = &fcp->portdb[dbidx];
 4037                 lp->handle = handle;
 4038                 lp->new_portid = portid;
 4039                 lp->new_roles = nr;
 4040                 if (lp->portid != portid || lp->roles != nr) {
 4041                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 4042                             "Chan %d Zombie Fabric Port 0x%06x Now Changed",
 4043                             chan, portid);
 4044                         lp->state = FC_PORTDB_STATE_CHANGED;
 4045                 } else {
 4046                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 4047                             "Chan %d Zombie Fabric Port 0x%06x "
 4048                             "Now Pending Valid", chan, portid);
 4049                         lp->state = FC_PORTDB_STATE_PENDING_VALID;
 4050                 }
 4051         }
 4052 
 4053         FC_SCRATCH_RELEASE(isp, chan);
 4054         if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 4055                 ISP_MARK_PORTDB(isp, chan, 1);
 4056                 return (-1);
 4057         }
 4058         fcp->isp_loopstate = LOOP_FSCAN_DONE;
 4059         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 4060             "Chan %d FC Scan Fabric Done", chan);
 4061         return (0);
 4062 }
 4063 
 4064 /*
 4065  * Find an unused handle and try and use to login to a port.
 4066  */
 4067 static int
 4068 isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p,
 4069     uint16_t *ohp)
 4070 {
 4071         int lim, i, r;
 4072         uint16_t handle;
 4073 
 4074         if (ISP_CAP_2KLOGIN(isp)) {
 4075                 lim = NPH_MAX_2K;
 4076         } else {
 4077                 lim = NPH_MAX;
 4078         }
 4079 
 4080         handle = isp_nxt_handle(isp, chan, *ohp);
 4081         for (i = 0; i < lim; i++) {
 4082                 /*
 4083                  * See if we're still logged into something with
 4084                  * this handle and that something agrees with this
 4085                  * port id.
 4086                  */
 4087                 r = isp_getpdb(isp, chan, handle, p, 0);
 4088                 if (r == 0 && p->portid != portid) {
 4089                         (void) isp_plogx(isp, chan, handle, portid,
 4090                             PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT, 1);
 4091                 } else if (r == 0) {
 4092                         break;
 4093                 }
 4094                 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
 4095                         return (-1);
 4096                 }
 4097                 /*
 4098                  * Now try and log into the device
 4099                  */
 4100                 r = isp_plogx(isp, chan, handle, portid,
 4101                     PLOGX_FLG_CMD_PLOGI, 1);
 4102                 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
 4103                         return (-1);
 4104                 }
 4105                 if (r == 0) {
 4106                         *ohp = handle;
 4107                         break;
 4108                 } else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
 4109                         handle = r >> 16;
 4110                         break;
 4111                 } else if (r != MBOX_LOOP_ID_USED) {
 4112                         i = lim;
 4113                         break;
 4114                 } else if (r == MBOX_TIMEOUT) {
 4115                         return (-1);
 4116                 } else {
 4117                         *ohp = handle;
 4118                         handle = isp_nxt_handle(isp, chan, *ohp);
 4119                 }
 4120         }
 4121 
 4122         if (i == lim) {
 4123                 isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed",
 4124                     chan, portid);
 4125                 return (-1);
 4126         }
 4127 
 4128         /*
 4129          * If we successfully logged into it, get the PDB for it
 4130          * so we can crosscheck that it is still what we think it
 4131          * is and that we also have the role it plays
 4132          */
 4133         r = isp_getpdb(isp, chan, handle, p, 0);
 4134         if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
 4135                 return (-1);
 4136         }
 4137         if (r != 0) {
 4138                 isp_prt(isp, ISP_LOGERR,
 4139                     "Chan %d new device 0x%06x@0x%x disappeared",
 4140                     chan, portid, handle);
 4141                 return (-1);
 4142         }
 4143 
 4144         if (p->handle != handle || p->portid != portid) {
 4145                 isp_prt(isp, ISP_LOGERR,
 4146                     "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
 4147                     chan, portid, handle, p->portid, p->handle);
 4148                 return (-1);
 4149         }
 4150         return (0);
 4151 }
 4152 
 4153 static int
 4154 isp_register_fc4_type(ispsoftc_t *isp, int chan)
 4155 {
 4156         fcparam *fcp = FCPARAM(isp, chan);
 4157         uint8_t local[SNS_RFT_ID_REQ_SIZE];
 4158         sns_screq_t *reqp = (sns_screq_t *) local;
 4159         mbreg_t mbs;
 4160 
 4161         MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
 4162         reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
 4163         reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
 4164         reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
 4165         reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
 4166         reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
 4167         reqp->snscb_sblen = 22;
 4168         reqp->snscb_data[0] = SNS_RFT_ID;
 4169         reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
 4170         reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
 4171         reqp->snscb_data[6] = (1 << FC4_SCSI);
 4172         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 4173                 isp_prt(isp, ISP_LOGERR, sacq);
 4174                 return (-1);
 4175         }
 4176         isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
 4177         MEMZERO(&mbs, sizeof (mbs));
 4178         mbs.param[0] = MBOX_SEND_SNS;
 4179         mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
 4180         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 4181         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 4182         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 4183         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 4184         mbs.logval = MBLOGALL;
 4185         mbs.timeout = 10000000;
 4186         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE);
 4187         isp_mboxcmd(isp, &mbs);
 4188         FC_SCRATCH_RELEASE(isp, chan);
 4189         if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 4190                 return (0);
 4191         } else {
 4192                 return (-1);
 4193         }
 4194 }
 4195 
 4196 static int
 4197 isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
 4198 {
 4199         mbreg_t mbs;
 4200         fcparam *fcp = FCPARAM(isp, chan);
 4201         union {
 4202                 isp_ct_pt_t plocal;
 4203                 rft_id_t clocal;
 4204                 uint8_t q[QENTRY_LEN];
 4205         } un;
 4206         isp_ct_pt_t *pt;
 4207         ct_hdr_t *ct;
 4208         rft_id_t *rp;
 4209         uint8_t *scp = fcp->isp_scratch;
 4210 
 4211         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 4212                 isp_prt(isp, ISP_LOGERR, sacq);
 4213                 return (-1);
 4214         }
 4215 
 4216         /*
 4217          * Build a Passthrough IOCB in memory.
 4218          */
 4219         MEMZERO(un.q, QENTRY_LEN);
 4220         pt = &un.plocal;
 4221         pt->ctp_header.rqs_entry_count = 1;
 4222         pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
 4223         pt->ctp_handle = 0xffffffff;
 4224         pt->ctp_nphdl = fcp->isp_sns_hdl;
 4225         pt->ctp_cmd_cnt = 1;
 4226         pt->ctp_vpidx = chan;
 4227         pt->ctp_time = 1;
 4228         pt->ctp_rsp_cnt = 1;
 4229         pt->ctp_rsp_bcnt = sizeof (ct_hdr_t);
 4230         pt->ctp_cmd_bcnt = sizeof (rft_id_t);
 4231         pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
 4232         pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
 4233         pt->ctp_dataseg[0].ds_count = sizeof (rft_id_t);
 4234         pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
 4235         pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
 4236         pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t);
 4237         isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
 4238         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 4239                 isp_print_bytes(isp, "IOCB CT Request", QENTRY_LEN, pt);
 4240         }
 4241 
 4242         /*
 4243          * Build the CT header and command in memory.
 4244          *
 4245          * Note that the CT header has to end up as Big Endian format in memory.
 4246          */
 4247         MEMZERO(&un.clocal, sizeof (un.clocal));
 4248         ct = &un.clocal.rftid_hdr;
 4249         ct->ct_revision = CT_REVISION;
 4250         ct->ct_fcs_type = CT_FC_TYPE_FC;
 4251         ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
 4252         ct->ct_cmd_resp = SNS_RFT_ID;
 4253         ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
 4254         rp = &un.clocal;
 4255         rp->rftid_portid[0] = fcp->isp_portid >> 16;
 4256         rp->rftid_portid[1] = fcp->isp_portid >> 8;
 4257         rp->rftid_portid[2] = fcp->isp_portid;
 4258         rp->rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
 4259         isp_put_rft_id(isp, rp, (rft_id_t *) &scp[XTXOFF]);
 4260         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 4261                 isp_print_bytes(isp, "CT Header", QENTRY_LEN, &scp[XTXOFF]);
 4262         }
 4263 
 4264         MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
 4265 
 4266         MEMZERO(&mbs, sizeof (mbs));
 4267         mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
 4268         mbs.param[1] = QENTRY_LEN;
 4269         mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
 4270         mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
 4271         mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
 4272         mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
 4273         mbs.timeout = 500000;
 4274         mbs.logval = MBLOGALL;
 4275         MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN);
 4276         isp_mboxcmd(isp, &mbs);
 4277         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 4278                 FC_SCRATCH_RELEASE(isp, chan);
 4279                 return (-1);
 4280         }
 4281         MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN);
 4282         pt = &un.plocal;
 4283         isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
 4284         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 4285                 isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
 4286         }
 4287         if (pt->ctp_status) {
 4288                 FC_SCRATCH_RELEASE(isp, chan);
 4289                 isp_prt(isp, ISP_LOGWARN,
 4290                     "Chan %d Register FC4 Type CT Passthrough returned 0x%x",
 4291                     chan, pt->ctp_status);
 4292                 return (1);
 4293         }
 4294 
 4295         isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct);
 4296         FC_SCRATCH_RELEASE(isp, chan);
 4297 
 4298         if (ct->ct_cmd_resp == LS_RJT) {
 4299                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 4300                     "Chan %d Register FC4 Type rejected", chan);
 4301                 return (-1);
 4302         } else if (ct->ct_cmd_resp == LS_ACC) {
 4303                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 4304                     "Chan %d Register FC4 Type accepted", chan);
 4305                 return(0);
 4306         } else {
 4307                 isp_prt(isp, ISP_LOGWARN,
 4308                     "Chan %d Register FC4 Type: 0x%x",
 4309                     chan, ct->ct_cmd_resp);
 4310                 return (-1);
 4311         }
 4312 }
 4313 
 4314 static uint16_t
 4315 isp_nxt_handle(ispsoftc_t *isp, int chan, uint16_t handle)
 4316 {
 4317         int i;
 4318         if (handle == NIL_HANDLE) {
 4319                 if (FCPARAM(isp, chan)->isp_topo == TOPO_F_PORT) {
 4320                         handle = 0;
 4321                 } else {
 4322                         handle = SNS_ID+1;
 4323                 }
 4324         } else {
 4325                 handle += 1;
 4326                 if (handle >= FL_ID && handle <= SNS_ID) {
 4327                         handle = SNS_ID+1;
 4328                 }
 4329                 if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
 4330                         handle = NPH_FL_ID+1;
 4331                 }
 4332                 if (ISP_CAP_2KLOGIN(isp)) {
 4333                         if (handle == NPH_MAX_2K) {
 4334                                 handle = 0;
 4335                         }
 4336                 } else {
 4337                         if (handle == NPH_MAX) {
 4338                                 handle = 0;
 4339                         }
 4340                 }
 4341         }
 4342         if (handle == FCPARAM(isp, chan)->isp_loopid) {
 4343                 return (isp_nxt_handle(isp, chan, handle));
 4344         }
 4345         for (i = 0; i < MAX_FC_TARG; i++) {
 4346                 if (FCPARAM(isp, chan)->portdb[i].state ==
 4347                     FC_PORTDB_STATE_NIL) {
 4348                         continue;
 4349                 }
 4350                 if (FCPARAM(isp, chan)->portdb[i].handle == handle) {
 4351                         return (isp_nxt_handle(isp, chan, handle));
 4352                 }
 4353         }
 4354         return (handle);
 4355 }
 4356 
 4357 /*
 4358  * Start a command. Locking is assumed done in the caller.
 4359  */
 4360 
 4361 int
 4362 isp_start(XS_T *xs)
 4363 {
 4364         ispsoftc_t *isp;
 4365         uint32_t nxti, optr, handle;
 4366         uint8_t local[QENTRY_LEN];
 4367         ispreq_t *reqp, *qep;
 4368         void *cdbp;
 4369         uint16_t *tptr;
 4370         int target, i, hdlidx = 0;
 4371 
 4372         XS_INITERR(xs);
 4373         isp = XS_ISP(xs);
 4374 
 4375         /*
 4376          * Now make sure we're running.
 4377          */
 4378 
 4379         if (isp->isp_state != ISP_RUNSTATE) {
 4380                 isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
 4381                 XS_SETERR(xs, HBA_BOTCH);
 4382                 return (CMD_COMPLETE);
 4383         }
 4384 
 4385         /*
 4386          * Check command CDB length, etc.. We really are limited to 16 bytes
 4387          * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
 4388          * but probably only if we're running fairly new firmware (we'll
 4389          * let the old f/w choke on an extended command queue entry).
 4390          */
 4391 
 4392         if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
 4393                 isp_prt(isp, ISP_LOGERR,
 4394                     "unsupported cdb length (%d, CDB[0]=0x%x)",
 4395                     XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
 4396                 XS_SETERR(xs, HBA_BOTCH);
 4397                 return (CMD_COMPLETE);
 4398         }
 4399 
 4400         /*
 4401          * Translate the target to device handle as appropriate, checking
 4402          * for correct device state as well.
 4403          */
 4404         target = XS_TGT(xs);
 4405         if (IS_FC(isp)) {
 4406                 fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
 4407 
 4408                 if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
 4409                         XS_SETERR(xs, HBA_SELTIMEOUT);
 4410                         return (CMD_COMPLETE);
 4411                 }
 4412 
 4413                 /*
 4414                  * Try again later.
 4415                  */
 4416                 if (fcp->isp_fwstate != FW_READY ||
 4417                     fcp->isp_loopstate != LOOP_READY) {
 4418                         return (CMD_RQLATER);
 4419                 }
 4420 
 4421                 if (XS_TGT(xs) >= MAX_FC_TARG) {
 4422                         XS_SETERR(xs, HBA_SELTIMEOUT);
 4423                         return (CMD_COMPLETE);
 4424                 }
 4425 
 4426                 hdlidx = fcp->isp_ini_map[XS_TGT(xs)] - 1;
 4427                 isp_prt(isp, ISP_LOGDEBUG1, "XS_TGT(xs)=%d- hdlidx value %d",
 4428                     XS_TGT(xs), hdlidx);
 4429                 if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
 4430                         XS_SETERR(xs, HBA_SELTIMEOUT);
 4431                         return (CMD_COMPLETE);
 4432                 }
 4433                 if (fcp->portdb[hdlidx].state == FC_PORTDB_STATE_ZOMBIE) {
 4434                         return (CMD_RQLATER);
 4435                 }
 4436                 if (fcp->portdb[hdlidx].state != FC_PORTDB_STATE_VALID) {
 4437                         XS_SETERR(xs, HBA_SELTIMEOUT);
 4438                         return (CMD_COMPLETE);
 4439                 }
 4440                 target = fcp->portdb[hdlidx].handle;
 4441         } else {
 4442                 sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
 4443                 if ((sdp->role & ISP_ROLE_INITIATOR) == 0) {
 4444                         XS_SETERR(xs, HBA_SELTIMEOUT);
 4445                         return (CMD_COMPLETE);
 4446                 }
 4447                 if (sdp->update) {
 4448                         isp_spi_update(isp, XS_CHANNEL(xs));
 4449                 }
 4450         }
 4451 
 4452  start_again:
 4453 
 4454         if (isp_getrqentry(isp, &nxti, &optr, (void *)&qep)) {
 4455                 isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
 4456                 XS_SETERR(xs, HBA_BOTCH);
 4457                 return (CMD_EAGAIN);
 4458         }
 4459 
 4460         /*
 4461          * Now see if we need to synchronize the ISP with respect to anything.
 4462          * We do dual duty here (cough) for synchronizing for busses other
 4463          * than which we got here to send a command to.
 4464          */
 4465         reqp = (ispreq_t *) local;
 4466         if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) {
 4467                 if (IS_24XX(isp)) {
 4468                         isp_marker_24xx_t *m = (isp_marker_24xx_t *) qep;
 4469                         MEMZERO(m, QENTRY_LEN);
 4470                         m->mrk_header.rqs_entry_count = 1;
 4471                         m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
 4472                         m->mrk_modifier = SYNC_ALL;
 4473                         isp_put_marker_24xx(isp, m, (isp_marker_24xx_t *)qep);
 4474                 } else {
 4475                         isp_marker_t *m = (isp_marker_t *) qep;
 4476                         MEMZERO(m, QENTRY_LEN);
 4477                         m->mrk_header.rqs_entry_count = 1;
 4478                         m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
 4479                         m->mrk_target = (XS_CHANNEL(xs) << 7);  /* bus # */
 4480                         m->mrk_modifier = SYNC_ALL;
 4481                         isp_put_marker(isp, m, (isp_marker_t *) qep);
 4482                 }
 4483                 ISP_ADD_REQUEST(isp, nxti);
 4484                 ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0);
 4485                 goto start_again;
 4486         }
 4487 
 4488         MEMZERO((void *)reqp, QENTRY_LEN);
 4489         reqp->req_header.rqs_entry_count = 1;
 4490         if (IS_24XX(isp)) {
 4491                 reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
 4492         } else if (IS_FC(isp)) {
 4493                 reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
 4494         } else {
 4495                 if (XS_CDBLEN(xs) > 12)
 4496                         reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
 4497                 else
 4498                         reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
 4499         }
 4500         /* reqp->req_header.rqs_flags = 0; */
 4501         /* reqp->req_header.rqs_seqno = 0; */
 4502         if (IS_24XX(isp)) {
 4503                 int ttype;
 4504                 if (XS_TAG_P(xs)) {
 4505                         ttype = XS_TAG_TYPE(xs);
 4506                 } else {
 4507                         if (XS_CDBP(xs)[0] == 0x3) {
 4508                                 ttype = REQFLAG_HTAG;
 4509                         } else {
 4510                                 ttype = REQFLAG_STAG;
 4511                         }
 4512                 }
 4513                 if (ttype == REQFLAG_OTAG) {
 4514                         ttype = FCP_CMND_TASK_ATTR_ORDERED;
 4515                 } else if (ttype == REQFLAG_HTAG) {
 4516                         ttype = FCP_CMND_TASK_ATTR_HEAD;
 4517                 } else {
 4518                         ttype = FCP_CMND_TASK_ATTR_SIMPLE;
 4519                 }
 4520                 ((ispreqt7_t *)reqp)->req_task_attribute = ttype;
 4521         } else if (IS_FC(isp)) {
 4522                 /*
 4523                  * See comment in isp_intr
 4524                  */
 4525                 /* XS_RESID(xs) = 0; */
 4526 
 4527                 /*
 4528                  * Fibre Channel always requires some kind of tag.
 4529                  * The Qlogic drivers seem be happy not to use a tag,
 4530                  * but this breaks for some devices (IBM drives).
 4531                  */
 4532                 if (XS_TAG_P(xs)) {
 4533                         ((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
 4534                 } else {
 4535                         /*
 4536                          * If we don't know what tag to use, use HEAD OF QUEUE
 4537                          * for Request Sense or Simple.
 4538                          */
 4539                         if (XS_CDBP(xs)[0] == 0x3)      /* REQUEST SENSE */
 4540                                 ((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
 4541                         else
 4542                                 ((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
 4543                 }
 4544         } else {
 4545                 sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
 4546                 if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) &&
 4547                     XS_TAG_P(xs)) {
 4548                         reqp->req_flags = XS_TAG_TYPE(xs);
 4549                 }
 4550         }
 4551         cdbp = reqp->req_cdb;
 4552         tptr = &reqp->req_time;
 4553 
 4554         if (IS_SCSI(isp)) {
 4555                 reqp->req_target = target | (XS_CHANNEL(xs) << 7);
 4556                 reqp->req_lun_trn = XS_LUN(xs);
 4557                 reqp->req_cdblen = XS_CDBLEN(xs);
 4558         } else if (IS_24XX(isp)) {
 4559                 fcportdb_t *lp;
 4560 
 4561                 lp = &FCPARAM(isp, XS_CHANNEL(xs))->portdb[hdlidx];
 4562                 ((ispreqt7_t *)reqp)->req_nphdl = target;
 4563                 ((ispreqt7_t *)reqp)->req_tidlo = lp->portid;
 4564                 ((ispreqt7_t *)reqp)->req_tidhi = lp->portid >> 16;
 4565                 ((ispreqt7_t *)reqp)->req_vpidx = XS_CHANNEL(xs);
 4566                 if (XS_LUN(xs) > 256) {
 4567                         ((ispreqt7_t *)reqp)->req_lun[0] = XS_LUN(xs) >> 8;
 4568                         ((ispreqt7_t *)reqp)->req_lun[0] |= 0x40;
 4569                 }
 4570                 ((ispreqt7_t *)reqp)->req_lun[1] = XS_LUN(xs);
 4571                 cdbp = ((ispreqt7_t *)reqp)->req_cdb;
 4572                 tptr = &((ispreqt7_t *)reqp)->req_time;
 4573         } else if (ISP_CAP_2KLOGIN(isp)) {
 4574                 ((ispreqt2e_t *)reqp)->req_target = target;
 4575                 ((ispreqt2e_t *)reqp)->req_scclun = XS_LUN(xs);
 4576         } else if (ISP_CAP_SCCFW(isp)) {
 4577                 ((ispreqt2_t *)reqp)->req_target = target;
 4578                 ((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
 4579         } else {
 4580                 ((ispreqt2_t *)reqp)->req_target = target;
 4581                 ((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
 4582         }
 4583         MEMCPY(cdbp, XS_CDBP(xs), XS_CDBLEN(xs));
 4584 
 4585         *tptr = XS_TIME(xs) / 1000;
 4586         if (*tptr == 0 && XS_TIME(xs)) {
 4587                 *tptr = 1;
 4588         }
 4589         if (IS_24XX(isp) && *tptr > 0x1999) {
 4590                 *tptr = 0x1999;
 4591         }
 4592 
 4593         if (isp_save_xs(isp, xs, &handle)) {
 4594                 isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
 4595                 XS_SETERR(xs, HBA_BOTCH);
 4596                 return (CMD_EAGAIN);
 4597         }
 4598         /* Whew. Thankfully the same for type 7 requests */
 4599         reqp->req_handle = handle;
 4600 
 4601         /*
 4602          * Set up DMA and/or do any bus swizzling of the request entry
 4603          * so that the Qlogic F/W understands what is being asked of it.
 4604          */
 4605         i = ISP_DMASETUP(isp, xs, reqp, &nxti, optr);
 4606         if (i != CMD_QUEUED) {
 4607                 isp_destroy_handle(isp, handle);
 4608                 /*
 4609                  * dmasetup sets actual error in packet, and
 4610                  * return what we were given to return.
 4611                  */
 4612                 return (i);
 4613         }
 4614         XS_SETERR(xs, HBA_NOERROR);
 4615         isp_prt(isp, ISP_LOGDEBUG0,
 4616             "START cmd for %d.%d.%d cmd 0x%x datalen %ld",
 4617             XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0],
 4618             (long) XS_XFRLEN(xs));
 4619         ISP_ADD_REQUEST(isp, nxti);
 4620         isp->isp_nactive++;
 4621         return (CMD_QUEUED);
 4622 }
 4623 
 4624 /*
 4625  * isp control
 4626  * Locks (ints blocked) assumed held.
 4627  */
 4628 
 4629 int
 4630 isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
 4631 {
 4632         XS_T *xs;
 4633         mbreg_t *mbr, mbs;
 4634         int chan, tgt;
 4635         uint32_t handle;
 4636         va_list ap;
 4637 
 4638         MEMZERO(&mbs, sizeof (mbs));
 4639 
 4640         switch (ctl) {
 4641         case ISPCTL_RESET_BUS:
 4642                 /*
 4643                  * Issue a bus reset.
 4644                  */
 4645                 if (IS_24XX(isp)) {
 4646                         isp_prt(isp, ISP_LOGWARN, "RESET BUS NOT IMPLEMENTED");
 4647                         break;
 4648                 } else if (IS_FC(isp)) {
 4649                         mbs.param[1] = 10;
 4650                         chan = 0;
 4651                 } else {
 4652                         va_start(ap, ctl);
 4653                         chan = va_arg(ap, int);
 4654                         va_end(ap);
 4655                         mbs.param[1] = SDPARAM(isp, chan)->isp_bus_reset_delay;
 4656                         if (mbs.param[1] < 2) {
 4657                                 mbs.param[1] = 2;
 4658                         }
 4659                         mbs.param[2] = chan;
 4660                 }
 4661                 mbs.param[0] = MBOX_BUS_RESET;
 4662                 ISP_SET_SENDMARKER(isp, chan, 1);
 4663                 mbs.logval = MBLOGALL;
 4664                 isp_mboxcmd(isp, &mbs);
 4665                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 4666                         break;
 4667                 }
 4668                 isp_prt(isp, ISP_LOGINFO,
 4669                     "driver initiated bus reset of bus %d", chan);
 4670                 return (0);
 4671 
 4672         case ISPCTL_RESET_DEV:
 4673                 va_start(ap, ctl);
 4674                 chan = va_arg(ap, int);
 4675                 tgt = va_arg(ap, int);
 4676                 va_end(ap);
 4677                 if (IS_24XX(isp)) {
 4678                         uint8_t local[QENTRY_LEN];
 4679                         isp24xx_tmf_t *tmf;
 4680                         isp24xx_statusreq_t *sp;
 4681                         fcparam *fcp = FCPARAM(isp, chan);
 4682                         fcportdb_t *lp;
 4683                         int hdlidx;
 4684 
 4685                         hdlidx = fcp->isp_ini_map[tgt] - 1;
 4686                         if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
 4687                                 isp_prt(isp, ISP_LOGWARN,
 4688                                     "Chan %d bad handle %d trying to reset"
 4689                                     "target %d", chan, hdlidx, tgt);
 4690                                 break;
 4691                         }
 4692                         lp = &fcp->portdb[hdlidx];
 4693                         if (lp->state != FC_PORTDB_STATE_VALID) {
 4694                                 isp_prt(isp, ISP_LOGWARN,
 4695                                     "Chan %d handle %d for abort of target %d "
 4696                                     "no longer valid", chan,
 4697                                     hdlidx, tgt);
 4698                                 break;
 4699                         }
 4700 
 4701                         tmf = (isp24xx_tmf_t *) local;
 4702                         MEMZERO(tmf, QENTRY_LEN);
 4703                         tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
 4704                         tmf->tmf_header.rqs_entry_count = 1;
 4705                         tmf->tmf_nphdl = lp->handle;
 4706                         tmf->tmf_delay = 2;
 4707                         tmf->tmf_timeout = 2;
 4708                         tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
 4709                         tmf->tmf_tidlo = lp->portid;
 4710                         tmf->tmf_tidhi = lp->portid >> 16;
 4711                         tmf->tmf_vpidx = chan;
 4712                         isp_prt(isp, ISP_LOGALL,
 4713                             "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x",
 4714                             chan, lp->handle, lp->portid);
 4715                         MEMZERO(&mbs, sizeof (mbs));
 4716                         mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
 4717                         mbs.param[1] = QENTRY_LEN;
 4718                         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 4719                         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 4720                         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 4721                         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 4722                         mbs.timeout = 5000000;
 4723                         mbs.logval = MBLOGALL;
 4724 
 4725                         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 4726                                 isp_prt(isp, ISP_LOGERR, sacq);
 4727                                 break;
 4728                         }
 4729                         isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch);
 4730                         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN);
 4731                         fcp->sendmarker = 1;
 4732                         isp_mboxcmd(isp, &mbs);
 4733                         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 4734                                 FC_SCRATCH_RELEASE(isp, chan);
 4735                                 break;
 4736                         }
 4737                         MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
 4738                             QENTRY_LEN);
 4739                         sp = (isp24xx_statusreq_t *) local;
 4740                         isp_get_24xx_response(isp,
 4741                             &((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp);
 4742                         FC_SCRATCH_RELEASE(isp, chan);
 4743                         if (sp->req_completion_status == 0) {
 4744                                 return (0);
 4745                         }
 4746                         isp_prt(isp, ISP_LOGWARN,
 4747                             "Chan %d reset of target %d returned 0x%x",
 4748                             chan, tgt, sp->req_completion_status);
 4749                         break;
 4750                 } else if (IS_FC(isp)) {
 4751                         if (ISP_CAP_2KLOGIN(isp)) {
 4752                                 mbs.param[1] = tgt;
 4753                                 mbs.ibits = (1 << 10);
 4754                         } else {
 4755                                 mbs.param[1] = (tgt << 8);
 4756                         }
 4757                 } else {
 4758                         mbs.param[1] = (chan << 15) | (tgt << 8);
 4759                 }
 4760                 mbs.param[0] = MBOX_ABORT_TARGET;
 4761                 mbs.param[2] = 3;       /* 'delay', in seconds */
 4762                 mbs.logval = MBLOGALL;
 4763                 isp_mboxcmd(isp, &mbs);
 4764                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 4765                         break;
 4766                 }
 4767                 isp_prt(isp, ISP_LOGINFO,
 4768                     "Target %d on Bus %d Reset Succeeded", tgt, chan);
 4769                 ISP_SET_SENDMARKER(isp, chan, 1);
 4770                 return (0);
 4771 
 4772         case ISPCTL_ABORT_CMD:
 4773                 va_start(ap, ctl);
 4774                 xs = va_arg(ap, XS_T *);
 4775                 va_end(ap);
 4776 
 4777                 tgt = XS_TGT(xs);
 4778                 chan = XS_CHANNEL(xs);
 4779 
 4780                 handle = isp_find_handle(isp, xs);
 4781                 if (handle == 0) {
 4782                         isp_prt(isp, ISP_LOGWARN,
 4783                             "cannot find handle for command to abort");
 4784                         break;
 4785                 }
 4786                 if (IS_24XX(isp)) {
 4787                         isp24xx_abrt_t local, *ab = &local, *ab2;
 4788                         fcparam *fcp;
 4789                         fcportdb_t *lp;
 4790                         int hdlidx;
 4791 
 4792                         fcp = FCPARAM(isp, chan);
 4793                         hdlidx = fcp->isp_ini_map[tgt] - 1;
 4794                         if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
 4795                                 isp_prt(isp, ISP_LOGWARN,
 4796                                     "Chan %d bad handle %d trying to abort"
 4797                                     "target %d", chan, hdlidx, tgt);
 4798                                 break;
 4799                         }
 4800                         lp = &fcp->portdb[hdlidx];
 4801                         if (lp->state != FC_PORTDB_STATE_VALID) {
 4802                                 isp_prt(isp, ISP_LOGWARN,
 4803                                     "Chan %d handle %d for abort of target %d "
 4804                                     "no longer valid", chan, hdlidx, tgt);
 4805                                 break;
 4806                         }
 4807                         isp_prt(isp, ISP_LOGALL,
 4808                             "Chan %d Abort Cmd for N-Port 0x%04x @ Port "
 4809                             "0x%06x %p", chan, lp->handle, lp->portid, xs);
 4810                         MEMZERO(ab, QENTRY_LEN);
 4811                         ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
 4812                         ab->abrt_header.rqs_entry_count = 1;
 4813                         ab->abrt_handle = lp->handle;
 4814                         ab->abrt_cmd_handle = handle;
 4815                         ab->abrt_tidlo = lp->portid;
 4816                         ab->abrt_tidhi = lp->portid >> 16;
 4817                         ab->abrt_vpidx = chan;
 4818 
 4819                         MEMZERO(&mbs, sizeof (mbs));
 4820                         mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
 4821                         mbs.param[1] = QENTRY_LEN;
 4822                         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 4823                         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 4824                         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 4825                         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 4826                         mbs.timeout = 5000000;
 4827                         mbs.logval = MBLOGALL;
 4828 
 4829                         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 4830                                 isp_prt(isp, ISP_LOGERR, sacq);
 4831                                 break;
 4832                         }
 4833                         isp_put_24xx_abrt(isp, ab, fcp->isp_scratch);
 4834                         ab2 = (isp24xx_abrt_t *)
 4835                             &((uint8_t *)fcp->isp_scratch)[QENTRY_LEN];
 4836                         ab2->abrt_nphdl = 0xdeaf;
 4837                         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, 2 * QENTRY_LEN);
 4838                         isp_mboxcmd(isp, &mbs);
 4839                         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 4840                                 FC_SCRATCH_RELEASE(isp, chan);
 4841                                 break;
 4842                         }
 4843                         MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
 4844                             QENTRY_LEN);
 4845                         isp_get_24xx_abrt(isp, ab2, ab);
 4846                         FC_SCRATCH_RELEASE(isp, chan);
 4847                         if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY) {
 4848                                 return (0);
 4849                         }
 4850                         isp_prt(isp, ISP_LOGWARN,
 4851                             "Chan %d handle %d abort returned 0x%x", chan,
 4852                             hdlidx, ab->abrt_nphdl);
 4853                         break;
 4854                 } else if (IS_FC(isp)) {
 4855                         if (ISP_CAP_SCCFW(isp)) {
 4856                                 if (ISP_CAP_2KLOGIN(isp)) {
 4857                                         mbs.param[1] = tgt;
 4858                                 } else {
 4859                                         mbs.param[1] = tgt << 8;
 4860                                 }
 4861                                 mbs.param[6] = XS_LUN(xs);
 4862                         } else {
 4863                                 mbs.param[1] = tgt << 8 | XS_LUN(xs);
 4864                         }
 4865                 } else {
 4866                         mbs.param[1] = (chan << 15) | (tgt << 8) | XS_LUN(xs);
 4867                 }
 4868                 mbs.param[0] = MBOX_ABORT;
 4869                 mbs.param[2] = handle;
 4870                 mbs.logval = MBLOGALL & ~MBOX_COMMAND_ERROR;
 4871                 isp_mboxcmd(isp, &mbs);
 4872                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 4873                         break;
 4874                 }
 4875                 return (0);
 4876 
 4877         case ISPCTL_UPDATE_PARAMS:
 4878 
 4879                 va_start(ap, ctl);
 4880                 chan = va_arg(ap, int);
 4881                 va_end(ap);
 4882                 isp_spi_update(isp, chan);
 4883                 return (0);
 4884 
 4885         case ISPCTL_FCLINK_TEST:
 4886 
 4887                 if (IS_FC(isp)) {
 4888                         int usdelay;
 4889                         va_start(ap, ctl);
 4890                         chan = va_arg(ap, int);
 4891                         usdelay = va_arg(ap, int);
 4892                         va_end(ap);
 4893                         if (usdelay == 0) {
 4894                                 usdelay =  250000;
 4895                         }
 4896                         return (isp_fclink_test(isp, chan, usdelay));
 4897                 }
 4898                 break;
 4899 
 4900         case ISPCTL_SCAN_FABRIC:
 4901 
 4902                 if (IS_FC(isp)) {
 4903                         va_start(ap, ctl);
 4904                         chan = va_arg(ap, int);
 4905                         va_end(ap);
 4906                         return (isp_scan_fabric(isp, chan));
 4907                 }
 4908                 break;
 4909 
 4910         case ISPCTL_SCAN_LOOP:
 4911 
 4912                 if (IS_FC(isp)) {
 4913                         va_start(ap, ctl);
 4914                         chan = va_arg(ap, int);
 4915                         va_end(ap);
 4916                         return (isp_scan_loop(isp, chan));
 4917                 }
 4918                 break;
 4919 
 4920         case ISPCTL_PDB_SYNC:
 4921 
 4922                 if (IS_FC(isp)) {
 4923                         va_start(ap, ctl);
 4924                         chan = va_arg(ap, int);
 4925                         va_end(ap);
 4926                         return (isp_pdb_sync(isp, chan));
 4927                 }
 4928                 break;
 4929 
 4930         case ISPCTL_SEND_LIP:
 4931 
 4932                 if (IS_FC(isp) && !IS_24XX(isp)) {
 4933                         mbs.param[0] = MBOX_INIT_LIP;
 4934                         if (ISP_CAP_2KLOGIN(isp)) {
 4935                                 mbs.ibits = (1 << 10);
 4936                         }
 4937                         mbs.logval = MBLOGALL;
 4938                         isp_mboxcmd(isp, &mbs);
 4939                         if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 4940                                 return (0);
 4941                         }
 4942                 }
 4943                 break;
 4944 
 4945         case ISPCTL_GET_PDB:
 4946                 if (IS_FC(isp)) {
 4947                         isp_pdb_t *pdb;
 4948                         va_start(ap, ctl);
 4949                         chan = va_arg(ap, int);
 4950                         tgt = va_arg(ap, int);
 4951                         pdb = va_arg(ap, isp_pdb_t *);
 4952                         va_end(ap);
 4953                         return (isp_getpdb(isp, chan, tgt, pdb, 1));
 4954                 }
 4955                 break;
 4956 
 4957         case ISPCTL_GET_NAMES:
 4958         {
 4959                 uint64_t *wwnn, *wwnp;
 4960                 va_start(ap, ctl);
 4961                 chan = va_arg(ap, int);
 4962                 tgt = va_arg(ap, int);
 4963                 wwnn = va_arg(ap, uint64_t *);
 4964                 wwnp = va_arg(ap, uint64_t *);
 4965                 va_end(ap);
 4966                 if (wwnn == NULL && wwnp == NULL) {
 4967                         break;
 4968                 }
 4969                 if (wwnn) {
 4970                         *wwnn = isp_get_wwn(isp, chan, tgt, 1);
 4971                         if (*wwnn == INI_NONE) {
 4972                                 break;
 4973                         }
 4974                 }
 4975                 if (wwnp) {
 4976                         *wwnp = isp_get_wwn(isp, chan, tgt, 0);
 4977                         if (*wwnp == INI_NONE) {
 4978                                 break;
 4979                         }
 4980                 }
 4981                 return (0);
 4982         }
 4983         case ISPCTL_RUN_MBOXCMD:
 4984         {
 4985                 va_start(ap, ctl);
 4986                 mbr = va_arg(ap, mbreg_t *);
 4987                 va_end(ap);
 4988                 isp_mboxcmd(isp, mbr);
 4989                 return(0);
 4990         }
 4991         case ISPCTL_PLOGX:
 4992         {
 4993                 isp_plcmd_t *p;
 4994                 int r;
 4995 
 4996                 va_start(ap, ctl);
 4997                 p = va_arg(ap, isp_plcmd_t *);
 4998                 va_end(ap);
 4999 
 5000                 if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI ||
 5001                     (p->handle != NIL_HANDLE)) {
 5002                         return (isp_plogx(isp, p->channel, p->handle,
 5003                             p->portid, p->flags, 0));
 5004                 }
 5005                 do {
 5006                         p->handle = isp_nxt_handle(isp, p->channel, p->handle);
 5007                         r = isp_plogx(isp, p->channel, p->handle, p->portid,
 5008                             p->flags, 0);
 5009                         if ((r & 0xffff) == MBOX_PORT_ID_USED) {
 5010                                 p->handle = r >> 16;
 5011                                 r = 0;
 5012                                 break;
 5013                         }
 5014                 } while ((r & 0xffff) == MBOX_LOOP_ID_USED);
 5015                 return (r);
 5016         }
 5017         default:
 5018                 isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
 5019                 break;
 5020 
 5021         }
 5022         return (-1);
 5023 }
 5024 
 5025 /*
 5026  * Interrupt Service Routine(s).
 5027  *
 5028  * External (OS) framework has done the appropriate locking,
 5029  * and the locking will be held throughout this function.
 5030  */
 5031 
 5032 /*
 5033  * Limit our stack depth by sticking with the max likely number
 5034  * of completions on a request queue at any one time.
 5035  */
 5036 #ifndef MAX_REQUESTQ_COMPLETIONS
 5037 #define MAX_REQUESTQ_COMPLETIONS        32
 5038 #endif
 5039 
 5040 void
 5041 isp_intr(ispsoftc_t *isp, uint32_t isr, uint16_t sema, uint16_t mbox)
 5042 {
 5043         XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
 5044         uint32_t iptr, optr, junk;
 5045         int i, nlooked = 0, ndone = 0;
 5046 
 5047 again:
 5048         optr = isp->isp_residx;
 5049         /*
 5050          * Is this a mailbox related interrupt?
 5051          * The mailbox semaphore will be nonzero if so.
 5052          */
 5053         if (sema) {
 5054  fmbox:
 5055                 if (mbox & 0x4000) {
 5056                         isp->isp_intmboxc++;
 5057                         if (isp->isp_mboxbsy) {
 5058                                 int obits = isp->isp_obits;
 5059                                 isp->isp_mboxtmp[0] = mbox;
 5060                                 for (i = 1; i < MAX_MAILBOX(isp); i++) {
 5061                                         if ((obits & (1 << i)) == 0) {
 5062                                                 continue;
 5063                                         }
 5064                                         isp->isp_mboxtmp[i] =
 5065                                             ISP_READ(isp, MBOX_OFF(i));
 5066                                 }
 5067                                 if (isp->isp_mbxwrk0) {
 5068                                         if (isp_mbox_continue(isp) == 0) {
 5069                                                 return;
 5070                                         }
 5071                                 }
 5072                                 MBOX_NOTIFY_COMPLETE(isp);
 5073                         } else {
 5074                                 isp_prt(isp, ISP_LOGWARN,
 5075                                     "mailbox cmd (0x%x) with no waiters", mbox);
 5076                         }
 5077                 } else if (isp_parse_async(isp, mbox) < 0) {
 5078                         return;
 5079                 }
 5080                 if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) ||
 5081                     isp->isp_state != ISP_RUNSTATE) {
 5082                         goto out;
 5083                 }
 5084         }
 5085 
 5086         /*
 5087          * We can't be getting this now.
 5088          */
 5089         if (isp->isp_state != ISP_RUNSTATE) {
 5090                 /*
 5091                  * This seems to happen to 23XX and 24XX cards- don't know why.
 5092                  */
 5093                  if (isp->isp_mboxbsy && isp->isp_lastmbxcmd ==
 5094                     MBOX_ABOUT_FIRMWARE) {
 5095                         goto fmbox;
 5096                 }
 5097                 isp_prt(isp, ISP_LOGINFO,
 5098                     "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
 5099                 /*
 5100                  * Thank you very much!  *Burrrp*!
 5101                  */
 5102                 ISP_WRITE(isp, isp->isp_respoutrp,
 5103                     ISP_READ(isp, isp->isp_respinrp));
 5104                 if (IS_24XX(isp)) {
 5105                         ISP_DISABLE_INTS(isp);
 5106                 }
 5107                 goto out;
 5108         }
 5109 
 5110 #ifdef  ISP_TARGET_MODE
 5111         /*
 5112          * Check for ATIO Queue entries.
 5113          */
 5114         if (IS_24XX(isp)) {
 5115                 iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
 5116                 optr = ISP_READ(isp, BIU2400_ATIO_RSPOUTP);
 5117 
 5118                 while (optr != iptr) {
 5119                         uint8_t qe[QENTRY_LEN];
 5120                         isphdr_t *hp;
 5121                         uint32_t oop;
 5122                         void *addr;
 5123 
 5124                         oop = optr;
 5125                         MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN);
 5126                         addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
 5127                         isp_get_hdr(isp, addr, (isphdr_t *)qe);
 5128                         hp = (isphdr_t *)qe;
 5129                         switch (hp->rqs_entry_type) {
 5130                         case RQSTYPE_NOTIFY:
 5131                         case RQSTYPE_ATIO:
 5132                                 (void) isp_target_notify(isp, addr, &oop);
 5133                                 break;
 5134                         default:
 5135                                 isp_print_qentry(isp, "?ATIOQ entry?",
 5136                                     oop, addr);
 5137                                 break;
 5138                         }
 5139                         optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
 5140                         ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
 5141                 }
 5142                 optr = isp->isp_residx;
 5143         }
 5144 #endif
 5145 
 5146         /*
 5147          * Get the current Response Queue Out Pointer.
 5148          *
 5149          * If we're a 2300 or 2400, we can ask what hardware what it thinks.
 5150          */
 5151         if (IS_23XX(isp) || IS_24XX(isp)) {
 5152                 optr = ISP_READ(isp, isp->isp_respoutrp);
 5153                 /*
 5154                  * Debug: to be taken out eventually
 5155                  */
 5156                 if (isp->isp_residx != optr) {
 5157                         isp_prt(isp, ISP_LOGINFO,
 5158                             "isp_intr: hard optr=%x, soft optr %x",
 5159                             optr, isp->isp_residx);
 5160                         isp->isp_residx = optr;
 5161                 }
 5162         } else {
 5163                 optr = isp->isp_residx;
 5164         }
 5165 
 5166         /*
 5167          * You *must* read the Response Queue In Pointer
 5168          * prior to clearing the RISC interrupt.
 5169          *
 5170          * Debounce the 2300 if revision less than 2.
 5171          */
 5172         if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
 5173                 i = 0;
 5174                 do {
 5175                         iptr = ISP_READ(isp, isp->isp_respinrp);
 5176                         junk = ISP_READ(isp, isp->isp_respinrp);
 5177                 } while (junk != iptr && ++i < 1000);
 5178 
 5179                 if (iptr != junk) {
 5180                         isp_prt(isp, ISP_LOGWARN,
 5181                             "Response Queue Out Pointer Unstable (%x, %x)",
 5182                             iptr, junk);
 5183                         goto out;
 5184                 }
 5185         } else {
 5186                 iptr = ISP_READ(isp, isp->isp_respinrp);
 5187         }
 5188         isp->isp_resodx = iptr;
 5189 
 5190 
 5191         if (optr == iptr && sema == 0) {
 5192                 /*
 5193                  * There are a lot of these- reasons unknown- mostly on
 5194                  * faster Alpha machines.
 5195                  *
 5196                  * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
 5197                  * make sure the old interrupt went away (to avoid 'ringing'
 5198                  * effects), but that didn't stop this from occurring.
 5199                  */
 5200                 if (IS_24XX(isp)) {
 5201                         junk = 0;
 5202                 } else if (IS_23XX(isp)) {
 5203                         USEC_DELAY(100);
 5204                         iptr = ISP_READ(isp, isp->isp_respinrp);
 5205                         junk = ISP_READ(isp, BIU_R2HSTSLO);
 5206                 } else {
 5207                         junk = ISP_READ(isp, BIU_ISR);
 5208                 }
 5209                 if (optr == iptr) {
 5210                         if (IS_23XX(isp) || IS_24XX(isp)) {
 5211                                 ;
 5212                         } else {
 5213                                 sema = ISP_READ(isp, BIU_SEMA);
 5214                                 mbox = ISP_READ(isp, OUTMAILBOX0);
 5215                                 if ((sema & 0x3) && (mbox & 0x8000)) {
 5216                                         goto again;
 5217                                 }
 5218                         }
 5219                         isp->isp_intbogus++;
 5220                         isp_prt(isp, ISP_LOGDEBUG1,
 5221                             "bogus intr- isr %x (%x) iptr %x optr %x",
 5222                             isr, junk, iptr, optr);
 5223                 }
 5224         }
 5225         isp->isp_resodx = iptr;
 5226 
 5227         while (optr != iptr) {
 5228                 uint8_t qe[QENTRY_LEN];
 5229                 ispstatusreq_t *sp = (ispstatusreq_t *) qe;
 5230                 isphdr_t *hp;
 5231                 int buddaboom, etype, scsi_status, completion_status;
 5232                 int req_status_flags, req_state_flags;
 5233                 uint8_t *snsp, *resp;
 5234                 uint32_t rlen, slen;
 5235                 long resid;
 5236                 uint16_t oop;
 5237 
 5238                 hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
 5239                 oop = optr;
 5240                 optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
 5241                 nlooked++;
 5242  read_again:
 5243                 buddaboom = req_status_flags = req_state_flags = 0;
 5244                 resid = 0L;
 5245 
 5246                 /*
 5247                  * Synchronize our view of this response queue entry.
 5248                  */
 5249                 MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN);
 5250                 isp_get_hdr(isp, hp, &sp->req_header);
 5251                 etype = sp->req_header.rqs_entry_type;
 5252 
 5253                 if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) {
 5254                         isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe;
 5255                         isp_get_24xx_response(isp,
 5256                             (isp24xx_statusreq_t *)hp, sp2);
 5257                         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 5258                                 isp_print_bytes(isp,
 5259                                     "Response Queue Entry", QENTRY_LEN, sp2);
 5260                         }
 5261                         scsi_status = sp2->req_scsi_status;
 5262                         completion_status = sp2->req_completion_status;
 5263                         req_state_flags = 0;
 5264                         resid = sp2->req_resid;
 5265                 } else if (etype == RQSTYPE_RESPONSE) {
 5266                         isp_get_response(isp, (ispstatusreq_t *) hp, sp);
 5267                         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 5268                                 isp_print_bytes(isp,
 5269                                     "Response Queue Entry", QENTRY_LEN, sp);
 5270                         }
 5271                         scsi_status = sp->req_scsi_status;
 5272                         completion_status = sp->req_completion_status;
 5273                         req_status_flags = sp->req_status_flags;
 5274                         req_state_flags = sp->req_state_flags;
 5275                         resid = sp->req_resid;
 5276                 } else if (etype == RQSTYPE_RIO2) {
 5277                         isp_rio2_t *rio = (isp_rio2_t *)qe;
 5278                         isp_get_rio2(isp, (isp_rio2_t *) hp, rio);
 5279                         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 5280                                 isp_print_bytes(isp,
 5281                                     "Response Queue Entry", QENTRY_LEN, rio);
 5282                         }
 5283                         for (i = 0; i < rio->req_header.rqs_seqno; i++) {
 5284                                 isp_fastpost_complete(isp, rio->req_handles[i]);
 5285                         }
 5286                         if (isp->isp_fpcchiwater < rio->req_header.rqs_seqno) {
 5287                                 isp->isp_fpcchiwater =
 5288                                     rio->req_header.rqs_seqno;
 5289                         }
 5290                         MEMZERO(hp, QENTRY_LEN);        /* PERF */
 5291                         continue;
 5292                 } else {
 5293                         /*
 5294                          * Somebody reachable via isp_handle_other_response
 5295                          * may have updated the response queue pointers for
 5296                          * us, so we reload our goal index.
 5297                          */
 5298                         int r;
 5299                         uint32_t tsto = oop;
 5300                         r = isp_handle_other_response(isp, etype, hp, &tsto);
 5301                         if (r < 0) {
 5302                                 goto read_again;
 5303                         }
 5304                         /*
 5305                          * If somebody updated the output pointer, then reset
 5306                          * optr to be one more than the updated amount.
 5307                          */
 5308                         while (tsto != oop) {
 5309                                 optr = ISP_NXT_QENTRY(tsto,
 5310                                     RESULT_QUEUE_LEN(isp));
 5311                         }
 5312                         if (r > 0) {
 5313                                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
 5314                                 MEMZERO(hp, QENTRY_LEN);        /* PERF */
 5315                                 continue;
 5316                         }
 5317 
 5318                         /*
 5319                          * After this point, we'll just look at the header as
 5320                          * we don't know how to deal with the rest of the
 5321                          * response.
 5322                          */
 5323 
 5324                         /*
 5325                          * It really has to be a bounced request just copied
 5326                          * from the request queue to the response queue. If
 5327                          * not, something bad has happened.
 5328                          */
 5329                         if (etype != RQSTYPE_REQUEST) {
 5330                                 isp_prt(isp, ISP_LOGERR, notresp,
 5331                                     etype, oop, optr, nlooked);
 5332                                 isp_print_bytes(isp,
 5333                                     "Request Queue Entry", QENTRY_LEN, sp);
 5334                                 MEMZERO(hp, QENTRY_LEN);        /* PERF */
 5335                                 continue;
 5336                         }
 5337                         buddaboom = 1;
 5338                         scsi_status = sp->req_scsi_status;
 5339                         completion_status = sp->req_completion_status;
 5340                         req_status_flags = sp->req_status_flags;
 5341                         req_state_flags = sp->req_state_flags;
 5342                         resid = sp->req_resid;
 5343                 }
 5344 
 5345                 if (sp->req_header.rqs_flags & RQSFLAG_MASK) {
 5346                         if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
 5347                                 isp_prt(isp, ISP_LOGWARN,
 5348                                     "continuation segment");
 5349                                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
 5350                                 continue;
 5351                         }
 5352                         if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
 5353                                 isp_prt(isp, ISP_LOGDEBUG1,
 5354                                     "internal queues full");
 5355                                 /*
 5356                                  * We'll synthesize a QUEUE FULL message below.
 5357                                  */
 5358                         }
 5359                         if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
 5360                                 isp_print_bytes(isp, "bad header flag",
 5361                                     QENTRY_LEN, sp);
 5362                                 buddaboom++;
 5363                         }
 5364                         if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
 5365                                 isp_print_bytes(isp, "bad request packet",
 5366                                     QENTRY_LEN, sp);
 5367                                 buddaboom++;
 5368                         }
 5369                 }
 5370 
 5371                 if ((sp->req_handle != ISP_SPCL_HANDLE) &&
 5372                     (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1)) {
 5373                         isp_prt(isp, ISP_LOGERR,
 5374                             "bad request handle %d (type 0x%x)",
 5375                             sp->req_handle, etype);
 5376                         MEMZERO(hp, QENTRY_LEN);        /* PERF */
 5377                         ISP_WRITE(isp, isp->isp_respoutrp, optr);
 5378                         continue;
 5379                 }
 5380                 xs = isp_find_xs(isp, sp->req_handle);
 5381                 if (xs == NULL) {
 5382                         uint8_t ts = completion_status & 0xff;
 5383                         /*
 5384                          * Only whine if this isn't the expected fallout of
 5385                          * aborting the command or resetting the target.
 5386                          */
 5387                         if (etype != RQSTYPE_RESPONSE) {
 5388                                 isp_prt(isp, ISP_LOGERR,
 5389                                     "cannot find handle 0x%x (type 0x%x)",
 5390                                     sp->req_handle, etype);
 5391                         } else if (ts != RQCS_ABORTED &&
 5392                             ts != RQCS_RESET_OCCURRED &&
 5393                             sp->req_handle != ISP_SPCL_HANDLE) {
 5394                                 isp_prt(isp, ISP_LOGERR,
 5395                                     "cannot find handle 0x%x (status 0x%x)",
 5396                                     sp->req_handle, ts);
 5397                         }
 5398                         MEMZERO(hp, QENTRY_LEN);        /* PERF */
 5399                         ISP_WRITE(isp, isp->isp_respoutrp, optr);
 5400                         continue;
 5401                 }
 5402                 isp_destroy_handle(isp, sp->req_handle);
 5403                 if (req_status_flags & RQSTF_BUS_RESET) {
 5404                         XS_SETERR(xs, HBA_BUSRESET);
 5405                         ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
 5406                 }
 5407                 if (buddaboom) {
 5408                         XS_SETERR(xs, HBA_BOTCH);
 5409                 }
 5410 
 5411                 resp = NULL;
 5412                 rlen = 0;
 5413                 snsp = NULL;
 5414                 slen = 0;
 5415                 if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) {
 5416                         resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
 5417                         rlen = ((isp24xx_statusreq_t *)sp)->req_response_len;
 5418                 } else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) {
 5419                         resp = sp->req_response;
 5420                         rlen = sp->req_response_len;
 5421                 }
 5422                 if (IS_FC(isp) && (scsi_status & RQCS_SV) != 0) {
 5423                         /*
 5424                          * Fibre Channel F/W doesn't say we got status
 5425                          * if there's Sense Data instead. I guess they
 5426                          * think it goes w/o saying.
 5427                          */
 5428                         req_state_flags |= RQSF_GOT_STATUS|RQSF_GOT_SENSE;
 5429                         if (IS_24XX(isp)) {
 5430                                 snsp =
 5431                                     ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
 5432                                 snsp += rlen;
 5433                                 slen =
 5434                                     ((isp24xx_statusreq_t *)sp)->req_sense_len;
 5435                         } else {
 5436                                 snsp = sp->req_sense_data;
 5437                                 slen = sp->req_sense_len;
 5438                         }
 5439                 } else if (IS_SCSI(isp) && (req_state_flags & RQSF_GOT_SENSE)) {
 5440                         snsp = sp->req_sense_data;
 5441                         slen = sp->req_sense_len;
 5442                 }
 5443                 if (req_state_flags & RQSF_GOT_STATUS) {
 5444                         *XS_STSP(xs) = scsi_status & 0xff;
 5445                 }
 5446 
 5447                 switch (etype) {
 5448                 case RQSTYPE_RESPONSE:
 5449                         if (resp && rlen >= 4 &&
 5450                             resp[FCP_RSPNS_CODE_OFFSET] != 0) {
 5451                                 isp_prt(isp, ISP_LOGWARN,
 5452                                     "%d.%d.%d FCP RESPONSE: 0x%x",
 5453                                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
 5454                                     resp[FCP_RSPNS_CODE_OFFSET]);
 5455                                 XS_SETERR(xs, HBA_BOTCH);
 5456                         }
 5457                         if (IS_24XX(isp)) {
 5458                                 isp_parse_status_24xx(isp,
 5459                                     (isp24xx_statusreq_t *)sp, xs, &resid);
 5460                         } else {
 5461                                 isp_parse_status(isp, (void *)sp, xs, &resid);
 5462                         }
 5463                         if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) &&
 5464                             (*XS_STSP(xs) == SCSI_BUSY)) {
 5465                                 XS_SETERR(xs, HBA_TGTBSY);
 5466                         }
 5467                         if (IS_SCSI(isp)) {
 5468                                 XS_RESID(xs) = resid;
 5469                                 /*
 5470                                  * A new synchronous rate was negotiated for
 5471                                  * this target. Mark state such that we'll go
 5472                                  * look up that which has changed later.
 5473                                  */
 5474                                 if (req_status_flags & RQSTF_NEGOTIATION) {
 5475                                         int t = XS_TGT(xs);
 5476                                         sdparam *sdp =
 5477                                             SDPARAM(isp, XS_CHANNEL(xs));
 5478                                         sdp->isp_devparam[t].dev_refresh = 1;
 5479                                         sdp->update = 1;
 5480                                 }
 5481                         } else {
 5482                                 if (req_status_flags & RQSF_XFER_COMPLETE) {
 5483                                         XS_RESID(xs) = 0;
 5484                                 } else if (scsi_status & RQCS_RESID) {
 5485                                         XS_RESID(xs) = resid;
 5486                                 } else {
 5487                                         XS_RESID(xs) = 0;
 5488                                 }
 5489                         }
 5490                         if (snsp && slen) {
 5491                                 XS_SAVE_SENSE(xs, snsp, slen);
 5492                         }
 5493                         isp_prt(isp, ISP_LOGDEBUG2,
 5494                            "asked for %ld got raw resid %ld settled for %ld",
 5495                             (long) XS_XFRLEN(xs), resid, (long) XS_RESID(xs));
 5496                         break;
 5497                 case RQSTYPE_REQUEST:
 5498                 case RQSTYPE_A64:
 5499                 case RQSTYPE_T2RQS:
 5500                 case RQSTYPE_T3RQS:
 5501                 case RQSTYPE_T7RQS:
 5502                         if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
 5503                                 /*
 5504                                  * Force Queue Full status.
 5505                                  */
 5506                                 *XS_STSP(xs) = SCSI_QFULL;
 5507                                 XS_SETERR(xs, HBA_NOERROR);
 5508                         } else if (XS_NOERR(xs)) {
 5509                                 /*
 5510                                  * ????
 5511                                  */
 5512                                 XS_SETERR(xs, HBA_BOTCH);
 5513                                 isp_prt(isp, ISP_LOGDEBUG0,
 5514                                     "Request Queue Entry bounced back");
 5515                                 if ((isp->isp_dblev & ISP_LOGDEBUG1) == 0) {
 5516                                         isp_print_bytes(isp, "Bounced Request",
 5517                                             QENTRY_LEN, qe);
 5518                                 }
 5519                         }
 5520                         XS_RESID(xs) = XS_XFRLEN(xs);
 5521                         break;
 5522                 default:
 5523                         isp_print_bytes(isp, "Unhandled Response Type",
 5524                             QENTRY_LEN, qe);
 5525                         if (XS_NOERR(xs)) {
 5526                                 XS_SETERR(xs, HBA_BOTCH);
 5527                         }
 5528                         break;
 5529                 }
 5530 
 5531                 /*
 5532                  * Free any DMA resources. As a side effect, this may
 5533                  * also do any cache flushing necessary for data coherence.
 5534                  */
 5535                 if (XS_XFRLEN(xs)) {
 5536                         ISP_DMAFREE(isp, xs, sp->req_handle);
 5537                 }
 5538 
 5539                 if (((isp->isp_dblev & (ISP_LOGDEBUG1|ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
 5540                     ((isp->isp_dblev & ISP_LOGDEBUG0) && ((!XS_NOERR(xs)) ||
 5541                     (*XS_STSP(xs) != SCSI_GOOD)))) {
 5542                         char skey;
 5543                         if (req_state_flags & RQSF_GOT_SENSE) {
 5544                                 skey = XS_SNSKEY(xs) & 0xf;
 5545                                 if (skey < 10)
 5546                                         skey += '';
 5547                                 else
 5548                                         skey += 'a' - 10;
 5549                         } else if (*XS_STSP(xs) == SCSI_CHECK) {
 5550                                 skey = '?';
 5551                         } else {
 5552                                 skey = '.';
 5553                         }
 5554                         isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs),
 5555                             XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), XS_RESID(xs),
 5556                             *XS_STSP(xs), skey, XS_ERR(xs));
 5557                 }
 5558 
 5559                 if (isp->isp_nactive > 0) {
 5560                     isp->isp_nactive--;
 5561                 }
 5562                 complist[ndone++] = xs; /* defer completion call until later */
 5563                 MEMZERO(hp, QENTRY_LEN);        /* PERF */
 5564                 if (ndone == MAX_REQUESTQ_COMPLETIONS) {
 5565                         break;
 5566                 }
 5567         }
 5568 
 5569         /*
 5570          * If we looked at any commands, then it's valid to find out
 5571          * what the outpointer is. It also is a trigger to update the
 5572          * ISP's notion of what we've seen so far.
 5573          */
 5574         if (nlooked) {
 5575                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
 5576                 /*
 5577                  * While we're at it, read the requst queue out pointer.
 5578                  */
 5579                 isp->isp_reqodx = ISP_READ(isp, isp->isp_rqstoutrp);
 5580                 if (isp->isp_rscchiwater < ndone) {
 5581                         isp->isp_rscchiwater = ndone;
 5582                 }
 5583         }
 5584 
 5585 out:
 5586 
 5587         if (IS_24XX(isp)) {
 5588                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
 5589         } else {
 5590                 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
 5591                 ISP_WRITE(isp, BIU_SEMA, 0);
 5592         }
 5593 
 5594         isp->isp_residx = optr;
 5595         for (i = 0; i < ndone; i++) {
 5596                 xs = complist[i];
 5597                 if (xs) {
 5598                         isp->isp_rsltccmplt++;
 5599                         isp_done(xs);
 5600                 }
 5601         }
 5602 }
 5603 
 5604 /*
 5605  * Support routines.
 5606  */
 5607 
 5608 #define GET_24XX_BUS(isp, chan, msg)                                    \
 5609         if (IS_24XX(isp)) {                                             \
 5610                 chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;               \
 5611                 if (chan >= isp->isp_nchan) {                           \
 5612                         isp_prt(isp, ISP_LOGERR,                        \
 5613                             "bogus channel %u for %s at line %d",       \
 5614                             chan, msg, __LINE__);                       \
 5615                         break;                                          \
 5616                 }                                                       \
 5617         }
 5618 
 5619 static int
 5620 isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
 5621 {
 5622         int rval = 0;
 5623         int pattern = 0;
 5624         uint16_t chan;
 5625 
 5626         if (IS_DUALBUS(isp)) {
 5627                 chan = ISP_READ(isp, OUTMAILBOX6);
 5628         } else {
 5629                 chan = 0;
 5630         }
 5631         isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
 5632 
 5633         switch (mbox) {
 5634         case ASYNC_BUS_RESET:
 5635                 if (IS_FC(isp)) {
 5636                         isp_prt(isp, ISP_LOGWARN,
 5637                             "ILLEGAL ASYNC_BUS_RESET for FC card");
 5638                         break;
 5639                 }
 5640                 ISP_SET_SENDMARKER(isp, chan, 1);
 5641 #ifdef  ISP_TARGET_MODE
 5642                 if (isp_target_async(isp, chan, mbox)) {
 5643                         rval = -1;
 5644                 }
 5645 #endif
 5646                 isp_async(isp, ISPASYNC_BUS_RESET, chan);
 5647                 break;
 5648         case ASYNC_SYSTEM_ERROR:
 5649                 isp->isp_dead = 1;
 5650                 isp->isp_state = ISP_CRASHED;
 5651                 if (IS_FC(isp)) {
 5652                         FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
 5653                         FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
 5654                 }
 5655                 /*
 5656                  * Were we waiting for a mailbox command to complete?
 5657                  * If so, it's dead, so wake up the waiter.
 5658                  */
 5659                 if (isp->isp_mboxbsy) {
 5660                         isp->isp_obits = 1;
 5661                         isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
 5662                         MBOX_NOTIFY_COMPLETE(isp);
 5663                 }
 5664                 /*
 5665                  * It's up to the handler for isp_async to reinit stuff and
 5666                  * restart the firmware
 5667                  */
 5668                 isp_async(isp, ISPASYNC_FW_CRASH);
 5669                 rval = -1;
 5670                 break;
 5671 
 5672         case ASYNC_RQS_XFER_ERR:
 5673                 isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
 5674                 break;
 5675 
 5676         case ASYNC_RSP_XFER_ERR:
 5677                 isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
 5678                 break;
 5679 
 5680         case ASYNC_QWAKEUP:
 5681 #ifdef  ISP_TARGET_MODE
 5682                 if (IS_24XX(isp)) {
 5683                         isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
 5684                         break;
 5685                 }
 5686 #endif
 5687                 if (IS_FC(isp)) {
 5688                         isp_prt(isp, ISP_LOGWARN,
 5689                             "ILLEGAL ASYNC_QWAKEUP for FC card");
 5690                         break;
 5691                 }
 5692                 /*
 5693                  * We've just been notified that the Queue has woken up.
 5694                  * We don't need to be chatty about this- just unlatch things
 5695                  * and move on.
 5696                  */
 5697                 mbox = ISP_READ(isp, isp->isp_rqstoutrp);
 5698                 break;
 5699 
 5700         case ASYNC_TIMEOUT_RESET:
 5701                 if (IS_FC(isp)) {
 5702                         isp_prt(isp, ISP_LOGWARN,
 5703                             "ILLEGAL ASYNC_TIMEOUT_RESET for FC card");
 5704                         break;
 5705                 }
 5706                 isp_prt(isp, ISP_LOGWARN,
 5707                     "timeout initiated SCSI bus reset of chan %d", chan);
 5708                 ISP_SET_SENDMARKER(isp, chan, 1);
 5709 #ifdef  ISP_TARGET_MODE
 5710                 if (isp_target_async(isp, chan, mbox)) {
 5711                         rval = -1;
 5712                 }
 5713 #endif
 5714                 break;
 5715 
 5716         case ASYNC_DEVICE_RESET:
 5717                 if (IS_FC(isp)) {
 5718                         isp_prt(isp, ISP_LOGWARN,
 5719                             "ILLEGAL DEVICE_RESET for FC card");
 5720                         break;
 5721                 }
 5722                 isp_prt(isp, ISP_LOGINFO, "device reset on chan %d", chan);
 5723                 ISP_SET_SENDMARKER(isp, chan, 1);
 5724 #ifdef  ISP_TARGET_MODE
 5725                 if (isp_target_async(isp, chan, mbox)) {
 5726                         rval = -1;
 5727                 }
 5728 #endif
 5729                 break;
 5730 
 5731         case ASYNC_EXTMSG_UNDERRUN:
 5732                 if (IS_FC(isp)) {
 5733                         isp_prt(isp, ISP_LOGWARN,
 5734                             "ILLEGAL ASYNC_EXTMSG_UNDERRUN for FC card");
 5735                         break;
 5736                 }
 5737                 isp_prt(isp, ISP_LOGWARN, "extended message underrun");
 5738                 break;
 5739 
 5740         case ASYNC_SCAM_INT:
 5741                 if (IS_FC(isp)) {
 5742                         isp_prt(isp, ISP_LOGWARN,
 5743                             "ILLEGAL ASYNC_SCAM_INT for FC card");
 5744                         break;
 5745                 }
 5746                 isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
 5747                 break;
 5748 
 5749         case ASYNC_HUNG_SCSI:
 5750                 if (IS_FC(isp)) {
 5751                         isp_prt(isp, ISP_LOGWARN,
 5752                             "ILLEGAL ASYNC_HUNG_SCSI for FC card");
 5753                         break;
 5754                 }
 5755                 isp_prt(isp, ISP_LOGERR,
 5756                     "stalled SCSI Bus after DATA Overrun");
 5757                 /* XXX: Need to issue SCSI reset at this point */
 5758                 break;
 5759 
 5760         case ASYNC_KILLED_BUS:
 5761                 if (IS_FC(isp)) {
 5762                         isp_prt(isp, ISP_LOGWARN,
 5763                             "ILLEGAL ASYNC_KILLED_BUS for FC card");
 5764                         break;
 5765                 }
 5766                 isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
 5767                 break;
 5768 
 5769         case ASYNC_BUS_TRANSIT:
 5770                 if (IS_FC(isp)) {
 5771                         isp_prt(isp, ISP_LOGWARN,
 5772                             "ILLEGAL ASYNC_BUS_TRANSIT for FC card");
 5773                         break;
 5774                 }
 5775                 mbox = ISP_READ(isp, OUTMAILBOX2);
 5776                 switch (mbox & 0x1c00) {
 5777                 case SXP_PINS_LVD_MODE:
 5778                         isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
 5779                         SDPARAM(isp, chan)->isp_diffmode = 0;
 5780                         SDPARAM(isp, chan)->isp_ultramode = 0;
 5781                         SDPARAM(isp, chan)->isp_lvdmode = 1;
 5782                         break;
 5783                 case SXP_PINS_HVD_MODE:
 5784                         isp_prt(isp, ISP_LOGINFO,
 5785                             "Transition to Differential mode");
 5786                         SDPARAM(isp, chan)->isp_diffmode = 1;
 5787                         SDPARAM(isp, chan)->isp_ultramode = 0;
 5788                         SDPARAM(isp, chan)->isp_lvdmode = 0;
 5789                         break;
 5790                 case SXP_PINS_SE_MODE:
 5791                         isp_prt(isp, ISP_LOGINFO,
 5792                             "Transition to Single Ended mode");
 5793                         SDPARAM(isp, chan)->isp_diffmode = 0;
 5794                         SDPARAM(isp, chan)->isp_ultramode = 1;
 5795                         SDPARAM(isp, chan)->isp_lvdmode = 0;
 5796                         break;
 5797                 default:
 5798                         isp_prt(isp, ISP_LOGWARN,
 5799                             "Transition to Unknown Mode 0x%x", mbox);
 5800                         break;
 5801                 }
 5802                 /*
 5803                  * XXX: Set up to renegotiate again!
 5804                  */
 5805                 /* Can only be for a 1080... */
 5806                 ISP_SET_SENDMARKER(isp, chan, 1);
 5807                 break;
 5808 
 5809         case ASYNC_RIO5:
 5810                 pattern = 0xce; /* outgoing mailbox regs 1-3, 6-7 */
 5811                 break;
 5812 
 5813         case ASYNC_RIO4:
 5814                 pattern = 0x4e; /* outgoing mailbox regs 1-3, 6 */
 5815                 break;
 5816 
 5817         case ASYNC_RIO3:
 5818                 pattern = 0x0e; /* outgoing mailbox regs 1-3 */
 5819                 break;
 5820 
 5821         case ASYNC_RIO2:
 5822                 pattern = 0x06; /* outgoing mailbox regs 1-2 */
 5823                 break;
 5824 
 5825         case ASYNC_RIO1:
 5826         case ASYNC_CMD_CMPLT:
 5827                 pattern = 0x02; /* outgoing mailbox regs 1 */
 5828                 break;
 5829 
 5830         case ASYNC_RIO_RESP:
 5831                 return (rval);
 5832 
 5833         case ASYNC_CTIO_DONE:
 5834         {
 5835 #ifdef  ISP_TARGET_MODE
 5836                 int handle;
 5837                 if (IS_SCSI(isp) || IS_24XX(isp)) {
 5838                         isp_prt(isp, ISP_LOGWARN,
 5839                             "bad ASYNC_CTIO_DONE for %s cards",
 5840                             IS_SCSI(isp)? "SCSI" : "24XX");
 5841                         break;
 5842                 }
 5843                 handle =
 5844                     (ISP_READ(isp, OUTMAILBOX2) << 16) | 
 5845                     (ISP_READ(isp, OUTMAILBOX1));
 5846                 if (isp_target_async(isp, handle, mbox)) {
 5847                         rval = -1;
 5848                 } else {
 5849                         /* count it as a fast posting intr */
 5850                         isp->isp_fphccmplt++;
 5851                 }
 5852 #else
 5853                 if (IS_SCSI(isp) || IS_24XX(isp)) {
 5854                         isp_prt(isp, ISP_LOGWARN,
 5855                             "bad ASYNC_CTIO_DONE for %s cards",
 5856                             IS_SCSI(isp)? "SCSI" : "24XX");
 5857                         break;
 5858                 }
 5859                 isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
 5860                 isp->isp_fphccmplt++;   /* count it as a fast posting intr */
 5861 #endif
 5862                 break;
 5863         }
 5864         case ASYNC_LIP_ERROR:
 5865         case ASYNC_LIP_F8:
 5866         case ASYNC_LIP_OCCURRED:
 5867         case ASYNC_PTPMODE:
 5868                 if (IS_SCSI(isp)) {
 5869                         isp_prt(isp, ISP_LOGWARN,
 5870                             "bad LIP event for SCSI cards");
 5871                         break;
 5872                 }
 5873                 /*
 5874                  * These are broadcast events that have to be sent across
 5875                  * all active channels.
 5876                  */
 5877                 for (chan = 0; chan < isp->isp_nchan; chan++) {
 5878                         fcparam *fcp = FCPARAM(isp, chan);
 5879                         int topo = fcp->isp_topo;
 5880 
 5881                         if (fcp->role == ISP_ROLE_NONE) {
 5882                                 continue;
 5883                         }
 5884 
 5885                         fcp->isp_fwstate = FW_CONFIG_WAIT;
 5886                         fcp->isp_loopstate = LOOP_LIP_RCVD;
 5887                         ISP_SET_SENDMARKER(isp, chan, 1);
 5888                         ISP_MARK_PORTDB(isp, chan, 1);
 5889                         isp_async(isp, ISPASYNC_LIP, chan);
 5890 #ifdef  ISP_TARGET_MODE
 5891                         if (isp_target_async(isp, chan, mbox)) {
 5892                                 rval = -1;
 5893                         }
 5894 #endif
 5895                         /*
 5896                          * We've had problems with data corruption occuring on
 5897                          * commands that complete (with no apparent error) after
 5898                          * we receive a LIP. This has been observed mostly on
 5899                          * Local Loop topologies. To be safe, let's just mark
 5900                          * all active commands as dead.
 5901                          */
 5902                         if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
 5903                                 int i, j;
 5904                                 for (i = j = 0; i < isp->isp_maxcmds; i++) {
 5905                                         XS_T *xs;
 5906                                         xs = isp->isp_xflist[i];
 5907                                         if (xs == NULL) {
 5908                                                 continue;
 5909                                         }
 5910                                         if (XS_CHANNEL(xs) != chan) {
 5911                                                 continue;
 5912                                         }
 5913                                         j++;
 5914                                         XS_SETERR(xs, HBA_BUSRESET);
 5915                                 }
 5916                                 if (j) {
 5917                                         isp_prt(isp, ISP_LOGERR, lipd, chan, j);
 5918                                 }
 5919                         }
 5920                 }
 5921                 break;
 5922 
 5923         case ASYNC_LOOP_UP:
 5924                 if (IS_SCSI(isp)) {
 5925                         isp_prt(isp, ISP_LOGWARN,
 5926                             "bad LOOP UP event for SCSI cards");
 5927                         break;
 5928                 }
 5929                 /*
 5930                  * This is a broadcast event that has to be sent across
 5931                  * all active channels.
 5932                  */
 5933                 for (chan = 0; chan < isp->isp_nchan; chan++) {
 5934                         fcparam *fcp = FCPARAM(isp, chan);
 5935 
 5936                         if (fcp->role == ISP_ROLE_NONE) {
 5937                                 continue;
 5938                         }
 5939 
 5940                         ISP_SET_SENDMARKER(isp, chan, 1);
 5941 
 5942                         fcp->isp_fwstate = FW_CONFIG_WAIT;
 5943                         fcp->isp_loopstate = LOOP_LIP_RCVD;
 5944                         ISP_MARK_PORTDB(isp, chan, 1);
 5945                         isp_async(isp, ISPASYNC_LOOP_UP, chan);
 5946 #ifdef  ISP_TARGET_MODE
 5947                         if (isp_target_async(isp, chan, mbox)) {
 5948                                 rval = -1;
 5949                         }
 5950 #endif
 5951                 }
 5952                 break;
 5953 
 5954         case ASYNC_LOOP_DOWN:
 5955                 if (IS_SCSI(isp)) {
 5956                         isp_prt(isp, ISP_LOGWARN,
 5957                             "bad LOOP DOWN event for SCSI cards");
 5958                         break;
 5959                 }
 5960                 /*
 5961                  * This is a broadcast event that has to be sent across
 5962                  * all active channels.
 5963                  */
 5964                 for (chan = 0; chan < isp->isp_nchan; chan++) {
 5965                         fcparam *fcp = FCPARAM(isp, chan);
 5966 
 5967                         if (fcp->role == ISP_ROLE_NONE) {
 5968                                 continue;
 5969                         }
 5970 
 5971                         ISP_SET_SENDMARKER(isp, chan, 1);
 5972                         fcp->isp_fwstate = FW_CONFIG_WAIT;
 5973                         fcp->isp_loopstate = LOOP_NIL;
 5974                         ISP_MARK_PORTDB(isp, chan, 1);
 5975                         isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
 5976 #ifdef  ISP_TARGET_MODE
 5977                         if (isp_target_async(isp, chan, mbox)) {
 5978                                 rval = -1;
 5979                         }
 5980 #endif
 5981                 }
 5982                 break;
 5983 
 5984         case ASYNC_LOOP_RESET:
 5985                 if (IS_SCSI(isp)) {
 5986                         isp_prt(isp, ISP_LOGWARN,
 5987                             "bad LIP RESET event for SCSI cards");
 5988                         break;
 5989                 }
 5990                 /*
 5991                  * This is a broadcast event that has to be sent across
 5992                  * all active channels.
 5993                  */
 5994                 for (chan = 0; chan < isp->isp_nchan; chan++) {
 5995                         fcparam *fcp = FCPARAM(isp, chan);
 5996 
 5997                         if (fcp->role == ISP_ROLE_NONE) {
 5998                                 continue;
 5999                         }
 6000 
 6001                         ISP_SET_SENDMARKER(isp, chan, 1);
 6002                         fcp->isp_fwstate = FW_CONFIG_WAIT;
 6003                         fcp->isp_loopstate = LOOP_NIL;
 6004                         ISP_MARK_PORTDB(isp, chan, 1);
 6005                         isp_async(isp, ISPASYNC_LOOP_RESET, chan);
 6006 #ifdef  ISP_TARGET_MODE
 6007                         if (isp_target_async(isp, chan, mbox)) {
 6008                                 rval = -1;
 6009                         }
 6010 #endif
 6011                 }
 6012                 break;
 6013 
 6014         case ASYNC_PDB_CHANGED:
 6015         {
 6016                 int nphdl, nlstate, reason;
 6017                 if (IS_SCSI(isp)) {
 6018                         isp_prt(isp, ISP_LOGWARN,
 6019                             "bad PDB CHANGED event for SCSI cards");
 6020                         break;
 6021                 }
 6022                 /*
 6023                  * We *should* get a channel out of the 24XX, but we don't seem
 6024                  * to get more than a PDB CHANGED on channel 0, so turn it into
 6025                  * a broadcast event.
 6026                  */
 6027                 if (IS_24XX(isp)) {
 6028                         nphdl = ISP_READ(isp, OUTMAILBOX1);
 6029                         nlstate = ISP_READ(isp, OUTMAILBOX2);
 6030                         reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
 6031                 } else {
 6032                         nphdl = NIL_HANDLE;
 6033                         nlstate = reason = 0;
 6034                 }
 6035                 for (chan = 0; chan < isp->isp_nchan; chan++) {
 6036                         fcparam *fcp = FCPARAM(isp, chan);
 6037 
 6038                         if (fcp->role == ISP_ROLE_NONE) {
 6039                                 continue;
 6040                         }
 6041                         ISP_SET_SENDMARKER(isp, chan, 1);
 6042                         fcp->isp_loopstate = LOOP_PDB_RCVD;
 6043                         ISP_MARK_PORTDB(isp, chan, 1);
 6044                         isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
 6045                             ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
 6046                 }
 6047                 break;
 6048         }
 6049         case ASYNC_CHANGE_NOTIFY:
 6050         {
 6051                 int lochan, hichan;
 6052 
 6053                 if (IS_SCSI(isp)) {
 6054                         isp_prt(isp, ISP_LOGWARN,
 6055                             "bad CHANGE NOTIFY event for SCSI cards");
 6056                         break;
 6057                 }
 6058                 if (ISP_FW_NEWER_THAN(isp, 4, 0, 25) && ISP_CAP_MULTI_ID(isp)) {
 6059                         GET_24XX_BUS(isp, chan, "ASYNC_CHANGE_NOTIFY");
 6060                         lochan = chan;
 6061                         hichan = chan + 1;
 6062                 } else {
 6063                         lochan = 0;
 6064                         hichan = isp->isp_nchan;
 6065                 }
 6066                 for (chan = lochan; chan < hichan; chan++) {
 6067                         fcparam *fcp = FCPARAM(isp, chan);
 6068 
 6069                         if (fcp->role == ISP_ROLE_NONE) {
 6070                                 continue;
 6071                         }
 6072 
 6073                         if (fcp->isp_topo == TOPO_F_PORT) {
 6074                                 fcp->isp_loopstate = LOOP_LSCAN_DONE;
 6075                         } else {
 6076                                 fcp->isp_loopstate = LOOP_PDB_RCVD;
 6077                         }
 6078                         ISP_MARK_PORTDB(isp, chan, 1);
 6079                         isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
 6080                             ISPASYNC_CHANGE_SNS);
 6081                 }
 6082                 break;
 6083         }
 6084 
 6085         case ASYNC_CONNMODE:
 6086                 /*
 6087                  * This only applies to 2100 amd 2200 cards
 6088                  */
 6089                 if (!IS_2200(isp) && !IS_2100(isp)) {
 6090                         isp_prt(isp, ISP_LOGWARN,
 6091                             "bad card for ASYNC_CONNMODE event");
 6092                         break;
 6093                 }
 6094                 chan = 0;
 6095                 mbox = ISP_READ(isp, OUTMAILBOX1);
 6096                 ISP_MARK_PORTDB(isp, chan, 1);
 6097                 switch (mbox) {
 6098                 case ISP_CONN_LOOP:
 6099                         isp_prt(isp, ISP_LOGINFO,
 6100                             "Point-to-Point -> Loop mode");
 6101                         break;
 6102                 case ISP_CONN_PTP:
 6103                         isp_prt(isp, ISP_LOGINFO,
 6104                             "Loop -> Point-to-Point mode");
 6105                         break;
 6106                 case ISP_CONN_BADLIP:
 6107                         isp_prt(isp, ISP_LOGWARN,
 6108                             "Point-to-Point -> Loop mode (BAD LIP)");
 6109                         break;
 6110                 case ISP_CONN_FATAL:
 6111                         isp->isp_dead = 1;
 6112                         isp->isp_state = ISP_CRASHED;
 6113                         isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
 6114                         isp_async(isp, ISPASYNC_FW_CRASH);
 6115                         return (-1);
 6116                 case ISP_CONN_LOOPBACK:
 6117                         isp_prt(isp, ISP_LOGWARN,
 6118                             "Looped Back in Point-to-Point mode");
 6119                         break;
 6120                 default:
 6121                         isp_prt(isp, ISP_LOGWARN,
 6122                             "Unknown connection mode (0x%x)", mbox);
 6123                         break;
 6124                 }
 6125                 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
 6126                     ISPASYNC_CHANGE_OTHER);
 6127                 FCPARAM(isp, chan)->sendmarker = 1;
 6128                 FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
 6129                 FCPARAM(isp, chan)->isp_loopstate = LOOP_LIP_RCVD;
 6130                 break;
 6131 
 6132         case ASYNC_RCV_ERR:
 6133                 if (IS_24XX(isp)) {
 6134                         isp_prt(isp, ISP_LOGWARN, "Receive Error");
 6135                 } else {
 6136                         isp_prt(isp, ISP_LOGWARN,
 6137                             "Unknown Async Code 0x%x", mbox);
 6138                 }
 6139                 break;
 6140         case ASYNC_RJT_SENT:    /* same as ASYNC_QFULL_SENT */
 6141                 if (IS_24XX(isp)) {
 6142                         isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
 6143                         break;
 6144                 } else if (IS_2200(isp)) {
 6145                         isp_prt(isp, ISP_LOGTDEBUG0, "QFULL sent");
 6146                         break;
 6147                 }
 6148                 /* FALLTHROUGH */
 6149         default:
 6150                 isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
 6151                 break;
 6152         }
 6153 
 6154         if (pattern) {
 6155                 int i, nh;
 6156                 uint16_t handles[16];
 6157 
 6158                 for (nh = 0, i = 1; i < MAX_MAILBOX(isp); i++) {
 6159                         if ((pattern & (1 << i)) == 0) {
 6160                                 continue;
 6161                         }
 6162                         handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
 6163                 }
 6164                 for (i = 0; i < nh; i++) {
 6165                         isp_fastpost_complete(isp, handles[i]);
 6166                         isp_prt(isp,  ISP_LOGDEBUG3,
 6167                             "fast post completion of %u", handles[i]);
 6168                 }
 6169                 if (isp->isp_fpcchiwater < nh) {
 6170                         isp->isp_fpcchiwater = nh;
 6171                 }
 6172         } else {
 6173                 isp->isp_intoasync++;
 6174         }
 6175         return (rval);
 6176 }
 6177 
 6178 /*
 6179  * Handle other response entries. A pointer to the request queue output
 6180  * index is here in case we want to eat several entries at once, although
 6181  * this is not used currently.
 6182  */
 6183 
 6184 static int
 6185 isp_handle_other_response(ispsoftc_t *isp, int type,
 6186     isphdr_t *hp, uint32_t *optrp)
 6187 {
 6188         switch (type) {
 6189         case RQSTYPE_STATUS_CONT:
 6190                 isp_prt(isp, ISP_LOGDEBUG0, "Ignored Continuation Response");
 6191                 return (1);
 6192         case RQSTYPE_MARKER:
 6193                 isp_prt(isp, ISP_LOGDEBUG0, "Marker Response");
 6194                 return (1);
 6195         case RQSTYPE_ATIO:
 6196         case RQSTYPE_CTIO:
 6197         case RQSTYPE_ENABLE_LUN:
 6198         case RQSTYPE_MODIFY_LUN:
 6199         case RQSTYPE_NOTIFY:
 6200         case RQSTYPE_NOTIFY_ACK:
 6201         case RQSTYPE_CTIO1:
 6202         case RQSTYPE_ATIO2:
 6203         case RQSTYPE_CTIO2:
 6204         case RQSTYPE_CTIO3:
 6205         case RQSTYPE_CTIO7:
 6206         case RQSTYPE_ABTS_RCVD:
 6207         case RQSTYPE_ABTS_RSP:
 6208                 isp->isp_rsltccmplt++;  /* count as a response completion */
 6209 #ifdef  ISP_TARGET_MODE
 6210                 if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
 6211                         return (1);
 6212                 }
 6213 #endif
 6214                 /* FALLTHROUGH */
 6215         case RQSTYPE_RPT_ID_ACQ:
 6216                 if (IS_24XX(isp)) {
 6217                         isp_ridacq_t rid;
 6218                         isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
 6219                         if (rid.ridacq_format == 0) {
 6220                         }
 6221                         return (1);
 6222                 }
 6223                 /* FALLTHROUGH */
 6224         case RQSTYPE_REQUEST:
 6225         default:
 6226                 USEC_DELAY(100);
 6227                 if (type != isp_get_response_type(isp, hp)) {
 6228                         /*
 6229                          * This is questionable- we're just papering over
 6230                          * something we've seen on SMP linux in target
 6231                          * mode- we don't really know what's happening
 6232                          * here that causes us to think we've gotten
 6233                          * an entry, but that either the entry isn't
 6234                          * filled out yet or our CPU read data is stale.
 6235                          */
 6236                         isp_prt(isp, ISP_LOGINFO,
 6237                                 "unstable type in response queue");
 6238                         return (-1);
 6239                 }
 6240                 isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
 6241                     isp_get_response_type(isp, hp));
 6242                 return (0);
 6243         }
 6244 }
 6245 
 6246 static void
 6247 isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
 6248 {
 6249         switch (sp->req_completion_status & 0xff) {
 6250         case RQCS_COMPLETE:
 6251                 if (XS_NOERR(xs)) {
 6252                         XS_SETERR(xs, HBA_NOERROR);
 6253                 }
 6254                 return;
 6255 
 6256         case RQCS_INCOMPLETE:
 6257                 if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
 6258                         isp_prt(isp, ISP_LOGDEBUG1,
 6259                             "Selection Timeout for %d.%d.%d",
 6260                             XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 6261                         if (XS_NOERR(xs)) {
 6262                                 XS_SETERR(xs, HBA_SELTIMEOUT);
 6263                                 *rp = XS_XFRLEN(xs);
 6264                         }
 6265                         return;
 6266                 }
 6267                 isp_prt(isp, ISP_LOGERR,
 6268                     "command incomplete for %d.%d.%d, state 0x%x",
 6269                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
 6270                     sp->req_state_flags);
 6271                 break;
 6272 
 6273         case RQCS_DMA_ERROR:
 6274                 isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
 6275                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 6276                 *rp = XS_XFRLEN(xs);
 6277                 break;
 6278 
 6279         case RQCS_TRANSPORT_ERROR:
 6280         {
 6281                 char buf[172];
 6282                 SNPRINTF(buf, sizeof (buf), "states=>");
 6283                 if (sp->req_state_flags & RQSF_GOT_BUS) {
 6284                         SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
 6285                 }
 6286                 if (sp->req_state_flags & RQSF_GOT_TARGET) {
 6287                         SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
 6288                 }
 6289                 if (sp->req_state_flags & RQSF_SENT_CDB) {
 6290                         SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
 6291                 }
 6292                 if (sp->req_state_flags & RQSF_XFRD_DATA) {
 6293                         SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
 6294                 }
 6295                 if (sp->req_state_flags & RQSF_GOT_STATUS) {
 6296                         SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
 6297                 }
 6298                 if (sp->req_state_flags & RQSF_GOT_SENSE) {
 6299                         SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
 6300                 }
 6301                 if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
 6302                         SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
 6303                 }
 6304                 SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
 6305                 if (sp->req_status_flags & RQSTF_DISCONNECT) {
 6306                         SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
 6307                 }
 6308                 if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
 6309                         SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
 6310                 }
 6311                 if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
 6312                         SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
 6313                 }
 6314                 if (sp->req_status_flags & RQSTF_BUS_RESET) {
 6315                         SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
 6316                 }
 6317                 if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
 6318                         SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
 6319                 }
 6320                 if (sp->req_status_flags & RQSTF_ABORTED) {
 6321                         SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
 6322                 }
 6323                 if (sp->req_status_flags & RQSTF_TIMEOUT) {
 6324                         SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
 6325                 }
 6326                 if (sp->req_status_flags & RQSTF_NEGOTIATION) {
 6327                         SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
 6328                 }
 6329                 isp_prt(isp, ISP_LOGERR, "%s", buf);
 6330                 isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
 6331                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
 6332                 *rp = XS_XFRLEN(xs);
 6333                 break;
 6334         }
 6335         case RQCS_RESET_OCCURRED:
 6336         {
 6337                 int chan;
 6338                 isp_prt(isp, ISP_LOGWARN,
 6339                     "bus reset destroyed command for %d.%d.%d",
 6340                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 6341                 for (chan = 0; chan < isp->isp_nchan; chan++) {
 6342                         FCPARAM(isp, chan)->sendmarker = 1;
 6343                 }
 6344                 if (XS_NOERR(xs)) {
 6345                         XS_SETERR(xs, HBA_BUSRESET);
 6346                 }
 6347                 *rp = XS_XFRLEN(xs);
 6348                 return;
 6349         }
 6350         case RQCS_ABORTED:
 6351                 isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
 6352                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));