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-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: isp.c,v 1.135 2021/12/12 13:05:14 andvar 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.135 2021/12/12 13:05:14 andvar 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 #define MBOX_DELAY_COUNT        1000000 / 100
   68 #define ISP_MARK_PORTDB(a, b, c)                                \
   69     isp_prt(isp, ISP_LOGSANCFG,                                 \
   70         "Chan %d ISP_MARK_PORTDB@LINE %d", b, __LINE__);        \
   71     isp_mark_portdb(a, b, c)
   72 
   73 /*
   74  * Local static data
   75  */
   76 static const char fconf[] = "Chan %d PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)\n database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)";
   77 static const char notresp[] = "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
   78 static const char topology[] = "Chan %d WWPN 0x%08x%08x PortID 0x%06x N-Port Handle %d, Connection '%s'";
   79 static const char bun[] = "bad underrun (count %d, resid %d, status %s)";
   80 static const char lipd[] = "Chan %d LIP destroyed %d active commands";
   81 static const char sacq[] = "unable to acquire scratch area";
   82 
   83 static const uint8_t alpa_map[] = {
   84         0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda,
   85         0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce,
   86         0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5,
   87         0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3,
   88         0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
   89         0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b,
   90         0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81,
   91         0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73,
   92         0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69,
   93         0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
   94         0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c,
   95         0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c,
   96         0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
   97         0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26,
   98         0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
   99         0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00
  100 };
  101 
  102 /*
  103  * Local function prototypes.
  104  */
  105 static void isp_prt_endcmd(ispsoftc_t *, XS_T *);
  106 static int isp_parse_async(ispsoftc_t *, uint16_t);
  107 static int isp_parse_async_fc(ispsoftc_t *, uint16_t);
  108 static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *);
  109 static void isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *); static void
  110 isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *);
  111 static void isp_fastpost_complete(ispsoftc_t *, uint32_t);
  112 static int isp_mbox_continue(ispsoftc_t *);
  113 static void isp_scsi_init(ispsoftc_t *);
  114 static void isp_scsi_channel_init(ispsoftc_t *, int);
  115 static void isp_fibre_init(ispsoftc_t *);
  116 static void isp_fibre_init_2400(ispsoftc_t *);
  117 static void isp_mark_portdb(ispsoftc_t *, int, int);
  118 static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int, int);
  119 static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t);
  120 static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t);
  121 static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *, int);
  122 static void isp_dump_chip_portdb(ispsoftc_t *, int, int);
  123 static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
  124 static int isp_fclink_test(ispsoftc_t *, int, int);
  125 static int isp_pdb_sync(ispsoftc_t *, int);
  126 static int isp_scan_loop(ispsoftc_t *, int);
  127 static int isp_gid_ft_sns(ispsoftc_t *, int);
  128 static int isp_gid_ft_ct_passthru(ispsoftc_t *, int);
  129 static int isp_scan_fabric(ispsoftc_t *, int);
  130 static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *);
  131 static int isp_register_fc4_type(ispsoftc_t *, int);
  132 static int isp_register_fc4_type_24xx(ispsoftc_t *, int);
  133 static uint16_t isp_nxt_handle(ispsoftc_t *, int, uint16_t);
  134 static void isp_fw_state(ispsoftc_t *, int);
  135 static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int);
  136 static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
  137 
  138 static void isp_spi_update(ispsoftc_t *, int);
  139 static void isp_setdfltsdparm(ispsoftc_t *);
  140 static void isp_setdfltfcparm(ispsoftc_t *, int);
  141 static int isp_read_nvram(ispsoftc_t *, int);
  142 static int isp_read_nvram_2400(ispsoftc_t *, uint8_t *);
  143 static void isp_rdnvram_word(ispsoftc_t *, int, uint16_t *);
  144 static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *);
  145 static void isp_parse_nvram_1020(ispsoftc_t *, uint8_t *);
  146 static void isp_parse_nvram_1080(ispsoftc_t *, int, uint8_t *);
  147 static void isp_parse_nvram_12160(ispsoftc_t *, int, uint8_t *);
  148 static void isp_parse_nvram_2100(ispsoftc_t *, uint8_t *);
  149 static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
  150 
  151 /*
  152  * Reset Hardware.
  153  *
  154  * Hit the chip over the head, download new f/w if available and set it running.
  155  *
  156  * Locking done elsewhere.
  157  */
  158 
  159 void
  160 isp_reset(ispsoftc_t *isp, int do_load_defaults)
  161 {
  162         mbreg_t mbs;
  163         uint32_t code_org, val;
  164         int loops, i, dodnld = 1;
  165         const char *btype = "????";
  166         static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
  167 
  168         isp->isp_state = ISP_NILSTATE;
  169         if (isp->isp_dead) {
  170                 isp_shutdown(isp);
  171                 ISP_DISABLE_INTS(isp);
  172                 return;
  173         }
  174 
  175         /*
  176          * Basic types (SCSI, FibreChannel and PCI or SBus)
  177          * have been set in the MD code. We figure out more
  178          * here. Possibly more refined types based upon PCI
  179          * identification. Chip revision has been gathered.
  180          *
  181          * After we've fired this chip up, zero out the conf1 register
  182          * for SCSI adapters and do other settings for the 2100.
  183          */
  184 
  185         ISP_DISABLE_INTS(isp);
  186 
  187         /*
  188          * Pick an initial maxcmds value which will be used
  189          * to allocate xflist pointer space. It may be changed
  190          * later by the firmware.
  191          */
  192         if (IS_24XX(isp)) {
  193                 isp->isp_maxcmds = 4096;
  194         } else if (IS_2322(isp)) {
  195                 isp->isp_maxcmds = 2048;
  196         } else if (IS_23XX(isp) || IS_2200(isp)) {
  197                 isp->isp_maxcmds = 1024;
  198         } else {
  199                 isp->isp_maxcmds = 512;
  200         }
  201 
  202         /*
  203          * Set up DMA for the request and response queues.
  204          *
  205          * We do this now so we can use the request queue
  206          * for dma to load firmware from.
  207          */
  208         if (ISP_MBOXDMASETUP(isp) != 0) {
  209                 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
  210                 return;
  211         }
  212 
  213         /*
  214          * Set up default request/response queue in-pointer/out-pointer
  215          * register indices.
  216          */
  217         if (IS_24XX(isp)) {
  218                 isp->isp_rqstinrp = BIU2400_REQINP;
  219                 isp->isp_rqstoutrp = BIU2400_REQOUTP;
  220                 isp->isp_respinrp = BIU2400_RSPINP;
  221                 isp->isp_respoutrp = BIU2400_RSPOUTP;
  222         } else if (IS_23XX(isp)) {
  223                 isp->isp_rqstinrp = BIU_REQINP;
  224                 isp->isp_rqstoutrp = BIU_REQOUTP;
  225                 isp->isp_respinrp = BIU_RSPINP;
  226                 isp->isp_respoutrp = BIU_RSPOUTP;
  227         } else {
  228                 isp->isp_rqstinrp = INMAILBOX4;
  229                 isp->isp_rqstoutrp = OUTMAILBOX4;
  230                 isp->isp_respinrp = OUTMAILBOX5;
  231                 isp->isp_respoutrp = INMAILBOX5;
  232         }
  233 
  234         /*
  235          * Put the board into PAUSE mode (so we can read the SXP registers
  236          * or write FPM/FBM registers).
  237          */
  238         if (IS_24XX(isp)) {
  239                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT);
  240                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
  241                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
  242         } else {
  243                 ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
  244         }
  245 
  246         if (IS_FC(isp)) {
  247                 switch (isp->isp_type) {
  248                 case ISP_HA_FC_2100:
  249                         btype = "2100";
  250                         break;
  251                 case ISP_HA_FC_2200:
  252                         btype = "2200";
  253                         break;
  254                 case ISP_HA_FC_2300:
  255                         btype = "2300";
  256                         break;
  257                 case ISP_HA_FC_2312:
  258                         btype = "2312";
  259                         break;
  260                 case ISP_HA_FC_2322:
  261                         btype = "2322";
  262                         break;
  263                 case ISP_HA_FC_2400:
  264                         btype = "2422";
  265                         break;
  266                 case ISP_HA_FC_2500:
  267                         btype = "2532";
  268                         break;
  269                 default:
  270                         break;
  271                 }
  272 
  273                 if (!IS_24XX(isp)) {
  274                         /*
  275                          * While we're paused, reset the FPM module and FBM
  276                          * fifos.
  277                          */
  278                         ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
  279                         ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
  280                         ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
  281                         ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
  282                         ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
  283                 }
  284         } else if (IS_1240(isp)) {
  285                 sdparam *sdp;
  286 
  287                 btype = "1240";
  288                 isp->isp_clock = 60;
  289                 sdp = SDPARAM(isp, 0);
  290                 sdp->isp_ultramode = 1;
  291                 sdp = SDPARAM(isp, 1);
  292                 sdp->isp_ultramode = 1;
  293                 /*
  294                  * XXX: Should probably do some bus sensing.
  295                  */
  296         } else if (IS_ULTRA3(isp)) {
  297                 sdparam *sdp = isp->isp_param;
  298 
  299                 isp->isp_clock = 100;
  300 
  301                 if (IS_10160(isp))
  302                         btype = "10160";
  303                 else if (IS_12160(isp))
  304                         btype = "12160";
  305                 else
  306                         btype = "<UNKLVD>";
  307                 sdp->isp_lvdmode = 1;
  308 
  309                 if (IS_DUALBUS(isp)) {
  310                         sdp++;
  311                         sdp->isp_lvdmode = 1;
  312                 }
  313         } else if (IS_ULTRA2(isp)) {
  314                 static const char m[] = "bus %d is in %s Mode";
  315                 uint16_t l;
  316                 sdparam *sdp = SDPARAM(isp, 0);
  317 
  318                 isp->isp_clock = 100;
  319 
  320                 if (IS_1280(isp))
  321                         btype = "1280";
  322                 else if (IS_1080(isp))
  323                         btype = "1080";
  324                 else
  325                         btype = "<UNKLVD>";
  326 
  327                 l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
  328                 switch (l) {
  329                 case ISP1080_LVD_MODE:
  330                         sdp->isp_lvdmode = 1;
  331                         isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
  332                         break;
  333                 case ISP1080_HVD_MODE:
  334                         sdp->isp_diffmode = 1;
  335                         isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
  336                         break;
  337                 case ISP1080_SE_MODE:
  338                         sdp->isp_ultramode = 1;
  339                         isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
  340                         break;
  341                 default:
  342                         isp_prt(isp, ISP_LOGERR,
  343                             "unknown mode on bus %d (0x%x)", 0, l);
  344                         break;
  345                 }
  346 
  347                 if (IS_DUALBUS(isp)) {
  348                         sdp = SDPARAM(isp, 1);
  349                         l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
  350                         l &= ISP1080_MODE_MASK;
  351                         switch (l) {
  352                         case ISP1080_LVD_MODE:
  353                                 sdp->isp_lvdmode = 1;
  354                                 isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
  355                                 break;
  356                         case ISP1080_HVD_MODE:
  357                                 sdp->isp_diffmode = 1;
  358                                 isp_prt(isp, ISP_LOGCONFIG,
  359                                     m, 1, "Differential");
  360                                 break;
  361                         case ISP1080_SE_MODE:
  362                                 sdp->isp_ultramode = 1;
  363                                 isp_prt(isp, ISP_LOGCONFIG,
  364                                     m, 1, "Single-Ended");
  365                                 break;
  366                         default:
  367                                 isp_prt(isp, ISP_LOGERR,
  368                                     "unknown mode on bus %d (0x%x)", 1, l);
  369                                 break;
  370                         }
  371                 }
  372         } else {
  373                 sdparam *sdp = SDPARAM(isp, 0);
  374                 i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
  375                 switch (i) {
  376                 default:
  377                         isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
  378                         /* FALLTHROUGH */
  379                 case 1:
  380                         btype = "1020";
  381                         isp->isp_type = ISP_HA_SCSI_1020;
  382                         isp->isp_clock = 40;
  383                         break;
  384                 case 2:
  385                         /*
  386                          * Some 1020A chips are Ultra Capable, but don't
  387                          * run the clock rate up for that unless told to
  388                          * do so by the Ultra Capable bits being set.
  389                          */
  390                         btype = "1020A";
  391                         isp->isp_type = ISP_HA_SCSI_1020A;
  392                         isp->isp_clock = 40;
  393                         break;
  394                 case 3:
  395                         btype = "1040";
  396                         isp->isp_type = ISP_HA_SCSI_1040;
  397                         isp->isp_clock = 60;
  398                         break;
  399                 case 4:
  400                         btype = "1040A";
  401                         isp->isp_type = ISP_HA_SCSI_1040A;
  402                         isp->isp_clock = 60;
  403                         break;
  404                 case 5:
  405                         btype = "1040B";
  406                         isp->isp_type = ISP_HA_SCSI_1040B;
  407                         isp->isp_clock = 60;
  408                         break;
  409                 case 6:
  410                         btype = "1040C";
  411                         isp->isp_type = ISP_HA_SCSI_1040C;
  412                         isp->isp_clock = 60;
  413                         break;
  414                 }
  415                 /*
  416                  * Now, while we're at it, gather info about ultra
  417                  * and/or differential mode.
  418                  */
  419                 if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
  420                         isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
  421                         sdp->isp_diffmode = 1;
  422                 } else {
  423                         sdp->isp_diffmode = 0;
  424                 }
  425                 i = ISP_READ(isp, RISC_PSR);
  426                 if (isp->isp_bustype == ISP_BT_SBUS) {
  427                         i &= RISC_PSR_SBUS_ULTRA;
  428                 } else {
  429                         i &= RISC_PSR_PCI_ULTRA;
  430                 }
  431                 if (i != 0) {
  432                         isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
  433                         sdp->isp_ultramode = 1;
  434                         /*
  435                          * If we're in Ultra Mode, we have to be 60MHz clock-
  436                          * even for the SBus version.
  437                          */
  438                         isp->isp_clock = 60;
  439                 } else {
  440                         sdp->isp_ultramode = 0;
  441                         /*
  442                          * Clock is known. Gronk.
  443                          */
  444                 }
  445 
  446                 /*
  447                  * Machine dependent clock (if set) overrides
  448                  * our generic determinations.
  449                  */
  450                 if (isp->isp_mdvec->dv_clock) {
  451                         if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
  452                                 isp->isp_clock = isp->isp_mdvec->dv_clock;
  453                         }
  454                 }
  455 
  456         }
  457 
  458         /*
  459          * Clear instrumentation
  460          */
  461         isp->isp_intcnt = isp->isp_intbogus = 0;
  462 
  463         /*
  464          * Do MD specific pre initialization
  465          */
  466         ISP_RESET0(isp);
  467 
  468         /*
  469          * Hit the chip over the head with hammer,
  470          * and give it a chance to recover.
  471          */
  472 
  473         if (IS_SCSI(isp)) {
  474                 ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
  475                 /*
  476                  * A slight delay...
  477                  */
  478                 ISP_DELAY(100);
  479 
  480                 /*
  481                  * Clear data && control DMA engines.
  482                  */
  483                 ISP_WRITE(isp, CDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
  484                 ISP_WRITE(isp, DDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
  485 
  486 
  487         } else if (IS_24XX(isp)) {
  488                 /*
  489                  * Stop DMA and wait for it to stop.
  490                  */
  491                 ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
  492                 for (val = loops = 0; loops < 30000; loops++) {
  493                         ISP_DELAY(10);
  494                         val = ISP_READ(isp, BIU2400_CSR);
  495                         if ((val & BIU2400_DMA_ACTIVE) == 0) {
  496                                 break;
  497                         }
  498                 }
  499                 if (val & BIU2400_DMA_ACTIVE) {
  500                         ISP_RESET0(isp);
  501                         isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
  502                         return;
  503                 }
  504                 /*
  505                  * Hold it in SOFT_RESET and STOP state for 100us.
  506                  */
  507                 ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
  508                 ISP_DELAY(100);
  509                 for (loops = 0; loops < 10000; loops++) {
  510                         ISP_DELAY(5);
  511                         val = ISP_READ(isp, OUTMAILBOX0);
  512                 }
  513                 for (val = loops = 0; loops < 500000; loops ++) {
  514                         val = ISP_READ(isp, BIU2400_CSR);
  515                         if ((val & BIU2400_SOFT_RESET) == 0) {
  516                                 break;
  517                         }
  518                 }
  519                 if (val & BIU2400_SOFT_RESET) {
  520                         ISP_RESET0(isp);
  521                         isp_prt(isp, ISP_LOGERR, "Failed to come out of reset");
  522                         return;
  523                 }
  524         } else {
  525                 ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
  526                 /*
  527                  * A slight delay...
  528                  */
  529                 ISP_DELAY(100);
  530 
  531                 /*
  532                  * Clear data && control DMA engines.
  533                  */
  534                 ISP_WRITE(isp, CDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
  535                 ISP_WRITE(isp, TDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
  536                 ISP_WRITE(isp, RDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
  537         }
  538 
  539         /*
  540          * Wait for ISP to be ready to go...
  541          */
  542         loops = MBOX_DELAY_COUNT;
  543         for (;;) {
  544                 if (IS_SCSI(isp)) {
  545                         if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET)) {
  546                                 break;
  547                         }
  548                 } else if (IS_24XX(isp)) {
  549                         if (ISP_READ(isp, OUTMAILBOX0) == 0) {
  550                                 break;
  551                         }
  552                 } else {
  553                         if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
  554                                 break;
  555                 }
  556                 ISP_DELAY(100);
  557                 if (--loops < 0) {
  558                         ISP_DUMPREGS(isp, "chip reset timed out");
  559                         ISP_RESET0(isp);
  560                         return;
  561                 }
  562         }
  563 
  564         /*
  565          * After we've fired this chip up, zero out the conf1 register
  566          * for SCSI adapters and other settings for the 2100.
  567          */
  568 
  569         if (IS_SCSI(isp)) {
  570                 ISP_WRITE(isp, BIU_CONF1, 0);
  571         } else if (!IS_24XX(isp)) {
  572                 ISP_WRITE(isp, BIU2100_CSR, 0);
  573         }
  574 
  575         /*
  576          * Reset RISC Processor
  577          */
  578         if (IS_24XX(isp)) {
  579                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
  580                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
  581                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
  582         } else {
  583                 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
  584                 ISP_DELAY(100);
  585                 ISP_WRITE(isp, BIU_SEMA, 0);
  586         }
  587 
  588         /*
  589          * Post-RISC Reset stuff.
  590          */
  591         if (IS_24XX(isp)) {
  592                 for (val = loops = 0; loops < 5000000; loops++) {
  593                         ISP_DELAY(5);
  594                         val = ISP_READ(isp, OUTMAILBOX0);
  595                         if (val == 0) {
  596                                 break;
  597                         }
  598                 }
  599                 if (val != 0) {
  600                         ISP_RESET0(isp);
  601                         isp_prt(isp, ISP_LOGERR, "reset didn't clear");
  602                         return;
  603                 }
  604         } else if (IS_SCSI(isp)) {
  605                 uint16_t tmp = isp->isp_mdvec->dv_conf1;
  606                 /*
  607                  * Busted FIFO. Turn off all but burst enables.
  608                  */
  609                 if (isp->isp_type == ISP_HA_SCSI_1040A) {
  610                         tmp &= BIU_BURST_ENABLE;
  611                 }
  612                 ISP_SETBITS(isp, BIU_CONF1, tmp);
  613                 if (tmp & BIU_BURST_ENABLE) {
  614                         ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
  615                         ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
  616                 }
  617                 if (SDPARAM(isp, 0)->isp_ptisp) {
  618                         if (SDPARAM(isp, 0)->isp_ultramode) {
  619                                 while (ISP_READ(isp, RISC_MTR) != 0x1313) {
  620                                         ISP_WRITE(isp, RISC_MTR, 0x1313);
  621                                         ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
  622                                 }
  623                         } else {
  624                                 ISP_WRITE(isp, RISC_MTR, 0x1212);
  625                         }
  626                         /*
  627                          * PTI specific register
  628                          */
  629                         ISP_WRITE(isp, RISC_EMB, DUAL_BANK);
  630                 } else {
  631                         ISP_WRITE(isp, RISC_MTR, 0x1212);
  632                 }
  633                 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
  634         } else {
  635                 ISP_WRITE(isp, RISC_MTR2100, 0x1212);
  636                 if (IS_2200(isp) || IS_23XX(isp)) {
  637                         ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
  638                 }
  639                 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
  640         }
  641 
  642         ISP_WRITE(isp, isp->isp_rqstinrp, 0);
  643         ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
  644         ISP_WRITE(isp, isp->isp_respinrp, 0);
  645         ISP_WRITE(isp, isp->isp_respoutrp, 0);
  646         if (IS_24XX(isp)) {
  647                 ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
  648                 ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
  649                 ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
  650                 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
  651         }
  652 
  653         /*
  654          * Do MD specific post initialization
  655          */
  656         ISP_RESET1(isp);
  657 
  658         /*
  659          * Wait for everything to finish firing up.
  660          *
  661          * Avoid doing this on early 2312s because you can generate a PCI
  662          * parity error (chip breakage).
  663          */
  664         if (IS_2312(isp) && isp->isp_revision < 2) {
  665                 ISP_DELAY(100);
  666         } else {
  667                 loops = MBOX_DELAY_COUNT;
  668                 while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
  669                         ISP_DELAY(100);
  670                         if (--loops < 0) {
  671                                 ISP_RESET0(isp);
  672                                 isp_prt(isp, ISP_LOGERR,
  673                                     "MBOX_BUSY never cleared on reset");
  674                                 return;
  675                         }
  676                 }
  677         }
  678 
  679         /*
  680          * Up until this point we've done everything by just reading or
  681          * setting registers. From this point on we rely on at least *some*
  682          * kind of firmware running in the card.
  683          */
  684 
  685         /*
  686          * Do some sanity checking by running a NOP command.
  687          * If it succeeds, the ROM firmware is now running.
  688          */
  689         ISP_MEMZERO(&mbs, sizeof (mbs));
  690         mbs.param[0] = MBOX_NO_OP;
  691         mbs.logval = MBLOGALL;
  692         isp_mboxcmd(isp, &mbs);
  693         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  694                 isp_prt(isp, ISP_LOGERR, "NOP command failed (%x)", mbs.param[0]);
  695                 ISP_RESET0(isp);
  696                 return;
  697         }
  698 
  699         /*
  700          * Do some operational tests
  701          */
  702 
  703         if (IS_SCSI(isp) || IS_24XX(isp)) {
  704                 ISP_MEMZERO(&mbs, sizeof (mbs));
  705                 mbs.param[0] = MBOX_MAILBOX_REG_TEST;
  706                 mbs.param[1] = 0xdead;
  707                 mbs.param[2] = 0xbeef;
  708                 mbs.param[3] = 0xffff;
  709                 mbs.param[4] = 0x1111;
  710                 mbs.param[5] = 0xa5a5;
  711                 mbs.param[6] = 0x0000;
  712                 mbs.param[7] = 0x0000;
  713                 mbs.logval = MBLOGALL;
  714                 isp_mboxcmd(isp, &mbs);
  715                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  716                         ISP_RESET0(isp);
  717                         return;
  718                 }
  719                 if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
  720                     mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
  721                     mbs.param[5] != 0xa5a5) {
  722                         ISP_RESET0(isp);
  723                         isp_prt(isp, ISP_LOGERR, "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)", mbs.param[1], mbs.param[2], mbs.param[3], mbs.param[4], mbs.param[5]);
  724                         return;
  725                 }
  726 
  727         }
  728 
  729         /*
  730          * Download new Firmware, unless requested not to do so.
  731          * This is made slightly trickier in some cases where the
  732          * firmware of the ROM revision is newer than the revision
  733          * compiled into the driver. So, where we used to compare
  734          * versions of our f/w and the ROM f/w, now we just see
  735          * whether we have f/w at all and whether a config flag
  736          * has disabled our download.
  737          */
  738         if ((isp->isp_mdvec->dv_ispfw == NULL) || (isp->isp_confopts & ISP_CFG_NORELOAD)) {
  739                 dodnld = 0;
  740         }
  741 
  742         if (IS_24XX(isp)) {
  743                 code_org = ISP_CODE_ORG_2400;
  744         } else if (IS_23XX(isp)) {
  745                 code_org = ISP_CODE_ORG_2300;
  746         } else {
  747                 code_org = ISP_CODE_ORG;
  748         }
  749 
  750         if (dodnld && IS_24XX(isp)) {
  751                 const uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
  752 
  753                 /*
  754                  * Keep loading until we run out of f/w.
  755                  */
  756                 code_org = ptr[2];      /* 1st load address is our start addr */
  757 
  758                 for (;;) {
  759                         uint32_t la, wi, wl;
  760 
  761                         isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], ptr[2]);
  762 
  763                         wi = 0;
  764                         la = ptr[2];
  765                         wl = ptr[3];
  766 
  767                         while (wi < ptr[3]) {
  768                                 uint32_t *cp;
  769                                 uint32_t nw;
  770 
  771                                 nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 2;
  772                                 if (nw > wl) {
  773                                         nw = wl;
  774                                 }
  775                                 cp = isp->isp_rquest;
  776                                 for (i = 0; i < nw; i++) {
  777                                         ISP_IOXPUT_32(isp,  ptr[wi++], &cp[i]);
  778                                         wl--;
  779                                 }
  780                                 MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1);
  781                                 ISP_MEMZERO(&mbs, sizeof (mbs));
  782                                 if (la < 0x10000 && nw < 0x10000) {
  783                                         mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
  784                                         mbs.param[1] = la;
  785                                         mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
  786                                         mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
  787                                         mbs.param[4] = nw;
  788                                         mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
  789                                         mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
  790                                 } else {
  791                                         mbs.param[0] = MBOX_LOAD_RISC_RAM;
  792                                         mbs.param[1] = la;
  793                                         mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
  794                                         mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
  795                                         mbs.param[4] = nw >> 16;
  796                                         mbs.param[5] = nw;
  797                                         mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
  798                                         mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
  799                                         mbs.param[8] = la >> 16;
  800                                 }
  801                                 mbs.logval = MBLOGALL;
  802                                 isp_mboxcmd(isp, &mbs);
  803                                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  804                                         isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
  805                                         ISP_RESET0(isp);
  806                                         return;
  807                                 }
  808                                 la += nw;
  809                         }
  810 
  811                         if (ptr[1] == 0) {
  812                                 break;
  813                         }
  814                         ptr += ptr[3];
  815                 }
  816                 isp->isp_loaded_fw = 1;
  817         } else if (dodnld && IS_23XX(isp)) {
  818                 const uint16_t *ptr = isp->isp_mdvec->dv_ispfw;
  819                 uint16_t wi, wl, segno;
  820                 uint32_t la;
  821 
  822                 la = code_org;
  823                 segno = 0;
  824 
  825                 for (;;) {
  826                         uint32_t nxtaddr;
  827 
  828                         isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], la);
  829 
  830                         wi = 0;
  831                         wl = ptr[3];
  832 
  833                         while (wi < ptr[3]) {
  834                                 uint16_t *cp;
  835                                 uint16_t nw;
  836 
  837                                 nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 1;
  838                                 if (nw > wl) {
  839                                         nw = wl;
  840                                 }
  841                                 if (nw > (1 << 15)) {
  842                                         nw = 1 << 15;
  843                                 }
  844                                 cp = isp->isp_rquest;
  845                                 for (i = 0; i < nw; i++) {
  846                                         ISP_IOXPUT_16(isp,  ptr[wi++], &cp[i]);
  847                                         wl--;
  848                                 }
  849                                 MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1);
  850                                 ISP_MEMZERO(&mbs, sizeof (mbs));
  851                                 if (la < 0x10000) {
  852                                         mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
  853                                         mbs.param[1] = la;
  854                                         mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
  855                                         mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
  856                                         mbs.param[4] = nw;
  857                                         mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
  858                                         mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
  859                                 } else {
  860                                         mbs.param[0] = MBOX_LOAD_RISC_RAM;
  861                                         mbs.param[1] = la;
  862                                         mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
  863                                         mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
  864                                         mbs.param[4] = nw;
  865                                         mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
  866                                         mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
  867                                         mbs.param[8] = la >> 16;
  868                                 }
  869                                 mbs.logval = MBLOGALL;
  870                                 isp_mboxcmd(isp, &mbs);
  871                                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  872                                         isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
  873                                         ISP_RESET0(isp);
  874                                         return;
  875                                 }
  876                                 la += nw;
  877                         }
  878 
  879                         if (!IS_2322(isp)) {
  880                                 break;
  881                         }
  882 
  883                         if (++segno == 3) {
  884                                 break;
  885                         }
  886 
  887                         /*
  888                          * If we're a 2322, the firmware actually comes in
  889                          * three chunks. We loaded the first at the code_org
  890                          * address. The other two chunks, which follow right
  891                          * after each other in memory here, get loaded at
  892                          * addresses specified at offset 0x9..0xB.
  893                          */
  894 
  895                         nxtaddr = ptr[3];
  896                         ptr = &ptr[nxtaddr];
  897                         la = ptr[5] | ((ptr[4] & 0x3f) << 16);
  898                 }
  899                 isp->isp_loaded_fw = 1;
  900         } else if (dodnld) {
  901                 union {
  902                         const uint16_t *cp;
  903                         uint16_t *np;
  904                 } ucd;
  905                 ucd.cp = isp->isp_mdvec->dv_ispfw;
  906                 isp->isp_mbxworkp = &ucd.np[1];
  907                 isp->isp_mbxwrk0 = ucd.np[3] - 1;
  908                 isp->isp_mbxwrk1 = code_org + 1;
  909                 ISP_MEMZERO(&mbs, sizeof (mbs));
  910                 mbs.param[0] = MBOX_WRITE_RAM_WORD;
  911                 mbs.param[1] = code_org;
  912                 mbs.param[2] = ucd.np[0];
  913                 mbs.logval = MBLOGNONE;
  914                 isp_mboxcmd(isp, &mbs);
  915                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  916                         isp_prt(isp, ISP_LOGERR, "F/W download failed at word %d", isp->isp_mbxwrk1 - code_org);
  917                         ISP_RESET0(isp);
  918                         return;
  919                 }
  920         } else {
  921                 isp->isp_loaded_fw = 0;
  922                 isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
  923         }
  924 
  925         /*
  926          * If we loaded firmware, verify its checksum
  927          */
  928         if (isp->isp_loaded_fw) {
  929                 ISP_MEMZERO(&mbs, sizeof (mbs));
  930                 mbs.param[0] = MBOX_VERIFY_CHECKSUM;
  931                 if (IS_24XX(isp)) {
  932                         mbs.param[1] = code_org >> 16;
  933                         mbs.param[2] = code_org;
  934                 } else {
  935                         mbs.param[1] = code_org;
  936                 }
  937                 isp_mboxcmd(isp, &mbs);
  938                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  939                         isp_prt(isp, ISP_LOGERR, dcrc);
  940                         ISP_RESET0(isp);
  941                         return;
  942                 }
  943         }
  944 
  945         /*
  946          * Now start it rolling.
  947          *
  948          * If we didn't actually download f/w,
  949          * we still need to (re)start it.
  950          */
  951 
  952 
  953         MBSINIT(&mbs, MBOX_EXEC_FIRMWARE, MBLOGALL, 1000000);
  954         if (IS_24XX(isp)) {
  955                 mbs.param[1] = code_org >> 16;
  956                 mbs.param[2] = code_org;
  957                 if (isp->isp_loaded_fw) {
  958                         mbs.param[3] = 0;
  959                 } else {
  960                         mbs.param[3] = 1;
  961                 }
  962                 if (IS_25XX(isp)) {
  963                         mbs.ibits |= 0x10;
  964                 }
  965         } else if (IS_2322(isp)) {
  966                 mbs.param[1] = code_org;
  967                 if (isp->isp_loaded_fw) {
  968                         mbs.param[2] = 0;
  969                 } else {
  970                         mbs.param[2] = 1;
  971                 }
  972         } else {
  973                 mbs.param[1] = code_org;
  974         }
  975         isp_mboxcmd(isp, &mbs);
  976         if (IS_2322(isp) || IS_24XX(isp)) {
  977                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  978                         ISP_RESET0(isp);
  979                         return;
  980                 }
  981         }
  982 
  983         /*
  984          * Give it a chance to finish starting up.
  985          * Give the 24XX more time.
  986          */
  987         if (IS_24XX(isp)) {
  988                 ISP_DELAY(500000);
  989                 /*
  990                  * Check to see if the 24XX firmware really started.
  991                  */
  992                 if (mbs.param[1] == 0xdead) {
  993                         isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start");
  994                         ISP_RESET0(isp);
  995                         return;
  996                 }
  997         } else {
  998                 ISP_DELAY(250000);
  999                 if (IS_SCSI(isp)) {
 1000                         /*
 1001                          * Set CLOCK RATE, but only if asked to.
 1002                          */
 1003                         if (isp->isp_clock) {
 1004                                 mbs.param[0] = MBOX_SET_CLOCK_RATE;
 1005                                 mbs.param[1] = isp->isp_clock;
 1006                                 mbs.logval = MBLOGNONE;
 1007                                 isp_mboxcmd(isp, &mbs);
 1008                                 /* we will try not to care if this fails */
 1009                         }
 1010                 }
 1011         }
 1012 
 1013         /*
 1014          * Ask the chip for the current firmware version.
 1015          * This should prove that the new firmware is working.
 1016          */
 1017         MBSINIT(&mbs, MBOX_ABOUT_FIRMWARE, MBLOGALL, 0);
 1018         isp_mboxcmd(isp, &mbs);
 1019         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1020                 ISP_RESET0(isp);
 1021                 return;
 1022         }
 1023 
 1024         /*
 1025          * The SBus firmware that we are using apparently does not return
 1026          * major, minor, micro revisions in the mailbox registers, which
 1027          * is really, really, annoying.
 1028          */
 1029         if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
 1030                 if (dodnld) {
 1031 #ifdef  ISP_TARGET_MODE
 1032                         isp->isp_fwrev[0] = 7;
 1033                         isp->isp_fwrev[1] = 55;
 1034 #else
 1035                         isp->isp_fwrev[0] = 1;
 1036                         isp->isp_fwrev[1] = 37;
 1037 #endif
 1038                         isp->isp_fwrev[2] = 0;
 1039                 }
 1040         } else {
 1041                 isp->isp_fwrev[0] = mbs.param[1];
 1042                 isp->isp_fwrev[1] = mbs.param[2];
 1043                 isp->isp_fwrev[2] = mbs.param[3];
 1044         }
 1045 
 1046         isp_prt(isp, ISP_LOGCONFIG, "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
 1047             btype, isp->isp_revision, dodnld? "loaded" : "resident", isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
 1048 
 1049         if (IS_FC(isp)) {
 1050                 /*
 1051                  * We do not believe firmware attributes for 2100 code less
 1052                  * than 1.17.0, unless it's the firmware we specifically
 1053                  * are loading.
 1054                  *
 1055                  * Note that all 22XX and later f/w is greater than 1.X.0.
 1056                  */
 1057                 if ((ISP_FW_OLDER_THAN(isp, 1, 17, 1))) {
 1058 #ifdef  USE_SMALLER_2100_FIRMWARE
 1059                         isp->isp_fwattr = ISP_FW_ATTR_SCCLUN;
 1060 #else
 1061                         isp->isp_fwattr = 0;
 1062 #endif
 1063                 } else {
 1064                         isp->isp_fwattr = mbs.param[6];
 1065                         isp_prt(isp, ISP_LOGDEBUG0, "Firmware Attributes = 0x%x", mbs.param[6]);
 1066                 }
 1067         } else {
 1068 #ifndef ISP_TARGET_MODE
 1069                 isp->isp_fwattr = ISP_FW_ATTR_TMODE;
 1070 #else
 1071                 isp->isp_fwattr = 0;
 1072 #endif
 1073         }
 1074 
 1075         if (!IS_24XX(isp)) {
 1076                 MBSINIT(&mbs, MBOX_GET_FIRMWARE_STATUS, MBLOGALL, 0);
 1077                 isp_mboxcmd(isp, &mbs);
 1078                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1079                         ISP_RESET0(isp);
 1080                         return;
 1081                 }
 1082                 if (isp->isp_maxcmds >= mbs.param[2]) {
 1083                         isp->isp_maxcmds = mbs.param[2];
 1084                 }
 1085         }
 1086         isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", isp->isp_maxcmds);
 1087 
 1088         /*
 1089          * If we don't have Multi-ID f/w loaded, we need to restrict channels to one.
 1090          * Only make this check for non-SCSI cards (I'm not sure firmware attributes
 1091          * work for them).
 1092          */
 1093         if (IS_FC(isp) && ISP_CAP_MULTI_ID(isp) == 0 && isp->isp_nchan > 1) {
 1094                 isp_prt(isp, ISP_LOGWARN, "non-MULTIID f/w loaded, only can enable 1 of %d channels", isp->isp_nchan);
 1095                 isp->isp_nchan = 1;
 1096         }
 1097 
 1098         for (i = 0; i < isp->isp_nchan; i++) {
 1099                 isp_fw_state(isp, i);
 1100         }
 1101         if (isp->isp_dead) {
 1102                 isp_shutdown(isp);
 1103                 ISP_DISABLE_INTS(isp);
 1104                 return;
 1105         }
 1106 
 1107         isp->isp_state = ISP_RESETSTATE;
 1108 
 1109         /*
 1110          * Okay- now that we have new firmware running, we now (re)set our
 1111          * notion of how many luns we support. This is somewhat tricky because
 1112          * if we haven't loaded firmware, we sometimes do not have an easy way
 1113          * of knowing how many luns we support.
 1114          *
 1115          * Expanded lun firmware gives you 32 luns for SCSI cards and
 1116          * 16384 luns for Fibre Channel cards.
 1117          *
 1118          * It turns out that even for QLogic 2100s with ROM 1.10 and above
 1119          * we do get a firmware attributes word returned in mailbox register 6.
 1120          *
 1121          * Because the lun is in a different position in the Request Queue
 1122          * Entry structure for Fibre Channel with expanded lun firmware, we
 1123          * can only support one lun (lun zero) when we don't know what kind
 1124          * of firmware we're running.
 1125          */
 1126         if (IS_SCSI(isp)) {
 1127                 if (dodnld) {
 1128                         if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
 1129                                 isp->isp_maxluns = 32;
 1130                         } else {
 1131                                 isp->isp_maxluns = 8;
 1132                         }
 1133                 } else {
 1134                         isp->isp_maxluns = 8;
 1135                 }
 1136         } else {
 1137                 if (ISP_CAP_SCCFW(isp)) {
 1138                         isp->isp_maxluns = 16384;
 1139                 } else {
 1140                         isp->isp_maxluns = 16;
 1141                 }
 1142         }
 1143 
 1144         /*
 1145          * We get some default values established. As a side
 1146          * effect, NVRAM is read here (unless overridden by
 1147          * a configuration flag).
 1148          */
 1149         if (do_load_defaults) {
 1150                 if (IS_SCSI(isp)) {
 1151                         isp_setdfltsdparm(isp);
 1152                 } else {
 1153                         for (i = 0; i < isp->isp_nchan; i++) {
 1154                                 isp_setdfltfcparm(isp, i);
 1155                         }
 1156                 }
 1157         }
 1158 }
 1159 
 1160 /*
 1161  * Initialize Parameters of Hardware to a known state.
 1162  *
 1163  * Locks are held before coming here.
 1164  */
 1165 
 1166 void
 1167 isp_init(ispsoftc_t *isp)
 1168 {
 1169         if (IS_FC(isp)) {
 1170                 if (IS_24XX(isp)) {
 1171                         isp_fibre_init_2400(isp);
 1172                 } else {
 1173                         isp_fibre_init(isp);
 1174                 }
 1175         } else {
 1176                 isp_scsi_init(isp);
 1177         }
 1178         GET_NANOTIME(&isp->isp_init_time);
 1179 }
 1180 
 1181 static void
 1182 isp_scsi_init(ispsoftc_t *isp)
 1183 {
 1184         sdparam *sdp_chan0, *sdp_chan1;
 1185         mbreg_t mbs;
 1186 
 1187         sdp_chan0 = SDPARAM(isp, 0);
 1188         sdp_chan1 = sdp_chan0;
 1189         if (IS_DUALBUS(isp)) {
 1190                 sdp_chan1 = SDPARAM(isp, 1);
 1191         }
 1192 
 1193         /* First do overall per-card settings. */
 1194 
 1195         /*
 1196          * If we have fast memory timing enabled, turn it on.
 1197          */
 1198         if (sdp_chan0->isp_fast_mttr) {
 1199                 ISP_WRITE(isp, RISC_MTR, 0x1313);
 1200         }
 1201 
 1202         /*
 1203          * Set Retry Delay and Count.
 1204          * You set both channels at the same time.
 1205          */
 1206         MBSINIT(&mbs, MBOX_SET_RETRY_COUNT, MBLOGALL, 0);
 1207         mbs.param[1] = sdp_chan0->isp_retry_count;
 1208         mbs.param[2] = sdp_chan0->isp_retry_delay;
 1209         mbs.param[6] = sdp_chan1->isp_retry_count;
 1210         mbs.param[7] = sdp_chan1->isp_retry_delay;
 1211         isp_mboxcmd(isp, &mbs);
 1212         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1213                 return;
 1214         }
 1215 
 1216         /*
 1217          * Set ASYNC DATA SETUP time. This is very important.
 1218          */
 1219         MBSINIT(&mbs, MBOX_SET_ASYNC_DATA_SETUP_TIME, MBLOGALL, 0);
 1220         mbs.param[1] = sdp_chan0->isp_async_data_setup;
 1221         mbs.param[2] = sdp_chan1->isp_async_data_setup;
 1222         isp_mboxcmd(isp, &mbs);
 1223         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1224                 return;
 1225         }
 1226 
 1227         /*
 1228          * Set ACTIVE Negation State.
 1229          */
 1230         MBSINIT(&mbs, MBOX_SET_ACT_NEG_STATE, MBLOGNONE, 0);
 1231         mbs.param[1] =
 1232             (sdp_chan0->isp_req_ack_active_neg << 4) |
 1233             (sdp_chan0->isp_data_line_active_neg << 5);
 1234         mbs.param[2] =
 1235             (sdp_chan1->isp_req_ack_active_neg << 4) |
 1236             (sdp_chan1->isp_data_line_active_neg << 5);
 1237         isp_mboxcmd(isp, &mbs);
 1238         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1239                 isp_prt(isp, ISP_LOGERR,
 1240                     "failed to set active negation state (%d,%d), (%d,%d)",
 1241                     sdp_chan0->isp_req_ack_active_neg,
 1242                     sdp_chan0->isp_data_line_active_neg,
 1243                     sdp_chan1->isp_req_ack_active_neg,
 1244                     sdp_chan1->isp_data_line_active_neg);
 1245                 /*
 1246                  * But don't return.
 1247                  */
 1248         }
 1249 
 1250         /*
 1251          * Set the Tag Aging limit
 1252          */
 1253         MBSINIT(&mbs, MBOX_SET_TAG_AGE_LIMIT, MBLOGALL, 0);
 1254         mbs.param[1] = sdp_chan0->isp_tag_aging;
 1255         mbs.param[2] = sdp_chan1->isp_tag_aging;
 1256         isp_mboxcmd(isp, &mbs);
 1257         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1258                 isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
 1259                     sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
 1260                 return;
 1261         }
 1262 
 1263         /*
 1264          * Set selection timeout.
 1265          */
 1266         MBSINIT(&mbs, MBOX_SET_SELECT_TIMEOUT, MBLOGALL, 0);
 1267         mbs.param[1] = sdp_chan0->isp_selection_timeout;
 1268         mbs.param[2] = sdp_chan1->isp_selection_timeout;
 1269         isp_mboxcmd(isp, &mbs);
 1270         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1271                 return;
 1272         }
 1273 
 1274         /* now do per-channel settings */
 1275         isp_scsi_channel_init(isp, 0);
 1276         if (IS_DUALBUS(isp))
 1277                 isp_scsi_channel_init(isp, 1);
 1278 
 1279         /*
 1280          * Now enable request/response queues
 1281          */
 1282 
 1283         if (IS_ULTRA2(isp) || IS_1240(isp)) {
 1284                 MBSINIT(&mbs, MBOX_INIT_RES_QUEUE_A64, MBLOGALL, 0);
 1285                 mbs.param[1] = RESULT_QUEUE_LEN(isp);
 1286                 mbs.param[2] = DMA_WD1(isp->isp_result_dma);
 1287                 mbs.param[3] = DMA_WD0(isp->isp_result_dma);
 1288                 mbs.param[4] = 0;
 1289                 mbs.param[6] = DMA_WD3(isp->isp_result_dma);
 1290                 mbs.param[7] = DMA_WD2(isp->isp_result_dma);
 1291                 isp_mboxcmd(isp, &mbs);
 1292                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1293                         return;
 1294                 }
 1295                 isp->isp_residx = mbs.param[5];
 1296 
 1297                 MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE_A64, MBLOGALL, 0);
 1298                 mbs.param[1] = RQUEST_QUEUE_LEN(isp);
 1299                 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
 1300                 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
 1301                 mbs.param[5] = 0;
 1302                 mbs.param[6] = DMA_WD3(isp->isp_result_dma);
 1303                 mbs.param[7] = DMA_WD2(isp->isp_result_dma);
 1304                 isp_mboxcmd(isp, &mbs);
 1305                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1306                         return;
 1307                 }
 1308                 isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
 1309         } else {
 1310                 MBSINIT(&mbs, MBOX_INIT_RES_QUEUE, MBLOGALL, 0);
 1311                 mbs.param[1] = RESULT_QUEUE_LEN(isp);
 1312                 mbs.param[2] = DMA_WD1(isp->isp_result_dma);
 1313                 mbs.param[3] = DMA_WD0(isp->isp_result_dma);
 1314                 mbs.param[4] = 0;
 1315                 isp_mboxcmd(isp, &mbs);
 1316                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1317                         return;
 1318                 }
 1319                 isp->isp_residx = mbs.param[5];
 1320 
 1321                 MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE, MBLOGALL, 0);
 1322                 mbs.param[1] = RQUEST_QUEUE_LEN(isp);
 1323                 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
 1324                 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
 1325                 mbs.param[5] = 0;
 1326                 isp_mboxcmd(isp, &mbs);
 1327                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1328                         return;
 1329                 }
 1330                 isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
 1331         }
 1332 
 1333         /*
 1334          * Turn on LVD transitions for ULTRA2 or better and other features
 1335          *
 1336          * Now that we have 32 bit handles, don't do any fast posting
 1337          * any more. For Ultra2/Ultra3 cards, we can turn on 32 bit RIO
 1338          * operation or use fast posting. To be conservative, we'll only
 1339          * do this for Ultra3 cards now because the other cards are so
 1340          * rare for this author to find and test with.
 1341          */
 1342 
 1343         MBSINIT(&mbs, MBOX_SET_FW_FEATURES, MBLOGALL, 0);
 1344         if (IS_ULTRA2(isp))
 1345                 mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
 1346 #ifdef  ISP_NO_RIO
 1347         if (IS_ULTRA3(isp))
 1348                 mbs.param[1] |= FW_FEATURE_FAST_POST;
 1349 #else
 1350         if (IS_ULTRA3(isp))
 1351                 mbs.param[1] |= FW_FEATURE_RIO_32BIT;
 1352 #endif
 1353         if (mbs.param[1] != 0) {
 1354                 uint16_t sfeat = mbs.param[1];
 1355                 isp_mboxcmd(isp, &mbs);
 1356                 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 1357                         isp_prt(isp, ISP_LOGINFO,
 1358                             "Enabled FW features (0x%x)", sfeat);
 1359                 }
 1360         }
 1361 
 1362         isp->isp_state = ISP_INITSTATE;
 1363 }
 1364 
 1365 static void
 1366 isp_scsi_channel_init(ispsoftc_t *isp, int chan)
 1367 {
 1368         sdparam *sdp;
 1369         mbreg_t mbs;
 1370         int tgt;
 1371 
 1372         sdp = SDPARAM(isp, chan);
 1373 
 1374         /*
 1375          * Set (possibly new) Initiator ID.
 1376          */
 1377         MBSINIT(&mbs, MBOX_SET_INIT_SCSI_ID, MBLOGALL, 0);
 1378         mbs.param[1] = (chan << 7) | sdp->isp_initiator_id;
 1379         isp_mboxcmd(isp, &mbs);
 1380         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1381                 return;
 1382         }
 1383         isp_prt(isp, ISP_LOGINFO, "Chan %d Initiator ID is %d",
 1384             chan, sdp->isp_initiator_id);
 1385 
 1386 
 1387         /*
 1388          * Set current per-target parameters to an initial safe minimum.
 1389          */
 1390         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 1391                 int lun;
 1392                 uint16_t sdf;
 1393 
 1394                 if (sdp->isp_devparam[tgt].dev_enable == 0) {
 1395                         continue;
 1396                 }
 1397 #ifndef ISP_TARGET_MODE
 1398                 sdf = sdp->isp_devparam[tgt].goal_flags;
 1399                 sdf &= DPARM_SAFE_DFLT;
 1400                 /*
 1401                  * It is not quite clear when this changed over so that
 1402                  * we could force narrow and async for 1000/1020 cards,
 1403                  * but assume that this is only the case for loaded
 1404                  * firmware.
 1405                  */
 1406                 if (isp->isp_loaded_fw) {
 1407                         sdf |= DPARM_NARROW | DPARM_ASYNC;
 1408                 }
 1409 #else
 1410                 /*
 1411                  * The !$*!)$!$)* f/w uses the same index into some
 1412                  * internal table to decide how to respond to negotiations,
 1413                  * so if we've said "let's be safe" for ID X, and ID X
 1414                  * selects *us*, the negotiations will back to 'safe'
 1415                  * (as in narrow/async). What the f/w *should* do is
 1416                  * use the initiator id settings to decide how to respond.
 1417                  */
 1418                 sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
 1419 #endif
 1420                 MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGNONE, 0);
 1421                 mbs.param[1] = (chan << 15) | (tgt << 8);
 1422                 mbs.param[2] = sdf;
 1423                 if ((sdf & DPARM_SYNC) == 0) {
 1424                         mbs.param[3] = 0;
 1425                 } else {
 1426                         mbs.param[3] =
 1427                             (sdp->isp_devparam[tgt].goal_offset << 8) |
 1428                             (sdp->isp_devparam[tgt].goal_period);
 1429                 }
 1430                 isp_prt(isp, ISP_LOGDEBUG0, "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
 1431                     chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff);
 1432                 isp_mboxcmd(isp, &mbs);
 1433                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1434                         sdf = DPARM_SAFE_DFLT;
 1435                         MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGALL, 0);
 1436                         mbs.param[1] = (tgt << 8) | (chan << 15);
 1437                         mbs.param[2] = sdf;
 1438                         mbs.param[3] = 0;
 1439                         isp_mboxcmd(isp, &mbs);
 1440                         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1441                                 continue;
 1442                         }
 1443                 }
 1444 
 1445                 /*
 1446                  * We don't update any information directly from the f/w
 1447                  * because we need to run at least one command to cause a
 1448                  * new state to be latched up. So, we just assume that we
 1449                  * converge to the values we just had set.
 1450                  *
 1451                  * Ensure that we don't believe tagged queuing is enabled yet.
 1452                  * It turns out that sometimes the ISP just ignores our
 1453                  * attempts to set parameters for devices that it hasn't
 1454                  * seen yet.
 1455                  */
 1456                 sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
 1457                 for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
 1458                         MBSINIT(&mbs, MBOX_SET_DEV_QUEUE_PARAMS, MBLOGALL, 0);
 1459                         mbs.param[1] = (chan << 15) | (tgt << 8) | lun;
 1460                         mbs.param[2] = sdp->isp_max_queue_depth;
 1461                         mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
 1462                         isp_mboxcmd(isp, &mbs);
 1463                         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1464                                 break;
 1465                         }
 1466                 }
 1467         }
 1468         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 1469                 if (sdp->isp_devparam[tgt].dev_refresh) {
 1470                         sdp->sendmarker = 1;
 1471                         sdp->update = 1;
 1472                         break;
 1473                 }
 1474         }
 1475 }
 1476 
 1477 /*
 1478  * Fibre Channel specific initialization.
 1479  */
 1480 static void
 1481 isp_fibre_init(ispsoftc_t *isp)
 1482 {
 1483         fcparam *fcp;
 1484         isp_icb_t local, *icbp = &local;
 1485         mbreg_t mbs;
 1486         int ownloopid;
 1487 
 1488         /*
 1489          * We only support one channel on non-24XX cards
 1490          */
 1491         fcp = FCPARAM(isp, 0);
 1492         if (fcp->role == ISP_ROLE_NONE) {
 1493                 isp->isp_state = ISP_INITSTATE;
 1494                 return;
 1495         }
 1496 
 1497         ISP_MEMZERO(icbp, sizeof (*icbp));
 1498         icbp->icb_version = ICB_VERSION1;
 1499         icbp->icb_fwoptions = fcp->isp_fwoptions;
 1500 
 1501         /*
 1502          * Firmware Options are either retrieved from NVRAM or
 1503          * are patched elsewhere. We check them for sanity here
 1504          * and make changes based on board revision, but otherwise
 1505          * let others decide policy.
 1506          */
 1507 
 1508         /*
 1509          * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
 1510          */
 1511         if (IS_2100(isp) && isp->isp_revision < 5) {
 1512                 icbp->icb_fwoptions &= ~ICBOPT_FAIRNESS;
 1513         }
 1514 
 1515         /*
 1516          * We have to use FULL LOGIN even though it resets the loop too much
 1517          * because otherwise port database entries don't get updated after
 1518          * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
 1519          */
 1520         if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
 1521                 icbp->icb_fwoptions |= ICBOPT_FULL_LOGIN;
 1522         }
 1523 
 1524         /*
 1525          * Insist on Port Database Update Async notifications
 1526          */
 1527         icbp->icb_fwoptions |= ICBOPT_PDBCHANGE_AE;
 1528 
 1529         /*
 1530          * Make sure that target role reflects into fwoptions.
 1531          */
 1532         if (fcp->role & ISP_ROLE_TARGET) {
 1533                 icbp->icb_fwoptions |= ICBOPT_TGT_ENABLE;
 1534         } else {
 1535                 icbp->icb_fwoptions &= ~ICBOPT_TGT_ENABLE;
 1536         }
 1537 
 1538         if (fcp->role & ISP_ROLE_INITIATOR) {
 1539                 icbp->icb_fwoptions &= ~ICBOPT_INI_DISABLE;
 1540         } else {
 1541                 icbp->icb_fwoptions |= ICBOPT_INI_DISABLE;
 1542         }
 1543 
 1544         icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
 1545         if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
 1546                 isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
 1547                 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
 1548         }
 1549         icbp->icb_maxalloc = fcp->isp_maxalloc;
 1550         if (icbp->icb_maxalloc < 1) {
 1551                 isp_prt(isp, ISP_LOGERR, "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
 1552                 icbp->icb_maxalloc = 16;
 1553         }
 1554         icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
 1555         if (icbp->icb_execthrottle < 1) {
 1556                 isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
 1557                 icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
 1558         }
 1559         icbp->icb_retry_delay = fcp->isp_retry_delay;
 1560         icbp->icb_retry_count = fcp->isp_retry_count;
 1561         icbp->icb_hardaddr = fcp->isp_loopid;
 1562         ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
 1563         if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
 1564                 icbp->icb_hardaddr = 0;
 1565                 ownloopid = 0;
 1566         }
 1567 
 1568         /*
 1569          * Our life seems so much better with 2200s and later with
 1570          * the latest f/w if we set Hard Address.
 1571          */
 1572         if (ownloopid || ISP_FW_NEWER_THAN(isp, 2, 2, 5)) {
 1573                 icbp->icb_fwoptions |= ICBOPT_HARD_ADDRESS;
 1574         }
 1575 
 1576         /*
 1577          * Right now we just set extended options to prefer point-to-point
 1578          * over loop based upon some soft config options.
 1579          *
 1580          * NB: for the 2300, ICBOPT_EXTENDED is required.
 1581          */
 1582         if (IS_2100(isp)) {
 1583                 /*
 1584                  * We can't have Fast Posting any more- we now
 1585                  * have 32 bit handles.
 1586                  */
 1587                 icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
 1588         } else if (IS_2200(isp) || IS_23XX(isp)) {
 1589                 icbp->icb_fwoptions |= ICBOPT_EXTENDED;
 1590                 /*
 1591                  * Prefer or force Point-To-Point instead Loop?
 1592                  */
 1593                 switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
 1594                 case ISP_CFG_NPORT:
 1595                         icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
 1596                         break;
 1597                 case ISP_CFG_NPORT_ONLY:
 1598                         icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY;
 1599                         break;
 1600                 case ISP_CFG_LPORT_ONLY:
 1601                         icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY;
 1602                         break;
 1603                 default:
 1604                         icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
 1605                         break;
 1606                 }
 1607                 if (IS_2200(isp)) {
 1608                         /*
 1609                          * We can't have Fast Posting any more- we now
 1610                          * have 32 bit handles.
 1611                          *
 1612                          * RIO seemed to have too much breakage.
 1613                          *
 1614                          * Just opt for safety.
 1615                          */
 1616                         icbp->icb_xfwoptions &= ~ICBXOPT_RIO_16BIT;
 1617                         icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
 1618                 } else {
 1619                         /*
 1620                          * QLogic recommends that FAST Posting be turned
 1621                          * off for 23XX cards and instead allow the HBA
 1622                          * to write response queue entries and interrupt
 1623                          * after a delay (ZIO).
 1624                          */
 1625                         icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
 1626                         if ((fcp->isp_xfwoptions & ICBXOPT_TIMER_MASK) == ICBXOPT_ZIO) {
 1627                                 icbp->icb_xfwoptions |= ICBXOPT_ZIO;
 1628                                 icbp->icb_idelaytimer = 10;
 1629                         }
 1630                         if (isp->isp_confopts & ISP_CFG_ONEGB) {
 1631                                 icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
 1632                         } else if (isp->isp_confopts & ISP_CFG_TWOGB) {
 1633                                 icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB;
 1634                         } else {
 1635                                 icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
 1636                         }
 1637                         if (fcp->isp_zfwoptions & ICBZOPT_50_OHM) {
 1638                                 icbp->icb_zfwoptions |= ICBZOPT_50_OHM;
 1639                         }
 1640                 }
 1641         }
 1642 
 1643 
 1644         /*
 1645          * For 22XX > 2.1.26 && 23XX, set some options.
 1646          */
 1647         if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
 1648                 MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
 1649                 mbs.param[1] = IFCOPT1_DISF7SWTCH|IFCOPT1_LIPASYNC|IFCOPT1_LIPF8;
 1650                 mbs.param[2] = 0;
 1651                 mbs.param[3] = 0;
 1652                 if (ISP_FW_NEWER_THAN(isp, 3, 16, 0)) {
 1653                         mbs.param[1] |= IFCOPT1_EQFQASYNC|IFCOPT1_CTIO_RETRY;
 1654                         if (fcp->role & ISP_ROLE_TARGET) {
 1655                                 mbs.param[3] = IFCOPT3_NOPRLI;
 1656                         }
 1657                 }
 1658                 isp_mboxcmd(isp, &mbs);
 1659                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1660                         return;
 1661                 }
 1662         }
 1663         icbp->icb_logintime = ICB_LOGIN_TOV;
 1664         icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV;
 1665 
 1666         if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
 1667                 icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
 1668                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
 1669                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
 1670                 isp_prt(isp, ISP_LOGDEBUG1,
 1671                     "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
 1672                     ((uint32_t) (fcp->isp_wwnn >> 32)),
 1673                     ((uint32_t) (fcp->isp_wwnn)),
 1674                     ((uint32_t) (fcp->isp_wwpn >> 32)),
 1675                     ((uint32_t) (fcp->isp_wwpn)));
 1676         } else if (fcp->isp_wwpn) {
 1677                 icbp->icb_fwoptions &= ~ICBOPT_BOTH_WWNS;
 1678                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
 1679                 isp_prt(isp, ISP_LOGDEBUG1,
 1680                     "Setting ICB Port 0x%08x%08x",
 1681                     ((uint32_t) (fcp->isp_wwpn >> 32)),
 1682                     ((uint32_t) (fcp->isp_wwpn)));
 1683         } else {
 1684                 isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
 1685                 return;
 1686         }
 1687         icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
 1688         if (icbp->icb_rqstqlen < 1) {
 1689                 isp_prt(isp, ISP_LOGERR, "bad request queue length");
 1690         }
 1691         icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
 1692         if (icbp->icb_rsltqlen < 1) {
 1693                 isp_prt(isp, ISP_LOGERR, "bad result queue length");
 1694         }
 1695         icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
 1696         icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
 1697         icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
 1698         icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
 1699         icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
 1700         icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
 1701         icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
 1702         icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
 1703 
 1704         if (FC_SCRATCH_ACQUIRE(isp, 0)) {
 1705                 isp_prt(isp, ISP_LOGERR, sacq);
 1706                 return;
 1707         }
 1708         isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
 1709             icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
 1710 
 1711         isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
 1712 
 1713         /*
 1714          * Init the firmware
 1715          */
 1716         MBSINIT(&mbs, MBOX_INIT_FIRMWARE, MBLOGALL, 30000000);
 1717         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 1718         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 1719         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 1720         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 1721         mbs.logval = MBLOGALL;
 1722         isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %p (%08x%08x)",
 1723             fcp->isp_scratch, (uint32_t) ((uint64_t)fcp->isp_scdma >> 32),
 1724             (uint32_t) fcp->isp_scdma);
 1725         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp), 0);
 1726         isp_mboxcmd(isp, &mbs);
 1727         FC_SCRATCH_RELEASE(isp, 0);
 1728         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1729                 isp_print_bytes(isp, "isp_fibre_init", sizeof (*icbp), icbp);
 1730                 return;
 1731         }
 1732         isp->isp_reqidx = 0;
 1733         isp->isp_reqodx = 0;
 1734         isp->isp_residx = 0;
 1735 
 1736         /*
 1737          * Whatever happens, we're now committed to being here.
 1738          */
 1739         isp->isp_state = ISP_INITSTATE;
 1740 }
 1741 
 1742 static void
 1743 isp_fibre_init_2400(ispsoftc_t *isp)
 1744 {
 1745         fcparam *fcp;
 1746         isp_icb_2400_t local, *icbp = &local;
 1747         mbreg_t mbs;
 1748         int chan;
 1749 
 1750         /*
 1751          * Check to see whether all channels have *some* kind of role
 1752          */
 1753         for (chan = 0; chan < isp->isp_nchan; chan++) {
 1754                 fcp = FCPARAM(isp, chan);
 1755                 if (fcp->role != ISP_ROLE_NONE) {
 1756                         break;
 1757                 }
 1758         }
 1759         if (chan == isp->isp_nchan) {
 1760                 isp_prt(isp, ISP_LOGDEBUG0, "all %d channels with role 'none'", chan);
 1761                 isp->isp_state = ISP_INITSTATE;
 1762                 return;
 1763         }
 1764 
 1765         /*
 1766          * Start with channel 0.
 1767          */
 1768         fcp = FCPARAM(isp, 0);
 1769 
 1770         /*
 1771          * Turn on LIP F8 async event (1)
 1772          */
 1773         MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
 1774         mbs.param[1] = 1;
 1775         isp_mboxcmd(isp, &mbs);
 1776         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1777                 return;
 1778         }
 1779 
 1780         ISP_MEMZERO(icbp, sizeof (*icbp));
 1781         icbp->icb_fwoptions1 = fcp->isp_fwoptions;
 1782         if (fcp->role & ISP_ROLE_TARGET) {
 1783                 icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
 1784         } else {
 1785                 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_TGT_ENABLE;
 1786         }
 1787 
 1788         if (fcp->role & ISP_ROLE_INITIATOR) {
 1789                 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
 1790         } else {
 1791                 icbp->icb_fwoptions1 |= ICB2400_OPT1_INI_DISABLE;
 1792         }
 1793 
 1794         icbp->icb_version = ICB_VERSION1;
 1795         icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
 1796         if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
 1797                 isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
 1798                 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
 1799         }
 1800 
 1801         icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
 1802         if (icbp->icb_execthrottle < 1) {
 1803                 isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
 1804                 icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
 1805         }
 1806 
 1807         if (icbp->icb_fwoptions1 & ICB2400_OPT1_TGT_ENABLE) {
 1808                 /*
 1809                  * Get current resource count
 1810                  */
 1811                 MBSINIT(&mbs, MBOX_GET_RESOURCE_COUNT, MBLOGALL, 0);
 1812                 mbs.obits = 0x4cf;
 1813                 isp_mboxcmd(isp, &mbs);
 1814                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1815                         return;
 1816                 }
 1817                 icbp->icb_xchgcnt = mbs.param[3];
 1818         }
 1819 
 1820 
 1821         icbp->icb_hardaddr = fcp->isp_loopid;
 1822         if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
 1823                 icbp->icb_hardaddr = 0;
 1824         }
 1825 
 1826         /*
 1827          * Force this on.
 1828          */
 1829         icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
 1830 
 1831         icbp->icb_fwoptions2 = fcp->isp_xfwoptions;
 1832         switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
 1833 #if     0
 1834         case ISP_CFG_NPORT:
 1835                 /*
 1836                  * XXX: This causes the f/w to crash.
 1837                  */
 1838                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
 1839                 icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_2_LOOP;
 1840                 break;
 1841 #endif
 1842         case ISP_CFG_NPORT_ONLY:
 1843                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
 1844                 icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY;
 1845                 break;
 1846         case ISP_CFG_LPORT_ONLY:
 1847                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
 1848                 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY;
 1849                 break;
 1850         default:
 1851                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
 1852                 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
 1853                 break;
 1854         }
 1855 
 1856         /* force this on for now */
 1857         icbp->icb_fwoptions2 |= ICB2400_OPT2_ZIO;
 1858 
 1859         switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) {
 1860         case ICB2400_OPT2_ZIO:
 1861         case ICB2400_OPT2_ZIO1:
 1862                 icbp->icb_idelaytimer = 0;
 1863                 break;
 1864         case 0:
 1865                 break;
 1866         default:
 1867                 isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field", icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
 1868                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK;
 1869                 break;
 1870         }
 1871 
 1872         /*
 1873          * We don't support FCTAPE, so clear it.
 1874          */
 1875         icbp->icb_fwoptions2 &= ~ICB2400_OPT2_FCTAPE;
 1876 
 1877         icbp->icb_fwoptions3 = fcp->isp_zfwoptions;
 1878         icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_AUTO;
 1879         if (isp->isp_confopts & ISP_CFG_ONEGB) {
 1880                 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_ONEGB;
 1881         } else if (isp->isp_confopts & ISP_CFG_TWOGB) {
 1882                 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_TWOGB;
 1883         } else if (isp->isp_confopts & ISP_CFG_FOURGB) {
 1884                 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_FOURGB;
 1885         } else {
 1886                 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
 1887         }
 1888 
 1889         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
 1890                 icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID;
 1891         }
 1892         icbp->icb_logintime = ICB_LOGIN_TOV;
 1893 
 1894         if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
 1895                 icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
 1896                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
 1897                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
 1898                 isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node 0x%08x%08x Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwnn >> 32)), ((uint32_t) (fcp->isp_wwnn)),
 1899                     ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
 1900         } else if (fcp->isp_wwpn) {
 1901                 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS;
 1902                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
 1903                 isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node to be same as Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
 1904         } else {
 1905                 isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
 1906                 return;
 1907         }
 1908         icbp->icb_retry_count = fcp->isp_retry_count;
 1909 
 1910         icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
 1911         if (icbp->icb_rqstqlen < 8) {
 1912                 isp_prt(isp, ISP_LOGERR, "bad request queue length %d", icbp->icb_rqstqlen);
 1913                 return;
 1914         }
 1915         icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
 1916         if (icbp->icb_rsltqlen < 8) {
 1917                 isp_prt(isp, ISP_LOGERR, "bad result queue length %d",
 1918                     icbp->icb_rsltqlen);
 1919                 return;
 1920         }
 1921         icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
 1922         icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
 1923         icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
 1924         icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
 1925 
 1926         icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
 1927         icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
 1928         icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
 1929         icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
 1930 
 1931 #ifdef  ISP_TARGET_MODE
 1932         /* unconditionally set up the ATIO queue if we support target mode */
 1933         icbp->icb_atioqlen = RESULT_QUEUE_LEN(isp);
 1934         if (icbp->icb_atioqlen < 8) {
 1935                 isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d", icbp->icb_atioqlen);
 1936                 return;
 1937         }
 1938         icbp->icb_atioqaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_atioq_dma);
 1939         icbp->icb_atioqaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_atioq_dma);
 1940         icbp->icb_atioqaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_atioq_dma);
 1941         icbp->icb_atioqaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_atioq_dma);
 1942         isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: atioq %04x%04x%04x%04x", DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma),
 1943             DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma));
 1944 #endif
 1945 
 1946         isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3);
 1947 
 1948         isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x", DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma),
 1949             DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma), DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
 1950             DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
 1951 
 1952         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 1953                 isp_print_bytes(isp, "isp_fibre_init_2400", sizeof (*icbp), icbp);
 1954         }
 1955 
 1956         if (FC_SCRATCH_ACQUIRE(isp, 0)) {
 1957                 isp_prt(isp, ISP_LOGERR, sacq);
 1958                 return;
 1959         }
 1960         ISP_MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
 1961         isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
 1962 
 1963         /*
 1964          * Now fill in information about any additional channels
 1965          */
 1966         if (isp->isp_nchan > 1) {
 1967                 isp_icb_2400_vpinfo_t vpinfo, *vdst;
 1968                 vp_port_info_t pi, *pdst;
 1969                 size_t amt = 0;
 1970                 uint8_t *off;
 1971 
 1972                 vpinfo.vp_count = isp->isp_nchan - 1;
 1973                 vpinfo.vp_global_options = 0;
 1974                 off = fcp->isp_scratch;
 1975                 off += ICB2400_VPINFO_OFF;
 1976                 vdst = (isp_icb_2400_vpinfo_t *) off;
 1977                 isp_put_icb_2400_vpinfo(isp, &vpinfo, vdst);
 1978                 amt = ICB2400_VPINFO_OFF + sizeof (isp_icb_2400_vpinfo_t);
 1979                 for (chan = 1; chan < isp->isp_nchan; chan++) {
 1980                         fcparam *fcp2;
 1981 
 1982                         ISP_MEMZERO(&pi, sizeof (pi));
 1983                         fcp2 = FCPARAM(isp, chan);
 1984                         if (fcp2->role != ISP_ROLE_NONE) {
 1985                                 pi.vp_port_options = ICB2400_VPOPT_ENABLED;
 1986                                 if (fcp2->role & ISP_ROLE_INITIATOR) {
 1987                                         pi.vp_port_options |= ICB2400_VPOPT_INI_ENABLE;
 1988                                 }
 1989                                 if ((fcp2->role & ISP_ROLE_TARGET) == 0) {
 1990                                         pi.vp_port_options |= ICB2400_VPOPT_TGT_DISABLE;
 1991                                 }
 1992                                 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname, fcp2->isp_wwpn);
 1993                                 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename, fcp2->isp_wwnn);
 1994                         }
 1995                         off = fcp->isp_scratch;
 1996                         off += ICB2400_VPINFO_PORT_OFF(chan);
 1997                         pdst = (vp_port_info_t *) off;
 1998                         isp_put_vp_port_info(isp, &pi, pdst);
 1999                         amt += ICB2400_VPOPT_WRITE_SIZE;
 2000                 }
 2001         }
 2002 
 2003         /*
 2004          * Init the firmware
 2005          */
 2006         MBSINIT(&mbs, 0, MBLOGALL, 30000000);
 2007         if (isp->isp_nchan > 1) {
 2008                 mbs.param[0] = MBOX_INIT_FIRMWARE_MULTI_ID;
 2009         } else {
 2010                 mbs.param[0] = MBOX_INIT_FIRMWARE;
 2011         }
 2012         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 2013         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 2014         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 2015         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 2016         isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %04x%04x%04x%04x", DMA_WD3(fcp->isp_scdma), DMA_WD2(fcp->isp_scdma), DMA_WD1(fcp->isp_scdma), DMA_WD0(fcp->isp_scdma));
 2017         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp), 0);
 2018         isp_mboxcmd(isp, &mbs);
 2019         FC_SCRATCH_RELEASE(isp, 0);
 2020 
 2021         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 2022                 return;
 2023         }
 2024         isp->isp_reqidx = 0;
 2025         isp->isp_reqodx = 0;
 2026         isp->isp_residx = 0;
 2027 
 2028         /*
 2029          * Whatever happens, we're now committed to being here.
 2030          */
 2031         isp->isp_state = ISP_INITSTATE;
 2032 }
 2033 
 2034 static void
 2035 isp_mark_portdb(ispsoftc_t *isp, int chan, int disposition)
 2036 {
 2037         fcparam *fcp = FCPARAM(isp, chan);
 2038         int i;
 2039 
 2040         if (chan < 0 || chan >= isp->isp_nchan) {
 2041                 isp_prt(isp, ISP_LOGWARN, "isp_mark_portdb: bad channel %d", chan);
 2042                 return;
 2043         }
 2044         for (i = 0; i < MAX_FC_TARG; i++) {
 2045                 if (fcp->portdb[i].target_mode) {
 2046                         if (disposition < 0) {
 2047                                 isp_prt(isp, ISP_LOGTINFO, "isp_mark_portdb: Chan %d zeroing handle 0x" "%04x port 0x%06x", chan,
 2048                                     fcp->portdb[i].handle, fcp->portdb[i].portid);
 2049                                 ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
 2050                         }
 2051                         continue;
 2052                 }
 2053                 if (disposition == 0) {
 2054                         ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
 2055                 } else {
 2056                         switch (fcp->portdb[i].state) {
 2057                         case FC_PORTDB_STATE_CHANGED:
 2058                         case FC_PORTDB_STATE_PENDING_VALID:
 2059                         case FC_PORTDB_STATE_VALID:
 2060                         case FC_PORTDB_STATE_PROBATIONAL:
 2061                                 fcp->portdb[i].state = FC_PORTDB_STATE_PROBATIONAL;
 2062                                 break;
 2063                         case FC_PORTDB_STATE_ZOMBIE:
 2064                                 break;
 2065                         case FC_PORTDB_STATE_NIL:
 2066                         default:
 2067                                 ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
 2068                                 fcp->portdb[i].state = FC_PORTDB_STATE_NIL;
 2069                                 break;
 2070                         }
 2071                 }
 2072         }
 2073 }
 2074 
 2075 /*
 2076  * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards
 2077  * or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
 2078  */
 2079 static int
 2080 isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags, int gs)
 2081 {
 2082         mbreg_t mbs;
 2083         uint8_t q[QENTRY_LEN];
 2084         isp_plogx_t *plp;
 2085         fcparam *fcp;
 2086         uint8_t *scp;
 2087         uint32_t sst, parm1;
 2088         int rval;
 2089         const char *msg;
 2090         char buf[64];
 2091 
 2092         if (!IS_24XX(isp)) {
 2093                 int action = flags & PLOGX_FLG_CMD_MASK;
 2094                 if (action == PLOGX_FLG_CMD_PLOGI) {
 2095                         return (isp_port_login(isp, handle, portid));
 2096                 } else if (action == PLOGX_FLG_CMD_LOGO) {
 2097                         return (isp_port_logout(isp, handle, portid));
 2098                 } else {
 2099                         return (MBOX_INVALID_COMMAND);
 2100                 }
 2101         }
 2102 
 2103         ISP_MEMZERO(q, QENTRY_LEN);
 2104         plp = (isp_plogx_t *) q;
 2105         plp->plogx_header.rqs_entry_count = 1;
 2106         plp->plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
 2107         plp->plogx_handle = 0xffffffff;
 2108         plp->plogx_nphdl = handle;
 2109         plp->plogx_vphdl = chan;
 2110         plp->plogx_portlo = portid;
 2111         plp->plogx_rspsz_porthi = (portid >> 16) & 0xff;
 2112         plp->plogx_flags = flags;
 2113 
 2114         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 2115                 isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, plp);
 2116         }
 2117 
 2118         if (gs == 0) {
 2119                 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 2120                         isp_prt(isp, ISP_LOGERR, sacq);
 2121                         return (-1);
 2122                 }
 2123         }
 2124         fcp = FCPARAM(isp, chan);
 2125         scp = fcp->isp_scratch;
 2126         isp_put_plogx(isp, plp, (isp_plogx_t *) scp);
 2127 
 2128         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
 2129         mbs.param[1] = QENTRY_LEN;
 2130         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 2131         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 2132         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 2133         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 2134         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN, chan);
 2135         isp_mboxcmd(isp, &mbs);
 2136         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 2137                 rval = mbs.param[0];
 2138                 goto out;
 2139         }
 2140         MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
 2141         scp += QENTRY_LEN;
 2142         isp_get_plogx(isp, (isp_plogx_t *) scp, plp);
 2143         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 2144                 isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, plp);
 2145         }
 2146 
 2147         if (plp->plogx_status == PLOGX_STATUS_OK) {
 2148                 rval = 0;
 2149                 goto out;
 2150         } else if (plp->plogx_status != PLOGX_STATUS_IOCBERR) {
 2151                 isp_prt(isp, ISP_LOGWARN,
 2152                     "status 0x%x on port login IOCB channel %d",
 2153                     plp->plogx_status, chan);
 2154                 rval = -1;
 2155                 goto out;
 2156         }
 2157 
 2158         sst = plp->plogx_ioparm[0].lo16 | (plp->plogx_ioparm[0].hi16 << 16);
 2159         parm1 = plp->plogx_ioparm[1].lo16 | (plp->plogx_ioparm[1].hi16 << 16);
 2160 
 2161         rval = -1;
 2162         msg = NULL;
 2163 
 2164         switch (sst) {
 2165         case PLOGX_IOCBERR_NOLINK:
 2166                 msg = "no link";
 2167                 break;
 2168         case PLOGX_IOCBERR_NOIOCB:
 2169                 msg = "no IOCB buffer";
 2170                 break;
 2171         case PLOGX_IOCBERR_NOXGHG:
 2172                 msg = "no Exchange Control Block";
 2173                 break;
 2174         case PLOGX_IOCBERR_FAILED:
 2175                 ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff);
 2176                 msg = buf;
 2177                 break;
 2178         case PLOGX_IOCBERR_NOFABRIC:
 2179                 msg = "no fabric";
 2180                 break;
 2181         case PLOGX_IOCBERR_NOTREADY:
 2182                 msg = "firmware not ready";
 2183                 break;
 2184         case PLOGX_IOCBERR_NOLOGIN:
 2185                 ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1);
 2186                 msg = buf;
 2187                 rval = MBOX_NOT_LOGGED_IN;
 2188                 break;
 2189         case PLOGX_IOCBERR_REJECT:
 2190                 ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1);
 2191                 msg = buf;
 2192                 break;
 2193         case PLOGX_IOCBERR_NOPCB:
 2194                 msg = "no PCB allocated";
 2195                 break;
 2196         case PLOGX_IOCBERR_EINVAL:
 2197                 ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1);
 2198                 msg = buf;
 2199                 break;
 2200         case PLOGX_IOCBERR_PORTUSED:
 2201                 ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1);
 2202                 msg = buf;
 2203                 rval = MBOX_PORT_ID_USED | (parm1 << 16);
 2204                 break;
 2205         case PLOGX_IOCBERR_HNDLUSED:
 2206                 ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1);
 2207                 msg = buf;
 2208                 rval = MBOX_LOOP_ID_USED;
 2209                 break;
 2210         case PLOGX_IOCBERR_NOHANDLE:
 2211                 msg = "no handle allocated";
 2212                 break;
 2213         case PLOGX_IOCBERR_NOFLOGI:
 2214                 msg = "no FLOGI_ACC";
 2215                 break;
 2216         default:
 2217                 ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", plp->plogx_status, flags);
 2218                 msg = buf;
 2219                 break;
 2220         }
 2221         if (msg) {
 2222                 isp_prt(isp, ISP_LOGERR, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s", chan, portid, handle, msg);
 2223         }
 2224 out:
 2225         if (gs == 0) {
 2226                 FC_SCRATCH_RELEASE(isp, chan);
 2227         }
 2228         return (rval);
 2229 }
 2230 
 2231 static int
 2232 isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
 2233 {
 2234         mbreg_t mbs;
 2235 
 2236         MBSINIT(&mbs, MBOX_FABRIC_LOGIN, MBLOGNONE, 500000);
 2237         if (ISP_CAP_2KLOGIN(isp)) {
 2238                 mbs.param[1] = handle;
 2239                 mbs.ibits = (1 << 10);
 2240         } else {
 2241                 mbs.param[1] = handle << 8;
 2242         }
 2243         mbs.param[2] = portid >> 16;
 2244         mbs.param[3] = portid;
 2245         mbs.logval = MBLOGNONE;
 2246         mbs.timeout = 500000;
 2247         isp_mboxcmd(isp, &mbs);
 2248 
 2249         switch (mbs.param[0]) {
 2250         case MBOX_PORT_ID_USED:
 2251                 isp_prt(isp, ISP_LOGDEBUG0,
 2252                     "isp_port_login: portid 0x%06x already logged in as %u",
 2253                     portid, mbs.param[1]);
 2254                 return (MBOX_PORT_ID_USED | (mbs.param[1] << 16));
 2255 
 2256         case MBOX_LOOP_ID_USED:
 2257                 isp_prt(isp, ISP_LOGDEBUG0,
 2258                     "isp_port_login: handle 0x%04x in use for port id 0x%02xXXXX",
 2259                     handle, mbs.param[1] & 0xff);
 2260                 return (MBOX_LOOP_ID_USED);
 2261 
 2262         case MBOX_COMMAND_COMPLETE:
 2263                 return (0);
 2264 
 2265         case MBOX_COMMAND_ERROR:
 2266                 isp_prt(isp, ISP_LOGINFO,
 2267                     "isp_port_login: error 0x%x in PLOGI to port 0x%06x",
 2268                     mbs.param[1], portid);
 2269                 return (MBOX_COMMAND_ERROR);
 2270 
 2271         case MBOX_ALL_IDS_USED:
 2272                 isp_prt(isp, ISP_LOGINFO,
 2273                     "isp_port_login: all IDs used for fabric login");
 2274                 return (MBOX_ALL_IDS_USED);
 2275 
 2276         default:
 2277                 isp_prt(isp, ISP_LOGINFO,
 2278                     "isp_port_login: error 0x%x on port login of 0x%06x@0x%0x",
 2279                     mbs.param[0], portid, handle);
 2280                 return (mbs.param[0]);
 2281         }
 2282 }
 2283 
 2284 static int
 2285 isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
 2286 {
 2287         mbreg_t mbs;
 2288 
 2289         MBSINIT(&mbs, MBOX_FABRIC_LOGOUT, MBLOGNONE, 500000);
 2290         if (ISP_CAP_2KLOGIN(isp)) {
 2291                 mbs.param[1] = handle;
 2292                 mbs.ibits = (1 << 10);
 2293         } else {
 2294                 mbs.param[1] = handle << 8;
 2295         }
 2296         isp_mboxcmd(isp, &mbs);
 2297         return (mbs.param[0] == MBOX_COMMAND_COMPLETE? 0 : mbs.param[0]);
 2298 }
 2299 
 2300 static int
 2301 isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
 2302 {
 2303         fcparam *fcp = FCPARAM(isp, chan);
 2304         mbreg_t mbs;
 2305         union {
 2306                 isp_pdb_21xx_t fred;
 2307                 isp_pdb_24xx_t bill;
 2308         } un;
 2309 
 2310         MBSINIT(&mbs, MBOX_GET_PORT_DB, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 250000);
 2311         if (IS_24XX(isp)) {
 2312                 mbs.ibits = (1 << 9)|(1 << 10);
 2313                 mbs.param[1] = id;
 2314                 mbs.param[9] = chan;
 2315         } else if (ISP_CAP_2KLOGIN(isp)) {
 2316                 mbs.param[1] = id;
 2317         } else {
 2318                 mbs.param[1] = id << 8;
 2319         }
 2320         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 2321         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 2322         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 2323         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 2324         if (dolock) {
 2325                 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 2326                         isp_prt(isp, ISP_LOGERR, sacq);
 2327                         return (-1);
 2328                 }
 2329         }
 2330         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (un), chan);
 2331         isp_mboxcmd(isp, &mbs);
 2332         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 2333                 if (dolock) {
 2334                         FC_SCRATCH_RELEASE(isp, chan);
 2335                 }
 2336                 return (mbs.param[0]);
 2337         }
 2338         if (IS_24XX(isp)) {
 2339                 isp_get_pdb_24xx(isp, fcp->isp_scratch, &un.bill);
 2340                 pdb->handle = un.bill.pdb_handle;
 2341                 pdb->s3_role = un.bill.pdb_prli_svc3;
 2342                 pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
 2343                 ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
 2344                 ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
 2345                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 2346                     "Chan %d Port 0x%06x flags 0x%x curstate %x",
 2347                     chan, pdb->portid, un.bill.pdb_flags,
 2348                     un.bill.pdb_curstate);
 2349                 if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE ||
 2350                     un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) {
 2351                         mbs.param[0] = MBOX_NOT_LOGGED_IN;
 2352                         if (dolock) {
 2353                                 FC_SCRATCH_RELEASE(isp, chan);
 2354                         }
 2355                         return (mbs.param[0]);
 2356                 }
 2357         } else {
 2358                 isp_get_pdb_21xx(isp, fcp->isp_scratch, &un.fred);
 2359                 pdb->handle = un.fred.pdb_loopid;
 2360                 pdb->s3_role = un.fred.pdb_prli_svc3;
 2361                 pdb->portid = BITS2WORD(un.fred.pdb_portid_bits);
 2362                 ISP_MEMCPY(pdb->portname, un.fred.pdb_portname, 8);
 2363                 ISP_MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8);
 2364         }
 2365         if (dolock) {
 2366                 FC_SCRATCH_RELEASE(isp, chan);
 2367         }
 2368         return (0);
 2369 }
 2370 
 2371 static void
 2372 isp_dump_chip_portdb(ispsoftc_t *isp, int chan, int dolock)
 2373 {
 2374         isp_pdb_t pdb;
 2375         int lim, loopid;
 2376 
 2377         if (ISP_CAP_2KLOGIN(isp)) {
 2378                 lim = NPH_MAX_2K;
 2379         } else {
 2380                 lim = NPH_MAX;
 2381         }
 2382         for (loopid = 0; loopid != lim; loopid++) {
 2383                 if (isp_getpdb(isp, chan, loopid, &pdb, dolock)) {
 2384                         continue;
 2385                 }
 2386                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGINFO, "Chan %d Loopid 0x%04x "
 2387                     "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x",
 2388                     chan, loopid, pdb.portid, pdb.portname[0], pdb.portname[1],
 2389                     pdb.portname[2], pdb.portname[3], pdb.portname[4],
 2390                     pdb.portname[5], pdb.portname[6], pdb.portname[7]);
 2391         }
 2392 }
 2393 
 2394 static uint64_t
 2395 isp_get_wwn(ispsoftc_t *isp, int chan, int loopid, int nodename)
 2396 {
 2397         uint64_t wwn = INI_NONE;
 2398         fcparam *fcp = FCPARAM(isp, chan);
 2399         mbreg_t mbs;
 2400 
 2401         if (fcp->isp_fwstate < FW_READY ||
 2402             fcp->isp_loopstate < LOOP_PDB_RCVD) {
 2403                 return (wwn);
 2404         }
 2405         MBSINIT(&mbs, MBOX_GET_PORT_NAME, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 500000);
 2406         if (ISP_CAP_2KLOGIN(isp)) {
 2407                 mbs.param[1] = loopid;
 2408                 mbs.ibits = (1 << 10);
 2409                 if (nodename) {
 2410                         mbs.param[10] = 1;
 2411                 }
 2412                 if (ISP_CAP_MULTI_ID(isp)) {
 2413                         mbs.ibits |= (1 << 9);
 2414                         mbs.param[9] = chan;
 2415                 }
 2416         } else {
 2417                 mbs.param[1] = loopid << 8;
 2418                 if (nodename) {
 2419                         mbs.param[1] |= 1;
 2420                 }
 2421         }
 2422         isp_mboxcmd(isp, &mbs);
 2423         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 2424                 return (wwn);
 2425         }
 2426         if (IS_24XX(isp)) {
 2427                 wwn =
 2428                     (((uint64_t)(mbs.param[2] >> 8))    << 56) |
 2429                     (((uint64_t)(mbs.param[2] & 0xff))  << 48) |
 2430                     (((uint64_t)(mbs.param[3] >> 8))    << 40) |
 2431                     (((uint64_t)(mbs.param[3] & 0xff))  << 32) |
 2432                     (((uint64_t)(mbs.param[6] >> 8))    << 24) |
 2433                     (((uint64_t)(mbs.param[6] & 0xff))  << 16) |
 2434                     (((uint64_t)(mbs.param[7] >> 8))    <<  8) |
 2435                     (((uint64_t)(mbs.param[7] & 0xff)));
 2436         } else {
 2437                 wwn =
 2438                     (((uint64_t)(mbs.param[2] & 0xff))  << 56) |
 2439                     (((uint64_t)(mbs.param[2] >> 8))    << 48) |
 2440                     (((uint64_t)(mbs.param[3] & 0xff))  << 40) |
 2441                     (((uint64_t)(mbs.param[3] >> 8))    << 32) |
 2442                     (((uint64_t)(mbs.param[6] & 0xff))  << 24) |
 2443                     (((uint64_t)(mbs.param[6] >> 8))    << 16) |
 2444                     (((uint64_t)(mbs.param[7] & 0xff))  <<  8) |
 2445                     (((uint64_t)(mbs.param[7] >> 8)));
 2446         }
 2447         return (wwn);
 2448 }
 2449 
 2450 /*
 2451  * Make sure we have good FC link.
 2452  */
 2453 
 2454 static int
 2455 isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
 2456 {
 2457         mbreg_t mbs;
 2458         int count, check_for_fabric, r;
 2459         uint8_t lwfs;
 2460         int loopid;
 2461         fcparam *fcp;
 2462         fcportdb_t *lp;
 2463         isp_pdb_t pdb;
 2464 
 2465         fcp = FCPARAM(isp, chan);
 2466 
 2467         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d FC Link Test Entry", chan);
 2468         ISP_MARK_PORTDB(isp, chan, 1);
 2469 
 2470         /*
 2471          * Wait up to N microseconds for F/W to go to a ready state.
 2472          */
 2473         lwfs = FW_CONFIG_WAIT;
 2474         count = 0;
 2475         while (count < usdelay) {
 2476                 uint64_t enano;
 2477                 uint32_t wrk;
 2478                 NANOTIME_T hra, hrb;
 2479 
 2480                 GET_NANOTIME(&hra);
 2481                 isp_fw_state(isp, chan);
 2482                 if (lwfs != fcp->isp_fwstate) {
 2483                         isp_prt(isp, ISP_LOGCONFIG|ISP_LOGSANCFG, "Chan %d Firmware State <%s->%s>", chan, isp_fc_fw_statename((int)lwfs), isp_fc_fw_statename((int)fcp->isp_fwstate));
 2484                         lwfs = fcp->isp_fwstate;
 2485                 }
 2486                 if (fcp->isp_fwstate == FW_READY) {
 2487                         break;
 2488                 }
 2489                 GET_NANOTIME(&hrb);
 2490 
 2491                 /*
 2492                  * Get the elapsed time in nanoseconds.
 2493                  * Always guaranteed to be non-zero.
 2494                  */
 2495                 enano = NANOTIME_SUB(&hrb, &hra);
 2496 
 2497                 isp_prt(isp, ISP_LOGDEBUG1, "usec%d: 0x%lx->0x%lx enano 0x%x%08x", count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb), (uint32_t)(enano >> 32), (uint32_t)(enano));
 2498 
 2499                 /*
 2500                  * If the elapsed time is less than 1 millisecond,
 2501                  * delay a period of time up to that millisecond of
 2502                  * waiting.
 2503                  *
 2504                  * This peculiar code is an attempt to try and avoid
 2505                  * invoking uint64_t math support functions for some
 2506                  * platforms where linkage is a problem.
 2507                  */
 2508                 if (enano < (1000 * 1000)) {
 2509                         count += 1000;
 2510                         enano = (1000 * 1000) - enano;
 2511                         while (enano > (uint64_t) 4000000000U) {
 2512                                 ISP_SLEEP(isp, 4000000);
 2513                                 enano -= (uint64_t) 4000000000U;
 2514                         }
 2515                         wrk = enano;
 2516                         wrk /= 1000;
 2517                         ISP_SLEEP(isp, wrk);
 2518                 } else {
 2519                         while (enano > (uint64_t) 4000000000U) {
 2520                                 count += 4000000;
 2521                                 enano -= (uint64_t) 4000000000U;
 2522                         }
 2523                         wrk = enano;
 2524                         count += (wrk / 1000);
 2525                 }
 2526         }
 2527 
 2528 
 2529 
 2530         /*
 2531          * If we haven't gone to 'ready' state, return.
 2532          */
 2533         if (fcp->isp_fwstate != FW_READY) {
 2534                 isp_prt(isp, ISP_LOGSANCFG, "%s: chan %d not at FW_READY state", __func__, chan);
 2535                 return (-1);
 2536         }
 2537 
 2538         /*
 2539          * Get our Loop ID and Port ID.
 2540          */
 2541         MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0);
 2542         if (ISP_CAP_MULTI_ID(isp)) {
 2543                 mbs.param[9] = chan;
 2544                 mbs.ibits = (1 << 9);
 2545                 mbs.obits = (1 << 7);
 2546         }
 2547         isp_mboxcmd(isp, &mbs);
 2548         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 2549                 return (-1);
 2550         }
 2551 
 2552         if (ISP_CAP_2KLOGIN(isp)) {
 2553                 fcp->isp_loopid = mbs.param[1];
 2554         } else {
 2555                 fcp->isp_loopid = mbs.param[1] & 0xff;
 2556         }
 2557 
 2558         if (IS_2100(isp)) {
 2559                 fcp->isp_topo = TOPO_NL_PORT;
 2560         } else {
 2561                 int topo = (int) mbs.param[6];
 2562                 if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB) {
 2563                         topo = TOPO_PTP_STUB;
 2564                 }
 2565                 fcp->isp_topo = topo;
 2566         }
 2567         fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
 2568 
 2569         if (IS_2100(isp)) {
 2570                 /*
 2571                  * Don't bother with fabric if we are using really old
 2572                  * 2100 firmware. It's just not worth it.
 2573                  */
 2574                 if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) {
 2575                         check_for_fabric = 1;
 2576                 } else {
 2577                         check_for_fabric = 0;
 2578                 }
 2579         } else if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_F_PORT) {
 2580                 check_for_fabric = 1;
 2581         } else {
 2582                 check_for_fabric = 0;
 2583         }
 2584 
 2585         /*
 2586          * Check to make sure we got a valid loopid
 2587          * The 24XX seems to mess this up for multiple channels.
 2588          */
 2589         if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT) {
 2590                 uint8_t alpa = fcp->isp_portid;
 2591 
 2592                 if (alpa == 0) {
 2593                         /* "Cannot Happen" */
 2594                         isp_prt(isp, ISP_LOGWARN, "Zero AL_PA for Loop Topology?");
 2595                 } else {
 2596                         int i;
 2597                         for (i = 0; alpa_map[i]; i++) {
 2598                                 if (alpa_map[i] == alpa) {
 2599                                         break;
 2600                                 }
 2601                         }
 2602                         if (alpa_map[i] && fcp->isp_loopid != i) {
 2603                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d deriving loopid %d from AL_PA map  (AL_PA 0x%x) and ignoring returned value %d (AL_PA 0x%x)", chan, i, alpa_map[i], fcp->isp_loopid, alpa);
 2604                                 fcp->isp_loopid = i;
 2605                         }
 2606                 }
 2607         }
 2608 
 2609 
 2610         if (IS_24XX(isp)) { /* XXX SHOULDN'T THIS BE FOR 2K F/W? XXX */
 2611                 loopid = NPH_FL_ID;
 2612         } else {
 2613                 loopid = FL_ID;
 2614         }
 2615         if (check_for_fabric) {
 2616                 r = isp_getpdb(isp, chan, loopid, &pdb, 1);
 2617                 if (r && (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT)) {
 2618                         isp_prt(isp, ISP_LOGWARN, "fabric topology but cannot get info about fabric controller (0x%x)", r);
 2619                         fcp->isp_topo = TOPO_PTP_STUB;
 2620                 }
 2621         } else {
 2622                 r = -1;
 2623         }
 2624         if (r == 0) {
 2625                 if (IS_2100(isp)) {
 2626                         fcp->isp_topo = TOPO_FL_PORT;
 2627                 }
 2628                 if (pdb.portid == 0) {
 2629                         /*
 2630                          * Crock.
 2631                          */
 2632                         fcp->isp_topo = TOPO_NL_PORT;
 2633                         goto not_on_fabric;
 2634                 }
 2635 
 2636                 /*
 2637                  * Save the Fabric controller's port database entry.
 2638                  */
 2639                 lp = &fcp->portdb[FL_ID];
 2640                 lp->state = FC_PORTDB_STATE_PENDING_VALID;
 2641                 MAKE_WWN_FROM_NODE_NAME(lp->node_wwn, pdb.nodename);
 2642                 MAKE_WWN_FROM_NODE_NAME(lp->port_wwn, pdb.portname);
 2643                 lp->roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
 2644                 lp->portid = pdb.portid;
 2645                 lp->handle = pdb.handle;
 2646                 lp->new_portid = lp->portid;
 2647                 lp->new_roles = lp->roles;
 2648                 if (IS_24XX(isp)) {
 2649                         fcp->inorder = (mbs.param[7] & ISP24XX_INORDER) != 0;
 2650                         if (ISP_FW_NEWER_THAN(isp, 4, 0, 27)) {
 2651                                 fcp->npiv_fabric = (mbs.param[7] & ISP24XX_NPIV_SAN) != 0;
 2652                                 if (fcp->npiv_fabric) {
 2653                                         isp_prt(isp, ISP_LOGCONFIG, "fabric supports NP-IV");
 2654                                 }
 2655                         }
 2656                         if (chan) {
 2657                                 fcp->isp_sns_hdl = NPH_SNS_HDLBASE + chan;
 2658                                 r = isp_plogx(isp, chan, fcp->isp_sns_hdl, SNS_PORT_ID, PLOGX_FLG_CMD_PLOGI | PLOGX_FLG_COND_PLOGI | PLOGX_FLG_SKIP_PRLI, 0);
 2659                                 if (r) {
 2660                                         isp_prt(isp, ISP_LOGWARN, "%s: Chan %d cannot log into SNS", __func__, chan);
 2661                                         return (-1);
 2662                                 }
 2663                         } else {
 2664                                 fcp->isp_sns_hdl = NPH_SNS_ID;
 2665                         }
 2666                         r = isp_register_fc4_type_24xx(isp, chan);
 2667                 } else {
 2668                         fcp->isp_sns_hdl = SNS_ID;
 2669                         r = isp_register_fc4_type(isp, chan);
 2670                 }
 2671                 if (r) {
 2672                         isp_prt(isp, ISP_LOGWARN|ISP_LOGSANCFG, "%s: register fc4 type failed", __func__);
 2673                         return (-1);
 2674                 }
 2675         } else {
 2676 not_on_fabric:
 2677                 fcp->portdb[FL_ID].state = FC_PORTDB_STATE_NIL;
 2678         }
 2679 
 2680         fcp->isp_gbspeed = 1;
 2681         if (IS_23XX(isp) || IS_24XX(isp)) {
 2682                 MBSINIT(&mbs, MBOX_GET_SET_DATA_RATE, MBLOGALL, 3000000);
 2683                 mbs.param[1] = MBGSD_GET_RATE;
 2684                 /* mbs.param[2] undefined if we're just getting rate */
 2685                 isp_mboxcmd(isp, &mbs);
 2686                 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 2687                         if (mbs.param[1] == MBGSD_EIGHTGB) {
 2688                                 isp_prt(isp, ISP_LOGINFO, "Chan %d 8Gb link speed", chan);
 2689                                 fcp->isp_gbspeed = 8;
 2690                         } else if (mbs.param[1] == MBGSD_FOURGB) {
 2691                                 isp_prt(isp, ISP_LOGINFO, "Chan %d 4Gb link speed", chan);
 2692                                 fcp->isp_gbspeed = 4;
 2693                         } else if (mbs.param[1] == MBGSD_TWOGB) {
 2694                                 isp_prt(isp, ISP_LOGINFO, "Chan %d 2Gb link speed", chan);
 2695                                 fcp->isp_gbspeed = 2;
 2696                         } else if (mbs.param[1] == MBGSD_ONEGB) {
 2697                                 isp_prt(isp, ISP_LOGINFO, "Chan %d 1Gb link speed", chan);
 2698                                 fcp->isp_gbspeed = 1;
 2699                         }
 2700                 }
 2701         }
 2702 
 2703         /*
 2704          * Announce ourselves, too.
 2705          */
 2706         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGCONFIG, topology, chan, (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) fcp->isp_wwpn, fcp->isp_portid, fcp->isp_loopid, isp_fc_toponame(fcp));
 2707         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d FC Link Test Complete", chan);
 2708         return (0);
 2709 }
 2710 
 2711 /*
 2712  * Complete the synchronization of our Port Database.
 2713  *
 2714  * At this point, we've scanned the local loop (if any) and the fabric
 2715  * and performed fabric logins on all new devices.
 2716  *
 2717  * Our task here is to go through our port database and remove any entities
 2718  * that are still marked probational (issuing PLOGO for ones which we had
 2719  * PLOGI'd into) or are dead.
 2720  *
 2721  * Our task here is to also check policy to decide whether devices which
 2722  * have *changed* in some way should still be kept active. For example,
 2723  * if a device has just changed PortID, we can either elect to treat it
 2724  * as an old device or as a newly arrived device (and notify the outer
 2725  * layer appropriately).
 2726  *
 2727  * We also do initiator map target id assignment here for new initiator
 2728  * devices and refresh old ones to make sure that they point to the correct
 2729  * entities.
 2730  */
 2731 static int
 2732 isp_pdb_sync(ispsoftc_t *isp, int chan)
 2733 {
 2734         fcparam *fcp = FCPARAM(isp, chan);
 2735         fcportdb_t *lp;
 2736         uint16_t dbidx;
 2737 
 2738         if (fcp->isp_loopstate == LOOP_READY) {
 2739                 return (0);
 2740         }
 2741 
 2742         /*
 2743          * Make sure we're okay for doing this right now.
 2744          */
 2745         if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
 2746             fcp->isp_loopstate != LOOP_FSCAN_DONE &&
 2747             fcp->isp_loopstate != LOOP_LSCAN_DONE) {
 2748                 isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d",
 2749                     fcp->isp_loopstate);
 2750                 return (-1);
 2751         }
 2752 
 2753         if (fcp->isp_topo == TOPO_FL_PORT ||
 2754             fcp->isp_topo == TOPO_NL_PORT ||
 2755             fcp->isp_topo == TOPO_N_PORT) {
 2756                 if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
 2757                         if (isp_scan_loop(isp, chan) != 0) {
 2758                                 isp_prt(isp, ISP_LOGWARN,
 2759                                     "isp_pdb_sync: isp_scan_loop failed");
 2760                                 return (-1);
 2761                         }
 2762                 }
 2763         }
 2764 
 2765         if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
 2766                 if (fcp->isp_loopstate < LOOP_FSCAN_DONE) {
 2767                         if (isp_scan_fabric(isp, chan) != 0) {
 2768                                 isp_prt(isp, ISP_LOGWARN,
 2769                                     "isp_pdb_sync: isp_scan_fabric failed");
 2770                                 return (-1);
 2771                         }
 2772                 }
 2773         }
 2774 
 2775         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 2776             "Chan %d Synchronizing PDBs", chan);
 2777 
 2778         fcp->isp_loopstate = LOOP_SYNCING_PDB;
 2779 
 2780         for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
 2781                 lp = &fcp->portdb[dbidx];
 2782 
 2783                 if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode) {
 2784                         continue;
 2785                 }
 2786 
 2787                 if (lp->state == FC_PORTDB_STATE_VALID) {
 2788                         if (dbidx != FL_ID) {
 2789                                 isp_prt(isp,
 2790                                     ISP_LOGERR, "portdb idx %d already valid",
 2791                                     dbidx);
 2792                         }
 2793                         continue;
 2794                 }
 2795 
 2796                 switch (lp->state) {
 2797                 case FC_PORTDB_STATE_PROBATIONAL:
 2798                 case FC_PORTDB_STATE_DEAD:
 2799                         /*
 2800                          * It's up to the outer layers to clear isp_dev_map.
 2801                          */
 2802                         lp->state = FC_PORTDB_STATE_NIL;
 2803                         isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
 2804                         if (lp->autologin == 0) {
 2805                                 (void) isp_plogx(isp, chan, lp->handle,
 2806                                     lp->portid,
 2807                                     PLOGX_FLG_CMD_LOGO |
 2808                                     PLOGX_FLG_IMPLICIT |
 2809                                     PLOGX_FLG_FREE_NPHDL, 0);
 2810                         } else {
 2811                                 lp->autologin = 0;
 2812                         }
 2813                         lp->new_roles = 0;
 2814                         lp->new_portid = 0;
 2815                         /*
 2816                          * Note that we might come out of this with our state
 2817                          * set to FC_PORTDB_STATE_ZOMBIE.
 2818                          */
 2819                         break;
 2820                 case FC_PORTDB_STATE_NEW:
 2821                         /*
 2822                          * It's up to the outer layers to assign a virtual
 2823                          * target id in isp_dev_map (if any).
 2824                          */
 2825                         lp->portid = lp->new_portid;
 2826                         lp->roles = lp->new_roles;
 2827                         lp->state = FC_PORTDB_STATE_VALID;
 2828                         isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
 2829                         lp->new_roles = 0;
 2830                         lp->new_portid = 0;
 2831                         lp->reserved = 0;
 2832                         lp->new_reserved = 0;
 2833                         break;
 2834                 case FC_PORTDB_STATE_CHANGED:
 2835 /*
 2836  * XXXX FIX THIS
 2837  */
 2838                         lp->state = FC_PORTDB_STATE_VALID;
 2839                         isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
 2840                         lp->new_roles = 0;
 2841                         lp->new_portid = 0;
 2842                         lp->reserved = 0;
 2843                         lp->new_reserved = 0;
 2844                         break;
 2845                 case FC_PORTDB_STATE_PENDING_VALID:
 2846                         lp->portid = lp->new_portid;
 2847                         lp->roles = lp->new_roles;
 2848                         if (lp->dev_map_idx) {
 2849                                 int t = lp->dev_map_idx - 1;
 2850                                 fcp->isp_dev_map[t] = dbidx + 1;
 2851                         }
 2852                         lp->state = FC_PORTDB_STATE_VALID;
 2853                         isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
 2854                         if (dbidx != FL_ID) {
 2855                                 lp->new_roles = 0;
 2856                                 lp->new_portid = 0;
 2857                         }
 2858                         lp->reserved = 0;
 2859                         lp->new_reserved = 0;
 2860                         break;
 2861                 case FC_PORTDB_STATE_ZOMBIE:
 2862                         break;
 2863                 default:
 2864                         isp_prt(isp, ISP_LOGWARN,
 2865                             "isp_scan_loop: state %d for idx %d",
 2866                             lp->state, dbidx);
 2867                         isp_dump_portdb(isp, chan);
 2868                 }
 2869         }
 2870 
 2871         /*
 2872          * If we get here, we've for sure seen not only a valid loop
 2873          * but know what is or isn't on it, so mark this for usage
 2874          * in isp_start.
 2875          */
 2876         fcp->loop_seen_once = 1;
 2877         fcp->isp_loopstate = LOOP_READY;
 2878         return (0);
 2879 }
 2880 
 2881 /*
 2882  * Scan local loop for devices.
 2883  */
 2884 static int
 2885 isp_scan_loop(ispsoftc_t *isp, int chan)
 2886 {
 2887         fcportdb_t *lp, tmp;
 2888         fcparam *fcp = FCPARAM(isp, chan);
 2889         int i;
 2890         isp_pdb_t pdb;
 2891         uint16_t handle, lim = 0;
 2892 
 2893         if (fcp->isp_fwstate < FW_READY ||
 2894             fcp->isp_loopstate < LOOP_PDB_RCVD) {
 2895                 return (-1);
 2896         }
 2897 
 2898         if (fcp->isp_loopstate > LOOP_SCANNING_LOOP) {
 2899                 return (0);
 2900         }
 2901 
 2902         /*
 2903          * Check our connection topology.
 2904          *
 2905          * If we're a public or private loop, we scan 0..125 as handle values.
 2906          * The firmware has (typically) performed a PLOGI for us. We skip this
 2907          * step if we're a ISP_24XX in NP-IV mode.
 2908          *
 2909          * If we're a N-port connection, we treat this is a short loop (0..1).
 2910          */
 2911         switch (fcp->isp_topo) {
 2912         case TOPO_NL_PORT:
 2913                 lim = LOCAL_LOOP_LIM;
 2914                 break;
 2915         case TOPO_FL_PORT:
 2916                 if (IS_24XX(isp) && isp->isp_nchan > 1) {
 2917                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 2918                             "Chan %d Skipping Local Loop Scan", chan);
 2919                         fcp->isp_loopstate = LOOP_LSCAN_DONE;
 2920                         return (0);
 2921                 }
 2922                 lim = LOCAL_LOOP_LIM;
 2923                 break;
 2924         case TOPO_N_PORT:
 2925                 lim = 2;
 2926                 break;
 2927         default:
 2928                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 2929                     "Chan %d no loop topology to scan", chan);
 2930                 fcp->isp_loopstate = LOOP_LSCAN_DONE;
 2931                 return (0);
 2932         }
 2933 
 2934         fcp->isp_loopstate = LOOP_SCANNING_LOOP;
 2935 
 2936         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 2937             "Chan %d FC scan loop 0..%d", chan, lim-1);
 2938 
 2939 
 2940         /*
 2941          * Run through the list and get the port database info for each one.
 2942          */
 2943         for (handle = 0; handle < lim; handle++) {
 2944                 int r;
 2945                 /*
 2946                  * Don't scan "special" ids.
 2947                  */
 2948                 if (handle >= FL_ID && handle <= SNS_ID) {
 2949                         continue;
 2950                 }
 2951                 if (ISP_CAP_2KLOGIN(isp)) {
 2952                         if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
 2953                                 continue;
 2954                         }
 2955                 }
 2956                 /*
 2957                  * In older cards with older f/w GET_PORT_DATABASE has been
 2958                  * known to hang. This trick gets around that problem.
 2959                  */
 2960                 if (IS_2100(isp) || IS_2200(isp)) {
 2961                         uint64_t node_wwn = isp_get_wwn(isp, chan, handle, 1);
 2962                         if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
 2963                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 2964                                     "Chan %d FC scan loop DONE (bad)", chan);
 2965                                 return (-1);
 2966                         }
 2967                         if (node_wwn == INI_NONE) {
 2968                                 continue;
 2969                         }
 2970                 }
 2971 
 2972                 /*
 2973                  * Get the port database entity for this index.
 2974                  */
 2975                 r = isp_getpdb(isp, chan, handle, &pdb, 1);
 2976                 if (r != 0) {
 2977                         isp_prt(isp, ISP_LOGDEBUG1,
 2978                             "Chan %d FC scan loop handle %d returned %x",
 2979                             chan, handle, r);
 2980                         if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
 2981                                 ISP_MARK_PORTDB(isp, chan, 1);
 2982                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 2983                                     "Chan %d FC scan loop DONE (bad)", chan);
 2984                                 return (-1);
 2985                         }
 2986                         continue;
 2987                 }
 2988 
 2989                 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
 2990                         ISP_MARK_PORTDB(isp, chan, 1);
 2991                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 2992                             "Chan %d FC scan loop DONE (bad)", chan);
 2993                         return (-1);
 2994                 }
 2995 
 2996                 /*
 2997                  * On *very* old 2100 firmware we would end up sometimes
 2998                  * with the firmware returning the port database entry
 2999                  * for something else. We used to restart this, but
 3000                  * now we just punt.
 3001                  */
 3002                 if (IS_2100(isp) && pdb.handle != handle) {
 3003                         isp_prt(isp, ISP_LOGWARN,
 3004                             "Chan %d cannot synchronize port database", chan);
 3005                         ISP_MARK_PORTDB(isp, chan, 1);
 3006                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3007                             "Chan %d FC scan loop DONE (bad)", chan);
 3008                         return (-1);
 3009                 }
 3010 
 3011                 /*
 3012                  * Save the pertinent info locally.
 3013                  */
 3014                 MAKE_WWN_FROM_NODE_NAME(tmp.node_wwn, pdb.nodename);
 3015                 MAKE_WWN_FROM_NODE_NAME(tmp.port_wwn, pdb.portname);
 3016                 tmp.roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
 3017                 tmp.portid = pdb.portid;
 3018                 tmp.handle = pdb.handle;
 3019 
 3020                 /*
 3021                  * Check to make sure it's still a valid entry. The 24XX seems
 3022                  * to return a portid but not a WWPN/WWNN or role for devices
 3023                  * which shift on a loop.
 3024                  */
 3025                 if (tmp.node_wwn == 0 || tmp.port_wwn == 0 || tmp.portid == 0) {
 3026                         int a, b, c;
 3027                         a = (tmp.node_wwn == 0);
 3028                         b = (tmp.port_wwn == 0);
 3029                         c = (tmp.portid == 0);
 3030                         if (a == 0 && b == 0) {
 3031                                 tmp.node_wwn =
 3032                                     isp_get_wwn(isp, chan, handle, 1);
 3033                                 tmp.port_wwn =
 3034                                     isp_get_wwn(isp, chan, handle, 0);
 3035                                 if (tmp.node_wwn && tmp.port_wwn) {
 3036                                         isp_prt(isp, ISP_LOGINFO, "DODGED!");
 3037                                         goto cont;
 3038                                 }
 3039                         }
 3040                         isp_prt(isp, ISP_LOGWARN,
 3041                             "Chan %d bad pdb (%1d%1d%1d) @ handle 0x%x", chan,
 3042                             a, b, c, handle);
 3043                         isp_dump_portdb(isp, chan);
 3044                         continue;
 3045                 }
 3046   cont:
 3047 
 3048                 /*
 3049                  * Now search the entire port database
 3050                  * for the same Port and Node WWN.
 3051                  */
 3052                 for (i = 0; i < MAX_FC_TARG; i++) {
 3053                         lp = &fcp->portdb[i];
 3054 
 3055                         if (lp->state == FC_PORTDB_STATE_NIL ||
 3056                             lp->target_mode) {
 3057                                 continue;
 3058                         }
 3059                         if (lp->node_wwn != tmp.node_wwn) {
 3060                                 continue;
 3061                         }
 3062                         if (lp->port_wwn != tmp.port_wwn) {
 3063                                 continue;
 3064                         }
 3065 
 3066                         /*
 3067                          * Okay- we've found a non-nil entry that matches.
 3068                          * Check to make sure it's probational or a zombie.
 3069                          */
 3070                         if (lp->state != FC_PORTDB_STATE_PROBATIONAL &&
 3071                             lp->state != FC_PORTDB_STATE_ZOMBIE) {
 3072                                 isp_prt(isp, ISP_LOGERR,
 3073                                     "Chan %d [%d] not probational/zombie (0x%x)",
 3074                                     chan, i, lp->state);
 3075                                 isp_dump_portdb(isp, chan);
 3076                                 ISP_MARK_PORTDB(isp, chan, 1);
 3077                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3078                                     "Chan %d FC scan loop DONE (bad)", chan);
 3079                                 return (-1);
 3080                         }
 3081 
 3082                         /*
 3083                          * Mark the device as something the f/w logs into
 3084                          * automatically.
 3085                          */
 3086                         lp->autologin = 1;
 3087 
 3088                         /*
 3089                          * Check to make see if really still the same
 3090                          * device. If it is, we mark it pending valid.
 3091                          */
 3092                         if (lp->portid == tmp.portid &&
 3093                             lp->handle == tmp.handle &&
 3094                             lp->roles == tmp.roles) {
 3095                                 lp->new_portid = tmp.portid;
 3096                                 lp->new_roles = tmp.roles;
 3097                                 lp->state = FC_PORTDB_STATE_PENDING_VALID;
 3098                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3099                                     "Chan %d Loop Port 0x%06x@0x%04x Pending "
 3100                                     "Valid", chan, tmp.portid, tmp.handle);
 3101                                 break;
 3102                         }
 3103 
 3104                         /*
 3105                          * We can wipe out the old handle value
 3106                          * here because it's no longer valid.
 3107                          */
 3108                         lp->handle = tmp.handle;
 3109 
 3110                         /*
 3111                          * Claim that this has changed and let somebody else
 3112                          * decide what to do.
 3113                          */
 3114                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3115                             "Chan %d Loop Port 0x%06x@0x%04x changed",
 3116                             chan, tmp.portid, tmp.handle);
 3117                         lp->state = FC_PORTDB_STATE_CHANGED;
 3118                         lp->new_portid = tmp.portid;
 3119                         lp->new_roles = tmp.roles;
 3120                         break;
 3121                 }
 3122 
 3123                 /*
 3124                  * Did we find and update an old entry?
 3125                  */
 3126                 if (i < MAX_FC_TARG) {
 3127                         continue;
 3128                 }
 3129 
 3130                 /*
 3131                  * Ah. A new device entry. Find an empty slot
 3132                  * for it and save info for later disposition.
 3133                  */
 3134                 for (i = 0; i < MAX_FC_TARG; i++) {
 3135                         if (fcp->portdb[i].target_mode) {
 3136                                 continue;
 3137                         }
 3138                         if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL) {
 3139                                 break;
 3140                         }
 3141                 }
 3142                 if (i == MAX_FC_TARG) {
 3143                         isp_prt(isp, ISP_LOGERR,
 3144                             "Chan %d out of portdb entries", chan);
 3145                         continue;
 3146                 }
 3147                 lp = &fcp->portdb[i];
 3148 
 3149                 ISP_MEMZERO(lp, sizeof (fcportdb_t));
 3150                 lp->autologin = 1;
 3151                 lp->state = FC_PORTDB_STATE_NEW;
 3152                 lp->new_portid = tmp.portid;
 3153                 lp->new_roles = tmp.roles;
 3154                 lp->handle = tmp.handle;
 3155                 lp->port_wwn = tmp.port_wwn;
 3156                 lp->node_wwn = tmp.node_wwn;
 3157                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3158                     "Chan %d Loop Port 0x%06x@0x%04x is New Entry",
 3159                     chan, tmp.portid, tmp.handle);
 3160         }
 3161         fcp->isp_loopstate = LOOP_LSCAN_DONE;
 3162         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3163             "Chan %d FC scan loop DONE", chan);
 3164         return (0);
 3165 }
 3166 
 3167 /*
 3168  * Scan the fabric for devices and add them to our port database.
 3169  *
 3170  * Use the GID_FT command to get all Port IDs for FC4 SCSI devices it knows.
 3171  *
 3172  * For 2100-23XX cards, we can use the SNS mailbox command to pass simple
 3173  * name server commands to the switch management server via the QLogic f/w.
 3174  *
 3175  * For the 24XX card, we have to use CT-Pass through run via the Execute IOCB
 3176  * mailbox command.
 3177  *
 3178  * The net result is to leave the list of Port IDs setting untranslated in
 3179  * offset IGPOFF of the FC scratch area, whereupon we'll canonicalize it to
 3180  * host order at OGPOFF.
 3181  */
 3182 
 3183 /*
 3184  * Take less than half of our scratch area to store Port IDs
 3185  */
 3186 #define GIDLEN  ((ISP_FC_SCRLEN >> 1) - 16 - SNS_GID_FT_REQ_SIZE)
 3187 #define NGENT   ((GIDLEN - 16) >> 2)
 3188 
 3189 #define IGPOFF  (2 * QENTRY_LEN)
 3190 #define OGPOFF  (ISP_FC_SCRLEN >> 1)
 3191 #define ZTXOFF  (ISP_FC_SCRLEN - (1 * QENTRY_LEN))
 3192 #define CTXOFF  (ISP_FC_SCRLEN - (2 * QENTRY_LEN))
 3193 #define XTXOFF  (ISP_FC_SCRLEN - (3 * QENTRY_LEN))
 3194 
 3195 static int
 3196 isp_gid_ft_sns(ispsoftc_t *isp, int chan)
 3197 {
 3198         union {
 3199                 sns_gid_ft_req_t _x;
 3200                 uint8_t _y[SNS_GID_FT_REQ_SIZE];
 3201         } un;
 3202         fcparam *fcp = FCPARAM(isp, chan);
 3203         sns_gid_ft_req_t *rq = &un._x;
 3204         mbreg_t mbs;
 3205 
 3206         isp_prt(isp, ISP_LOGDEBUG0,
 3207             "Chan %d scanning fabric (GID_FT) via SNS", chan);
 3208 
 3209         ISP_MEMZERO(rq, SNS_GID_FT_REQ_SIZE);
 3210         rq->snscb_rblen = GIDLEN >> 1;
 3211         rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + IGPOFF);
 3212         rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + IGPOFF);
 3213         rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + IGPOFF);
 3214         rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + IGPOFF);
 3215         rq->snscb_sblen = 6;
 3216         rq->snscb_cmd = SNS_GID_FT;
 3217         rq->snscb_mword_div_2 = NGENT;
 3218         rq->snscb_fc4_type = FC4_SCSI;
 3219 
 3220         isp_put_gid_ft_request(isp, rq, fcp->isp_scratch);
 3221         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE, chan);
 3222 
 3223         MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 10000000);
 3224         mbs.param[0] = MBOX_SEND_SNS;
 3225         mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
 3226         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 3227         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 3228         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 3229         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 3230         isp_mboxcmd(isp, &mbs);
 3231         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 3232                 if (mbs.param[0] == MBOX_INVALID_COMMAND) {
 3233                         return (1);
 3234                 } else {
 3235                         return (-1);
 3236                 }
 3237         }
 3238         return (0);
 3239 }
 3240 
 3241 static int
 3242 isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
 3243 {
 3244         mbreg_t mbs;
 3245         fcparam *fcp = FCPARAM(isp, chan);
 3246         union {
 3247                 isp_ct_pt_t plocal;
 3248                 ct_hdr_t clocal;
 3249                 uint8_t q[QENTRY_LEN];
 3250         } un;
 3251         isp_ct_pt_t *pt;
 3252         ct_hdr_t *ct;
 3253         uint32_t *rp;
 3254         uint8_t *scp = fcp->isp_scratch;
 3255 
 3256         isp_prt(isp, ISP_LOGDEBUG0,
 3257             "Chan %d scanning fabric (GID_FT) via CT", chan);
 3258 
 3259         if (!IS_24XX(isp)) {
 3260                 return (1);
 3261         }
 3262 
 3263         /*
 3264          * Build a Passthrough IOCB in memory.
 3265          */
 3266         pt = &un.plocal;
 3267         ISP_MEMZERO(un.q, QENTRY_LEN);
 3268         pt->ctp_header.rqs_entry_count = 1;
 3269         pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
 3270         pt->ctp_handle = 0xffffffff;
 3271         pt->ctp_nphdl = fcp->isp_sns_hdl;
 3272         pt->ctp_cmd_cnt = 1;
 3273         pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
 3274         pt->ctp_time = 30;
 3275         pt->ctp_rsp_cnt = 1;
 3276         pt->ctp_rsp_bcnt = GIDLEN;
 3277         pt->ctp_cmd_bcnt = sizeof (*ct) + sizeof (uint32_t);
 3278         pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
 3279         pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
 3280         pt->ctp_dataseg[0].ds_count = sizeof (*ct) + sizeof (uint32_t);
 3281         pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
 3282         pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
 3283         pt->ctp_dataseg[1].ds_count = GIDLEN;
 3284         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 3285                 isp_print_bytes(isp, "ct IOCB", QENTRY_LEN, pt);
 3286         }
 3287         isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
 3288 
 3289         /*
 3290          * Build the CT header and command in memory.
 3291          *
 3292          * Note that the CT header has to end up as Big Endian format in memory.
 3293          */
 3294         ct = &un.clocal;
 3295         ISP_MEMZERO(ct, sizeof (*ct));
 3296         ct->ct_revision = CT_REVISION;
 3297         ct->ct_fcs_type = CT_FC_TYPE_FC;
 3298         ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
 3299         ct->ct_cmd_resp = SNS_GID_FT;
 3300         ct->ct_bcnt_resid = (GIDLEN - 16) >> 2;
 3301 
 3302         isp_put_ct_hdr(isp, ct, (ct_hdr_t *) &scp[XTXOFF]);
 3303         rp = (uint32_t *) &scp[XTXOFF+sizeof (*ct)];
 3304         ISP_IOZPUT_32(isp, FC4_SCSI, rp);
 3305         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 3306                 isp_print_bytes(isp, "CT HDR + payload after put",
 3307                     sizeof (*ct) + sizeof (uint32_t), &scp[XTXOFF]);
 3308         }
 3309         ISP_MEMZERO(&scp[ZTXOFF], QENTRY_LEN);
 3310         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
 3311         mbs.param[1] = QENTRY_LEN;
 3312         mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
 3313         mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
 3314         mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
 3315         mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
 3316         MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN, chan);
 3317         isp_mboxcmd(isp, &mbs);
 3318         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 3319                 return (-1);
 3320         }
 3321         MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN, chan);
 3322         pt = &un.plocal;
 3323         isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
 3324         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 3325                 isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
 3326         }
 3327 
 3328         if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) {
 3329                 isp_prt(isp, ISP_LOGWARN,
 3330                     "Chan %d ISP GID FT CT Passthrough returned 0x%x",
 3331                     chan, pt->ctp_status);
 3332                 return (-1);
 3333         }
 3334         MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN + 16, chan);
 3335         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 3336                 isp_print_bytes(isp, "CT response", GIDLEN+16, &scp[IGPOFF]);
 3337         }
 3338         return (0);
 3339 }
 3340 
 3341 static int
 3342 isp_scan_fabric(ispsoftc_t *isp, int chan)
 3343 {
 3344         fcparam *fcp = FCPARAM(isp, chan);
 3345         uint32_t portid;
 3346         uint16_t handle, oldhandle, loopid;
 3347         isp_pdb_t pdb;
 3348         int portidx, portlim, r;
 3349         sns_gid_ft_rsp_t *rs0, *rs1;
 3350 
 3351         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3352             "Chan %d FC Scan Fabric", chan);
 3353         if (fcp->isp_fwstate != FW_READY ||
 3354             fcp->isp_loopstate < LOOP_LSCAN_DONE) {
 3355                 return (-1);
 3356         }
 3357         if (fcp->isp_loopstate > LOOP_SCANNING_FABRIC) {
 3358                 return (0);
 3359         }
 3360         if (fcp->isp_topo != TOPO_FL_PORT && fcp->isp_topo != TOPO_F_PORT) {
 3361                 fcp->isp_loopstate = LOOP_FSCAN_DONE;
 3362                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3363                     "Chan %d FC Scan Fabric Done (no fabric)", chan);
 3364                 return (0);
 3365         }
 3366 
 3367         fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
 3368         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 3369                 isp_prt(isp, ISP_LOGERR, sacq);
 3370                 ISP_MARK_PORTDB(isp, chan, 1);
 3371                 return (-1);
 3372         }
 3373         if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
 3374                 FC_SCRATCH_RELEASE(isp, chan);
 3375                 ISP_MARK_PORTDB(isp, chan, 1);
 3376                 return (-1);
 3377         }
 3378 
 3379         /*
 3380          * Make sure we still are logged into the fabric controller.
 3381          */
 3382         if (IS_24XX(isp)) {     /* XXX SHOULDN'T THIS BE TRUE FOR 2K F/W? XXX */
 3383                 loopid = NPH_FL_ID;
 3384         } else {
 3385                 loopid = FL_ID;
 3386         }
 3387         r = isp_getpdb(isp, chan, loopid, &pdb, 0);
 3388         if (r == MBOX_NOT_LOGGED_IN) {
 3389                 isp_dump_chip_portdb(isp, chan, 0);
 3390         }
 3391         if (r) {
 3392                 fcp->isp_loopstate = LOOP_PDB_RCVD;
 3393                 FC_SCRATCH_RELEASE(isp, chan);
 3394                 ISP_MARK_PORTDB(isp, chan, 1);
 3395                 return (-1);
 3396         }
 3397 
 3398         if (IS_24XX(isp)) {
 3399                 r = isp_gid_ft_ct_passthru(isp, chan);
 3400         } else {
 3401                 r = isp_gid_ft_sns(isp, chan);
 3402         }
 3403 
 3404         if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
 3405                 FC_SCRATCH_RELEASE(isp, chan);
 3406                 ISP_MARK_PORTDB(isp, chan, 1);
 3407                 return (-1);
 3408         }
 3409 
 3410         if (r > 0) {
 3411                 fcp->isp_loopstate = LOOP_FSCAN_DONE;
 3412                 FC_SCRATCH_RELEASE(isp, chan);
 3413                 return (0);
 3414         } else if (r < 0) {
 3415                 fcp->isp_loopstate = LOOP_PDB_RCVD;     /* try again */
 3416                 FC_SCRATCH_RELEASE(isp, chan);
 3417                 return (0);
 3418         }
 3419 
 3420         MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN, chan);
 3421         rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF);
 3422         rs1 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+OGPOFF);
 3423         isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
 3424         if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
 3425                 FC_SCRATCH_RELEASE(isp, chan);
 3426                 ISP_MARK_PORTDB(isp, chan, 1);
 3427                 return (-1);
 3428         }
 3429         if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) {
 3430                 int level;
 3431                 if (rs1->snscb_cthdr.ct_reason == 9 &&
 3432                     rs1->snscb_cthdr.ct_explanation == 7) {
 3433                         level = ISP_LOGSANCFG|ISP_LOGDEBUG0;
 3434                 } else {
 3435                         level = ISP_LOGWARN;
 3436                 }
 3437                 isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_FT"
 3438                     " (Reason=0x%x Expl=0x%x)", chan,
 3439                     rs1->snscb_cthdr.ct_reason,
 3440                     rs1->snscb_cthdr.ct_explanation);
 3441                 FC_SCRATCH_RELEASE(isp, chan);
 3442                 fcp->isp_loopstate = LOOP_FSCAN_DONE;
 3443                 return (0);
 3444         }
 3445 
 3446 
 3447         /*
 3448          * If we get this far, we certainly still have the fabric controller.
 3449          */
 3450         fcp->portdb[FL_ID].state = FC_PORTDB_STATE_PENDING_VALID;
 3451 
 3452         /*
 3453          * Prime the handle we will start using.
 3454          */
 3455         oldhandle = FCPARAM(isp, 0)->isp_lasthdl;
 3456 
 3457         /*
 3458          * Go through the list and remove duplicate port ids.
 3459          */
 3460 
 3461         portlim = 0;
 3462         portidx = 0;
 3463         for (portidx = 0; portidx < NGENT-1; portidx++) {
 3464                 if (rs1->snscb_ports[portidx].control & 0x80) {
 3465                         break;
 3466                 }
 3467         }
 3468 
 3469         /*
 3470          * If we're not at the last entry, our list wasn't big enough.
 3471          */
 3472         if ((rs1->snscb_ports[portidx].control & 0x80) == 0) {
 3473                 isp_prt(isp, ISP_LOGWARN,
 3474                     "fabric too big for scratch area: increase ISP_FC_SCRLEN");
 3475         }
 3476         portlim = portidx + 1;
 3477         isp_prt(isp, ISP_LOGSANCFG,
 3478             "Chan %d got %d ports back from name server", chan, portlim);
 3479 
 3480         for (portidx = 0; portidx < portlim; portidx++) {
 3481                 int npidx;
 3482 
 3483                 portid =
 3484                     ((rs1->snscb_ports[portidx].portid[0]) << 16) |
 3485                     ((rs1->snscb_ports[portidx].portid[1]) << 8) |
 3486                     ((rs1->snscb_ports[portidx].portid[2]));
 3487 
 3488                 for (npidx = portidx + 1; npidx < portlim; npidx++) {
 3489                         uint32_t new_portid =
 3490                             ((rs1->snscb_ports[npidx].portid[0]) << 16) |
 3491                             ((rs1->snscb_ports[npidx].portid[1]) << 8) |
 3492                             ((rs1->snscb_ports[npidx].portid[2]));
 3493                         if (new_portid == portid) {
 3494                                 break;
 3495                         }
 3496                 }
 3497 
 3498                 if (npidx < portlim) {
 3499                         rs1->snscb_ports[npidx].portid[0] = 0;
 3500                         rs1->snscb_ports[npidx].portid[1] = 0;
 3501                         rs1->snscb_ports[npidx].portid[2] = 0;
 3502                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3503                             "Chan %d removing duplicate PortID 0x%06x"
 3504                             " entry from list", chan, portid);
 3505                 }
 3506         }
 3507 
 3508         /*
 3509          * We now have a list of Port IDs for all FC4 SCSI devices
 3510          * that the Fabric Name server knows about.
 3511          *
 3512          * For each entry on this list go through our port database looking
 3513          * for probational entries- if we find one, then an old entry is
 3514          * maybe still this one. We get some information to find out.
 3515          *
 3516          * Otherwise, it's a new fabric device, and we log into it
 3517          * (unconditionally). After searching the entire database
 3518          * again to make sure that we never ever ever ever have more
 3519          * than one entry that has the same PortID or the same
 3520          * WWNN/WWPN duple, we enter the device into our database.
 3521          */
 3522 
 3523         for (portidx = 0; portidx < portlim; portidx++) {
 3524                 fcportdb_t *lp;
 3525                 uint64_t wwnn, wwpn;
 3526                 int dbidx, nr;
 3527 
 3528                 portid =
 3529                     ((rs1->snscb_ports[portidx].portid[0]) << 16) |
 3530                     ((rs1->snscb_ports[portidx].portid[1]) << 8) |
 3531                     ((rs1->snscb_ports[portidx].portid[2]));
 3532 
 3533                 if (portid == 0) {
 3534                         isp_prt(isp, ISP_LOGSANCFG,
 3535                             "Chan %d skipping null PortID at idx %d",
 3536                             chan, portidx);
 3537                         continue;
 3538                 }
 3539 
 3540                 /*
 3541                  * Skip ourselves here and on other channels. If we're
 3542                  * multi-id, we can't check the portids in other FCPARAM
 3543                  * arenas because the resolutions here aren't synchronized.
 3544                  * The best way to do this is to exclude looking at portids
 3545                  * that have the same domain and area code as our own
 3546                  * portid.
 3547                  */
 3548                 if (ISP_CAP_MULTI_ID(isp)) {
 3549                         if ((portid >> 8) == (fcp->isp_portid >> 8)) {
 3550                                 isp_prt(isp, ISP_LOGSANCFG,
 3551                                     "Chan %d skip PortID 0x%06x",
 3552                                     chan, portid);
 3553                                 continue;
 3554                         }
 3555                 } else if (portid == fcp->isp_portid) {
 3556                         isp_prt(isp, ISP_LOGSANCFG,
 3557                             "Chan %d skip ourselves on @ PortID 0x%06x",
 3558                             chan, portid);
 3559                         continue;
 3560                 }
 3561 
 3562                 isp_prt(isp, ISP_LOGSANCFG,
 3563                     "Chan %d Checking Fabric Port 0x%06x", chan, portid);
 3564 
 3565                 /*
 3566                  * We now search our Port Database for any
 3567                  * probational entries with this PortID. We don't
 3568                  * look for zombies here- only probational
 3569                  * entries (we've already logged out of zombies).
 3570                  */
 3571                 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
 3572                         lp = &fcp->portdb[dbidx];
 3573 
 3574                         if (lp->state != FC_PORTDB_STATE_PROBATIONAL ||
 3575                             lp->target_mode) {
 3576                                 continue;
 3577                         }
 3578                         if (lp->portid == portid) {
 3579                                 break;
 3580                         }
 3581                 }
 3582 
 3583                 /*
 3584                  * We found a probational entry with this Port ID.
 3585                  */
 3586                 if (dbidx < MAX_FC_TARG) {
 3587                         int handle_changed = 0;
 3588 
 3589                         lp = &fcp->portdb[dbidx];
 3590 
 3591                         /*
 3592                          * See if we're still logged into it.
 3593                          *
 3594                          * If we aren't, mark it as a dead device and
 3595                          * leave the new portid in the database entry
 3596                          * for somebody further along to decide what to
 3597                          * do (policy choice).
 3598                          *
 3599                          * If we are, check to see if it's the same
 3600                          * device still (it should be). If for some
 3601                          * reason it isn't, mark it as a changed device
 3602                          * and leave the new portid and role in the
 3603                          * database entry for somebody further along to
 3604                          * decide what to do (policy choice).
 3605                          *
 3606                          */
 3607 
 3608                         r = isp_getpdb(isp, chan, lp->handle, &pdb, 0);
 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 (r != 0) {
 3615                                 lp->new_portid = portid;
 3616                                 lp->state = FC_PORTDB_STATE_DEAD;
 3617                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3618                                     "Chan %d Fabric Port 0x%06x is dead",
 3619                                     chan, portid);
 3620                                 continue;
 3621                         }
 3622 
 3623 
 3624                         /*
 3625                          * Check to make sure that handle, portid, WWPN and
 3626                          * WWNN agree. If they don't, then the association
 3627                          * between this PortID and the stated handle has been
 3628                          * broken by the firmware.
 3629                          */
 3630                         MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
 3631                         MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
 3632                         if (pdb.handle != lp->handle ||
 3633                             pdb.portid != portid ||
 3634                             wwpn != lp->port_wwn ||
 3635                             wwnn != lp->node_wwn) {
 3636                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3637                                     fconf, chan, dbidx, pdb.handle, pdb.portid,
 3638                                     (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
 3639                                     (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
 3640                                     lp->handle, portid,
 3641                                     (uint32_t) (lp->node_wwn >> 32),
 3642                                     (uint32_t) lp->node_wwn,
 3643                                     (uint32_t) (lp->port_wwn >> 32),
 3644                                     (uint32_t) lp->port_wwn);
 3645                                 /*
 3646                                  * Try to re-login to this device using a
 3647                                  * new handle. If that fails, mark it dead.
 3648                                  *
 3649                                  * isp_login_device will check for handle and
 3650                                  * portid consistency after re-login.
 3651                                  *
 3652                                  */
 3653                                 if (isp_login_device(isp, chan, portid, &pdb,
 3654                                     &oldhandle)) {
 3655                                         lp->new_portid = portid;
 3656                                         lp->state = FC_PORTDB_STATE_DEAD;
 3657                                         if (fcp->isp_loopstate !=
 3658                                             LOOP_SCANNING_FABRIC) {
 3659                                                 FC_SCRATCH_RELEASE(isp, chan);
 3660                                                 ISP_MARK_PORTDB(isp, chan, 1);
 3661                                                 return (-1);
 3662                                         }
 3663                                         continue;
 3664                                 }
 3665                                 if (fcp->isp_loopstate !=
 3666                                     LOOP_SCANNING_FABRIC) {
 3667                                         FC_SCRATCH_RELEASE(isp, chan);
 3668                                         ISP_MARK_PORTDB(isp, chan, 1);
 3669                                         return (-1);
 3670                                 }
 3671                                 FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
 3672                                 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
 3673                                 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
 3674                                 if (wwpn != lp->port_wwn ||
 3675                                     wwnn != lp->node_wwn) {
 3676                                         isp_prt(isp, ISP_LOGWARN, "changed WWN"
 3677                                             " after relogin");
 3678                                         lp->new_portid = portid;
 3679                                         lp->state = FC_PORTDB_STATE_DEAD;
 3680                                         continue;
 3681                                 }
 3682 
 3683                                 lp->handle = pdb.handle;
 3684                                 handle_changed++;
 3685                         }
 3686 
 3687                         nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
 3688 
 3689                         /*
 3690                          * Check to see whether the portid and roles have
 3691                          * stayed the same. If they have stayed the same,
 3692                          * we believe that this is the same device and it
 3693                          * hasn't become disconnected and reconnected, so
 3694                          * mark it as pending valid.
 3695                          *
 3696                          * If they aren't the same, mark the device as a
 3697                          * changed device and save the new port id and role
 3698                          * and let somebody else decide.
 3699                          */
 3700 
 3701                         lp->new_portid = portid;
 3702                         lp->new_roles = nr;
 3703                         if (pdb.portid != lp->portid || nr != lp->roles ||
 3704                             handle_changed) {
 3705                                 isp_prt(isp, ISP_LOGSANCFG,
 3706                                     "Chan %d Fabric Port 0x%06x changed",
 3707                                     chan, portid);
 3708                                 lp->state = FC_PORTDB_STATE_CHANGED;
 3709                         } else {
 3710                                 isp_prt(isp, ISP_LOGSANCFG,
 3711                                     "Chan %d Fabric Port 0x%06x "
 3712                                     "Now Pending Valid", chan, portid);
 3713                                 lp->state = FC_PORTDB_STATE_PENDING_VALID;
 3714                         }
 3715                         continue;
 3716                 }
 3717 
 3718                 /*
 3719                  * Ah- a new entry. Search the database again for all non-NIL
 3720                  * entries to make sure we never ever make a new database entry
 3721                  * with the same port id. While we're at it, mark where the
 3722                  * last free entry was.
 3723                  */
 3724 
 3725                 dbidx = MAX_FC_TARG;
 3726                 for (lp = fcp->portdb; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
 3727                         if (lp >= &fcp->portdb[FL_ID] &&
 3728                             lp <= &fcp->portdb[SNS_ID]) {
 3729                                 continue;
 3730                         }
 3731                         /*
 3732                          * Skip any target mode entries.
 3733                          */
 3734                         if (lp->target_mode) {
 3735                                 continue;
 3736                         }
 3737                         if (lp->state == FC_PORTDB_STATE_NIL) {
 3738                                 if (dbidx == MAX_FC_TARG) {
 3739                                         dbidx = lp - fcp->portdb;
 3740                                 }
 3741                                 continue;
 3742                         }
 3743                         if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
 3744                                 continue;
 3745                         }
 3746                         if (lp->portid == portid) {
 3747                                 break;
 3748                         }
 3749                 }
 3750 
 3751                 if (lp < &fcp->portdb[MAX_FC_TARG]) {
 3752                         isp_prt(isp, ISP_LOGWARN, "Chan %d PortID 0x%06x "
 3753                             "already at %d handle %d state %d",
 3754                             chan, portid, dbidx, lp->handle, lp->state);
 3755                         continue;
 3756                 }
 3757 
 3758                 /*
 3759                  * We should have the index of the first free entry seen.
 3760                  */
 3761                 if (dbidx == MAX_FC_TARG) {
 3762                         isp_prt(isp, ISP_LOGERR,
 3763                             "port database too small to login PortID 0x%06x"
 3764                             "- increase MAX_FC_TARG", portid);
 3765                         continue;
 3766                 }
 3767 
 3768                 /*
 3769                  * Otherwise, point to our new home.
 3770                  */
 3771                 lp = &fcp->portdb[dbidx];
 3772 
 3773                 /*
 3774                  * Try to see if we are logged into this device,
 3775                  * and maybe log into it.
 3776                  *
 3777                  * isp_login_device will check for handle and
 3778                  * portid consistency after login.
 3779                  */
 3780                 if (isp_login_device(isp, chan, portid, &pdb, &oldhandle)) {
 3781                         if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 3782                                 FC_SCRATCH_RELEASE(isp, chan);
 3783                                 ISP_MARK_PORTDB(isp, chan, 1);
 3784                                 return (-1);
 3785                         }
 3786                         continue;
 3787                 }
 3788                 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 3789                         FC_SCRATCH_RELEASE(isp, chan);
 3790                         ISP_MARK_PORTDB(isp, chan, 1);
 3791                         return (-1);
 3792                 }
 3793                 FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
 3794 
 3795                 handle = pdb.handle;
 3796                 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
 3797                 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
 3798                 nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
 3799 
 3800                 /*
 3801                  * And go through the database *one* more time to make sure
 3802                  * that we do not make more than one entry that has the same
 3803                  * WWNN/WWPN duple
 3804                  */
 3805                 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
 3806                         if (dbidx >= FL_ID && dbidx <= SNS_ID) {
 3807                                 continue;
 3808                         }
 3809                         if (fcp->portdb[dbidx].target_mode) {
 3810                                 continue;
 3811                         }
 3812                         if (fcp->portdb[dbidx].node_wwn == wwnn &&
 3813                             fcp->portdb[dbidx].port_wwn == wwpn) {
 3814                                 break;
 3815                         }
 3816                 }
 3817 
 3818                 if (dbidx == MAX_FC_TARG) {
 3819                         ISP_MEMZERO(lp, sizeof (fcportdb_t));
 3820                         lp->handle = handle;
 3821                         lp->node_wwn = wwnn;
 3822                         lp->port_wwn = wwpn;
 3823                         lp->new_portid = portid;
 3824                         lp->new_roles = nr;
 3825                         lp->state = FC_PORTDB_STATE_NEW;
 3826                         isp_prt(isp, ISP_LOGSANCFG,
 3827                             "Chan %d Fabric Port 0x%06x is a New Entry",
 3828                             chan, portid);
 3829                         continue;
 3830                 }
 3831 
 3832                 if (fcp->portdb[dbidx].state != FC_PORTDB_STATE_ZOMBIE) {
 3833                         isp_prt(isp, ISP_LOGWARN,
 3834                             "Chan %d PortID 0x%x 0x%08x%08x/0x%08x%08x %ld "
 3835                             "already at idx %d, state 0x%x", chan, portid,
 3836                             (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
 3837                             (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
 3838                             (long) (lp - fcp->portdb), dbidx,
 3839                             fcp->portdb[dbidx].state);
 3840                         continue;
 3841                 }
 3842 
 3843                 /*
 3844                  * We found a zombie entry that matches us.
 3845                  * Revive it. We know that WWN and WWPN
 3846                  * are the same. For fabric devices, we
 3847                  * don't care that handle is different
 3848                  * as we assign that. If role or portid
 3849                  * are different, it maybe a changed device.
 3850                  */
 3851                 lp = &fcp->portdb[dbidx];
 3852                 lp->handle = handle;
 3853                 lp->new_portid = portid;
 3854                 lp->new_roles = nr;
 3855                 if (lp->portid != portid || lp->roles != nr) {
 3856                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3857                             "Chan %d Zombie Fabric Port 0x%06x Now Changed",
 3858                             chan, portid);
 3859                         lp->state = FC_PORTDB_STATE_CHANGED;
 3860                 } else {
 3861                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3862                             "Chan %d Zombie Fabric Port 0x%06x "
 3863                             "Now Pending Valid", chan, portid);
 3864                         lp->state = FC_PORTDB_STATE_PENDING_VALID;
 3865                 }
 3866         }
 3867 
 3868         FC_SCRATCH_RELEASE(isp, chan);
 3869         if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 3870                 ISP_MARK_PORTDB(isp, chan, 1);
 3871                 return (-1);
 3872         }
 3873         fcp->isp_loopstate = LOOP_FSCAN_DONE;
 3874         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 3875             "Chan %d FC Scan Fabric Done", chan);
 3876         return (0);
 3877 }
 3878 
 3879 /*
 3880  * Find an unused handle and try and use to login to a port.
 3881  */
 3882 static int
 3883 isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
 3884 {
 3885         int lim, i, r;
 3886         uint16_t handle;
 3887 
 3888         if (ISP_CAP_2KLOGIN(isp)) {
 3889                 lim = NPH_MAX_2K;
 3890         } else {
 3891                 lim = NPH_MAX;
 3892         }
 3893 
 3894         handle = isp_nxt_handle(isp, chan, *ohp);
 3895         for (i = 0; i < lim; i++) {
 3896                 /*
 3897                  * See if we're still logged into something with
 3898                  * this handle and that something agrees with this
 3899                  * port id.
 3900                  */
 3901                 r = isp_getpdb(isp, chan, handle, p, 0);
 3902                 if (r == 0 && p->portid != portid) {
 3903                         (void) isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1);
 3904                 } else if (r == 0) {
 3905                         break;
 3906                 }
 3907                 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
 3908                         return (-1);
 3909                 }
 3910                 /*
 3911                  * Now try and log into the device
 3912                  */
 3913                 r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
 3914                 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
 3915                         return (-1);
 3916                 }
 3917                 if (r == 0) {
 3918                         *ohp = handle;
 3919                         break;
 3920                 } else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
 3921                         /*
 3922                          * If we get here, then the firmware still thinks we're logged into this device, but with a different
 3923                          * handle. We need to break that association. We used to try and just substitute the handle, but then
 3924                          * failed to get any data via isp_getpdb (below).
 3925                          */
 3926                         if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1)) {
 3927                                 isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16);
 3928                         }
 3929                         if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
 3930                                 return (-1);
 3931                         }
 3932                         r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
 3933                         if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
 3934                                 return (-1);
 3935                         }
 3936                         if (r == 0) {
 3937                                 *ohp = handle;
 3938                         } else {
 3939                                 i = lim;
 3940                         }
 3941                         break;
 3942                 } else if ((r & 0xffff) == MBOX_LOOP_ID_USED) {
 3943                         /*
 3944                          * Try the next loop id.
 3945                          */
 3946                         *ohp = handle;
 3947                         handle = isp_nxt_handle(isp, chan, handle);
 3948                 } else {
 3949                         /*
 3950                          * Give up.
 3951                          */
 3952                         i = lim;
 3953                         break;
 3954                 }
 3955         }
 3956 
 3957         if (i == lim) {
 3958                 isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid);
 3959                 return (-1);
 3960         }
 3961 
 3962         /*
 3963          * If we successfully logged into it, get the PDB for it
 3964          * so we can crosscheck that it is still what we think it
 3965          * is and that we also have the role it plays
 3966          */
 3967         r = isp_getpdb(isp, chan, handle, p, 0);
 3968         if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
 3969                 return (-1);
 3970         }
 3971         if (r != 0) {
 3972                 isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
 3973                 return (-1);
 3974         }
 3975 
 3976         if (p->handle != handle || p->portid != portid) {
 3977                 isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
 3978                     chan, portid, handle, p->portid, p->handle);
 3979                 return (-1);
 3980         }
 3981         return (0);
 3982 }
 3983 
 3984 static int
 3985 isp_register_fc4_type(ispsoftc_t *isp, int chan)
 3986 {
 3987         fcparam *fcp = FCPARAM(isp, chan);
 3988         uint8_t local[SNS_RFT_ID_REQ_SIZE];
 3989         sns_screq_t *reqp = (sns_screq_t *) local;
 3990         mbreg_t mbs;
 3991 
 3992         ISP_MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
 3993         reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
 3994         reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
 3995         reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
 3996         reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
 3997         reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
 3998         reqp->snscb_sblen = 22;
 3999         reqp->snscb_data[0] = SNS_RFT_ID;
 4000         reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
 4001         reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
 4002         reqp->snscb_data[6] = (1 << FC4_SCSI);
 4003         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 4004                 isp_prt(isp, ISP_LOGERR, sacq);
 4005                 return (-1);
 4006         }
 4007         isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
 4008         MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 1000000);
 4009         mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
 4010         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 4011         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 4012         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 4013         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 4014         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE, chan);
 4015         isp_mboxcmd(isp, &mbs);
 4016         FC_SCRATCH_RELEASE(isp, chan);
 4017         if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 4018                 return (0);
 4019         } else {
 4020                 return (-1);
 4021         }
 4022 }
 4023 
 4024 static int
 4025 isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
 4026 {
 4027         mbreg_t mbs;
 4028         fcparam *fcp = FCPARAM(isp, chan);
 4029         union {
 4030                 isp_ct_pt_t plocal;
 4031                 rft_id_t clocal;
 4032                 uint8_t q[QENTRY_LEN];
 4033         } un;
 4034         isp_ct_pt_t *pt;
 4035         ct_hdr_t *ct;
 4036         rft_id_t *rp;
 4037         uint8_t *scp = fcp->isp_scratch;
 4038 
 4039         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 4040                 isp_prt(isp, ISP_LOGERR, sacq);
 4041                 return (-1);
 4042         }
 4043 
 4044         /*
 4045          * Build a Passthrough IOCB in memory.
 4046          */
 4047         ISP_MEMZERO(un.q, QENTRY_LEN);
 4048         pt = &un.plocal;
 4049         pt->ctp_header.rqs_entry_count = 1;
 4050         pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
 4051         pt->ctp_handle = 0xffffffff;
 4052         pt->ctp_nphdl = fcp->isp_sns_hdl;
 4053         pt->ctp_cmd_cnt = 1;
 4054         pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
 4055         pt->ctp_time = 1;
 4056         pt->ctp_rsp_cnt = 1;
 4057         pt->ctp_rsp_bcnt = sizeof (ct_hdr_t);
 4058         pt->ctp_cmd_bcnt = sizeof (rft_id_t);
 4059         pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
 4060         pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
 4061         pt->ctp_dataseg[0].ds_count = sizeof (rft_id_t);
 4062         pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
 4063         pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
 4064         pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t);
 4065         isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
 4066         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 4067                 isp_print_bytes(isp, "IOCB CT Request", QENTRY_LEN, pt);
 4068         }
 4069 
 4070         /*
 4071          * Build the CT header and command in memory.
 4072          *
 4073          * Note that the CT header has to end up as Big Endian format in memory.
 4074          */
 4075         ISP_MEMZERO(&un.clocal, sizeof (un.clocal));
 4076         ct = &un.clocal.rftid_hdr;
 4077         ct->ct_revision = CT_REVISION;
 4078         ct->ct_fcs_type = CT_FC_TYPE_FC;
 4079         ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
 4080         ct->ct_cmd_resp = SNS_RFT_ID;
 4081         ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
 4082         rp = &un.clocal;
 4083         rp->rftid_portid[0] = fcp->isp_portid >> 16;
 4084         rp->rftid_portid[1] = fcp->isp_portid >> 8;
 4085         rp->rftid_portid[2] = fcp->isp_portid;
 4086         rp->rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
 4087         isp_put_rft_id(isp, rp, (rft_id_t *) &scp[XTXOFF]);
 4088         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 4089                 isp_print_bytes(isp, "CT Header", QENTRY_LEN, &scp[XTXOFF]);
 4090         }
 4091 
 4092         ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
 4093 
 4094         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 1000000);
 4095         mbs.param[1] = QENTRY_LEN;
 4096         mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
 4097         mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
 4098         mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
 4099         mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
 4100         MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN, chan);
 4101         isp_mboxcmd(isp, &mbs);
 4102         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 4103                 FC_SCRATCH_RELEASE(isp, chan);
 4104                 return (-1);
 4105         }
 4106         MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN, chan);
 4107         pt = &un.plocal;
 4108         isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
 4109         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 4110                 isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
 4111         }
 4112         if (pt->ctp_status) {
 4113                 FC_SCRATCH_RELEASE(isp, chan);
 4114                 isp_prt(isp, ISP_LOGWARN,
 4115                     "Chan %d Register FC4 Type CT Passthrough returned 0x%x",
 4116                     chan, pt->ctp_status);
 4117                 return (1);
 4118         }
 4119 
 4120         isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct);
 4121         FC_SCRATCH_RELEASE(isp, chan);
 4122 
 4123         if (ct->ct_cmd_resp == LS_RJT) {
 4124                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 4125                     "Chan %d Register FC4 Type rejected", chan);
 4126                 return (-1);
 4127         } else if (ct->ct_cmd_resp == LS_ACC) {
 4128                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
 4129                     "Chan %d Register FC4 Type accepted", chan);
 4130                 return (0);
 4131         } else {
 4132                 isp_prt(isp, ISP_LOGWARN,
 4133                     "Chan %d Register FC4 Type: 0x%x",
 4134                     chan, ct->ct_cmd_resp);
 4135                 return (-1);
 4136         }
 4137 }
 4138 
 4139 static uint16_t
 4140 isp_nxt_handle(ispsoftc_t *isp, int chan, uint16_t handle)
 4141 {
 4142         int i;
 4143         if (handle == NIL_HANDLE) {
 4144                 if (FCPARAM(isp, chan)->isp_topo == TOPO_F_PORT) {
 4145                         handle = 0;
 4146                 } else {
 4147                         handle = SNS_ID+1;
 4148                 }
 4149         } else {
 4150                 handle += 1;
 4151                 if (handle >= FL_ID && handle <= SNS_ID) {
 4152                         handle = SNS_ID+1;
 4153                 }
 4154                 if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
 4155                         handle = NPH_FL_ID+1;
 4156                 }
 4157                 if (ISP_CAP_2KLOGIN(isp)) {
 4158                         if (handle == NPH_MAX_2K) {
 4159                                 handle = 0;
 4160                         }
 4161                 } else {
 4162                         if (handle == NPH_MAX) {
 4163                                 handle = 0;
 4164                         }
 4165                 }
 4166         }
 4167         if (handle == FCPARAM(isp, chan)->isp_loopid) {
 4168                 return (isp_nxt_handle(isp, chan, handle));
 4169         }
 4170         for (i = 0; i < MAX_FC_TARG; i++) {
 4171                 if (FCPARAM(isp, chan)->portdb[i].state ==
 4172                     FC_PORTDB_STATE_NIL) {
 4173                         continue;
 4174                 }
 4175                 if (FCPARAM(isp, chan)->portdb[i].handle == handle) {
 4176                         return (isp_nxt_handle(isp, chan, handle));
 4177                 }
 4178         }
 4179         return (handle);
 4180 }
 4181 
 4182 /*
 4183  * Start a command. Locking is assumed done in the caller.
 4184  */
 4185 
 4186 int
 4187 isp_start(XS_T *xs)
 4188 {
 4189         ispsoftc_t *isp;
 4190         uint32_t handle, cdblen;
 4191         uint8_t local[QENTRY_LEN];
 4192         ispreq_t *reqp;
 4193         void *cdbp, *qep;
 4194         uint16_t *tptr;
 4195         int target, dmaresult, hdlidx = 0;
 4196 
 4197         XS_INITERR(xs);
 4198         isp = XS_ISP(xs);
 4199 
 4200         /*
 4201          * Now make sure we're running.
 4202          */
 4203 
 4204         if (isp->isp_state != ISP_RUNSTATE) {
 4205                 isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
 4206                 XS_SETERR(xs, HBA_BOTCH);
 4207                 return (CMD_COMPLETE);
 4208         }
 4209 
 4210         /*
 4211          * Check command CDB length, etc.. We really are limited to 16 bytes
 4212          * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
 4213          * but probably only if we're running fairly new firmware (we'll
 4214          * let the old f/w choke on an extended command queue entry).
 4215          */
 4216 
 4217         if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
 4218                 isp_prt(isp, ISP_LOGERR, "unsupported cdb length (%d, CDB[0]=0x%x)", XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
 4219                 XS_SETERR(xs, HBA_BOTCH);
 4220                 return (CMD_COMPLETE);
 4221         }
 4222 
 4223         /*
 4224          * Translate the target to device handle as appropriate, checking
 4225          * for correct device state as well.
 4226          */
 4227         target = XS_TGT(xs);
 4228         if (IS_FC(isp)) {
 4229                 fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
 4230 
 4231                 if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
 4232                         XS_SETERR(xs, HBA_SELTIMEOUT);
 4233                         return (CMD_COMPLETE);
 4234                 }
 4235 
 4236                 /*
 4237                  * Try again later.
 4238                  */
 4239                 if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate != LOOP_READY) {
 4240                         return (CMD_RQLATER);
 4241                 }
 4242 
 4243                 if (XS_TGT(xs) >= MAX_FC_TARG) {
 4244                         XS_SETERR(xs, HBA_SELTIMEOUT);
 4245                         return (CMD_COMPLETE);
 4246                 }
 4247 
 4248                 hdlidx = fcp->isp_dev_map[XS_TGT(xs)] - 1;
 4249                 isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d- hdlidx value %d", XS_TGT(xs), hdlidx);
 4250                 if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
 4251                         XS_SETERR(xs, HBA_SELTIMEOUT);
 4252                         return (CMD_COMPLETE);
 4253                 }
 4254                 if (fcp->portdb[hdlidx].state == FC_PORTDB_STATE_ZOMBIE) {
 4255                         return (CMD_RQLATER);
 4256                 }
 4257                 if (fcp->portdb[hdlidx].state != FC_PORTDB_STATE_VALID) {
 4258                         XS_SETERR(xs, HBA_SELTIMEOUT);
 4259                         return (CMD_COMPLETE);
 4260                 }
 4261                 target = fcp->portdb[hdlidx].handle;
 4262                 fcp->portdb[hdlidx].dirty = 1;
 4263         } else {
 4264                 sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
 4265                 if ((sdp->role & ISP_ROLE_INITIATOR) == 0) {
 4266                         XS_SETERR(xs, HBA_SELTIMEOUT);
 4267                         return (CMD_COMPLETE);
 4268                 }
 4269                 if (sdp->update) {
 4270                         isp_spi_update(isp, XS_CHANNEL(xs));
 4271                 }
 4272         }
 4273 
 4274  start_again:
 4275 
 4276         qep = isp_getrqentry(isp);
 4277         if (qep == NULL) {
 4278                 isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
 4279                 XS_SETERR(xs, HBA_BOTCH);
 4280                 return (CMD_EAGAIN);
 4281         }
 4282         XS_SETERR(xs, HBA_NOERROR);
 4283 
 4284         /*
 4285          * Now see if we need to synchronize the ISP with respect to anything.
 4286          * We do dual duty here (cough) for synchronizing for busses other
 4287          * than which we got here to send a command to.
 4288          */
 4289         reqp = (ispreq_t *) local;
 4290         ISP_MEMZERO(local, QENTRY_LEN);
 4291         if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) {
 4292                 if (IS_24XX(isp)) {
 4293                         isp_marker_24xx_t *m = (isp_marker_24xx_t *) reqp;
 4294                         m->mrk_header.rqs_entry_count = 1;
 4295                         m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
 4296                         m->mrk_modifier = SYNC_ALL;
 4297                         isp_put_marker_24xx(isp, m, qep);
 4298                 } else {
 4299                         isp_marker_t *m = (isp_marker_t *) reqp;
 4300                         m->mrk_header.rqs_entry_count = 1;
 4301                         m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
 4302                         m->mrk_target = (XS_CHANNEL(xs) << 7);  /* bus # */
 4303                         m->mrk_modifier = SYNC_ALL;
 4304                         isp_put_marker(isp, m, qep);
 4305                 }
 4306                 ISP_SYNC_REQUEST(isp);
 4307                 ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0);
 4308                 goto start_again;
 4309         }
 4310 
 4311         reqp->req_header.rqs_entry_count = 1;
 4312         if (IS_24XX(isp)) {
 4313                 reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
 4314         } else if (IS_FC(isp)) {
 4315                 reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
 4316         } else {
 4317                 if (XS_CDBLEN(xs) > 12) {
 4318                         reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
 4319                 } else {
 4320                         reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
 4321                 }
 4322         }
 4323 
 4324         if (IS_24XX(isp)) {
 4325                 int ttype;
 4326                 if (XS_TAG_P(xs)) {
 4327                         ttype = XS_TAG_TYPE(xs);
 4328                 } else {
 4329                         if (XS_CDBP(xs)[0] == 0x3) {
 4330                                 ttype = REQFLAG_HTAG;
 4331                         } else {
 4332                                 ttype = REQFLAG_STAG;
 4333                         }
 4334                 }
 4335                 if (ttype == REQFLAG_OTAG) {
 4336                         ttype = FCP_CMND_TASK_ATTR_ORDERED;
 4337                 } else if (ttype == REQFLAG_HTAG) {
 4338                         ttype = FCP_CMND_TASK_ATTR_HEAD;
 4339                 } else {
 4340                         ttype = FCP_CMND_TASK_ATTR_SIMPLE;
 4341                 }
 4342                 ((ispreqt7_t *)reqp)->req_task_attribute = ttype;
 4343         } else if (IS_FC(isp)) {
 4344                 /*
 4345                  * See comment in isp_intr
 4346                  */
 4347                 /* XS_SET_RESID(xs, 0); */
 4348 
 4349                 /*
 4350                  * Fibre Channel always requires some kind of tag.
 4351                  * The Qlogic drivers seem be happy not to use a tag,
 4352                  * but this breaks for some devices (IBM drives).
 4353                  */
 4354                 if (XS_TAG_P(xs)) {
 4355                         ((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
 4356                 } else {
 4357                         /*
 4358                          * If we don't know what tag to use, use HEAD OF QUEUE
 4359                          * for Request Sense or Simple.
 4360                          */
 4361                         if (XS_CDBP(xs)[0] == 0x3)      /* REQUEST SENSE */
 4362                                 ((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
 4363                         else
 4364                                 ((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
 4365                 }
 4366         } else {
 4367                 sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
 4368                 if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) && XS_TAG_P(xs)) {
 4369                         reqp->req_flags = XS_TAG_TYPE(xs);
 4370                 }
 4371         }
 4372 
 4373         tptr = &reqp->req_time;
 4374 
 4375         /*
 4376          * NB: we do not support long CDBs
 4377          */
 4378         cdblen = XS_CDBLEN(xs);
 4379 
 4380         if (IS_SCSI(isp)) {
 4381                 reqp->req_target = target | (XS_CHANNEL(xs) << 7);
 4382                 reqp->req_lun_trn = XS_LUN(xs);
 4383                 cdblen = ISP_MIN(cdblen, sizeof (reqp->req_cdb));
 4384                 cdbp = reqp->req_cdb;
 4385                 reqp->req_cdblen = cdblen;
 4386         } else if (IS_24XX(isp)) {
 4387                 ispreqt7_t *t7 = (ispreqt7_t *)local;
 4388                 fcportdb_t *lp;
 4389 
 4390                 lp = &FCPARAM(isp, XS_CHANNEL(xs))->portdb[hdlidx];
 4391                 t7->req_nphdl = target;
 4392                 t7->req_tidlo = lp->portid;
 4393                 t7->req_tidhi = lp->portid >> 16;
 4394                 t7->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs));
 4395                 if (XS_LUN(xs) > 256) {
 4396                         t7->req_lun[0] = XS_LUN(xs) >> 8;
 4397                         t7->req_lun[0] |= 0x40;
 4398                 }
 4399                 t7->req_lun[1] = XS_LUN(xs);
 4400                 tptr = &t7->req_time;
 4401                 cdbp = t7->req_cdb;
 4402                 cdblen = ISP_MIN(cdblen, sizeof (t7->req_cdb));
 4403         } else if (ISP_CAP_2KLOGIN(isp)) {
 4404                 ispreqt2e_t *t2e = (ispreqt2e_t *)local;
 4405                 t2e->req_target = target;
 4406                 t2e->req_scclun = XS_LUN(xs);
 4407                 cdbp = t2e->req_cdb;
 4408                 cdblen = ISP_MIN(cdblen, sizeof (t2e->req_cdb));
 4409         } else if (ISP_CAP_SCCFW(isp)) {
 4410                 ispreqt2_t *t2 = (ispreqt2_t *)local;
 4411                 t2->req_target = target;
 4412                 t2->req_scclun = XS_LUN(xs);
 4413                 cdbp = t2->req_cdb;
 4414                 cdblen = ISP_MIN(cdblen, sizeof (t2->req_cdb));
 4415         } else {
 4416                 ispreqt2_t *t2 = (ispreqt2_t *)local;
 4417                 t2->req_target = target;
 4418                 t2->req_lun_trn = XS_LUN(xs);
 4419                 cdbp = t2->req_cdb;
 4420                 cdblen = ISP_MIN(cdblen, sizeof (t2->req_cdb));
 4421         }
 4422         ISP_MEMCPY(cdbp, XS_CDBP(xs), cdblen);
 4423 
 4424         *tptr = XS_TIME(xs) / 1000;
 4425         if (*tptr == 0 && XS_TIME(xs)) {
 4426                 *tptr = 1;
 4427         }
 4428         if (IS_24XX(isp) && *tptr > 0x1999) {
 4429                 *tptr = 0x1999;
 4430         }
 4431 
 4432         if (isp_allocate_xs(isp, xs, &handle)) {
 4433                 isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
 4434                 XS_SETERR(xs, HBA_BOTCH);
 4435                 return (CMD_EAGAIN);
 4436         }
 4437         /* Whew. Thankfully the same for type 7 requests */
 4438         reqp->req_handle = handle;
 4439 
 4440         /*
 4441          * Set up DMA and/or do any platform dependent swizzling of the request entry
 4442          * so that the Qlogic F/W understands what is being asked of it.
 4443          *
 4444          * The callee is responsible for adding all requests at this point.
 4445          */
 4446         dmaresult = ISP_DMASETUP(isp, xs, reqp);
 4447         if (dmaresult != CMD_QUEUED) {
 4448                 isp_destroy_handle(isp, handle);
 4449                 /*
 4450                  * dmasetup sets actual error in packet, and
 4451                  * return what we were given to return.
 4452                  */
 4453                 return (dmaresult);
 4454         }
 4455         isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "START cmd cdb[0]=0x%x datalen %ld", XS_CDBP(xs)[0], (long) XS_XFRLEN(xs));
 4456         isp->isp_nactive++;
 4457         return (CMD_QUEUED);
 4458 }
 4459 
 4460 /*
 4461  * isp control
 4462  * Locks (ints blocked) assumed held.
 4463  */
 4464 
 4465 int
 4466 isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
 4467 {
 4468         XS_T *xs;
 4469         mbreg_t *mbr, mbs;
 4470         int chan, tgt;
 4471         uint32_t handle;
 4472         va_list ap;
 4473 
 4474         switch (ctl) {
 4475         case ISPCTL_RESET_BUS:
 4476                 /*
 4477                  * Issue a bus reset.
 4478                  */
 4479                 if (IS_24XX(isp)) {
 4480                         isp_prt(isp, ISP_LOGWARN, "RESET BUS NOT IMPLEMENTED");
 4481                         break;
 4482                 } else if (IS_FC(isp)) {
 4483                         mbs.param[1] = 10;
 4484                         chan = 0;
 4485                 } else {
 4486                         va_start(ap, ctl);
 4487                         chan = va_arg(ap, int);
 4488                         va_end(ap);
 4489                         mbs.param[1] = SDPARAM(isp, chan)->isp_bus_reset_delay;
 4490                         if (mbs.param[1] < 2) {
 4491                                 mbs.param[1] = 2;
 4492                         }
 4493                         mbs.param[2] = chan;
 4494                 }
 4495                 MBSINIT(&mbs, MBOX_BUS_RESET, MBLOGALL, 0);
 4496                 ISP_SET_SENDMARKER(isp, chan, 1);
 4497                 isp_mboxcmd(isp, &mbs);
 4498                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 4499                         break;
 4500                 }
 4501                 isp_prt(isp, ISP_LOGINFO,
 4502                     "driver initiated bus reset of bus %d", chan);
 4503                 return (0);
 4504 
 4505         case ISPCTL_RESET_DEV:
 4506                 va_start(ap, ctl);
 4507                 chan = va_arg(ap, int);
 4508                 tgt = va_arg(ap, int);
 4509                 va_end(ap);
 4510                 if (IS_24XX(isp)) {
 4511                         uint8_t local[QENTRY_LEN];
 4512                         isp24xx_tmf_t *tmf;
 4513                         isp24xx_statusreq_t *sp;
 4514                         fcparam *fcp = FCPARAM(isp, chan);
 4515                         fcportdb_t *lp;
 4516                         int hdlidx;
 4517 
 4518                         hdlidx = fcp->isp_dev_map[tgt] - 1;
 4519                         if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
 4520                                 isp_prt(isp, ISP_LOGWARN,
 4521                                     "Chan %d bad handle %d trying to reset"
 4522                                     "target %d", chan, hdlidx, tgt);
 4523                                 break;
 4524                         }
 4525                         lp = &fcp->portdb[hdlidx];
 4526                         if (lp->state != FC_PORTDB_STATE_VALID) {
 4527                                 isp_prt(isp, ISP_LOGWARN,
 4528                                     "Chan %d handle %d for abort of target %d "
 4529                                     "no longer valid", chan,
 4530                                     hdlidx, tgt);
 4531                                 break;
 4532                         }
 4533 
 4534                         tmf = (isp24xx_tmf_t *) local;
 4535                         ISP_MEMZERO(tmf, QENTRY_LEN);
 4536                         tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
 4537                         tmf->tmf_header.rqs_entry_count = 1;
 4538                         tmf->tmf_nphdl = lp->handle;
 4539                         tmf->tmf_delay = 2;
 4540                         tmf->tmf_timeout = 2;
 4541                         tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
 4542                         tmf->tmf_tidlo = lp->portid;
 4543                         tmf->tmf_tidhi = lp->portid >> 16;
 4544                         tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
 4545                         isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
 4546                         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
 4547                         mbs.param[1] = QENTRY_LEN;
 4548                         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 4549                         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 4550                         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 4551                         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 4552 
 4553                         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 4554                                 isp_prt(isp, ISP_LOGERR, sacq);
 4555                                 break;
 4556                         }
 4557                         isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch);
 4558                         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN, chan);
 4559                         fcp->sendmarker = 1;
 4560                         isp_mboxcmd(isp, &mbs);
 4561                         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 4562                                 FC_SCRATCH_RELEASE(isp, chan);
 4563                                 break;
 4564                         }
 4565                         MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
 4566                             QENTRY_LEN, chan);
 4567                         sp = (isp24xx_statusreq_t *) local;
 4568                         isp_get_24xx_response(isp,
 4569                             &((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp);
 4570                         FC_SCRATCH_RELEASE(isp, chan);
 4571                         if (sp->req_completion_status == 0) {
 4572                                 return (0);
 4573                         }
 4574                         isp_prt(isp, ISP_LOGWARN,
 4575                             "Chan %d reset of target %d returned 0x%x",
 4576                             chan, tgt, sp->req_completion_status);
 4577                         break;
 4578                 } else if (IS_FC(isp)) {
 4579                         if (ISP_CAP_2KLOGIN(isp)) {
 4580                                 mbs.param[1] = tgt;
 4581                                 mbs.ibits = (1 << 10);
 4582                         } else {
 4583                                 mbs.param[1] = (tgt << 8);
 4584                         }
 4585                 } else {
 4586                         mbs.param[1] = (chan << 15) | (tgt << 8);
 4587                 }
 4588                 MBSINIT(&mbs, MBOX_ABORT_TARGET, MBLOGALL, 0);
 4589                 mbs.param[2] = 3;       /* 'delay', in seconds */
 4590                 isp_mboxcmd(isp, &mbs);
 4591                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 4592                         break;
 4593                 }
 4594                 isp_prt(isp, ISP_LOGINFO,
 4595                     "Target %d on Bus %d Reset Succeeded", tgt, chan);
 4596                 ISP_SET_SENDMARKER(isp, chan, 1);
 4597                 return (0);
 4598 
 4599         case ISPCTL_ABORT_CMD:
 4600                 va_start(ap, ctl);
 4601                 xs = va_arg(ap, XS_T *);
 4602                 va_end(ap);
 4603 
 4604                 tgt = XS_TGT(xs);
 4605                 chan = XS_CHANNEL(xs);
 4606 
 4607                 handle = isp_find_handle(isp, xs);
 4608                 if (handle == 0) {
 4609                         isp_prt(isp, ISP_LOGWARN,
 4610                             "cannot find handle for command to abort");
 4611                         break;
 4612                 }
 4613                 if (IS_24XX(isp)) {
 4614                         isp24xx_abrt_t local, *ab = &local, *ab2;
 4615                         fcparam *fcp;
 4616                         fcportdb_t *lp;
 4617                         int hdlidx;
 4618 
 4619                         fcp = FCPARAM(isp, chan);
 4620                         hdlidx = fcp->isp_dev_map[tgt] - 1;
 4621                         if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
 4622                                 isp_prt(isp, ISP_LOGWARN,
 4623                                     "Chan %d bad handle %d trying to abort"
 4624                                     "target %d", chan, hdlidx, tgt);
 4625                                 break;
 4626                         }
 4627                         lp = &fcp->portdb[hdlidx];
 4628                         if (lp->state != FC_PORTDB_STATE_VALID) {
 4629                                 isp_prt(isp, ISP_LOGWARN,
 4630                                     "Chan %d handle %d for abort of target %d "
 4631                                     "no longer valid", chan, hdlidx, tgt);
 4632                                 break;
 4633                         }
 4634                         isp_prt(isp, ISP_LOGALL,
 4635                             "Chan %d Abort Cmd for N-Port 0x%04x @ Port "
 4636                             "0x%06x %p", chan, lp->handle, lp->portid, xs);
 4637                         ISP_MEMZERO(ab, QENTRY_LEN);
 4638                         ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
 4639                         ab->abrt_header.rqs_entry_count = 1;
 4640                         ab->abrt_handle = lp->handle;
 4641                         ab->abrt_cmd_handle = handle;
 4642                         ab->abrt_tidlo = lp->portid;
 4643                         ab->abrt_tidhi = lp->portid >> 16;
 4644                         ab->abrt_vpidx = ISP_GET_VPIDX(isp, chan);
 4645 
 4646                         ISP_MEMZERO(&mbs, sizeof (mbs));
 4647                         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
 4648                         mbs.param[1] = QENTRY_LEN;
 4649                         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 4650                         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 4651                         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 4652                         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 4653 
 4654                         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 4655                                 isp_prt(isp, ISP_LOGERR, sacq);
 4656                                 break;
 4657                         }
 4658                         isp_put_24xx_abrt(isp, ab, fcp->isp_scratch);
 4659                         ab2 = (isp24xx_abrt_t *)
 4660                             &((uint8_t *)fcp->isp_scratch)[QENTRY_LEN];
 4661                         ab2->abrt_nphdl = 0xdeaf;
 4662                         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, 2 * QENTRY_LEN, chan);
 4663                         isp_mboxcmd(isp, &mbs);
 4664                         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 4665                                 FC_SCRATCH_RELEASE(isp, chan);
 4666                                 break;
 4667                         }
 4668                         MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
 4669                             QENTRY_LEN, chan);
 4670                         isp_get_24xx_abrt(isp, ab2, ab);
 4671                         FC_SCRATCH_RELEASE(isp, chan);
 4672                         if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY) {
 4673                                 return (0);
 4674                         }
 4675                         isp_prt(isp, ISP_LOGWARN,
 4676                             "Chan %d handle %d abort returned 0x%x", chan,
 4677                             hdlidx, ab->abrt_nphdl);
 4678                         break;
 4679                 } else if (IS_FC(isp)) {
 4680                         if (ISP_CAP_SCCFW(isp)) {
 4681                                 if (ISP_CAP_2KLOGIN(isp)) {
 4682                                         mbs.param[1] = tgt;
 4683                                 } else {
 4684                                         mbs.param[1] = tgt << 8;
 4685                                 }
 4686                                 mbs.param[6] = XS_LUN(xs);
 4687                         } else {
 4688                                 mbs.param[1] = tgt << 8 | XS_LUN(xs);
 4689                         }
 4690                 } else {
 4691                         mbs.param[1] = (chan << 15) | (tgt << 8) | XS_LUN(xs);
 4692                 }
 4693                 MBSINIT(&mbs, MBOX_ABORT, MBLOGALL & ~MBOX_COMMAND_ERROR, 0);
 4694                 mbs.param[2] = handle;
 4695                 isp_mboxcmd(isp, &mbs);
 4696                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 4697                         break;
 4698                 }
 4699                 return (0);
 4700 
 4701         case ISPCTL_UPDATE_PARAMS:
 4702 
 4703                 va_start(ap, ctl);
 4704                 chan = va_arg(ap, int);
 4705                 va_end(ap);
 4706                 isp_spi_update(isp, chan);
 4707                 return (0);
 4708 
 4709         case ISPCTL_FCLINK_TEST:
 4710 
 4711                 if (IS_FC(isp)) {
 4712                         int usdelay;
 4713                         va_start(ap, ctl);
 4714                         chan = va_arg(ap, int);
 4715                         usdelay = va_arg(ap, int);
 4716                         va_end(ap);
 4717                         if (usdelay == 0) {
 4718                                 usdelay =  250000;
 4719                         }
 4720                         return (isp_fclink_test(isp, chan, usdelay));
 4721                 }
 4722                 break;
 4723 
 4724         case ISPCTL_SCAN_FABRIC:
 4725 
 4726                 if (IS_FC(isp)) {
 4727                         va_start(ap, ctl);
 4728                         chan = va_arg(ap, int);
 4729                         va_end(ap);
 4730                         return (isp_scan_fabric(isp, chan));
 4731                 }
 4732                 break;
 4733 
 4734         case ISPCTL_SCAN_LOOP:
 4735 
 4736                 if (IS_FC(isp)) {
 4737                         va_start(ap, ctl);
 4738                         chan = va_arg(ap, int);
 4739                         va_end(ap);
 4740                         return (isp_scan_loop(isp, chan));
 4741                 }
 4742                 break;
 4743 
 4744         case ISPCTL_PDB_SYNC:
 4745 
 4746                 if (IS_FC(isp)) {
 4747                         va_start(ap, ctl);
 4748                         chan = va_arg(ap, int);
 4749                         va_end(ap);
 4750                         return (isp_pdb_sync(isp, chan));
 4751                 }
 4752                 break;
 4753 
 4754         case ISPCTL_SEND_LIP:
 4755 
 4756                 if (IS_FC(isp) && !IS_24XX(isp)) {
 4757                         MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
 4758                         if (ISP_CAP_2KLOGIN(isp)) {
 4759                                 mbs.ibits = (1 << 10);
 4760                         }
 4761                         isp_mboxcmd(isp, &mbs);
 4762                         if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 4763                                 return (0);
 4764                         }
 4765                 }
 4766                 break;
 4767 
 4768         case ISPCTL_GET_PDB:
 4769                 if (IS_FC(isp)) {
 4770                         isp_pdb_t *pdb;
 4771                         va_start(ap, ctl);
 4772                         chan = va_arg(ap, int);
 4773                         tgt = va_arg(ap, int);
 4774                         pdb = va_arg(ap, isp_pdb_t *);
 4775                         va_end(ap);
 4776                         return (isp_getpdb(isp, chan, tgt, pdb, 1));
 4777                 }
 4778                 break;
 4779 
 4780         case ISPCTL_GET_NAMES:
 4781         {
 4782                 uint64_t *wwnn, *wwnp;
 4783                 va_start(ap, ctl);
 4784                 chan = va_arg(ap, int);
 4785                 tgt = va_arg(ap, int);
 4786                 wwnn = va_arg(ap, uint64_t *);
 4787                 wwnp = va_arg(ap, uint64_t *);
 4788                 va_end(ap);
 4789                 if (wwnn == NULL && wwnp == NULL) {
 4790                         break;
 4791                 }
 4792                 if (wwnn) {
 4793                         *wwnn = isp_get_wwn(isp, chan, tgt, 1);
 4794                         if (*wwnn == INI_NONE) {
 4795                                 break;
 4796                         }
 4797                 }
 4798                 if (wwnp) {
 4799                         *wwnp = isp_get_wwn(isp, chan, tgt, 0);
 4800                         if (*wwnp == INI_NONE) {
 4801                                 break;
 4802                         }
 4803                 }
 4804                 return (0);
 4805         }
 4806         case ISPCTL_RUN_MBOXCMD:
 4807         {
 4808                 va_start(ap, ctl);
 4809                 mbr = va_arg(ap, mbreg_t *);
 4810                 va_end(ap);
 4811                 isp_mboxcmd(isp, mbr);
 4812                 return (0);
 4813         }
 4814         case ISPCTL_PLOGX:
 4815         {
 4816                 isp_plcmd_t *p;
 4817                 int r;
 4818 
 4819                 va_start(ap, ctl);
 4820                 p = va_arg(ap, isp_plcmd_t *);
 4821                 va_end(ap);
 4822 
 4823                 if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
 4824                         return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0));
 4825                 }
 4826                 do {
 4827                         p->handle = isp_nxt_handle(isp, p->channel, p->handle);
 4828                         r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0);
 4829                         if ((r & 0xffff) == MBOX_PORT_ID_USED) {
 4830                                 p->handle = r >> 16;
 4831                                 r = 0;
 4832                                 break;
 4833                         }
 4834                 } while ((r & 0xffff) == MBOX_LOOP_ID_USED);
 4835                 return (r);
 4836         }
 4837         default:
 4838                 isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
 4839                 break;
 4840 
 4841         }
 4842         return (-1);
 4843 }
 4844 
 4845 /*
 4846  * Interrupt Service Routine(s).
 4847  *
 4848  * External (OS) framework has done the appropriate locking,
 4849  * and the locking will be held throughout this function.
 4850  */
 4851 
 4852 /*
 4853  * Limit our stack depth by sticking with the max likely number
 4854  * of completions on a request queue at any one time.
 4855  */
 4856 #ifndef MAX_REQUESTQ_COMPLETIONS
 4857 #define MAX_REQUESTQ_COMPLETIONS        32
 4858 #endif
 4859 
 4860 void
 4861 isp_intr(ispsoftc_t *isp, uint32_t isr, uint16_t sema, uint16_t mbox)
 4862 {
 4863         XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
 4864         uint32_t iptr, optr, junk;
 4865         int i, nlooked = 0, ndone = 0;
 4866 
 4867 again:
 4868         optr = isp->isp_residx;
 4869         /*
 4870          * Is this a mailbox related interrupt?
 4871          * The mailbox semaphore will be nonzero if so.
 4872          */
 4873         if (sema) {
 4874  fmbox:
 4875                 if (mbox & MBOX_COMMAND_COMPLETE) {
 4876                         isp->isp_intmboxc++;
 4877                         if (isp->isp_mboxbsy) {
 4878                                 int obits = isp->isp_obits;
 4879                                 isp->isp_mboxtmp[0] = mbox;
 4880                                 for (i = 1; i < MAX_MAILBOX(isp); i++) {
 4881                                         if ((obits & (1 << i)) == 0) {
 4882                                                 continue;
 4883                                         }
 4884                                         isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
 4885                                 }
 4886                                 if (isp->isp_mbxwrk0) {
 4887                                         if (isp_mbox_continue(isp) == 0) {
 4888                                                 return;
 4889                                         }
 4890                                 }
 4891                                 MBOX_NOTIFY_COMPLETE(isp);
 4892                         } else {
 4893                                 isp_prt(isp, ISP_LOGWARN, "mailbox cmd (0x%x) with no waiters", mbox);
 4894                         }
 4895                 } else {
 4896                         i = IS_FC(isp)? isp_parse_async_fc(isp, mbox) : isp_parse_async(isp, mbox);
 4897                         if (i < 0) {
 4898                                 return;
 4899                         }
 4900                 }
 4901                 if ((IS_FC(isp) && mbox != ASYNC_RIOZIO_STALL) || isp->isp_state != ISP_RUNSTATE) {
 4902                         goto out;
 4903                 }
 4904         }
 4905 
 4906         /*
 4907          * We can't be getting this now.
 4908          */
 4909         if (isp->isp_state != ISP_RUNSTATE) {
 4910                 /*
 4911                  * This seems to happen to 23XX and 24XX cards- don't know why.
 4912                  */
 4913                  if (isp->isp_mboxbsy && isp->isp_lastmbxcmd == MBOX_ABOUT_FIRMWARE) {
 4914                         goto fmbox;
 4915                 }
 4916                 isp_prt(isp, ISP_LOGINFO, "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
 4917                 /*
 4918                  * Thank you very much!  *Burrrp*!
 4919                  */
 4920                 ISP_WRITE(isp, isp->isp_respoutrp, ISP_READ(isp, isp->isp_respinrp));
 4921                 if (IS_24XX(isp)) {
 4922                         ISP_DISABLE_INTS(isp);
 4923                 }
 4924                 goto out;
 4925         }
 4926 
 4927 #ifdef  ISP_TARGET_MODE
 4928         /*
 4929          * Check for ATIO Queue entries.
 4930          */
 4931         if (IS_24XX(isp)) {
 4932                 iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
 4933                 optr = ISP_READ(isp, BIU2400_ATIO_RSPOUTP);
 4934 
 4935                 while (optr != iptr) {
 4936                         uint8_t qe[QENTRY_LEN];
 4937                         isphdr_t *hp;
 4938                         uint32_t oop;
 4939                         void *addr;
 4940 
 4941                         oop = optr;
 4942                         MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1);
 4943                         addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
 4944                         isp_get_hdr(isp, addr, (isphdr_t *)qe);
 4945                         hp = (isphdr_t *)qe;
 4946                         switch (hp->rqs_entry_type) {
 4947                         case RQSTYPE_NOTIFY:
 4948                         case RQSTYPE_ATIO:
 4949                                 (void) isp_target_notify(isp, addr, &oop);
 4950                                 break;
 4951                         default:
 4952                                 isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
 4953                                 break;
 4954                         }
 4955                         optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
 4956                         ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
 4957                 }
 4958                 optr = isp->isp_residx;
 4959         }
 4960 #endif
 4961 
 4962         /*
 4963          * Get the current Response Queue Out Pointer.
 4964          *
 4965          * If we're a 2300 or 2400, we can ask what hardware what it thinks.
 4966          */
 4967         if (IS_23XX(isp) || IS_24XX(isp)) {
 4968                 optr = ISP_READ(isp, isp->isp_respoutrp);
 4969                 /*
 4970                  * Debug: to be taken out eventually
 4971                  */
 4972                 if (isp->isp_residx != optr) {
 4973                         isp_prt(isp, ISP_LOGINFO, "isp_intr: hard optr=%x, soft optr %x", optr, isp->isp_residx);
 4974                         isp->isp_residx = optr;
 4975                 }
 4976         } else {
 4977                 optr = isp->isp_residx;
 4978         }
 4979 
 4980         /*
 4981          * You *must* read the Response Queue In Pointer
 4982          * prior to clearing the RISC interrupt.
 4983          *
 4984          * Debounce the 2300 if revision less than 2.
 4985          */
 4986         if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
 4987                 i = 0;
 4988                 do {
 4989                         iptr = ISP_READ(isp, isp->isp_respinrp);
 4990                         junk = ISP_READ(isp, isp->isp_respinrp);
 4991                 } while (junk != iptr && ++i < 1000);
 4992 
 4993                 if (iptr != junk) {
 4994                         isp_prt(isp, ISP_LOGWARN, "Response Queue Out Pointer Unstable (%x, %x)", iptr, junk);
 4995                         goto out;
 4996                 }
 4997         } else {
 4998                 iptr = ISP_READ(isp, isp->isp_respinrp);
 4999         }
 5000         isp->isp_resodx = iptr;
 5001 
 5002 
 5003         if (optr == iptr && sema == 0) {
 5004                 /*
 5005                  * There are a lot of these- reasons unknown- mostly on
 5006                  * faster Alpha machines.
 5007                  *
 5008                  * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
 5009                  * make sure the old interrupt went away (to avoid 'ringing'
 5010                  * effects), but that didn't stop this from occurring.
 5011                  */
 5012                 if (IS_24XX(isp)) {
 5013                         junk = 0;
 5014                 } else if (IS_23XX(isp)) {
 5015                         ISP_DELAY(100);
 5016                         iptr = ISP_READ(isp, isp->isp_respinrp);
 5017                         junk = ISP_READ(isp, BIU_R2HSTSLO);
 5018                 } else {
 5019                         junk = ISP_READ(isp, BIU_ISR);
 5020                 }
 5021                 if (optr == iptr) {
 5022                         if (IS_23XX(isp) || IS_24XX(isp)) {
 5023                                 ;
 5024                         } else {
 5025                                 sema = ISP_READ(isp, BIU_SEMA);
 5026                                 mbox = ISP_READ(isp, OUTMAILBOX0);
 5027                                 if ((sema & 0x3) && (mbox & 0x8000)) {
 5028                                         goto again;
 5029                                 }
 5030                         }
 5031                         isp->isp_intbogus++;
 5032                         isp_prt(isp, ISP_LOGDEBUG1, "bogus intr- isr %x (%x) iptr %x optr %x", isr, junk, iptr, optr);
 5033                 }
 5034         }
 5035         isp->isp_resodx = iptr;
 5036 
 5037         while (optr != iptr) {
 5038                 uint8_t qe[QENTRY_LEN];
 5039                 ispstatusreq_t *sp = (ispstatusreq_t *) qe;
 5040                 isphdr_t *hp;
 5041                 int buddaboom, etype, scsi_status, completion_status;
 5042                 int req_status_flags, req_state_flags;
 5043                 uint8_t *snsp, *resp;
 5044                 uint32_t rlen, slen;
 5045                 long resid;
 5046                 uint16_t oop;
 5047 
 5048                 hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
 5049                 oop = optr;
 5050                 optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
 5051                 nlooked++;
 5052  read_again:
 5053                 buddaboom = req_status_flags = req_state_flags = 0;
 5054                 resid = 0L;
 5055 
 5056                 /*
 5057                  * Synchronize our view of this response queue entry.
 5058                  */
 5059                 MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN, -1);
 5060                 isp_get_hdr(isp, hp, &sp->req_header);
 5061                 etype = sp->req_header.rqs_entry_type;
 5062 
 5063                 if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) {
 5064                         isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe;
 5065                         isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp2);
 5066                         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 5067                                 isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp2);
 5068                         }
 5069                         scsi_status = sp2->req_scsi_status;
 5070                         completion_status = sp2->req_completion_status;
 5071                         req_state_flags = 0;
 5072                         resid = sp2->req_resid;
 5073                 } else if (etype == RQSTYPE_RESPONSE) {
 5074                         isp_get_response(isp, (ispstatusreq_t *) hp, sp);
 5075                         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 5076                                 isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp);
 5077                         }
 5078                         scsi_status = sp->req_scsi_status;
 5079                         completion_status = sp->req_completion_status;
 5080                         req_status_flags = sp->req_status_flags;
 5081                         req_state_flags = sp->req_state_flags;
 5082                         resid = sp->req_resid;
 5083                 } else if (etype == RQSTYPE_RIO1) {
 5084                         isp_rio1_t *rio = (isp_rio1_t *) qe;
 5085                         isp_get_rio1(isp, (isp_rio1_t *) hp, rio);
 5086                         if (isp->isp_dblev & ISP_LOGDEBUG1) {
 5087                                 isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, rio);
 5088                         }
 5089                         for (i = 0; i < rio->req_header.rqs_seqno; i++) {
 5090                                 isp_fastpost_complete(isp, rio->req_handles[i]);
 5091                         }
 5092                         if (isp->isp_fpcchiwater < rio->req_header.rqs_seqno) {
 5093                                 isp->isp_fpcchiwater = rio->req_header.rqs_seqno;
 5094                         }
 5095                         ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
 5096                         continue;
 5097                 } else if (etype == RQSTYPE_RIO2) {
 5098                         isp_prt(isp, ISP_LOGERR, "dropping RIO2 response\n");
 5099                         ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
 5100                         continue;
 5101                 } else {
 5102                         /*
 5103                          * Somebody reachable via isp_handle_other_response
 5104                          * may have updated the response queue pointers for
 5105                          * us, so we reload our goal index.
 5106                          */
 5107                         int r;
 5108                         uint32_t tsto = oop;
 5109                         r = isp_handle_other_response(isp, etype, hp, &tsto);
 5110                         if (r < 0) {
 5111                                 goto read_again;
 5112                         }
 5113                         /*
 5114                          * If somebody updated the output pointer, then reset
 5115                          * optr to be one more than the updated amount.
 5116                          */
 5117                         if (tsto != oop) {
 5118                                 optr = ISP_NXT_QENTRY(tsto,
 5119                                     RESULT_QUEUE_LEN(isp));
 5120                         }
 5121                         if (r > 0) {
 5122                                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
 5123                                 ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
 5124                                 continue;
 5125                         }
 5126 
 5127                         /*
 5128                          * After this point, we'll just look at the header as
 5129                          * we don't know how to deal with the rest of the
 5130                          * response.
 5131                          */
 5132 
 5133                         /*
 5134                          * It really has to be a bounced request just copied
 5135                          * from the request queue to the response queue. If
 5136                          * not, something bad has happened.
 5137                          */
 5138                         if (etype != RQSTYPE_REQUEST) {
 5139                                 isp_prt(isp, ISP_LOGERR, notresp,
 5140                                     etype, oop, optr, nlooked);
 5141                                 isp_print_bytes(isp,
 5142                                     "Request Queue Entry", QENTRY_LEN, sp);
 5143                                 ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
 5144                                 continue;
 5145                         }
 5146                         buddaboom = 1;
 5147                         scsi_status = sp->req_scsi_status;
 5148                         completion_status = sp->req_completion_status;
 5149                         req_status_flags = sp->req_status_flags;
 5150                         req_state_flags = sp->req_state_flags;
 5151                         resid = sp->req_resid;
 5152                 }
 5153 
 5154                 if (sp->req_header.rqs_flags & RQSFLAG_MASK) {
 5155                         if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
 5156                                 isp_print_bytes(isp, "unexpected continuation segment", QENTRY_LEN, sp);
 5157                                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
 5158                                 continue;
 5159                         }
 5160                         if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
 5161                                 isp_prt(isp, ISP_LOGDEBUG0, "internal queues full");
 5162                                 /*
 5163                                  * We'll synthesize a QUEUE FULL message below.
 5164                                  */
 5165                         }
 5166                         if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
 5167                                 isp_print_bytes(isp, "bad header flag", QENTRY_LEN, sp);
 5168                                 buddaboom++;
 5169                         }
 5170                         if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
 5171                                 isp_print_bytes(isp, "bad request packet", QENTRY_LEN, sp);
 5172                                 buddaboom++;
 5173                         }
 5174                         if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
 5175                                 isp_print_bytes(isp, "invalid entry count", QENTRY_LEN, sp);
 5176                                 buddaboom++;
 5177                         }
 5178                         if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
 5179                                 isp_print_bytes(isp, "invalid IOCB ordering", QENTRY_LEN, sp);
 5180                                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
 5181                                 continue;
 5182                         }
 5183                 }
 5184 
 5185                 if (!ISP_VALID_HANDLE(isp, sp->req_handle)) {
 5186                         isp_prt(isp, ISP_LOGERR, "bad request handle 0x%x (iocb type 0x%x)", sp->req_handle, etype);
 5187                         ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
 5188                         ISP_WRITE(isp, isp->isp_respoutrp, optr);
 5189                         continue;
 5190                 }
 5191                 xs = isp_find_xs(isp, sp->req_handle);
 5192                 if (xs == NULL) {
 5193                         uint8_t ts = completion_status & 0xff;
 5194                         /*
 5195                          * Only whine if this isn't the expected fallout of
 5196                          * aborting the command or resetting the target.
 5197                          */
 5198                         if (etype != RQSTYPE_RESPONSE) {
 5199                                 isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (type 0x%x)", sp->req_handle, etype);
 5200                         } else if (ts != RQCS_ABORTED && ts != RQCS_RESET_OCCURRED) {
 5201                                 isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", sp->req_handle, ts);
 5202                         }
 5203                         ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
 5204                         ISP_WRITE(isp, isp->isp_respoutrp, optr);
 5205                         continue;
 5206                 }
 5207                 if (req_status_flags & RQSTF_BUS_RESET) {
 5208                         XS_SETERR(xs, HBA_BUSRESET);
 5209                         ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
 5210                 }
 5211                 if (buddaboom) {
 5212                         XS_SETERR(xs, HBA_BOTCH);
 5213                 }
 5214 
 5215                 resp = NULL;
 5216                 rlen = 0;
 5217                 snsp = NULL;
 5218                 slen = 0;
 5219                 if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) {
 5220                         resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
 5221                         rlen = ((isp24xx_statusreq_t *)sp)->req_response_len;
 5222                 } else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) {
 5223                         resp = sp->req_response;
 5224                         rlen = sp->req_response_len;
 5225                 }
 5226                 if (IS_FC(isp) && (scsi_status & RQCS_SV) != 0) {
 5227                         /*
 5228                          * Fibre Channel F/W doesn't say we got status
 5229                          * if there's Sense Data instead. I guess they
 5230                          * think it goes w/o saying.
 5231                          */
 5232                         req_state_flags |= RQSF_GOT_STATUS|RQSF_GOT_SENSE;
 5233                         if (IS_24XX(isp)) {
 5234                                 snsp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
 5235                                 snsp += rlen;
 5236                                 slen = ((isp24xx_statusreq_t *)sp)->req_sense_len;
 5237                         } else {
 5238                                 snsp = sp->req_sense_data;
 5239                                 slen = sp->req_sense_len;
 5240                         }
 5241                 } else if (IS_SCSI(isp) && (req_state_flags & RQSF_GOT_SENSE)) {
 5242                         snsp = sp->req_sense_data;
 5243                         slen = sp->req_sense_len;
 5244                 }
 5245                 if (req_state_flags & RQSF_GOT_STATUS) {
 5246                         *XS_STSP(xs) = scsi_status & 0xff;
 5247                 }
 5248 
 5249                 switch (etype) {
 5250                 case RQSTYPE_RESPONSE:
 5251                         if (resp && rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
 5252                                 const char *ptr;
 5253                                 char lb[64];
 5254                                 const char *rnames[6] = {
 5255                                         "Task Management Function Done",
 5256                                         "Data Length Differs From Burst Length",
 5257                                         "Invalid FCP Cmnd",
 5258                                         "FCP DATA RO mismatch with FCP DATA_XFR_RDY RO",
 5259                                         "Task Management Function Rejected",
 5260                                         "Task Management Function Failed",
 5261                                 };
 5262                                 if (resp[FCP_RSPNS_CODE_OFFSET] > 5) {
 5263                                         ISP_SNPRINTF(lb, sizeof lb, "Unknown FCP Response Code 0x%x", resp[FCP_RSPNS_CODE_OFFSET]);
 5264                                         ptr = lb;
 5265                                 } else {
 5266                                         ptr = rnames[resp[FCP_RSPNS_CODE_OFFSET]];
 5267                                 }
 5268                                 isp_xs_prt(isp, xs, ISP_LOGWARN, "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x", rlen, ptr, XS_CDBP(xs)[0] & 0xff);
 5269                                 if (resp[FCP_RSPNS_CODE_OFFSET] != 0) {
 5270                                         XS_SETERR(xs, HBA_BOTCH);
 5271                                 }
 5272                         }
 5273                         if (IS_24XX(isp)) {
 5274                                 isp_parse_status_24xx(isp, (isp24xx_statusreq_t *)sp, xs, &resid);
 5275                         } else {
 5276                                 isp_parse_status(isp, (void *)sp, xs, &resid);
 5277                         }
 5278                         if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) && (*XS_STSP(xs) == SCSI_BUSY)) {
 5279                                 XS_SETERR(xs, HBA_TGTBSY);
 5280                         }
 5281                         if (IS_SCSI(isp)) {
 5282                                 XS_SET_RESID(xs, resid);
 5283                                 /*
 5284                                  * A new synchronous rate was negotiated for
 5285                                  * this target. Mark state such that we'll go
 5286                                  * look up that which has changed later.
 5287                                  */
 5288                                 if (req_status_flags & RQSTF_NEGOTIATION) {
 5289                                         int t = XS_TGT(xs);
 5290                                         sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
 5291                                         sdp->isp_devparam[t].dev_refresh = 1;
 5292                                         sdp->update = 1;
 5293                                 }
 5294                         } else {
 5295                                 if (req_status_flags & RQSF_XFER_COMPLETE) {
 5296                                         XS_SET_RESID(xs, 0);
 5297                                 } else if (scsi_status & RQCS_RESID) {
 5298                                         XS_SET_RESID(xs, resid);
 5299                                 } else {
 5300                                         XS_SET_RESID(xs, 0);
 5301                                 }
 5302                         }
 5303                         if (snsp && slen) {
 5304                                 XS_SAVE_SENSE(xs, snsp, slen);
 5305                         } else if ((req_status_flags & RQSF_GOT_STATUS) && (scsi_status & 0xff) == SCSI_CHECK && IS_FC(isp)) {
 5306                                 isp_prt(isp, ISP_LOGWARN, "CHECK CONDITION w/o sense data for CDB=0x%x", XS_CDBP(xs)[0] & 0xff);
 5307                                 isp_print_bytes(isp, "CC with no Sense", QENTRY_LEN, qe);
 5308                         }
 5309                         isp_prt(isp, ISP_LOGDEBUG2, "asked for %ld got raw resid %ld settled for %ld", (long) XS_XFRLEN(xs), resid, (long) XS_GET_RESID(xs));
 5310                         break;
 5311                 case RQSTYPE_REQUEST:
 5312                 case RQSTYPE_A64:
 5313                 case RQSTYPE_T2RQS:
 5314                 case RQSTYPE_T3RQS:
 5315                 case RQSTYPE_T7RQS:
 5316                         if (!IS_24XX(isp) && (sp->req_header.rqs_flags & RQSFLAG_FULL)) {
 5317                                 /*
 5318                                  * Force Queue Full status.
 5319                                  */
 5320                                 *XS_STSP(xs) = SCSI_QFULL;
 5321                                 XS_SETERR(xs, HBA_NOERROR);
 5322                         } else if (XS_NOERR(xs)) {
 5323                                 XS_SETERR(xs, HBA_BOTCH);
 5324                         }
 5325                         XS_SET_RESID(xs, XS_XFRLEN(xs));
 5326                         break;
 5327                 default:
 5328                         isp_print_bytes(isp, "Unhandled Response Type", QENTRY_LEN, qe);
 5329                         if (XS_NOERR(xs)) {
 5330                                 XS_SETERR(xs, HBA_BOTCH);
 5331                         }
 5332                         break;
 5333                 }
 5334 
 5335                 /*
 5336                  * Free any DMA resources. As a side effect, this may
 5337                  * also do any cache flushing necessary for data coherence.
 5338                  */
 5339                 if (XS_XFRLEN(xs)) {
 5340                         ISP_DMAFREE(isp, xs, sp->req_handle);
 5341                 }
 5342                 isp_destroy_handle(isp, sp->req_handle);
 5343 
 5344                 if (((isp->isp_dblev & (ISP_LOGDEBUG1|ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
 5345                     ((isp->isp_dblev & (ISP_LOGDEBUG0|ISP_LOG_CWARN) && ((!XS_NOERR(xs)) || (*XS_STSP(xs) != SCSI_GOOD))))) {
 5346                         isp_prt_endcmd(isp, xs);
 5347                 }
 5348                 if (isp->isp_nactive > 0) {
 5349                     isp->isp_nactive--;
 5350                 }
 5351                 complist[ndone++] = xs; /* defer completion call until later */
 5352                 ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
 5353                 if (ndone == MAX_REQUESTQ_COMPLETIONS) {
 5354                         break;
 5355                 }
 5356         }
 5357 
 5358         /*
 5359          * If we looked at any commands, then it's valid to find out
 5360          * what the outpointer is. It also is a trigger to update the
 5361          * ISP's notion of what we've seen so far.
 5362          */
 5363         if (nlooked) {
 5364                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
 5365                 /*
 5366                  * While we're at it, read the request queue out pointer.
 5367                  */
 5368                 isp->isp_reqodx = ISP_READ(isp, isp->isp_rqstoutrp);
 5369                 if (isp->isp_rscchiwater < ndone) {
 5370                         isp->isp_rscchiwater = ndone;
 5371                 }
 5372         }
 5373 
 5374 out:
 5375 
 5376         if (IS_24XX(isp)) {
 5377                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
 5378         } else {
 5379                 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
 5380                 ISP_WRITE(isp, BIU_SEMA, 0);
 5381         }
 5382 
 5383         isp->isp_residx = optr;
 5384         for (i = 0; i < ndone; i++) {
 5385                 xs = complist[i];
 5386                 if (xs) {
 5387                         isp->isp_rsltccmplt++;
 5388                         isp_done(xs);
 5389                 }
 5390         }
 5391 }
 5392 
 5393 /*
 5394  * Support routines.
 5395  */
 5396 
 5397 static void
 5398 isp_prt_endcmd(ispsoftc_t *isp, XS_T *xs)
 5399 {
 5400         char cdbstr[16 * 5 + 1];
 5401         int i, lim;
 5402 
 5403         lim = XS_CDBLEN(xs) > 16? 16 : XS_CDBLEN(xs);
 5404         ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "0x%02x ", XS_CDBP(xs)[0]);
 5405         for (i = 1; i < lim; i++) {
 5406                 ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "%s0x%02x ", cdbstr, XS_CDBP(xs)[i]);
 5407         }
 5408         if (XS_SENSE_VALID(xs)) {
 5409                 isp_xs_prt(isp, xs, ISP_LOGALL, "FIN dl%d resid %ld CDB=%s KEY/ASC/ASCQ=0x%02x/0x%02x/0x%02x",
 5410                     XS_XFRLEN(xs), (long) XS_GET_RESID(xs), cdbstr, XS_SNSKEY(xs), XS_SNSASC(xs), XS_SNSASCQ(xs));
 5411         } else {
 5412                 isp_xs_prt(isp, xs, ISP_LOGALL, "FIN dl%d resid %ld CDB=%s STS 0x%x XS_ERR=0x%x", XS_XFRLEN(xs), (long) XS_GET_RESID(xs), cdbstr, *XS_STSP(xs), XS_ERR(xs));
 5413         }
 5414 }
 5415 
 5416 /*
 5417  * Parse an ASYNC mailbox complete
 5418  *
 5419  * Return non-zero if the event has been acknowledged.
 5420  */
 5421 static int
 5422 isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
 5423 {
 5424         int acked = 0;
 5425         uint32_t h1 = 0, h2 = 0;
 5426         uint16_t chan = 0;
 5427 
 5428         /*
 5429          * Pick up the channel, but not if this is a ASYNC_RIO32_2,
 5430          * where Mailboxes 6/7 have the second handle.
 5431          */
 5432         if (mbox != ASYNC_RIO32_2) {
 5433                 if (IS_DUALBUS(isp)) {
 5434                         chan = ISP_READ(isp, OUTMAILBOX6);
 5435                 }
 5436         }
 5437         isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
 5438 
 5439         switch (mbox) {
 5440         case ASYNC_BUS_RESET:
 5441                 ISP_SET_SENDMARKER(isp, chan, 1);
 5442 #ifdef  ISP_TARGET_MODE
 5443                 if (isp_target_async(isp, chan, mbox)) {
 5444                         acked = 1;
 5445                 }
 5446 #endif
 5447                 isp_async(isp, ISPASYNC_BUS_RESET, chan);
 5448                 break;
 5449         case ASYNC_SYSTEM_ERROR:
 5450                 isp->isp_dead = 1;
 5451                 isp->isp_state = ISP_CRASHED;
 5452                 /*
 5453                  * Were we waiting for a mailbox command to complete?
 5454                  * If so, it's dead, so wake up the waiter.
 5455                  */
 5456                 if (isp->isp_mboxbsy) {
 5457                         isp->isp_obits = 1;
 5458                         isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
 5459                         MBOX_NOTIFY_COMPLETE(isp);
 5460                 }
 5461                 /*
 5462                  * It's up to the handler for isp_async to reinit stuff and
 5463                  * restart the firmware
 5464                  */
 5465                 isp_async(isp, ISPASYNC_FW_CRASH);
 5466                 acked = 1;
 5467                 break;
 5468 
 5469         case ASYNC_RQS_XFER_ERR:
 5470                 isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
 5471                 break;
 5472 
 5473         case ASYNC_RSP_XFER_ERR:
 5474                 isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
 5475                 break;
 5476 
 5477         case ASYNC_QWAKEUP:
 5478                 /*
 5479                  * We've just been notified that the Queue has woken up.
 5480                  * We don't need to be chatty about this- just unlatch things
 5481                  * and move on.
 5482                  */
 5483                 mbox = ISP_READ(isp, isp->isp_rqstoutrp);
 5484                 break;
 5485 
 5486         case ASYNC_TIMEOUT_RESET:
 5487                 isp_prt(isp, ISP_LOGWARN, "timeout initiated SCSI bus reset of chan %d", chan);
 5488                 ISP_SET_SENDMARKER(isp, chan, 1);
 5489 #ifdef  ISP_TARGET_MODE
 5490                 if (isp_target_async(isp, chan, mbox)) {
 5491                         acked = 1;
 5492                 }
 5493 #endif
 5494                 break;
 5495 
 5496         case ASYNC_DEVICE_RESET:
 5497                 isp_prt(isp, ISP_LOGINFO, "device reset on chan %d", chan);
 5498                 ISP_SET_SENDMARKER(isp, chan, 1);
 5499 #ifdef  ISP_TARGET_MODE
 5500                 if (isp_target_async(isp, chan, mbox)) {
 5501                         acked = 1;
 5502                 }
 5503 #endif
 5504                 break;
 5505 
 5506         case ASYNC_EXTMSG_UNDERRUN:
 5507                 isp_prt(isp, ISP_LOGWARN, "extended message underrun");
 5508                 break;
 5509 
 5510         case ASYNC_SCAM_INT:
 5511                 isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
 5512                 break;
 5513 
 5514         case ASYNC_HUNG_SCSI:
 5515                 isp_prt(isp, ISP_LOGERR, "stalled SCSI Bus after DATA Overrun");
 5516                 /* XXX: Need to issue SCSI reset at this point */
 5517                 break;
 5518 
 5519         case ASYNC_KILLED_BUS:
 5520                 isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
 5521                 break;
 5522 
 5523         case ASYNC_BUS_TRANSIT:
 5524                 mbox = ISP_READ(isp, OUTMAILBOX2);
 5525                 switch (mbox & SXP_PINS_MODE_MASK) {
 5526                 case SXP_PINS_LVD_MODE:
 5527                         isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
 5528                         SDPARAM(isp, chan)->isp_diffmode = 0;
 5529                         SDPARAM(isp, chan)->isp_ultramode = 0;
 5530                         SDPARAM(isp, chan)->isp_lvdmode = 1;
 5531                         break;
 5532                 case SXP_PINS_HVD_MODE:
 5533                         isp_prt(isp, ISP_LOGINFO,
 5534                             "Transition to Differential mode");
 5535                         SDPARAM(isp, chan)->isp_diffmode = 1;
 5536                         SDPARAM(isp, chan)->isp_ultramode = 0;
 5537                         SDPARAM(isp, chan)->isp_lvdmode = 0;
 5538                         break;
 5539                 case SXP_PINS_SE_MODE:
 5540                         isp_prt(isp, ISP_LOGINFO,
 5541                             "Transition to Single Ended mode");
 5542                         SDPARAM(isp, chan)->isp_diffmode = 0;
 5543                         SDPARAM(isp, chan)->isp_ultramode = 1;
 5544                         SDPARAM(isp, chan)->isp_lvdmode = 0;
 5545                         break;
 5546                 default:
 5547                         isp_prt(isp, ISP_LOGWARN,
 5548                             "Transition to Unknown Mode 0x%x", mbox);
 5549                         break;
 5550                 }
 5551                 /*
 5552                  * XXX: Set up to renegotiate again!
 5553                  */
 5554                 /* Can only be for a 1080... */
 5555                 ISP_SET_SENDMARKER(isp, chan, 1);
 5556                 break;
 5557 
 5558         case ASYNC_CMD_CMPLT:
 5559         case ASYNC_RIO32_1:
 5560                 if (!IS_ULTRA3(isp)) {
 5561                         isp_prt(isp, ISP_LOGERR, "unexpected fast posting completion");
 5562                         break;
 5563                 }
 5564                 /* FALLTHROUGH */
 5565                 h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1);
 5566                 break;
 5567 
 5568         case ASYNC_RIO32_2:
 5569                 h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1);
 5570                 h2 = (ISP_READ(isp, OUTMAILBOX7) << 16) | ISP_READ(isp, OUTMAILBOX6);
 5571                 break;
 5572 
 5573         case ASYNC_RIO16_5:
 5574         case ASYNC_RIO16_4:
 5575         case ASYNC_RIO16_3:
 5576         case ASYNC_RIO16_2:
 5577         case ASYNC_RIO16_1:
 5578                 isp_prt(isp, ISP_LOGERR, "unexpected 16 bit RIO handle");
 5579                 break;
 5580         default:
 5581                 isp_prt(isp, ISP_LOGWARN, "%s: unhandled async code 0x%x", __func__, mbox);
 5582                 break;
 5583         }
 5584 
 5585         if (h1 || h2) {
 5586                 isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h1);
 5587                 isp_fastpost_complete(isp, h1);
 5588                 if (h2) {
 5589                         isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h2);
 5590                         isp_fastpost_complete(isp, h2);
 5591                         if (isp->isp_fpcchiwater < 2) {
 5592                                 isp->isp_fpcchiwater = 2;
 5593                         }
 5594                 } else {
 5595                         if (isp->isp_fpcchiwater < 1) {
 5596                                 isp->isp_fpcchiwater = 1;
 5597                         }
 5598                 }
 5599         } else {
 5600                 isp->isp_intoasync++;
 5601         }
 5602         return (acked);
 5603 }
 5604 
 5605 #define GET_24XX_BUS(isp, chan, msg)                                                                            \
 5606         if (IS_24XX(isp)) {                                                                                     \
 5607                 chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;                                                       \
 5608                 if (chan >= isp->isp_nchan) {                                                                   \
 5609                         isp_prt(isp, ISP_LOGERR, "bogus channel %u for %s at line %d",  chan, msg, __LINE__);   \
 5610                         break;                                                                                  \
 5611                 }                                                                                               \
 5612         }
 5613 
 5614 
 5615 static int
 5616 isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox)
 5617 {
 5618         int acked = 0;
 5619         uint16_t chan;
 5620 
 5621         if (IS_DUALBUS(isp)) {
 5622                 chan = ISP_READ(isp, OUTMAILBOX6);
 5623         } else {
 5624                 chan = 0;
 5625         }
 5626         isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
 5627 
 5628         switch (mbox) {
 5629         case ASYNC_SYSTEM_ERROR:
 5630                 isp->isp_dead = 1;
 5631                 isp->isp_state = ISP_CRASHED;
 5632                 FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
 5633                 FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
 5634                 /*
 5635                  * Were we waiting for a mailbox command to complete?
 5636                  * If so, it's dead, so wake up the waiter.
 5637                  */
 5638                 if (isp->isp_mboxbsy) {
 5639                         isp->isp_obits = 1;
 5640                         isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
 5641                         MBOX_NOTIFY_COMPLETE(isp);
 5642                 }
 5643                 /*
 5644                  * It's up to the handler for isp_async to reinit stuff and
 5645                  * restart the firmware
 5646                  */
 5647                 isp_async(isp, ISPASYNC_FW_CRASH);
 5648                 acked = 1;
 5649                 break;
 5650 
 5651         case ASYNC_RQS_XFER_ERR:
 5652                 isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
 5653                 break;
 5654 
 5655         case ASYNC_RSP_XFER_ERR:
 5656                 isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
 5657                 break;
 5658 
 5659         case ASYNC_QWAKEUP:
 5660 #ifdef  ISP_TARGET_MODE
 5661                 if (IS_24XX(isp)) {
 5662                         isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
 5663                         break;
 5664                 }
 5665 #endif
 5666                 isp_prt(isp, ISP_LOGERR, "%s: unexpected ASYNC_QWAKEUP code", __func__);
 5667                 break;
 5668 
 5669         case ASYNC_CMD_CMPLT:
 5670                 isp_fastpost_complete(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1));
 5671                 if (isp->isp_fpcchiwater < 1) {
 5672                         isp->isp_fpcchiwater = 1;
 5673                 }
 5674                 break;
 5675 
 5676         case ASYNC_RIOZIO_STALL:
 5677                 break;
 5678 
 5679         case ASYNC_CTIO_DONE:
 5680 #ifdef  ISP_TARGET_MODE
 5681                 if (isp_target_async(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1), mbox)) {
 5682                         acked = 1;
 5683                 } else {
 5684                         isp->isp_fphccmplt++;
 5685                 }
 5686 #else
 5687                 isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC CTIO done");
 5688 #endif
 5689                 break;
 5690         case ASYNC_LIP_ERROR:
 5691         case ASYNC_LIP_F8:
 5692         case ASYNC_LIP_OCCURRED:
 5693         case ASYNC_PTPMODE:
 5694                 /*
 5695                  * These are broadcast events that have to be sent across
 5696                  * all active channels.
 5697                  */
 5698                 for (chan = 0; chan < isp->isp_nchan; chan++) {
 5699                         fcparam *fcp = FCPARAM(isp, chan);
 5700                         int topo = fcp->isp_topo;
 5701 
 5702                         if (fcp->role == ISP_ROLE_NONE) {
 5703                                 continue;
 5704                         }
 5705 
 5706                         fcp->isp_fwstate = FW_CONFIG_WAIT;
 5707                         fcp->isp_loopstate = LOOP_LIP_RCVD;
 5708                         ISP_SET_SENDMARKER(isp, chan, 1);
 5709                         ISP_MARK_PORTDB(isp, chan, 1);
 5710                         isp_async(isp, ISPASYNC_LIP, chan);
 5711 #ifdef  ISP_TARGET_MODE
 5712                         if (isp_target_async(isp, chan, mbox)) {
 5713                                 acked = 1;
 5714                         }
 5715 #endif
 5716                         /*
 5717                          * We've had problems with data corruption occurring on
 5718                          * commands that complete (with no apparent error) after
 5719                          * we receive a LIP. This has been observed mostly on
 5720                          * Local Loop topologies. To be safe, let's just mark
 5721                          * all active initiator commands as dead.
 5722                          */
 5723                         if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
 5724                                 int i, j;
 5725                                 for (i = j = 0; i < isp->isp_maxcmds; i++) {
 5726                                         XS_T *xs;
 5727                                         isp_hdl_t *hdp;
 5728 
 5729                                         hdp = &isp->isp_xflist[i];
 5730                                         if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) {
 5731                                                 continue;
 5732                                         }
 5733                                         xs = hdp->cmd;
 5734                                         if (XS_CHANNEL(xs) != chan) {
 5735                                                 continue;
 5736                                         }
 5737                                         j++;
 5738                                         XS_SETERR(xs, HBA_BUSRESET);
 5739                                 }
 5740                                 if (j) {
 5741                                         isp_prt(isp, ISP_LOGERR, lipd, chan, j);
 5742                                 }
 5743                         }
 5744                 }
 5745                 break;
 5746 
 5747         case ASYNC_LOOP_UP:
 5748                 /*
 5749                  * This is a broadcast event that has to be sent across
 5750                  * all active channels.
 5751                  */
 5752                 for (chan = 0; chan < isp->isp_nchan; chan++) {
 5753                         fcparam *fcp = FCPARAM(isp, chan);
 5754 
 5755                         if (fcp->role == ISP_ROLE_NONE) {
 5756                                 continue;
 5757                         }
 5758 
 5759                         ISP_SET_SENDMARKER(isp, chan, 1);
 5760 
 5761                         fcp->isp_fwstate = FW_CONFIG_WAIT;
 5762                         fcp->isp_loopstate = LOOP_LIP_RCVD;
 5763                         ISP_MARK_PORTDB(isp, chan, 1);
 5764                         isp_async(isp, ISPASYNC_LOOP_UP, chan);
 5765 #ifdef  ISP_TARGET_MODE
 5766                         if (isp_target_async(isp, chan, mbox)) {
 5767                                 acked = 1;
 5768                         }
 5769 #endif
 5770                 }
 5771                 break;
 5772 
 5773         case ASYNC_LOOP_DOWN:
 5774                 /*
 5775                  * This is a broadcast event that has to be sent across
 5776                  * all active channels.
 5777                  */
 5778                 for (chan = 0; chan < isp->isp_nchan; chan++) {
 5779                         fcparam *fcp = FCPARAM(isp, chan);
 5780 
 5781                         if (fcp->role == ISP_ROLE_NONE) {
 5782                                 continue;
 5783                         }
 5784 
 5785                         ISP_SET_SENDMARKER(isp, chan, 1);
 5786                         fcp->isp_fwstate = FW_CONFIG_WAIT;
 5787                         fcp->isp_loopstate = LOOP_NIL;
 5788                         ISP_MARK_PORTDB(isp, chan, 1);
 5789                         isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
 5790 #ifdef  ISP_TARGET_MODE
 5791                         if (isp_target_async(isp, chan, mbox)) {
 5792                                 acked = 1;
 5793                         }
 5794 #endif
 5795                 }
 5796                 break;
 5797 
 5798         case ASYNC_LOOP_RESET:
 5799                 /*
 5800                  * This is a broadcast event that has to be sent across
 5801                  * all active channels.
 5802                  */
 5803                 for (chan = 0; chan < isp->isp_nchan; chan++) {
 5804                         fcparam *fcp = FCPARAM(isp, chan);
 5805 
 5806                         if (fcp->role == ISP_ROLE_NONE) {
 5807                                 continue;
 5808                         }
 5809 
 5810                         ISP_SET_SENDMARKER(isp, chan, 1);
 5811                         fcp->isp_fwstate = FW_CONFIG_WAIT;
 5812                         fcp->isp_loopstate = LOOP_NIL;
 5813                         ISP_MARK_PORTDB(isp, chan, 1);
 5814                         isp_async(isp, ISPASYNC_LOOP_RESET, chan);
 5815 #ifdef  ISP_TARGET_MODE
 5816                         if (isp_target_async(isp, chan, mbox)) {
 5817                                 acked = 1;
 5818                         }
 5819 #endif
 5820                 }
 5821                 break;
 5822 
 5823         case ASYNC_PDB_CHANGED:
 5824         {
 5825                 int nphdl, nlstate, reason;
 5826                 /*
 5827                  * We *should* get a channel out of the 24XX, but we don't seem
 5828                  * to get more than a PDB CHANGED on channel 0, so turn it into
 5829                  * a broadcast event.
 5830                  */
 5831                 if (IS_24XX(isp)) {
 5832                         nphdl = ISP_READ(isp, OUTMAILBOX1);
 5833                         nlstate = ISP_READ(isp, OUTMAILBOX2);
 5834                         reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
 5835                 } else {
 5836                         nphdl = NIL_HANDLE;
 5837                         nlstate = reason = 0;
 5838                 }
 5839                 for (chan = 0; chan < isp->isp_nchan; chan++) {
 5840                         fcparam *fcp = FCPARAM(isp, chan);
 5841 
 5842                         if (fcp->role == ISP_ROLE_NONE) {
 5843                                 continue;
 5844                         }
 5845                         ISP_SET_SENDMARKER(isp, chan, 1);
 5846                         fcp->isp_loopstate = LOOP_PDB_RCVD;
 5847                         ISP_MARK_PORTDB(isp, chan, 1);
 5848                         isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
 5849                 }
 5850                 break;
 5851         }
 5852         case ASYNC_CHANGE_NOTIFY:
 5853         {
 5854                 int lochan, hichan;
 5855 
 5856                 if (ISP_FW_NEWER_THAN(isp, 4, 0, 25) && ISP_CAP_MULTI_ID(isp)) {
 5857                         GET_24XX_BUS(isp, chan, "ASYNC_CHANGE_NOTIFY");
 5858                         lochan = chan;
 5859                         hichan = chan + 1;
 5860                 } else {
 5861                         lochan = 0;
 5862                         hichan = isp->isp_nchan;
 5863                 }
 5864                 for (chan = lochan; chan < hichan; chan++) {
 5865                         fcparam *fcp = FCPARAM(isp, chan);
 5866 
 5867                         if (fcp->role == ISP_ROLE_NONE) {
 5868                                 continue;
 5869                         }
 5870 
 5871                         if (fcp->isp_topo == TOPO_F_PORT) {
 5872                                 fcp->isp_loopstate = LOOP_LSCAN_DONE;
 5873                         } else {
 5874                                 fcp->isp_loopstate = LOOP_PDB_RCVD;
 5875                         }
 5876                         ISP_MARK_PORTDB(isp, chan, 1);
 5877                         isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_SNS);
 5878                 }
 5879                 break;
 5880         }
 5881 
 5882         case ASYNC_CONNMODE:
 5883                 /*
 5884                  * This only applies to 2100 amd 2200 cards
 5885                  */
 5886                 if (!IS_2200(isp) && !IS_2100(isp)) {
 5887                         isp_prt(isp, ISP_LOGWARN, "bad card for ASYNC_CONNMODE event");
 5888                         break;
 5889                 }
 5890                 chan = 0;
 5891                 mbox = ISP_READ(isp, OUTMAILBOX1);
 5892                 ISP_MARK_PORTDB(isp, chan, 1);
 5893                 switch (mbox) {
 5894                 case ISP_CONN_LOOP:
 5895                         isp_prt(isp, ISP_LOGINFO,
 5896                             "Point-to-Point -> Loop mode");
 5897                         break;
 5898                 case ISP_CONN_PTP:
 5899                         isp_prt(isp, ISP_LOGINFO,
 5900                             "Loop -> Point-to-Point mode");
 5901                         break;
 5902                 case ISP_CONN_BADLIP:
 5903                         isp_prt(isp, ISP_LOGWARN,
 5904                             "Point-to-Point -> Loop mode (BAD LIP)");
 5905                         break;
 5906                 case ISP_CONN_FATAL:
 5907                         isp->isp_dead = 1;
 5908                         isp->isp_state = ISP_CRASHED;
 5909                         isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
 5910                         isp_async(isp, ISPASYNC_FW_CRASH);
 5911                         return (-1);
 5912                 case ISP_CONN_LOOPBACK:
 5913                         isp_prt(isp, ISP_LOGWARN,
 5914                             "Looped Back in Point-to-Point mode");
 5915                         break;
 5916                 default:
 5917                         isp_prt(isp, ISP_LOGWARN,
 5918                             "Unknown connection mode (0x%x)", mbox);
 5919                         break;
 5920                 }
 5921                 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_OTHER);
 5922                 FCPARAM(isp, chan)->sendmarker = 1;
 5923                 FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
 5924                 FCPARAM(isp, chan)->isp_loopstate = LOOP_LIP_RCVD;
 5925                 break;
 5926 
 5927         case ASYNC_RCV_ERR:
 5928                 if (IS_24XX(isp)) {
 5929                         isp_prt(isp, ISP_LOGWARN, "Receive Error");
 5930                 } else {
 5931                         isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC_RCV_ERR");
 5932                 }
 5933                 break;
 5934         case ASYNC_RJT_SENT:    /* same as ASYNC_QFULL_SENT */
 5935                 if (IS_24XX(isp)) {
 5936                         isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
 5937                         break;
 5938                 } else if (IS_2200(isp)) {
 5939                         isp_prt(isp, ISP_LOGTDEBUG0, "QFULL sent");
 5940                         break;
 5941                 }
 5942                 /* FALLTHROUGH */
 5943         default:
 5944                 isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
 5945                 break;
 5946         }
 5947         if (mbox != ASYNC_CTIO_DONE && mbox != ASYNC_CMD_CMPLT) {
 5948                 isp->isp_intoasync++;
 5949         }
 5950         return (acked);
 5951 }
 5952 
 5953 /*
 5954  * Handle other response entries. A pointer to the request queue output
 5955  * index is here in case we want to eat several entries at once, although
 5956  * this is not used currently.
 5957  */
 5958 
 5959 static int
 5960 isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *optrp)
 5961 {
 5962         switch (type) {
 5963         case RQSTYPE_STATUS_CONT:
 5964                 isp_prt(isp, ISP_LOGDEBUG0, "Ignored Continuation Response");
 5965                 return (1);
 5966         case RQSTYPE_MARKER:
 5967                 isp_prt(isp, ISP_LOGDEBUG0, "Marker Response");
 5968                 return (1);
 5969         case RQSTYPE_ATIO:
 5970         case RQSTYPE_CTIO:
 5971         case RQSTYPE_ENABLE_LUN:
 5972         case RQSTYPE_MODIFY_LUN:
 5973         case RQSTYPE_NOTIFY:
 5974         case RQSTYPE_NOTIFY_ACK:
 5975         case RQSTYPE_CTIO1:
 5976         case RQSTYPE_ATIO2:
 5977         case RQSTYPE_CTIO2:
 5978         case RQSTYPE_CTIO3:
 5979         case RQSTYPE_CTIO7:
 5980         case RQSTYPE_ABTS_RCVD:
 5981         case RQSTYPE_ABTS_RSP:
 5982                 isp->isp_rsltccmplt++;  /* count as a response completion */
 5983 #ifdef  ISP_TARGET_MODE
 5984                 if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
 5985                         return (1);
 5986                 }
 5987 #endif
 5988                 /* FALLTHROUGH */
 5989         case RQSTYPE_RPT_ID_ACQ:
 5990                 if (IS_24XX(isp)) {
 5991                         isp_ridacq_t rid;
 5992                         isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
 5993                         if (rid.ridacq_format == 0) {
 5994                         }
 5995                         return (1);
 5996                 }
 5997                 /* FALLTHROUGH */
 5998         case RQSTYPE_REQUEST:
 5999         default:
 6000                 ISP_DELAY(100);
 6001                 if (type != isp_get_response_type(isp, hp)) {
 6002                         /*
 6003                          * This is questionable- we're just papering over
 6004                          * something we've seen on SMP linux in target
 6005                          * mode- we don't really know what's happening
 6006                          * here that causes us to think we've gotten
 6007                          * an entry, but that either the entry isn't
 6008                          * filled out yet or our CPU read data is stale.
 6009                          */
 6010                         isp_prt(isp, ISP_LOGINFO,
 6011                                 "unstable type in response queue");
 6012                         return (-1);
 6013                 }
 6014                 isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
 6015                     isp_get_response_type(isp, hp));
 6016                 return (0);
 6017         }
 6018 }
 6019 
 6020 static void
 6021 isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
 6022 {
 6023         switch (sp->req_completion_status & 0xff) {
 6024         case RQCS_COMPLETE:
 6025                 if (XS_NOERR(xs)) {
 6026                         XS_SETERR(xs, HBA_NOERROR);
 6027                 }
 6028                 return;
 6029 
 6030         case RQCS_INCOMPLETE:
 6031                 if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
 6032                         isp_xs_prt(isp, xs, ISP_LOGDEBUG1, "Selection Timeout");
 6033                         if (XS_NOERR(xs)) {
 6034                                 XS_SETERR(xs, HBA_SELTIMEOUT);
 6035                                 *rp = XS_XFRLEN(xs);
 6036                         }
 6037                         return;
 6038                 }
 6039                 isp_xs_prt(isp, xs, ISP_LOGERR, "Command Incomplete, state 0x%x", sp->req_state_flags);
 6040                 break;
 6041 
 6042         case RQCS_DMA_ERROR:
 6043                 isp_xs_prt(isp, xs, ISP_LOGERR, "DMA Error");
 6044                 *rp = XS_XFRLEN(xs);
 6045                 break;
 6046 
 6047         case RQCS_TRANSPORT_ERROR:
 6048         {
 6049                 char buf[172];
 6050                 ISP_SNPRINTF(buf, sizeof (buf), "states=>");
 6051                 if (sp->req_state_flags & RQSF_GOT_BUS) {
 6052                         ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
 6053                 }
 6054                 if (sp->req_state_flags & RQSF_GOT_TARGET) {
 6055                         ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
 6056                 }
 6057                 if (sp->req_state_flags & RQSF_SENT_CDB) {
 6058                         ISP_SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
 6059                 }
 6060                 if (sp->req_state_flags & RQSF_XFRD_DATA) {
 6061                         ISP_SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
 6062                 }
 6063                 if (sp->req_state_flags & RQSF_GOT_STATUS) {
 6064                         ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
 6065                 }
 6066                 if (sp->req_state_flags & RQSF_GOT_SENSE) {
 6067                         ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
 6068                 }
 6069                 if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
 6070                         ISP_SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
 6071                 }
 6072                 ISP_SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
 6073                 if (sp->req_status_flags & RQSTF_DISCONNECT) {
 6074                         ISP_SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
 6075                 }
 6076                 if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
 6077                         ISP_SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
 6078                 }
 6079                 if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
 6080                         ISP_SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
 6081                 }
 6082                 if (sp->req_status_flags & RQSTF_BUS_RESET) {
 6083                         ISP_SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
 6084                 }
 6085                 if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
 6086                         ISP_SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
 6087                 }
 6088                 if (sp->req_status_flags & RQSTF_ABORTED) {
 6089                         ISP_SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
 6090                 }
 6091                 if (sp->req_status_flags & RQSTF_TIMEOUT) {
 6092                         ISP_SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
 6093                 }
 6094                 if (sp->req_status_flags & RQSTF_NEGOTIATION) {
 6095                         ISP_SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
 6096                 }
 6097                 isp_xs_prt(isp, xs,  ISP_LOGERR, "Transport Error: %s", buf);
 6098                 *rp = XS_XFRLEN(xs);
 6099                 break;
 6100         }
 6101         case RQCS_RESET_OCCURRED:
 6102         {
 6103                 int chan;
 6104                 isp_xs_prt(isp, xs, ISP_LOGWARN, "Bus Reset destroyed command");
 6105                 for (chan = 0; chan < isp->isp_nchan; chan++) {
 6106                         FCPARAM(isp, chan)->sendmarker = 1;
 6107                 }
 6108                 if (XS_NOERR(xs)) {
 6109                         XS_SETERR(xs, HBA_BUSRESET);
 6110                 }
 6111                 *rp = XS_XFRLEN(xs);
 6112                 return;
 6113         }
 6114         case RQCS_ABORTED:
 6115                 isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
 6116                 ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
 6117                 if (XS_NOERR(xs)) {
 6118                         XS_SETERR(xs, HBA_ABORTED);
 6119                 }
 6120                 return;
 6121 
 6122         case RQCS_TIMEOUT:
 6123                 isp_xs_prt(isp, xs, ISP_LOGWARN, "Command timed out");
 6124                 /*
 6125                  * XXX: Check to see if we logged out of the device.
 6126                  */
 6127                 if (XS_NOERR(xs)) {
 6128                         XS_SETERR(xs, HBA_CMDTIMEOUT);
 6129                 }
 6130                 return;
 6131 
 6132         case RQCS_DATA_OVERRUN:
 6133                 XS_SET_RESID(xs, sp->req_resid);
 6134                 isp_xs_prt(isp, xs, ISP_LOGERR, "data overrun (%ld)", (long) XS_GET_RESID(xs));
 6135                 if (XS_NOERR(xs)) {
 6136                         XS_SETERR(xs, HBA_DATAOVR);
 6137                 }
 6138                 return;
 6139 
 6140         case RQCS_COMMAND_OVERRUN:
 6141                 isp_xs_prt(isp, xs, ISP_LOGERR, "command overrun");
 6142                 break;
 6143 
 6144         case RQCS_STATUS_OVERRUN:
 6145                 isp_xs_prt(isp, xs, ISP_LOGERR, "status overrun");
 6146                 break;
 6147 
 6148         case RQCS_BAD_MESSAGE:
 6149                 isp_xs_prt(isp, xs, ISP_LOGERR, "msg not COMMAND COMPLETE after status");
 6150                 break;
 6151 
 6152         case RQCS_NO_MESSAGE_OUT:
 6153                 isp_xs_prt(isp, xs, ISP_LOGERR, "No MESSAGE OUT phase after selection");
 6154                 break;
 6155 
 6156         case RQCS_EXT_ID_FAILED:
 6157                 isp_xs_prt(isp, xs, ISP_LOGERR, "EXTENDED IDENTIFY failed");
 6158                 break;
 6159 
 6160         case RQCS_IDE_MSG_FAILED:
 6161                 isp_xs_prt(isp, xs, ISP_LOGERR, "INITIATOR DETECTED ERROR rejected");
 6162                 break;
 6163 
 6164         case RQCS_ABORT_MSG_FAILED:
 6165                 isp_xs_prt(isp, xs, ISP_LOGERR, "ABORT OPERATION rejected");
 6166                 break;
 6167 
 6168         case RQCS_REJECT_MSG_FAILED:
 6169                 isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE REJECT rejected");
 6170                 break;
 6171 
 6172         case RQCS_NOP_MSG_FAILED:
 6173                 isp_xs_prt(isp, xs, ISP_LOGERR, "NOP rejected");
 6174                 break;
 6175 
 6176         case RQCS_PARITY_ERROR_MSG_FAILED:
 6177                 isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE PARITY ERROR rejected");
 6178                 break;
 6179 
 6180         case RQCS_DEVICE_RESET_MSG_FAILED:
 6181                 isp_xs_prt(isp, xs, ISP_LOGWARN, "BUS DEVICE RESET rejected");
 6182                 break;
 6183 
 6184         case RQCS_ID_MSG_FAILED:
 6185                 isp_xs_prt(isp, xs, ISP_LOGERR, "IDENTIFY rejected");
 6186                 break;
 6187 
 6188         case RQCS_UNEXP_BUS_FREE:
 6189                 isp_xs_prt(isp, xs, ISP_LOGERR, "Unexpected Bus Free");
 6190                 break;
 6191 
 6192         case RQCS_DATA_UNDERRUN:
 6193         {
 6194                 if (IS_FC(isp)) {
 6195                         int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
 6196                         if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
 6197                                 isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
 6198                                 if (XS_NOERR(xs)) {
 6199                                         XS_SETERR(xs, HBA_BOTCH);
 6200                                 }
 6201                                 return;
 6202                         }
 6203                 }
 6204                 XS_SET_RESID(xs, sp->req_resid);
 6205                 if (XS_NOERR(xs)) {
 6206                         XS_SETERR(xs, HBA_NOERROR);
 6207                 }
 6208                 return;
 6209         }
 6210 
 6211         case RQCS_XACT_ERR1:
 6212                 isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued transaction with disconnect not set");
 6213                 break;
 6214 
 6215         case RQCS_XACT_ERR2:
 6216                 isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued transaction to target routine %d", XS_LUN(xs));
 6217                 break;
 6218 
 6219         case RQCS_XACT_ERR3:
 6220                 isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued cmd when queueing disabled");
 6221                 break;
 6222 
 6223         case RQCS_BAD_ENTRY:
 6224                 isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
 6225                 break;
 6226 
 6227         case RQCS_QUEUE_FULL:
 6228                 isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "internal queues full status 0x%x", *XS_STSP(xs));
 6229 
 6230                 /*
 6231                  * If QFULL or some other status byte is set, then this
 6232                  * isn't an error, per se.
 6233                  *
 6234                  * Unfortunately, some QLogic f/w writers have, in
 6235                  * some cases, omitted to *set* status to QFULL.
 6236                  *
 6237 
 6238                 if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
 6239                         XS_SETERR(xs, HBA_NOERROR);
 6240                         return;
 6241                 }
 6242 
 6243                  *
 6244                  *
 6245                  */
 6246 
 6247                 *XS_STSP(xs) = SCSI_QFULL;
 6248                 XS_SETERR(xs, HBA_NOERROR);
 6249                 return;
 6250 
 6251         case RQCS_PHASE_SKIPPED:
 6252                 isp_xs_prt(isp, xs, ISP_LOGERR, "SCSI phase skipped");
 6253                 break;
 6254 
 6255         case RQCS_ARQS_FAILED:
 6256                 isp_xs_prt(isp, xs, ISP_LOGERR, "Auto Request Sense Failed");
 6257                 if (XS_NOERR(xs)) {
 6258                         XS_SETERR(xs, HBA_ARQFAIL);
 6259                 }
 6260                 return;
 6261 
 6262         case RQCS_WIDE_FAILED:
 6263                 isp_xs_prt(isp, xs, ISP_LOGERR, "Wide Negotiation Failed");
 6264                 if (IS_SCSI(isp)) {
 6265                         sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
 6266                         sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
 6267                         sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
 6268                         sdp->update = 1;
 6269                 }
 6270                 if (XS_NOERR(xs)) {
 6271                         XS_SETERR(xs, HBA_NOERROR);
 6272                 }
 6273                 return;
 6274 
 6275         case RQCS_SYNCXFER_FAILED:
 6276                 isp_xs_prt(isp, xs, ISP_LOGERR, "SDTR Message Failed");
 6277                 if (IS_SCSI(isp)) {
 6278                         sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
 6279                         sdp += XS_CHANNEL(xs);
 6280                         sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
 6281                         sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
 6282                         sdp->update = 1;
 6283                 }
 6284                 break;
 6285 
 6286         case RQCS_LVD_BUSERR:
 6287                 isp_xs_prt(isp, xs, ISP_LOGERR, "Bad LVD condition");
 6288                 break;
 6289 
 6290         case RQCS_PORT_UNAVAILABLE:
 6291                 /*
 6292                  * No such port on the loop. Moral equivalent of SELTIMEO
 6293                  */
 6294         case RQCS_PORT_LOGGED_OUT:
 6295         {
 6296                 const char *reason;
 6297                 uint8_t sts = sp->req_completion_status & 0xff;
 6298 
 6299                 /*
 6300                  * It was there (maybe)- treat as a selection timeout.
 6301                  */
 6302                 if (sts == RQCS_PORT_UNAVAILABLE) {
 6303                         reason = "unavailable";
 6304                 } else {
 6305                         reason = "logout";
 6306                 }
 6307 
 6308                 isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
 6309                     reason, XS_TGT(xs));
 6310 
 6311                 /*
 6312                  * If we're on a local loop, force a LIP (which is overkill)
 6313                  * to force a re-login of this unit. If we're on fabric,
 6314                  * then we'll have to log in again as a matter of course.
 6315                  */
 6316                 if (FCPARAM(isp, 0)->isp_topo == TOPO_NL_PORT ||
 6317                     FCPARAM(isp, 0)->isp_topo == TOPO_FL_PORT) {
 6318                         mbreg_t mbs;
 6319                         MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
 6320                         if (ISP_CAP_2KLOGIN(isp)) {
 6321                                 mbs.ibits = (1 << 10);
 6322                         }
 6323                         isp_mboxcmd_qnw(isp, &mbs, 1);
 6324                 }
 6325                 if (XS_NOERR(xs)) {
 6326                         XS_SETERR(xs, HBA_SELTIMEOUT);
 6327                 }
 6328                 return;
 6329         }
 6330         case RQCS_PORT_CHANGED:
 6331                 isp_prt(isp, ISP_LOGWARN,
 6332                     "port changed for target %d", XS_TGT(xs));
 6333                 if (XS_NOERR(xs)) {
 6334                         XS_SETERR(xs, HBA_SELTIMEOUT);
 6335                 }
 6336                 return;
 6337 
 6338         case RQCS_PORT_BUSY:
 6339                 isp_prt(isp, ISP_LOGWARN,
 6340                     "port busy for target %d", XS_TGT(xs));
 6341                 if (XS_NOERR(xs)) {
 6342                         XS_SETERR(xs, HBA_TGTBSY);
 6343                 }
 6344                 return;
 6345 
 6346         default:
 6347                 isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
 6348                     sp->req_completion_status);
 6349                 break;
 6350         }
 6351         if (XS_NOERR(xs)) {
 6352                 XS_SETERR(xs, HBA_BOTCH);
 6353         }
 6354 }
 6355 
 6356 static void
 6357 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs, long *rp)
 6358 {
 6359         int ru_marked, sv_marked;
 6360         int chan = XS_CHANNEL(xs);
 6361 
 6362         switch (sp->req_completion_status) {
 6363         case RQCS_COMPLETE:
 6364                 if (XS_NOERR(xs)) {
 6365                         XS_SETERR(xs, HBA_NOERROR);
 6366                 }
 6367                 return;
 6368 
 6369         case RQCS_DMA_ERROR:
 6370                 isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error");
 6371                 break;
 6372 
 6373         case RQCS_TRANSPORT_ERROR:
 6374                 isp_xs_prt(isp, xs,  ISP_LOGERR, "Transport Error");
 6375                 break;
 6376 
 6377         case RQCS_RESET_OCCURRED:
 6378                 isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command");
 6379                 FCPARAM(isp, chan)->sendmarker = 1;
 6380                 if (XS_NOERR(xs)) {
 6381                         XS_SETERR(xs, HBA_BUSRESET);
 6382                 }
 6383                 return;
 6384 
 6385         case RQCS_ABORTED:
 6386                 isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
 6387                 FCPARAM(isp, chan)->sendmarker = 1;
 6388                 if (XS_NOERR(xs)) {
 6389                         XS_SETERR(xs, HBA_ABORTED);
 6390                 }
 6391                 return;
 6392 
 6393         case RQCS_TIMEOUT:
 6394                 isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out");
 6395                 if (XS_NOERR(xs)) {
 6396                         XS_SETERR(xs, HBA_CMDTIMEOUT);
 6397                 }
 6398                 return;
 6399 
 6400         case RQCS_DATA_OVERRUN:
 6401                 XS_SET_RESID(xs, sp->req_resid);
 6402                 isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun");
 6403                 if (XS_NOERR(xs)) {
 6404                         XS_SETERR(xs, HBA_DATAOVR);
 6405                 }
 6406                 return;
 6407 
 6408         case RQCS_24XX_DRE:     /* data reassembly error */
 6409                 isp_prt(isp, ISP_LOGERR,
 6410                     "Chan %d data reassembly error for target %d",
 6411                     chan, XS_TGT(xs));
 6412                 if (XS_NOERR(xs)) {
 6413                         XS_SETERR(xs, HBA_ABORTED);
 6414                 }
 6415                 *rp = XS_XFRLEN(xs);
 6416                 return;
 6417 
 6418         case RQCS_24XX_TABORT:  /* aborted by target */
 6419                 isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS",
 6420                     chan, XS_TGT(xs));
 6421                 if (XS_NOERR(xs)) {
 6422                         XS_SETERR(xs, HBA_ABORTED);
 6423                 }
 6424                 return;
 6425 
 6426         case RQCS_DATA_UNDERRUN:
 6427                 ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
 6428                 /*
 6429                  * We can get an underrun w/o things being marked
 6430                  * if we got a non-zero status.
 6431                  */
 6432                 sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
 6433                 if ((ru_marked == 0 && sv_marked == 0) ||
 6434                     (sp->req_resid > XS_XFRLEN(xs))) {
 6435                         isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
 6436                         if (XS_NOERR(xs)) {
 6437                                 XS_SETERR(xs, HBA_BOTCH);
 6438                         }
 6439                         return;
 6440                 }
 6441                 XS_SET_RESID(xs, sp->req_resid);
 6442                 isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff);
 6443                 if (XS_NOERR(xs)) {
 6444                         XS_SETERR(xs, HBA_NOERROR);
 6445                 }
 6446                 return;
 6447 
 6448         case RQCS_PORT_UNAVAILABLE:
 6449                 /*
 6450                  * No such port on the loop. Moral equivalent of SELTIMEO
 6451                  */
 6452         case RQCS_PORT_LOGGED_OUT:
 6453         {
 6454                 const char *reason;
 6455                 uint8_t sts = sp->req_completion_status & 0xff;
 6456 
 6457                 /*
 6458                  * It was there (maybe)- treat as a selection timeout.
 6459                  */
 6460                 if (sts == RQCS_PORT_UNAVAILABLE) {
 6461                         reason = "unavailable";
 6462                 } else {
 6463                         reason = "logout";
 6464                 }
 6465 
 6466                 isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d",
 6467                     chan, reason, XS_TGT(xs));
 6468 
 6469                 /*
 6470                  * There is no MBOX_INIT_LIP for the 24XX.
 6471                  */
 6472                 if (XS_NOERR(xs)) {
 6473                         XS_SETERR(xs, HBA_SELTIMEOUT);
 6474                 }
 6475                 return;
 6476         }
 6477         case RQCS_PORT_CHANGED:
 6478                 isp_prt(isp, ISP_LOGWARN,
 6479                     "port changed for target %d chan %d", XS_TGT(xs), chan);
 6480                 if (XS_NOERR(xs)) {
 6481                         XS_SETERR(xs, HBA_SELTIMEOUT);
 6482                 }
 6483                 return;
 6484 
 6485 
 6486         case RQCS_24XX_ENOMEM:  /* f/w resource unavailable */
 6487                 isp_prt(isp, ISP_LOGWARN,
 6488                     "f/w resource unavailable for target %d chan %d",
 6489                     XS_TGT(xs), chan);
 6490                 if (XS_NOERR(xs)) {
 6491                         *XS_STSP(xs) = SCSI_BUSY;
 6492                         XS_SETERR(xs, HBA_TGTBSY);
 6493                 }
 6494                 return;
 6495 
 6496         case RQCS_24XX_TMO:     /* task management overrun */
 6497                 isp_prt(isp, ISP_LOGWARN,
 6498                     "command for target %d overlapped task management for "
 6499                     "chan %d", XS_TGT(xs), chan);
 6500                 if (XS_NOERR(xs)) {
 6501                         *XS_STSP(xs) = SCSI_BUSY;
 6502                         XS_SETERR(xs, HBA_TGTBSY);
 6503                 }
 6504                 return;
 6505 
 6506         default:
 6507                 isp_prt(isp, ISP_LOGERR,
 6508                     "Unknown Completion Status 0x%x on chan %d",
 6509                     sp->req_completion_status, chan);
 6510                 break;
 6511         }
 6512         if (XS_NOERR(xs)) {
 6513                 XS_SETERR(xs, HBA_BOTCH);
 6514         }
 6515 }
 6516 
 6517 static void
 6518 isp_fastpost_complete(ispsoftc_t *isp, uint32_t fph)
 6519 {
 6520         XS_T *xs;
 6521 
 6522         if (fph == 0) {
 6523                 return;
 6524         }
 6525         xs = isp_find_xs(isp, fph);
 6526         if (xs == NULL) {
 6527                 isp_prt(isp, ISP_LOGWARN,
 6528                     "Command for fast post handle 0x%x not found", fph);
 6529                 return;
 6530         }
 6531         isp_destroy_handle(isp, fph);
 6532 
 6533         /*
 6534          * Since we don't have a result queue entry item,
 6535          * we must believe that SCSI status is zero and
 6536          * that all data transferred.
 6537          */
 6538         XS_SET_RESID(xs, 0);
 6539         *XS_STSP(xs) = SCSI_GOOD;
 6540         if (XS_XFRLEN(xs)) {
 6541                 ISP_DMAFREE(isp, xs, fph);
 6542         }
 6543         if (isp->isp_nactive) {
 6544                 isp->isp_nactive--;
 6545         }
 6546         isp->isp_fphccmplt++;
 6547         isp_done(xs);
 6548 }
 6549 
 6550 static int
 6551 isp_mbox_continue(ispsoftc_t *isp)
 6552 {
 6553         mbreg_t mbs;
 6554         uint16_t *ptr;
 6555         uint32_t offset;
 6556 
 6557         switch (isp->isp_lastmbxcmd) {
 6558         case MBOX_WRITE_RAM_WORD:
 6559         case MBOX_READ_RAM_WORD:
 6560         case MBOX_WRITE_RAM_WORD_EXTENDED:
 6561         case MBOX_READ_RAM_WORD_EXTENDED:
 6562                 break;
 6563         default:
 6564                 return (1);
 6565         }
 6566         if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
 6567                 isp->isp_mbxwrk0 = 0;
 6568                 return (-1);
 6569         }
 6570 
 6571         /*
 6572          * Clear the previous interrupt.
 6573          */
 6574         if (IS_24XX(isp)) {
 6575                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
 6576         } else {
 6577                 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
 6578                 ISP_WRITE(isp, BIU_SEMA, 0);
 6579         }
 6580 
 6581         /*
 6582          * Continue with next word.
 6583          */
 6584         ISP_MEMZERO(&mbs, sizeof (mbs));
 6585         ptr = isp->isp_mbxworkp;
 6586         switch (isp->isp_lastmbxcmd) {
 6587         case MBOX_WRITE_RAM_WORD:
 6588                 mbs.param[1] = isp->isp_mbxwrk1++;
 6589                 mbs.param[2] = *ptr++;
 6590                 break;
 6591         case MBOX_READ_RAM_WORD:
 6592                 *ptr++ = isp->isp_mboxtmp[2];
 6593                 mbs.param[1] = isp->isp_mbxwrk1++;
 6594                 break;
 6595         case MBOX_WRITE_RAM_WORD_EXTENDED:
 6596                 offset = isp->isp_mbxwrk1;
 6597                 offset |= isp->isp_mbxwrk8 << 16;
 6598 
 6599                 mbs.param[2] = *ptr++;
 6600                 mbs.param[1] = offset;
 6601                 mbs.param[8] = offset >> 16;
 6602                 isp->isp_mbxwrk1 = ++offset;
 6603                 isp->isp_mbxwrk8 = offset >> 16;
 6604                 break;
 6605         case MBOX_READ_RAM_WORD_EXTENDED:
 6606                 offset = isp->isp_mbxwrk1;
 6607                 offset |= isp->isp_mbxwrk8 << 16;
 6608 
 6609                 *ptr++ = isp->isp_mboxtmp[2];
 6610                 mbs.param[1] = offset;
 6611                 mbs.param[8] = offset >> 16;
 6612                 isp->isp_mbxwrk1 = ++offset;
 6613                 isp->isp_mbxwrk8 = offset >> 16;
 6614                 break;
 6615         }
 6616         isp->isp_mbxworkp = ptr;
 6617         isp->isp_mbxwrk0--;
 6618         mbs.param[0] = isp->isp_lastmbxcmd;
 6619         mbs.logval = MBLOGALL;
 6620         isp_mboxcmd_qnw(isp, &mbs, 0);
 6621         return (0);
 6622 }
 6623 
 6624 #define HIWRD(x)                        ((x) >> 16)
 6625 #define LOWRD(x)                        ((x)  & 0xffff)
 6626 #define ISPOPMAP(a, b)                  (((a) << 16) | (b))
 6627 static const uint32_t mbpscsi[] = {
 6628         ISPOPMAP(0x01, 0x01),   /* 0x00: MBOX_NO_OP */
 6629         ISPOPMAP(0x1f, 0x01),   /* 0x01: MBOX_LOAD_RAM */
 6630         ISPOPMAP(0x03, 0x01),   /* 0x02: MBOX_EXEC_FIRMWARE */
 6631         ISPOPMAP(0x1f, 0x01),   /* 0x03: MBOX_DUMP_RAM */
 6632         ISPOPMAP(0x07, 0x07),   /* 0x04: MBOX_WRITE_RAM_WORD */
 6633         ISPOPMAP(0x03, 0x07),   /* 0x05: MBOX_READ_RAM_WORD */
 6634         ISPOPMAP(0x3f, 0x3f),   /* 0x06: MBOX_MAILBOX_REG_TEST */
 6635         ISPOPMAP(0x07, 0x07),   /* 0x07: MBOX_VERIFY_CHECKSUM   */
 6636         ISPOPMAP(0x01, 0x0f),   /* 0x08: MBOX_ABOUT_FIRMWARE */
 6637         ISPOPMAP(0x00, 0x00),   /* 0x09: */
 6638         ISPOPMAP(0x00, 0x00),   /* 0x0a: */
 6639         ISPOPMAP(0x00, 0x00),   /* 0x0b: */
 6640         ISPOPMAP(0x00, 0x00),   /* 0x0c: */
 6641         ISPOPMAP(0x00, 0x00),   /* 0x0d: */
 6642         ISPOPMAP(0x01, 0x05),   /* 0x0e: MBOX_CHECK_FIRMWARE */
 6643         ISPOPMAP(0x00, 0x00),   /* 0x0f: */
 6644         ISPOPMAP(0x1f, 0x1f),   /* 0x10: MBOX_INIT_REQ_QUEUE */
 6645         ISPOPMAP(0x3f, 0x3f),   /* 0x11: MBOX_INIT_RES_QUEUE */
 6646         ISPOPMAP(0x0f, 0x0f),   /* 0x12: MBOX_EXECUTE_IOCB */
 6647         ISPOPMAP(0x03, 0x03),   /* 0x13: MBOX_WAKE_UP   */
 6648         ISPOPMAP(0x01, 0x3f),   /* 0x14: MBOX_STOP_FIRMWARE */
 6649         ISPOPMAP(0x0f, 0x0f),   /* 0x15: MBOX_ABORT */
 6650         ISPOPMAP(0x03, 0x03),   /* 0x16: MBOX_ABORT_DEVICE */
 6651         ISPOPMAP(0x07, 0x07),   /* 0x17: MBOX_ABORT_TARGET */
 6652         ISPOPMAP(0x07, 0x07),   /* 0x18: MBOX_BUS_RESET */
 6653         ISPOPMAP(0x03, 0x07),   /* 0x19: MBOX_STOP_QUEUE */
 6654         ISPOPMAP(0x03, 0x07),   /* 0x1a: MBOX_START_QUEUE */
 6655         ISPOPMAP(0x03, 0x07),   /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
 6656         ISPOPMAP(0x03, 0x07),   /* 0x1c: MBOX_ABORT_QUEUE */
 6657         ISPOPMAP(0x03, 0x4f),   /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
 6658         ISPOPMAP(0x00, 0x00),   /* 0x1e: */
 6659         ISPOPMAP(0x01, 0x07),   /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
 6660         ISPOPMAP(0x01, 0x07),   /* 0x20: MBOX_GET_INIT_SCSI_ID */
 6661         ISPOPMAP(0x01, 0x07),   /* 0x21: MBOX_GET_SELECT_TIMEOUT */
 6662         ISPOPMAP(0x01, 0xc7),   /* 0x22: MBOX_GET_RETRY_COUNT   */
 6663         ISPOPMAP(0x01, 0x07),   /* 0x23: MBOX_GET_TAG_AGE_LIMIT */
 6664         ISPOPMAP(0x01, 0x03),   /* 0x24: MBOX_GET_CLOCK_RATE */
 6665         ISPOPMAP(0x01, 0x07),   /* 0x25: MBOX_GET_ACT_NEG_STATE */
 6666         ISPOPMAP(0x01, 0x07),   /* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
 6667         ISPOPMAP(0x01, 0x07),   /* 0x27: MBOX_GET_PCI_PARAMS */
 6668         ISPOPMAP(0x03, 0x4f),   /* 0x28: MBOX_GET_TARGET_PARAMS */
 6669         ISPOPMAP(0x03, 0x0f),   /* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
 6670         ISPOPMAP(0x01, 0x07),   /* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
 6671         ISPOPMAP(0x00, 0x00),   /* 0x2b: */
 6672         ISPOPMAP(0x00, 0x00),   /* 0x2c: */
 6673         ISPOPMAP(0x00, 0x00),   /* 0x2d: */
 6674         ISPOPMAP(0x00, 0x00),   /* 0x2e: */
 6675         ISPOPMAP(0x00, 0x00),   /* 0x2f: */
 6676         ISPOPMAP(0x03, 0x03),   /* 0x30: MBOX_SET_INIT_SCSI_ID */
 6677         ISPOPMAP(0x07, 0x07),   /* 0x31: MBOX_SET_SELECT_TIMEOUT */
 6678         ISPOPMAP(0xc7, 0xc7),   /* 0x32: MBOX_SET_RETRY_COUNT   */
 6679         ISPOPMAP(0x07, 0x07),   /* 0x33: MBOX_SET_TAG_AGE_LIMIT */
 6680         ISPOPMAP(0x03, 0x03),   /* 0x34: MBOX_SET_CLOCK_RATE */
 6681         ISPOPMAP(0x07, 0x07),   /* 0x35: MBOX_SET_ACT_NEG_STATE */
 6682         ISPOPMAP(0x07, 0x07),   /* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
 6683         ISPOPMAP(0x07, 0x07),   /* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
 6684         ISPOPMAP(0x4f, 0x4f),   /* 0x38: MBOX_SET_TARGET_PARAMS */
 6685         ISPOPMAP(0x0f, 0x0f),   /* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
 6686         ISPOPMAP(0x07, 0x07),   /* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
 6687         ISPOPMAP(0x00, 0x00),   /* 0x3b: */
 6688         ISPOPMAP(0x00, 0x00),   /* 0x3c: */
 6689         ISPOPMAP(0x00, 0x00),   /* 0x3d: */
 6690         ISPOPMAP(0x00, 0x00),   /* 0x3e: */
 6691         ISPOPMAP(0x00, 0x00),   /* 0x3f: */
 6692         ISPOPMAP(0x01, 0x03),   /* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
 6693         ISPOPMAP(0x3f, 0x01),   /* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
 6694         ISPOPMAP(0x03, 0x07),   /* 0x42: MBOX_EXEC_BIOS_IOCB */
 6695         ISPOPMAP(0x00, 0x00),   /* 0x43: */
 6696         ISPOPMAP(0x00, 0x00),   /* 0x44: */
 6697         ISPOPMAP(0x03, 0x03),   /* 0x45: SET SYSTEM PARAMETER */
 6698         ISPOPMAP(0x01, 0x03),   /* 0x46: GET SYSTEM PARAMETER */
 6699         ISPOPMAP(0x00, 0x00),   /* 0x47: */
 6700         ISPOPMAP(0x01, 0xcf),   /* 0x48: GET SCAM CONFIGURATION */
 6701         ISPOPMAP(0xcf, 0xcf),   /* 0x49: SET SCAM CONFIGURATION */
 6702         ISPOPMAP(0x03, 0x03),   /* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
 6703         ISPOPMAP(0x01, 0x03),   /* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
 6704         ISPOPMAP(0x00, 0x00),   /* 0x4c: */
 6705         ISPOPMAP(0x00, 0x00),   /* 0x4d: */
 6706         ISPOPMAP(0x00, 0x00),   /* 0x4e: */
 6707         ISPOPMAP(0x00, 0x00),   /* 0x4f: */
 6708         ISPOPMAP(0xdf, 0xdf),   /* 0x50: LOAD RAM A64 */
 6709         ISPOPMAP(0xdf, 0xdf),   /* 0x51: DUMP RAM A64 */
 6710         ISPOPMAP(0xdf, 0xff),   /* 0x52: INITIALIZE REQUEST QUEUE A64 */
 6711         ISPOPMAP(0xef, 0xff),   /* 0x53: INITIALIZE RESPONSE QUEUE A64 */
 6712         ISPOPMAP(0xcf, 0x01),   /* 0x54: EXECUTE COMMAND IOCB A64 */
 6713         ISPOPMAP(0x07, 0x01),   /* 0x55: ENABLE TARGET MODE */
 6714         ISPOPMAP(0x03, 0x0f),   /* 0x56: GET TARGET STATUS */
 6715         ISPOPMAP(0x00, 0x00),   /* 0x57: */
 6716         ISPOPMAP(0x00, 0x00),   /* 0x58: */
 6717         ISPOPMAP(0x00, 0x00),   /* 0x59: */
 6718         ISPOPMAP(0x03, 0x03),   /* 0x5a: SET DATA OVERRUN RECOVERY MODE */
 6719         ISPOPMAP(0x01, 0x03),   /* 0x5b: GET DATA OVERRUN RECOVERY MODE */
 6720         ISPOPMAP(0x0f, 0x0f),   /* 0x5c: SET HOST DATA */
 6721         ISPOPMAP(0x01, 0x01)    /* 0x5d: GET HOST DATA */
 6722 };
 6723 
 6724 static const char *scsi_mbcmd_names[] = {
 6725         "NO-OP",
 6726         "LOAD RAM",
 6727         "EXEC FIRMWARE",
 6728         "DUMP RAM",
 6729         "WRITE RAM WORD",
 6730         "READ RAM WORD",
 6731         "MAILBOX REG TEST",
 6732         "VERIFY CHECKSUM",
 6733         "ABOUT FIRMWARE",
 6734         NULL,
 6735         NULL,
 6736         NULL,
 6737         NULL,
 6738         NULL,
 6739         "CHECK FIRMWARE",
 6740         NULL,
 6741         "INIT REQUEST QUEUE",
 6742         "INIT RESULT QUEUE",
 6743         "EXECUTE IOCB",
 6744         "WAKE UP",
 6745         "STOP FIRMWARE",
 6746         "ABORT",
 6747         "ABORT DEVICE",
 6748         "ABORT TARGET",
 6749         "BUS RESET",
 6750         "STOP QUEUE",
 6751         "START QUEUE",
 6752         "SINGLE STEP QUEUE",
 6753         "ABORT QUEUE",
 6754         "GET DEV QUEUE STATUS",
 6755         NULL,
 6756         "GET FIRMWARE STATUS",
 6757         "GET INIT SCSI ID",
 6758         "GET SELECT TIMEOUT",
 6759         "GET RETRY COUNT",
 6760         "GET TAG AGE LIMIT",
 6761         "GET CLOCK RATE",
 6762         "GET ACT NEG STATE",
 6763         "GET ASYNC DATA SETUP TIME",
 6764         "GET PCI PARAMS",
 6765         "GET TARGET PARAMS",
 6766         "GET DEV QUEUE PARAMS",
 6767         "GET RESET DELAY PARAMS",
 6768         NULL,
 6769         NULL,
 6770         NULL,
 6771         NULL,
 6772         NULL,
 6773         "SET INIT SCSI ID",
 6774         "SET SELECT TIMEOUT",
 6775         "SET RETRY COUNT",
 6776         "SET TAG AGE LIMIT",
 6777         "SET CLOCK RATE",
 6778         "SET ACT NEG STATE",
 6779         "SET ASYNC DATA SETUP TIME",
 6780         "SET PCI CONTROL PARAMS",
 6781         "SET TARGET PARAMS",
 6782         "SET DEV QUEUE PARAMS",
 6783         "SET RESET DELAY PARAMS",
 6784         NULL,
 6785         NULL,
 6786         NULL,
 6787         NULL,
 6788         NULL,
 6789         "RETURN BIOS BLOCK ADDR",
 6790         "WRITE FOUR RAM WORDS",
 6791         "EXEC BIOS IOCB",
 6792         NULL,
 6793         NULL,
 6794         "SET SYSTEM PARAMETER",
 6795         "GET SYSTEM PARAMETER",
 6796         NULL,
 6797         "GET SCAM CONFIGURATION",
 6798         "SET SCAM CONFIGURATION",
 6799         "SET FIRMWARE FEATURES",
 6800         "GET FIRMWARE FEATURES",
 6801         NULL,
 6802         NULL,
 6803         NULL,
 6804         NULL,
 6805         "LOAD RAM A64",
 6806         "DUMP RAM A64",
 6807         "INITIALIZE REQUEST QUEUE A64",
 6808         "INITIALIZE RESPONSE QUEUE A64",
 6809         "EXECUTE IOCB A64",
 6810         "ENABLE TARGET MODE",
 6811         "GET TARGET MODE STATE",
 6812         NULL,
 6813         NULL,
 6814         NULL,
 6815         "SET DATA OVERRUN RECOVERY MODE",
 6816         "GET DATA OVERRUN RECOVERY MODE",
 6817         "SET HOST DATA",
 6818         "GET HOST DATA",
 6819 };
 6820 
 6821 static const uint32_t mbpfc[] = {
 6822         ISPOPMAP(0x01, 0x01),   /* 0x00: MBOX_NO_OP */
 6823         ISPOPMAP(0x1f, 0x01),   /* 0x01: MBOX_LOAD_RAM */
 6824         ISPOPMAP(0x0f, 0x01),   /* 0x02: MBOX_EXEC_FIRMWARE */
 6825         ISPOPMAP(0xdf, 0x01),   /* 0x03: MBOX_DUMP_RAM */
 6826         ISPOPMAP(0x07, 0x07),   /* 0x04: MBOX_WRITE_RAM_WORD */
 6827         ISPOPMAP(0x03, 0x07),   /* 0x05: MBOX_READ_RAM_WORD */
 6828         ISPOPMAP(0xff, 0xff),   /* 0x06: MBOX_MAILBOX_REG_TEST */
 6829         ISPOPMAP(0x07, 0x07),   /* 0x07: MBOX_VERIFY_CHECKSUM   */
 6830         ISPOPMAP(0x01, 0x4f),   /* 0x08: MBOX_ABOUT_FIRMWARE */
 6831         ISPOPMAP(0xdf, 0x01),   /* 0x09: MBOX_LOAD_RISC_RAM_2100 */
 6832         ISPOPMAP(0xdf, 0x01),   /* 0x0a: DUMP RAM */
 6833         ISPOPMAP(0x1ff, 0x01),  /* 0x0b: MBOX_LOAD_RISC_RAM */
 6834         ISPOPMAP(0x00, 0x00),   /* 0x0c: */
 6835         ISPOPMAP(0x10f, 0x01),  /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
 6836         ISPOPMAP(0x01, 0x05),   /* 0x0e: MBOX_CHECK_FIRMWARE */
 6837         ISPOPMAP(0x10f, 0x05),  /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
 6838         ISPOPMAP(0x1f, 0x11),   /* 0x10: MBOX_INIT_REQ_QUEUE */
 6839         ISPOPMAP(0x2f, 0x21),   /* 0x11: MBOX_INIT_RES_QUEUE */
 6840         ISPOPMAP(0x0f, 0x01),   /* 0x12: MBOX_EXECUTE_IOCB */
 6841         ISPOPMAP(0x03, 0x03),   /* 0x13: MBOX_WAKE_UP   */
 6842         ISPOPMAP(0x01, 0xff),   /* 0x14: MBOX_STOP_FIRMWARE */
 6843         ISPOPMAP(0x4f, 0x01),   /* 0x15: MBOX_ABORT */
 6844         ISPOPMAP(0x07, 0x01),   /* 0x16: MBOX_ABORT_DEVICE */
 6845         ISPOPMAP(0x07, 0x01),   /* 0x17: MBOX_ABORT_TARGET */
 6846         ISPOPMAP(0x03, 0x03),   /* 0x18: MBOX_BUS_RESET */
 6847         ISPOPMAP(0x07, 0x05),   /* 0x19: MBOX_STOP_QUEUE */
 6848         ISPOPMAP(0x07, 0x05),   /* 0x1a: MBOX_START_QUEUE */
 6849         ISPOPMAP(0x07, 0x05),   /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
 6850         ISPOPMAP(0x07, 0x05),   /* 0x1c: MBOX_ABORT_QUEUE */
 6851         ISPOPMAP(0x07, 0x03),   /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
 6852         ISPOPMAP(0x00, 0x00),   /* 0x1e: */
 6853         ISPOPMAP(0x01, 0x07),   /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
 6854         ISPOPMAP(0x01, 0x4f),   /* 0x20: MBOX_GET_LOOP_ID */
 6855         ISPOPMAP(0x00, 0x00),   /* 0x21: */
 6856         ISPOPMAP(0x01, 0x07),   /* 0x22: MBOX_GET_RETRY_COUNT   */
 6857         ISPOPMAP(0x00, 0x00),   /* 0x23: */
 6858         ISPOPMAP(0x00, 0x00),   /* 0x24: */
 6859         ISPOPMAP(0x00, 0x00),   /* 0x25: */
 6860         ISPOPMAP(0x00, 0x00),   /* 0x26: */
 6861         ISPOPMAP(0x00, 0x00),   /* 0x27: */
 6862         ISPOPMAP(0x01, 0x03),   /* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
 6863         ISPOPMAP(0x03, 0x07),   /* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
 6864         ISPOPMAP(0x00, 0x00),   /* 0x2a: */
 6865         ISPOPMAP(0x00, 0x00),   /* 0x2b: */
 6866         ISPOPMAP(0x00, 0x00),   /* 0x2c: */
 6867         ISPOPMAP(0x00, 0x00),   /* 0x2d: */
 6868         ISPOPMAP(0x00, 0x00),   /* 0x2e: */
 6869         ISPOPMAP(0x00, 0x00),   /* 0x2f: */
 6870         ISPOPMAP(0x00, 0x00),   /* 0x30: */
 6871         ISPOPMAP(0x00, 0x00),   /* 0x31: */
 6872         ISPOPMAP(0x07, 0x07),   /* 0x32: MBOX_SET_RETRY_COUNT   */
 6873         ISPOPMAP(0x00, 0x00),   /* 0x33: */
 6874         ISPOPMAP(0x00, 0x00),   /* 0x34: */
 6875         ISPOPMAP(0x00, 0x00),   /* 0x35: */
 6876         ISPOPMAP(0x00, 0x00),   /* 0x36: */
 6877         ISPOPMAP(0x00, 0x00),   /* 0x37: */
 6878         ISPOPMAP(0x0f, 0x01),   /* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
 6879         ISPOPMAP(0x0f, 0x07),   /* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
 6880         ISPOPMAP(0x00, 0x00),   /* 0x3a: */
 6881         ISPOPMAP(0x00, 0x00),   /* 0x3b: */
 6882         ISPOPMAP(0x00, 0x00),   /* 0x3c: */
 6883         ISPOPMAP(0x00, 0x00),   /* 0x3d: */
 6884         ISPOPMAP(0x00, 0x00),   /* 0x3e: */
 6885         ISPOPMAP(0x00, 0x00),   /* 0x3f: */
 6886         ISPOPMAP(0x03, 0x01),   /* 0x40: MBOX_LOOP_PORT_BYPASS */
 6887         ISPOPMAP(0x03, 0x01),   /* 0x41: MBOX_LOOP_PORT_ENABLE */
 6888         ISPOPMAP(0x03, 0x07),   /* 0x42: MBOX_GET_RESOURCE_COUNT */
 6889         ISPOPMAP(0x01, 0x01),   /* 0x43: MBOX_REQUEST_OFFLINE_MODE */
 6890         ISPOPMAP(0x00, 0x00),   /* 0x44: */
 6891         ISPOPMAP(0x00, 0x00),   /* 0x45: */
 6892         ISPOPMAP(0x00, 0x00),   /* 0x46: */
 6893         ISPOPMAP(0xcf, 0x03),   /* 0x47: GET PORT_DATABASE ENHANCED */
 6894         ISPOPMAP(0xcd, 0x01),   /* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */
 6895         ISPOPMAP(0xcd, 0x01),   /* 0x49: MBOX_GET_VP_DATABASE */
 6896         ISPOPMAP(0x2cd, 0x01),  /* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */
 6897         ISPOPMAP(0x00, 0x00),   /* 0x4b: */
 6898         ISPOPMAP(0x00, 0x00),   /* 0x4c: */
 6899         ISPOPMAP(0x00, 0x00),   /* 0x4d: */
 6900         ISPOPMAP(0x00, 0x00),   /* 0x4e: */
 6901         ISPOPMAP(0x00, 0x00),   /* 0x4f: */
 6902         ISPOPMAP(0x00, 0x00),   /* 0x50: */
 6903         ISPOPMAP(0x00, 0x00),   /* 0x51: */
 6904         ISPOPMAP(0x00, 0x00),   /* 0x52: */
 6905         ISPOPMAP(0x00, 0x00),   /* 0x53: */
 6906         ISPOPMAP(0xcf, 0x01),   /* 0x54: EXECUTE IOCB A64 */
 6907         ISPOPMAP(0x00, 0x00),   /* 0x55: */
 6908         ISPOPMAP(0x00, 0x00),   /* 0x56: */
 6909         ISPOPMAP(0x00, 0x00),   /* 0x57: */
 6910         ISPOPMAP(0x00, 0x00),   /* 0x58: */
 6911         ISPOPMAP(0x00, 0x00),   /* 0x59: */
 6912         ISPOPMAP(0x00, 0x00),   /* 0x5a: */
 6913         ISPOPMAP(0x03, 0x01),   /* 0x5b: MBOX_DRIVER_HEARTBEAT */
 6914         ISPOPMAP(0xcf, 0x01),   /* 0x5c: MBOX_FW_HEARTBEAT */
 6915         ISPOPMAP(0x07, 0x03),   /* 0x5d: MBOX_GET_SET_DATA_RATE */
 6916         ISPOPMAP(0x00, 0x00),   /* 0x5e: */
 6917         ISPOPMAP(0x00, 0x00),   /* 0x5f: */
 6918         ISPOPMAP(0xcd, 0x01),   /* 0x60: MBOX_INIT_FIRMWARE */
 6919         ISPOPMAP(0x00, 0x00),   /* 0x61: */
 6920         ISPOPMAP(0x01, 0x01),   /* 0x62: MBOX_INIT_LIP */
 6921         ISPOPMAP(0xcd, 0x03),   /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
 6922         ISPOPMAP(0xcf, 0x01),   /* 0x64: MBOX_GET_PORT_DB */
 6923         ISPOPMAP(0x07, 0x01),   /* 0x65: MBOX_CLEAR_ACA */
 6924         ISPOPMAP(0x07, 0x01),   /* 0x66: MBOX_TARGET_RESET */
 6925         ISPOPMAP(0x07, 0x01),   /* 0x67: MBOX_CLEAR_TASK_SET */
 6926         ISPOPMAP(0x07, 0x01),   /* 0x68: MBOX_ABORT_TASK_SET */
 6927         ISPOPMAP(0x01, 0x07),   /* 0x69: MBOX_GET_FW_STATE */
 6928         ISPOPMAP(0x03, 0xcf),   /* 0x6a: MBOX_GET_PORT_NAME */
 6929         ISPOPMAP(0xcf, 0x01),   /* 0x6b: MBOX_GET_LINK_STATUS */
 6930         ISPOPMAP(0x0f, 0x01),   /* 0x6c: MBOX_INIT_LIP_RESET */
 6931         ISPOPMAP(0x00, 0x00),   /* 0x6d: */
 6932         ISPOPMAP(0xcf, 0x03),   /* 0x6e: MBOX_SEND_SNS */
 6933         ISPOPMAP(0x0f, 0x07),   /* 0x6f: MBOX_FABRIC_LOGIN */
 6934         ISPOPMAP(0x03, 0x01),   /* 0x70: MBOX_SEND_CHANGE_REQUEST */
 6935         ISPOPMAP(0x03, 0x03),   /* 0x71: MBOX_FABRIC_LOGOUT */
 6936         ISPOPMAP(0x0f, 0x0f),   /* 0x72: MBOX_INIT_LIP_LOGIN */
 6937         ISPOPMAP(0x00, 0x00),   /* 0x73: */
 6938         ISPOPMAP(0x07, 0x01),   /* 0x74: LOGIN LOOP PORT */
 6939         ISPOPMAP(0xcf, 0x03),   /* 0x75: GET PORT/NODE NAME LIST */
 6940         ISPOPMAP(0x4f, 0x01),   /* 0x76: SET VENDOR ID */
 6941         ISPOPMAP(0xcd, 0x01),   /* 0x77: INITIALIZE IP MAILBOX */
 6942         ISPOPMAP(0x00, 0x00),   /* 0x78: */
 6943         ISPOPMAP(0x00, 0x00),   /* 0x79: */
 6944         ISPOPMAP(0x00, 0x00),   /* 0x7a: */
 6945         ISPOPMAP(0x00, 0x00),   /* 0x7b: */
 6946         ISPOPMAP(0x4f, 0x03),   /* 0x7c: Get ID List */
 6947         ISPOPMAP(0xcf, 0x01),   /* 0x7d: SEND LFA */
 6948         ISPOPMAP(0x0f, 0x01)    /* 0x7e: LUN RESET */
 6949 };
 6950 /*
 6951  * Footnotes
 6952  *
 6953  * (1): this sets bits 21..16 in mailbox register #8, which we nominally
 6954  *      do not access at this time in the core driver. The caller is
 6955  *      responsible for setting this register first (Gross!). The assumption
 6956  *      is that we won't overflow.
 6957  */
 6958 
 6959 static const char *fc_mbcmd_names[] = {
 6960         "NO-OP",
 6961         "LOAD RAM",
 6962         "EXEC FIRMWARE",
 6963         "DUMP RAM",
 6964         "WRITE RAM WORD",
 6965         "READ RAM WORD",
 6966         "MAILBOX REG TEST",
 6967         "VERIFY CHECKSUM",
 6968         "ABOUT FIRMWARE",
 6969         "LOAD RAM",
 6970         "DUMP RAM",
 6971         "WRITE RAM WORD EXTENDED",
 6972         NULL,
 6973         "READ RAM WORD EXTENDED",
 6974         "CHECK FIRMWARE",
 6975         NULL,
 6976         "INIT REQUEST QUEUE",
 6977         "INIT RESULT QUEUE",
 6978         "EXECUTE IOCB",
 6979         "WAKE UP",
 6980         "STOP FIRMWARE",
 6981         "ABORT",
 6982         "ABORT DEVICE",
 6983         "ABORT TARGET",
 6984         "BUS RESET",
 6985         "STOP QUEUE",
 6986         "START QUEUE",
 6987         "SINGLE STEP QUEUE",
 6988         "ABORT QUEUE",
 6989         "GET DEV QUEUE STATUS",
 6990         NULL,
 6991         "GET FIRMWARE STATUS",
 6992         "GET LOOP ID",
 6993         NULL,
 6994         "GET RETRY COUNT",
 6995         NULL,
 6996         NULL,
 6997         NULL,
 6998         NULL,
 6999         NULL,
 7000         "GET FIRMWARE OPTIONS",
 7001         "GET PORT QUEUE PARAMS",
 7002         NULL,
 7003         NULL,
 7004         NULL,
 7005         NULL,
 7006         NULL,
 7007         NULL,
 7008         NULL,
 7009         NULL,
 7010         "SET RETRY COUNT",
 7011         NULL,
 7012         NULL,
 7013         NULL,
 7014         NULL,
 7015         NULL,
 7016         "SET FIRMWARE OPTIONS",
 7017         "SET PORT QUEUE PARAMS",
 7018         NULL,
 7019         NULL,
 7020         NULL,
 7021         NULL,
 7022         NULL,
 7023         NULL,
 7024         "LOOP PORT BYPASS",
 7025         "LOOP PORT ENABLE",
 7026         "GET RESOURCE COUNT",
 7027         "REQUEST NON PARTICIPATING MODE",
 7028         NULL,
 7029         NULL,
 7030         NULL,
 7031         "GET PORT DATABASE ENHANCED",
 7032         "INIT FIRMWARE MULTI ID",
 7033         "GET VP DATABASE",
 7034         "GET VP DATABASE ENTRY",
 7035         NULL,
 7036         NULL,
 7037         NULL,
 7038         NULL,
 7039         NULL,
 7040         NULL,
 7041         NULL,
 7042         NULL,
 7043         NULL,
 7044         "EXECUTE IOCB A64",
 7045         NULL,
 7046         NULL,
 7047         NULL,
 7048         NULL,
 7049         NULL,
 7050         NULL,
 7051         "DRIVER HEARTBEAT",
 7052         NULL,
 7053         "GET/SET DATA RATE",
 7054         NULL,
 7055         NULL,
 7056         "INIT FIRMWARE",
 7057         NULL,
 7058         "INIT LIP",
 7059         "GET FC-AL POSITION MAP",
 7060         "GET PORT DATABASE",
 7061         "CLEAR ACA",
 7062         "TARGET RESET",
 7063         "CLEAR TASK SET",
 7064         "ABORT TASK SET",
 7065         "GET FW STATE",
 7066         "GET PORT NAME",
 7067         "GET LINK STATUS",
 7068         "INIT LIP RESET",
 7069         NULL,
 7070         "SEND SNS",
 7071         "FABRIC LOGIN",
 7072         "SEND CHANGE REQUEST",
 7073         "FABRIC LOGOUT",
 7074         "INIT LIP LOGIN",
 7075         NULL,
 7076         "LOGIN LOOP PORT",
 7077         "GET PORT/NODE NAME LIST",
 7078         "SET VENDOR ID",
 7079         "INITIALIZE IP MAILBOX",
 7080         NULL,
 7081         NULL,
 7082         NULL,
 7083         NULL,
 7084         "Get ID List",
 7085         "SEND LFA",
 7086         "Lun RESET"
 7087 };
 7088 
 7089 static void
 7090 isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay)
 7091 {
 7092         unsigned int ibits, obits, box, opcode;
 7093         const uint32_t *mcp;
 7094 
 7095         if (IS_FC(isp)) {
 7096                 mcp = mbpfc;
 7097         } else {
 7098                 mcp = mbpscsi;
 7099         }
 7100         opcode = mbp->param[0];
 7101         ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
 7102         obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
 7103         ibits |= mbp->ibits;
 7104         obits |= mbp->obits;
 7105         for (box = 0; box < MAX_MAILBOX(isp); box++) {
 7106                 if (ibits & (1 << box)) {
 7107                         ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
 7108                 }
 7109                 if (nodelay == 0) {
 7110                         isp->isp_mboxtmp[box] = mbp->param[box] = 0;
 7111                 }
 7112         }
 7113         if (nodelay == 0) {
 7114                 isp->isp_lastmbxcmd = opcode;
 7115                 isp->isp_obits = obits;
 7116                 isp->isp_mboxbsy = 1;
 7117         }
 7118         if (IS_24XX(isp)) {
 7119                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
 7120         } else {
 7121                 ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
 7122         }
 7123         /*
 7124          * Oddly enough, if we're not delaying for an answer,
 7125          * delay a bit to give the f/w a chance to pick up the
 7126          * command.
 7127          */
 7128         if (nodelay) {
 7129                 ISP_DELAY(1000);
 7130         }
 7131 }
 7132 
 7133 static void
 7134 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
 7135 {
 7136         const char *cname, *xname;
 7137         char tname[16], mname[16];
 7138         unsigned int lim, ibits, obits, box, opcode;
 7139         const uint32_t *mcp;
 7140 
 7141         if (IS_FC(isp)) {
 7142                 mcp = mbpfc;
 7143                 lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
 7144         } else {
 7145                 mcp = mbpscsi;
 7146                 lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
 7147         }
 7148 
 7149         if ((opcode = mbp->param[0]) >= lim) {
 7150                 mbp->param[0] = MBOX_INVALID_COMMAND;
 7151                 isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
 7152                 return;
 7153         }
 7154 
 7155         ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
 7156         obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
 7157 
 7158         /*
 7159          * Pick up any additional bits that the caller might have set.
 7160          */
 7161         ibits |= mbp->ibits;
 7162         obits |= mbp->obits;
 7163 
 7164         if (ibits == 0 && obits == 0) {
 7165                 mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
 7166                 isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
 7167                 return;
 7168         }
 7169 
 7170         /*
 7171          * Get exclusive usage of mailbox registers.
 7172          */
 7173         if (MBOX_ACQUIRE(isp)) {
 7174                 mbp->param[0] = MBOX_REGS_BUSY;
 7175                 goto out;
 7176         }
 7177 
 7178         for (box = 0; box < MAX_MAILBOX(isp); box++) {
 7179                 if (ibits & (1 << box)) {
 7180                         isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box,
 7181                             mbp->param[box]);
 7182                         ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
 7183                 }
 7184                 isp->isp_mboxtmp[box] = mbp->param[box] = 0;
 7185         }
 7186 
 7187         isp->isp_lastmbxcmd = opcode;
 7188 
 7189         /*
 7190          * We assume that we can't overwrite a previous command.
 7191          */
 7192         isp->isp_obits = obits;
 7193         isp->isp_mboxbsy = 1;
 7194 
 7195         /*
 7196          * Set Host Interrupt condition so that RISC will pick up mailbox regs.
 7197          */
 7198         if (IS_24XX(isp)) {
 7199                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
 7200         } else {
 7201                 ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
 7202         }
 7203 
 7204         /*
 7205          * While we haven't finished the command, spin our wheels here.
 7206          */
 7207         MBOX_WAIT_COMPLETE(isp, mbp);
 7208 
 7209         /*
 7210          * Did the command time out?
 7211          */
 7212         if (mbp->param[0] == MBOX_TIMEOUT) {
 7213                 isp->isp_mboxbsy = 0;
 7214                 MBOX_RELEASE(isp);
 7215                 goto out;
 7216         }
 7217 
 7218         /*
 7219          * Copy back output registers.
 7220          */
 7221         for (box = 0; box < MAX_MAILBOX(isp); box++) {
 7222                 if (obits & (1 << box)) {
 7223                         mbp->param[box] = isp->isp_mboxtmp[box];
 7224                         isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box,
 7225                             mbp->param[box]);
 7226                 }
 7227         }
 7228 
 7229         isp->isp_mboxbsy = 0;
 7230         MBOX_RELEASE(isp);
 7231  out:
 7232         if (mbp->logval == 0 || opcode == MBOX_EXEC_FIRMWARE) {
 7233                 return;
 7234         }
 7235         cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
 7236         if (cname == NULL) {
 7237                 cname = tname;
 7238                 ISP_SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
 7239         }
 7240 
 7241         /*
 7242          * Just to be chatty here...
 7243          */
 7244         xname = NULL;
 7245         switch (mbp->param[0]) {
 7246         case MBOX_COMMAND_COMPLETE:
 7247                 break;
 7248         case MBOX_INVALID_COMMAND:
 7249                 if (mbp->logval & MBLOGMASK(MBOX_COMMAND_COMPLETE)) {
 7250                         xname = "INVALID COMMAND";
 7251                 }
 7252                 break;
 7253         case MBOX_HOST_INTERFACE_ERROR:
 7254                 if (mbp->logval & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR)) {
 7255                         xname = "HOST INTERFACE ERROR";
 7256                 }
 7257                 break;
 7258         case MBOX_TEST_FAILED:
 7259                 if (mbp->logval & MBLOGMASK(MBOX_TEST_FAILED)) {
 7260                         xname = "TEST FAILED";
 7261                 }
 7262                 break;
 7263         case MBOX_COMMAND_ERROR:
 7264                 if (mbp->logval & MBLOGMASK(MBOX_COMMAND_ERROR)) {
 7265                         xname = "COMMAND ERROR";
 7266                 }
 7267                 break;
 7268         case MBOX_COMMAND_PARAM_ERROR:
 7269                 if (mbp->logval & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR)) {
 7270                         xname = "COMMAND PARAMETER ERROR";
 7271                 }
 7272                 break;
 7273         case MBOX_LOOP_ID_USED:
 7274                 if (mbp->logval & MBLOGMASK(MBOX_LOOP_ID_USED)) {
 7275                         xname = "LOOP ID ALREADY IN USE";
 7276                 }
 7277                 break;
 7278         case MBOX_PORT_ID_USED:
 7279                 if (mbp->logval & MBLOGMASK(MBOX_PORT_ID_USED)) {
 7280                         xname = "PORT ID ALREADY IN USE";
 7281                 }
 7282                 break;
 7283         case MBOX_ALL_IDS_USED:
 7284                 if (mbp->logval & MBLOGMASK(MBOX_ALL_IDS_USED)) {
 7285                         xname = "ALL LOOP IDS IN USE";
 7286                 }
 7287                 break;
 7288         case MBOX_REGS_BUSY:
 7289                 xname = "REGISTERS BUSY";
 7290                 break;
 7291         case MBOX_TIMEOUT:
 7292                 xname = "TIMEOUT";
 7293                 break;
 7294         default:
 7295                 ISP_SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
 7296                 xname = mname;
 7297                 break;
 7298         }
 7299         if (xname) {
 7300                 isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
 7301                     cname, xname);
 7302         }
 7303 }
 7304 
 7305 static void
 7306 isp_fw_state(ispsoftc_t *isp, int chan)
 7307 {
 7308         if (IS_FC(isp)) {
 7309                 mbreg_t mbs;
 7310                 fcparam *fcp = FCPARAM(isp, chan);
 7311 
 7312                 MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0);
 7313                 isp_mboxcmd(isp, &mbs);
 7314                 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 7315                         fcp->isp_fwstate = mbs.param[1];
 7316                 }
 7317         }
 7318 }
 7319 
 7320 static void
 7321 isp_spi_update(ispsoftc_t *isp, int chan)
 7322 {
 7323         int tgt;
 7324         mbreg_t mbs;
 7325         sdparam *sdp;
 7326 
 7327         if (IS_FC(isp)) {
 7328                 /*
 7329                  * There are no 'per-bus' settings for Fibre Channel.
 7330                  */
 7331                 return;
 7332         }
 7333         sdp = SDPARAM(isp, chan);
 7334         sdp->update = 0;
 7335 
 7336         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 7337                 uint16_t flags, period, offset;
 7338                 int get;
 7339 
 7340                 if (sdp->isp_devparam[tgt].dev_enable == 0) {
 7341                         sdp->isp_devparam[tgt].dev_update = 0;
 7342                         sdp->isp_devparam[tgt].dev_refresh = 0;
 7343                         isp_prt(isp, ISP_LOGDEBUG0, "skipping target %d bus %d update", tgt, chan);
 7344                         continue;
 7345                 }
 7346                 /*
 7347                  * If the goal is to update the status of the device,
 7348                  * take what's in goal_flags and try and set the device
 7349                  * toward that. Otherwise, if we're just refreshing the
 7350                  * current device state, get the current parameters.
 7351                  */
 7352 
 7353                 MBSINIT(&mbs, 0, MBLOGALL, 0);
 7354 
 7355                 /*
 7356                  * Refresh overrides set
 7357                  */
 7358                 if (sdp->isp_devparam[tgt].dev_refresh) {
 7359                         mbs.param[0] = MBOX_GET_TARGET_PARAMS;
 7360                         get = 1;
 7361                 } else if (sdp->isp_devparam[tgt].dev_update) {
 7362                         mbs.param[0] = MBOX_SET_TARGET_PARAMS;
 7363 
 7364                         /*
 7365                          * Make sure goal_flags has "Renegotiate on Error"
 7366                          * on and "Freeze Queue on Error" off.
 7367                          */
 7368                         sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
 7369                         sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
 7370                         mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
 7371 
 7372                         /*
 7373                          * Insist that PARITY must be enabled
 7374                          * if SYNC or WIDE is enabled.
 7375                          */
 7376                         if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
 7377                                 mbs.param[2] |= DPARM_PARITY;
 7378                         }
 7379 
 7380                         if (mbs.param[2] & DPARM_SYNC) {
 7381                                 mbs.param[3] =
 7382                                     (sdp->isp_devparam[tgt].goal_offset << 8) |
 7383                                     (sdp->isp_devparam[tgt].goal_period);
 7384                         }
 7385                         /*
 7386                          * A command completion later that has
 7387                          * RQSTF_NEGOTIATION set can cause
 7388                          * the dev_refresh/announce cycle also.
 7389                          *
 7390                          * Note: It is really important to update our current
 7391                          * flags with at least the state of TAG capabilities-
 7392                          * otherwise we might try and send a tagged command
 7393                          * when we have it all turned off. So change it here
 7394                          * to say that current already matches goal.
 7395                          */
 7396                         sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
 7397                         sdp->isp_devparam[tgt].actv_flags |=
 7398                             (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
 7399                         isp_prt(isp, ISP_LOGDEBUG0, "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
 7400                             chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff);
 7401                         get = 0;
 7402                 } else {
 7403                         continue;
 7404                 }
 7405                 mbs.param[1] = (chan << 15) | (tgt << 8);
 7406                 isp_mboxcmd(isp, &mbs);
 7407                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 7408                         continue;
 7409                 }
 7410                 if (get == 0) {
 7411                         sdp->sendmarker = 1;
 7412                         sdp->isp_devparam[tgt].dev_update = 0;
 7413                         sdp->isp_devparam[tgt].dev_refresh = 1;
 7414                 } else {
 7415                         sdp->isp_devparam[tgt].dev_refresh = 0;
 7416                         flags = mbs.param[2];
 7417                         period = mbs.param[3] & 0xff;
 7418                         offset = mbs.param[3] >> 8;
 7419                         sdp->isp_devparam[tgt].actv_flags = flags;
 7420                         sdp->isp_devparam[tgt].actv_period = period;
 7421                         sdp->isp_devparam[tgt].actv_offset = offset;
 7422                         isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, chan, tgt);
 7423                 }
 7424         }
 7425 
 7426         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 7427                 if (sdp->isp_devparam[tgt].dev_update ||
 7428                     sdp->isp_devparam[tgt].dev_refresh) {
 7429                         sdp->update = 1;
 7430                         break;
 7431                 }
 7432         }
 7433 }
 7434 
 7435 static void
 7436 isp_setdfltsdparm(ispsoftc_t *isp)
 7437 {
 7438         int tgt;
 7439         sdparam *sdp, *sdp1;
 7440 
 7441         sdp = SDPARAM(isp, 0);
 7442         sdp->role = GET_DEFAULT_ROLE(isp, 0);
 7443         if (IS_DUALBUS(isp)) {
 7444                 sdp1 = sdp + 1;
 7445                 sdp1->role = GET_DEFAULT_ROLE(isp, 1);
 7446         } else {
 7447                 sdp1 = NULL;
 7448         }
 7449 
 7450         /*
 7451          * Establish some default parameters.
 7452          */
 7453         sdp->isp_cmd_dma_burst_enable = 0;
 7454         sdp->isp_data_dma_burst_enabl = 1;
 7455         sdp->isp_fifo_threshold = 0;
 7456         sdp->isp_initiator_id = DEFAULT_IID(isp, 0);
 7457         if (isp->isp_type >= ISP_HA_SCSI_1040) {
 7458                 sdp->isp_async_data_setup = 9;
 7459         } else {
 7460                 sdp->isp_async_data_setup = 6;
 7461         }
 7462         sdp->isp_selection_timeout = 250;
 7463         sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
 7464         sdp->isp_tag_aging = 8;
 7465         sdp->isp_bus_reset_delay = 5;
 7466         /*
 7467          * Don't retry selection, busy or queue full automatically- reflect
 7468          * these back to us.
 7469          */
 7470         sdp->isp_retry_count = 0;
 7471         sdp->isp_retry_delay = 0;
 7472 
 7473         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 7474                 sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
 7475                 sdp->isp_devparam[tgt].dev_enable = 1;
 7476         }
 7477 
 7478         /*
 7479          * The trick here is to establish a default for the default (honk!)
 7480          * state (goal_flags). Then try and get the current status from
 7481          * the card to fill in the current state. We don't, in fact, set
 7482          * the default to the SAFE default state- that's not the goal state.
 7483          */
 7484         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 7485                 uint8_t off, per;
 7486                 sdp->isp_devparam[tgt].actv_offset = 0;
 7487                 sdp->isp_devparam[tgt].actv_period = 0;
 7488                 sdp->isp_devparam[tgt].actv_flags = 0;
 7489 
 7490                 sdp->isp_devparam[tgt].goal_flags =
 7491                     sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
 7492 
 7493                 /*
 7494                  * We default to Wide/Fast for versions less than a 1040
 7495                  * (unless it's SBus).
 7496                  */
 7497                 if (IS_ULTRA3(isp)) {
 7498                         off = ISP_80M_SYNCPARMS >> 8;
 7499                         per = ISP_80M_SYNCPARMS & 0xff;
 7500                 } else if (IS_ULTRA2(isp)) {
 7501                         off = ISP_40M_SYNCPARMS >> 8;
 7502                         per = ISP_40M_SYNCPARMS & 0xff;
 7503                 } else if (IS_1240(isp)) {
 7504                         off = ISP_20M_SYNCPARMS >> 8;
 7505                         per = ISP_20M_SYNCPARMS & 0xff;
 7506                 } else if ((isp->isp_bustype == ISP_BT_SBUS &&
 7507                     isp->isp_type < ISP_HA_SCSI_1020A) ||
 7508                     (isp->isp_bustype == ISP_BT_PCI &&
 7509                     isp->isp_type < ISP_HA_SCSI_1040) ||
 7510                     (isp->isp_clock && isp->isp_clock < 60) ||
 7511                     (sdp->isp_ultramode == 0)) {
 7512                         off = ISP_10M_SYNCPARMS >> 8;
 7513                         per = ISP_10M_SYNCPARMS & 0xff;
 7514                 } else {
 7515                         off = ISP_20M_SYNCPARMS_1040 >> 8;
 7516                         per = ISP_20M_SYNCPARMS_1040 & 0xff;
 7517                 }
 7518                 sdp->isp_devparam[tgt].goal_offset =
 7519                     sdp->isp_devparam[tgt].nvrm_offset = off;
 7520                 sdp->isp_devparam[tgt].goal_period =
 7521                     sdp->isp_devparam[tgt].nvrm_period = per;
 7522 
 7523         }
 7524 
 7525         /*
 7526          * If we're a dual bus card, just copy the data over
 7527          */
 7528         if (sdp1) {
 7529                 *sdp1 = *sdp;
 7530                 sdp1->isp_initiator_id = DEFAULT_IID(isp, 1);
 7531         }
 7532 
 7533         /*
 7534          * If we've not been told to avoid reading NVRAM, try and read it.
 7535          * If we're successful reading it, we can then return because NVRAM
 7536          * will tell us what the desired settings are. Otherwise, we establish
 7537          * some reasonable 'fake' nvram and goal defaults.
 7538          */
 7539         if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
 7540                 mbreg_t mbs;
 7541 
 7542                 if (isp_read_nvram(isp, 0) == 0) {
 7543                         if (IS_DUALBUS(isp)) {
 7544                                 if (isp_read_nvram(isp, 1) == 0) {
 7545                                         return;
 7546                                 }
 7547                         }
 7548                 }
 7549                 MBSINIT(&mbs, MBOX_GET_ACT_NEG_STATE, MBLOGNONE, 0);
 7550                 isp_mboxcmd(isp, &mbs);
 7551                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 7552                         sdp->isp_req_ack_active_neg = 1;
 7553                         sdp->isp_data_line_active_neg = 1;
 7554                         if (sdp1) {
 7555                                 sdp1->isp_req_ack_active_neg = 1;
 7556                                 sdp1->isp_data_line_active_neg = 1;
 7557                         }
 7558                 } else {
 7559                         sdp->isp_req_ack_active_neg =
 7560                             (mbs.param[1] >> 4) & 0x1;
 7561                         sdp->isp_data_line_active_neg =
 7562                             (mbs.param[1] >> 5) & 0x1;
 7563                         if (sdp1) {
 7564                                 sdp1->isp_req_ack_active_neg =
 7565                                     (mbs.param[2] >> 4) & 0x1;
 7566                                 sdp1->isp_data_line_active_neg =
 7567                                     (mbs.param[2] >> 5) & 0x1;
 7568                         }
 7569                 }
 7570         }
 7571 
 7572 }
 7573 
 7574 static void
 7575 isp_setdfltfcparm(ispsoftc_t *isp, int chan)
 7576 {
 7577         fcparam *fcp = FCPARAM(isp, chan);
 7578 
 7579         /*
 7580          * Establish some default parameters.
 7581          */
 7582         fcp->role = GET_DEFAULT_ROLE(isp, chan);
 7583         fcp->isp_maxalloc = ICB_DFLT_ALLOC;
 7584         fcp->isp_retry_delay = ICB_DFLT_RDELAY;
 7585         fcp->isp_retry_count = ICB_DFLT_RCOUNT;
 7586         fcp->isp_loopid = DEFAULT_LOOPID(isp, chan);
 7587         fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
 7588         fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
 7589         fcp->isp_fwoptions = 0;
 7590         fcp->isp_lasthdl = NIL_HANDLE;
 7591 
 7592         if (IS_24XX(isp)) {
 7593                 fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS;
 7594                 fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS;
 7595                 if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
 7596                         fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
 7597                 }
 7598                 fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
 7599         } else {
 7600                 fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
 7601                 fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
 7602                 fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
 7603                 if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
 7604                         fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
 7605                 }
 7606                 /*
 7607                  * Make sure this is turned off now until we get
 7608                  * extended options from NVRAM
 7609                  */
 7610                 fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
 7611         }
 7612 
 7613 
 7614         /*
 7615          * Now try and read NVRAM unless told to not do so.
 7616          * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
 7617          */
 7618         if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
 7619                 int i, j = 0;
 7620                 /*
 7621                  * Give a couple of tries at reading NVRAM.
 7622                  */
 7623                 for (i = 0; i < 2; i++) {
 7624                         j = isp_read_nvram(isp, chan);
 7625                         if (j == 0) {
 7626                                 break;
 7627                         }
 7628                 }
 7629                 if (j) {
 7630                         isp->isp_confopts |= ISP_CFG_NONVRAM;
 7631                 }
 7632         }
 7633 
 7634         fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan);
 7635         fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan);
 7636         isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s",
 7637             chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn),
 7638             (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn),
 7639             isp_class3_roles[fcp->role]);
 7640 }
 7641 
 7642 /*
 7643  * Re-initialize the ISP and complete all orphaned commands
 7644  * with a 'botched' notice. The reset/init routines should
 7645  * not disturb an already active list of commands.
 7646  */
 7647 
 7648 void
 7649 isp_reinit(ispsoftc_t *isp, int do_load_defaults)
 7650 {
 7651         int i;
 7652 
 7653         isp_reset(isp, do_load_defaults);
 7654 
 7655         if (isp->isp_state != ISP_RESETSTATE) {
 7656                 isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
 7657                 ISP_DISABLE_INTS(isp);
 7658                 goto cleanup;
 7659         }
 7660 
 7661         isp_init(isp);
 7662 
 7663         if (isp->isp_state == ISP_INITSTATE) {
 7664                 isp->isp_state = ISP_RUNSTATE;
 7665         }
 7666 
 7667         if (isp->isp_state != ISP_RUNSTATE) {
 7668 #ifndef ISP_TARGET_MODE
 7669                 isp_prt(isp, ISP_LOGWARN, "%s: not at runstate", __func__);
 7670 #endif
 7671                 ISP_DISABLE_INTS(isp);
 7672                 if (IS_FC(isp)) {
 7673                         /*
 7674                          * If we're in ISP_ROLE_NONE, turn off the lasers.
 7675                          */
 7676                         if (!IS_24XX(isp)) {
 7677                                 ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
 7678                                 ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
 7679                                 ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
 7680                                 ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
 7681                                 ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
 7682                         }
 7683                 }
 7684         }
 7685 
 7686  cleanup:
 7687 
 7688         isp->isp_nactive = 0;
 7689 
 7690         isp_clear_commands(isp);
 7691         if (IS_FC(isp)) {
 7692                 for (i = 0; i < isp->isp_nchan; i++) {
 7693                         ISP_MARK_PORTDB(isp, i, -1);
 7694                 }
 7695         }
 7696 }
 7697 
 7698 /*
 7699  * NVRAM Routines
 7700  */
 7701 static int
 7702 isp_read_nvram(ispsoftc_t *isp, int bus)
 7703 {
 7704         int i, amt, retval;
 7705         uint8_t csum, minversion;
 7706         union {
 7707                 uint8_t _x[ISP2400_NVRAM_SIZE];
 7708                 uint16_t _s[ISP2400_NVRAM_SIZE>>1];
 7709         } _n;
 7710 #define nvram_data      _n._x
 7711 #define nvram_words     _n._s
 7712 
 7713         if (IS_24XX(isp)) {
 7714                 return (isp_read_nvram_2400(isp, nvram_data));
 7715         } else if (IS_FC(isp)) {
 7716                 amt = ISP2100_NVRAM_SIZE;
 7717                 minversion = 1;
 7718         } else if (IS_ULTRA2(isp)) {
 7719                 amt = ISP1080_NVRAM_SIZE;
 7720                 minversion = 0;
 7721         } else {
 7722                 amt = ISP_NVRAM_SIZE;
 7723                 minversion = 2;
 7724         }
 7725 
 7726         for (i = 0; i < amt>>1; i++) {
 7727                 isp_rdnvram_word(isp, i, &nvram_words[i]);
 7728         }
 7729 
 7730         if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
 7731             nvram_data[2] != 'P') {
 7732                 if (isp->isp_bustype != ISP_BT_SBUS) {
 7733                         isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
 7734                         isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x", nvram_data[0], nvram_data[1], nvram_data[2]);
 7735                 }
 7736                 retval = -1;
 7737                 goto out;
 7738         }
 7739 
 7740         for (csum = 0, i = 0; i < amt; i++) {
 7741                 csum += nvram_data[i];
 7742         }
 7743         if (csum != 0) {
 7744                 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
 7745                 retval = -1;
 7746                 goto out;
 7747         }
 7748 
 7749         if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
 7750                 isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
 7751                     ISP_NVRAM_VERSION(nvram_data));
 7752                 retval = -1;
 7753                 goto out;
 7754         }
 7755 
 7756         if (IS_ULTRA3(isp)) {
 7757                 isp_parse_nvram_12160(isp, bus, nvram_data);
 7758         } else if (IS_1080(isp)) {
 7759                 isp_parse_nvram_1080(isp, bus, nvram_data);
 7760         } else if (IS_1280(isp) || IS_1240(isp)) {
 7761                 isp_parse_nvram_1080(isp, bus, nvram_data);
 7762         } else if (IS_SCSI(isp)) {
 7763                 isp_parse_nvram_1020(isp, nvram_data);
 7764         } else {
 7765                 isp_parse_nvram_2100(isp, nvram_data);
 7766         }
 7767         retval = 0;
 7768 out:
 7769         return (retval);
 7770 #undef  nvram_data
 7771 #undef  nvram_words
 7772 }
 7773 
 7774 static int
 7775 isp_read_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
 7776 {
 7777         int retval = 0;
 7778         uint32_t addr, csum, lwrds, *dptr;
 7779 
 7780         if (isp->isp_port) {
 7781                 addr = ISP2400_NVRAM_PORT1_ADDR;
 7782         } else {
 7783                 addr = ISP2400_NVRAM_PORT0_ADDR;
 7784         }
 7785 
 7786         dptr = (uint32_t *) nvram_data;
 7787         for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
 7788                 isp_rd_2400_nvram(isp, addr++, dptr++);
 7789         }
 7790         if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
 7791             nvram_data[2] != 'P') {
 7792                 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
 7793                     nvram_data[0], nvram_data[1], nvram_data[2]);
 7794                 retval = -1;
 7795                 goto out;
 7796         }
 7797         dptr = (uint32_t *) nvram_data;
 7798         for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
 7799                 uint32_t tmp;
 7800                 ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
 7801                 csum += tmp;
 7802         }
 7803         if (csum != 0) {
 7804                 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
 7805                 retval = -1;
 7806                 goto out;
 7807         }
 7808         isp_parse_nvram_2400(isp, nvram_data);
 7809 out:
 7810         return (retval);
 7811 }
 7812 
 7813 static void
 7814 isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
 7815 {
 7816         int i, cbits;
 7817         uint16_t bit, rqst;
 7818 
 7819         ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
 7820         ISP_DELAY(10);
 7821         ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
 7822         ISP_DELAY(10);
 7823 
 7824         if (IS_FC(isp)) {
 7825                 wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
 7826                 if (IS_2312(isp) && isp->isp_port) {
 7827                         wo += 128;
 7828                 }
 7829                 rqst = (ISP_NVRAM_READ << 8) | wo;
 7830                 cbits = 10;
 7831         } else if (IS_ULTRA2(isp)) {
 7832                 wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
 7833                 rqst = (ISP_NVRAM_READ << 8) | wo;
 7834                 cbits = 10;
 7835         } else {
 7836                 wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
 7837                 rqst = (ISP_NVRAM_READ << 6) | wo;
 7838                 cbits = 8;
 7839         }
 7840 
 7841         /*
 7842          * Clock the word select request out...
 7843          */
 7844         for (i = cbits; i >= 0; i--) {
 7845                 if ((rqst >> i) & 1) {
 7846                         bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
 7847                 } else {
 7848                         bit = BIU_NVRAM_SELECT;
 7849                 }
 7850                 ISP_WRITE(isp, BIU_NVRAM, bit);
 7851                 ISP_DELAY(10);
 7852                 (void)ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
 7853                 ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
 7854                 ISP_DELAY(10);
 7855                 (void)ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
 7856                 ISP_WRITE(isp, BIU_NVRAM, bit);
 7857                 ISP_DELAY(10);
 7858                 (void)ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
 7859         }
 7860         /*
 7861          * Now read the result back in (bits come back in MSB format).
 7862          */
 7863         *rp = 0;
 7864         for (i = 0; i < 16; i++) {
 7865                 uint16_t rv;
 7866                 *rp <<= 1;
 7867                 ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
 7868                 ISP_DELAY(10);
 7869                 rv = ISP_READ(isp, BIU_NVRAM);
 7870                 if (rv & BIU_NVRAM_DATAIN) {
 7871                         *rp |= 1;
 7872                 }
 7873                 ISP_DELAY(10);
 7874                 ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
 7875                 ISP_DELAY(10);
 7876                 (void)ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
 7877         }
 7878         ISP_WRITE(isp, BIU_NVRAM, 0);
 7879         ISP_DELAY(10);
 7880         (void)ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
 7881         ISP_SWIZZLE_NVRAM_WORD(isp, rp);
 7882 }
 7883 
 7884 static void
 7885 isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
 7886 {
 7887         int loops = 0;
 7888         uint32_t base = 0x7ffe0000;
 7889         uint32_t tmp = 0;
 7890 
 7891         if (IS_25XX(isp)) {
 7892                 base = 0x7ff00000 | 0x48000;
 7893         }
 7894         ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
 7895         for (loops = 0; loops < 5000; loops++) {
 7896                 ISP_DELAY(10);
 7897                 tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
 7898                 if ((tmp & (1U << 31)) != 0) {
 7899                         break;
 7900                 }
 7901         }
 7902         if (tmp & (1U << 31)) {
 7903                 *rp = ISP_READ(isp, BIU2400_FLASH_DATA);
 7904                 ISP_SWIZZLE_NVRAM_LONG(isp, rp);
 7905         } else {
 7906                 *rp = 0xffffffff;
 7907         }
 7908 }
 7909 
 7910 static void
 7911 isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
 7912 {
 7913         sdparam *sdp = SDPARAM(isp, 0);
 7914         int tgt;
 7915 
 7916         sdp->isp_fifo_threshold =
 7917                 ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
 7918                 (ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
 7919 
 7920         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
 7921                 sdp->isp_initiator_id =
 7922                         ISP_NVRAM_INITIATOR_ID(nvram_data);
 7923 
 7924         sdp->isp_bus_reset_delay =
 7925                 ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
 7926 
 7927         sdp->isp_retry_count =
 7928                 ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
 7929 
 7930         sdp->isp_retry_delay =
 7931                 ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
 7932 
 7933         sdp->isp_async_data_setup =
 7934                 ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
 7935 
 7936         if (isp->isp_type >= ISP_HA_SCSI_1040) {
 7937                 if (sdp->isp_async_data_setup < 9) {
 7938                         sdp->isp_async_data_setup = 9;
 7939                 }
 7940         } else {
 7941                 if (sdp->isp_async_data_setup != 6) {
 7942                         sdp->isp_async_data_setup = 6;
 7943                 }
 7944         }
 7945 
 7946         sdp->isp_req_ack_active_neg =
 7947                 ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
 7948 
 7949         sdp->isp_data_line_active_neg =
 7950                 ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
 7951 
 7952         sdp->isp_data_dma_burst_enabl =
 7953                 ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
 7954 
 7955         sdp->isp_cmd_dma_burst_enable =
 7956                 ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
 7957 
 7958         sdp->isp_tag_aging =
 7959                 ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
 7960 
 7961         sdp->isp_selection_timeout =
 7962                 ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
 7963 
 7964         sdp->isp_max_queue_depth =
 7965                 ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
 7966 
 7967         sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
 7968 
 7969         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 7970                 sdp->isp_devparam[tgt].dev_enable =
 7971                         ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
 7972                 sdp->isp_devparam[tgt].exc_throttle =
 7973                         ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
 7974                 sdp->isp_devparam[tgt].nvrm_offset =
 7975                         ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
 7976                 sdp->isp_devparam[tgt].nvrm_period =
 7977                         ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
 7978                 /*
 7979                  * We probably shouldn't lie about this, but it
 7980                  * it makes it much safer if we limit NVRAM values
 7981                  * to sanity.
 7982                  */
 7983                 if (isp->isp_type < ISP_HA_SCSI_1040) {
 7984                         /*
 7985                          * If we're not ultra, we can't possibly
 7986                          * be a shorter period than this.
 7987                          */
 7988                         if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
 7989                                 sdp->isp_devparam[tgt].nvrm_period = 0x19;
 7990                         }
 7991                         if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
 7992                                 sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
 7993                         }
 7994                 } else {
 7995                         if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
 7996                                 sdp->isp_devparam[tgt].nvrm_offset = 0x8;
 7997                         }
 7998                 }
 7999                 sdp->isp_devparam[tgt].nvrm_flags = 0;
 8000                 if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
 8001                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
 8002                 sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
 8003                 if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
 8004                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
 8005                 if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
 8006                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
 8007                 if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
 8008                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
 8009                 if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
 8010                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
 8011                 if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
 8012                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
 8013                 sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
 8014                 sdp->isp_devparam[tgt].goal_offset =
 8015                     sdp->isp_devparam[tgt].nvrm_offset;
 8016                 sdp->isp_devparam[tgt].goal_period =
 8017                     sdp->isp_devparam[tgt].nvrm_period;
 8018                 sdp->isp_devparam[tgt].goal_flags =
 8019                     sdp->isp_devparam[tgt].nvrm_flags;
 8020         }
 8021 }
 8022 
 8023 static void
 8024 isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
 8025 {
 8026         sdparam *sdp = SDPARAM(isp, bus);
 8027         int tgt;
 8028 
 8029         sdp->isp_fifo_threshold =
 8030             ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
 8031 
 8032         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
 8033                 sdp->isp_initiator_id =
 8034                     ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
 8035 
 8036         sdp->isp_bus_reset_delay =
 8037             ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
 8038 
 8039         sdp->isp_retry_count =
 8040             ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
 8041 
 8042         sdp->isp_retry_delay =
 8043             ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
 8044 
 8045         sdp->isp_async_data_setup =
 8046             ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
 8047 
 8048         sdp->isp_req_ack_active_neg =
 8049             ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
 8050 
 8051         sdp->isp_data_line_active_neg =
 8052             ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
 8053 
 8054         sdp->isp_data_dma_burst_enabl =
 8055             ISP1080_NVRAM_BURST_ENABLE(nvram_data);
 8056 
 8057         sdp->isp_cmd_dma_burst_enable =
 8058             ISP1080_NVRAM_BURST_ENABLE(nvram_data);
 8059 
 8060         sdp->isp_selection_timeout =
 8061             ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
 8062 
 8063         sdp->isp_max_queue_depth =
 8064              ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
 8065 
 8066         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 8067                 sdp->isp_devparam[tgt].dev_enable =
 8068                     ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
 8069                 sdp->isp_devparam[tgt].exc_throttle =
 8070                         ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
 8071                 sdp->isp_devparam[tgt].nvrm_offset =
 8072                         ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
 8073                 sdp->isp_devparam[tgt].nvrm_period =
 8074                         ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
 8075                 sdp->isp_devparam[tgt].nvrm_flags = 0;
 8076                 if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
 8077                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
 8078                 sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
 8079                 if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
 8080                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
 8081                 if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
 8082                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
 8083                 if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
 8084                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
 8085                 if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
 8086                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
 8087                 if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
 8088                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
 8089                 sdp->isp_devparam[tgt].actv_flags = 0;
 8090                 sdp->isp_devparam[tgt].goal_offset =
 8091                     sdp->isp_devparam[tgt].nvrm_offset;
 8092                 sdp->isp_devparam[tgt].goal_period =
 8093                     sdp->isp_devparam[tgt].nvrm_period;
 8094                 sdp->isp_devparam[tgt].goal_flags =
 8095                     sdp->isp_devparam[tgt].nvrm_flags;
 8096         }
 8097 }
 8098 
 8099 static void
 8100 isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
 8101 {
 8102         sdparam *sdp = SDPARAM(isp, bus);
 8103         int tgt;
 8104 
 8105         sdp->isp_fifo_threshold =
 8106             ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
 8107 
 8108         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
 8109                 sdp->isp_initiator_id =
 8110                     ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
 8111 
 8112         sdp->isp_bus_reset_delay =
 8113             ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
 8114 
 8115         sdp->isp_retry_count =
 8116             ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
 8117 
 8118         sdp->isp_retry_delay =
 8119             ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
 8120 
 8121         sdp->isp_async_data_setup =
 8122             ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
 8123 
 8124         sdp->isp_req_ack_active_neg =
 8125             ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
 8126 
 8127         sdp->isp_data_line_active_neg =
 8128             ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
 8129 
 8130         sdp->isp_data_dma_burst_enabl =
 8131             ISP12160_NVRAM_BURST_ENABLE(nvram_data);
 8132 
 8133         sdp->isp_cmd_dma_burst_enable =
 8134             ISP12160_NVRAM_BURST_ENABLE(nvram_data);
 8135 
 8136         sdp->isp_selection_timeout =
 8137             ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
 8138 
 8139         sdp->isp_max_queue_depth =
 8140              ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
 8141 
 8142         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 8143                 sdp->isp_devparam[tgt].dev_enable =
 8144                     ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
 8145                 sdp->isp_devparam[tgt].exc_throttle =
 8146                         ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
 8147                 sdp->isp_devparam[tgt].nvrm_offset =
 8148                         ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
 8149                 sdp->isp_devparam[tgt].nvrm_period =
 8150                         ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
 8151                 sdp->isp_devparam[tgt].nvrm_flags = 0;
 8152                 if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
 8153                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
 8154                 sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
 8155                 if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
 8156                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
 8157                 if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
 8158                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
 8159                 if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
 8160                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
 8161                 if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
 8162                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
 8163                 if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
 8164                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
 8165                 sdp->isp_devparam[tgt].actv_flags = 0;
 8166                 sdp->isp_devparam[tgt].goal_offset =
 8167                     sdp->isp_devparam[tgt].nvrm_offset;
 8168                 sdp->isp_devparam[tgt].goal_period =
 8169                     sdp->isp_devparam[tgt].nvrm_period;
 8170                 sdp->isp_devparam[tgt].goal_flags =
 8171                     sdp->isp_devparam[tgt].nvrm_flags;
 8172         }
 8173 }
 8174 
 8175 static void
 8176 isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
 8177 {
 8178         fcparam *fcp = FCPARAM(isp, 0);
 8179         uint64_t wwn;
 8180 
 8181         /*
 8182          * There is NVRAM storage for both Port and Node entities-
 8183          * but the Node entity appears to be unused on all the cards
 8184          * I can find. However, we should account for this being set
 8185          * at some point in the future.
 8186          *
 8187          * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
 8188          * bits 48..60. In the case of the 2202, it appears that they do
 8189          * use bit 48 to distinguish between the two instances on the card.
 8190          * The 2204, which I've never seen, *probably* extends this method.
 8191          */
 8192         wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
 8193         if (wwn) {
 8194                 isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
 8195                     (uint32_t) (wwn >> 32), (uint32_t) (wwn));
 8196                 if ((wwn >> 60) == 0) {
 8197                         wwn |= (((uint64_t) 2)<< 60);
 8198                 }
 8199         }
 8200         fcp->isp_wwpn_nvram = wwn;
 8201         if (IS_2200(isp) || IS_23XX(isp)) {
 8202                 wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
 8203                 if (wwn) {
 8204                         isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
 8205                             (uint32_t) (wwn >> 32),
 8206                             (uint32_t) (wwn));
 8207                         if ((wwn >> 60) == 0) {
 8208                                 wwn |= (((uint64_t) 2)<< 60);
 8209                         }
 8210                 } else {
 8211                         wwn = fcp->isp_wwpn_nvram & ~((uint64_t) 0xfff << 48);
 8212                 }
 8213         } else {
 8214                 wwn &= ~((uint64_t) 0xfff << 48);
 8215         }
 8216         fcp->isp_wwnn_nvram = wwn;
 8217 
 8218         fcp->isp_maxalloc = ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
 8219         if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
 8220                 DEFAULT_FRAMESIZE(isp) =
 8221                     ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
 8222         }
 8223         fcp->isp_retry_delay = ISP2100_NVRAM_RETRY_DELAY(nvram_data);
 8224         fcp->isp_retry_count = ISP2100_NVRAM_RETRY_COUNT(nvram_data);
 8225         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
 8226                 fcp->isp_loopid = ISP2100_NVRAM_HARDLOOPID(nvram_data);
 8227         }
 8228         if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
 8229                 DEFAULT_EXEC_THROTTLE(isp) =
 8230                         ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
 8231         }
 8232         fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
 8233         isp_prt(isp, ISP_LOGDEBUG0,
 8234             "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d",
 8235             (uint32_t) (fcp->isp_wwnn_nvram >> 32),
 8236             (uint32_t) fcp->isp_wwnn_nvram,
 8237             (uint32_t) (fcp->isp_wwpn_nvram >> 32),
 8238             (uint32_t) fcp->isp_wwpn_nvram,
 8239             ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data),
 8240             ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data));
 8241         isp_prt(isp, ISP_LOGDEBUG0,
 8242             "execthrottle %d fwoptions 0x%x hardloop %d tov %d",
 8243             ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
 8244             ISP2100_NVRAM_OPTIONS(nvram_data),
 8245             ISP2100_NVRAM_HARDLOOPID(nvram_data),
 8246             ISP2100_NVRAM_TOV(nvram_data));
 8247         fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data);
 8248         fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data);
 8249         isp_prt(isp, ISP_LOGDEBUG0, "xfwoptions 0x%x zfw options 0x%x",
 8250             ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data));
 8251 }
 8252 
 8253 static void
 8254 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
 8255 {
 8256         fcparam *fcp = FCPARAM(isp, 0);
 8257         uint64_t wwn;
 8258 
 8259         isp_prt(isp, ISP_LOGDEBUG0,
 8260             "NVRAM 0x%08x%08x 0x%08x%08x exchg_cnt %d maxframelen %d",
 8261             (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
 8262             (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
 8263             (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
 8264             (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
 8265             ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data),
 8266             ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
 8267         isp_prt(isp, ISP_LOGDEBUG0,
 8268             "NVRAM execthr %d loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
 8269             ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data),
 8270             ISP2400_NVRAM_HARDLOOPID(nvram_data),
 8271             ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
 8272             ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
 8273             ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
 8274 
 8275         wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
 8276         fcp->isp_wwpn_nvram = wwn;
 8277 
 8278         wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
 8279         if (wwn) {
 8280                 if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
 8281                         wwn = 0;
 8282                 }
 8283         }
 8284         if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
 8285                 wwn = fcp->isp_wwpn_nvram;
 8286                 wwn &= ~((uint64_t) 0xfff << 48);
 8287         }
 8288         fcp->isp_wwnn_nvram = wwn;
 8289 
 8290         if (ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data)) {
 8291                 fcp->isp_maxalloc = ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data);
 8292         }
 8293         if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
 8294                 DEFAULT_FRAMESIZE(isp) =
 8295                     ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
 8296         }
 8297         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
 8298                 fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
 8299         }
 8300         if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
 8301                 DEFAULT_EXEC_THROTTLE(isp) =
 8302                         ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data);
 8303         }
 8304         fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
 8305         fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
 8306         fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
 8307 }

Cache object: ac96216e1c9ac6bc15261ce2b3feed06


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


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.