1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2009-2020 Alexander Motin <mav@FreeBSD.org> 5 * Copyright (c) 1997-2009 by Matthew Jacob 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 32 /* 33 * Machine and OS Independent (well, as best as possible) 34 * code for the Qlogic ISP SCSI and FC-SCSI adapters. 35 */ 36 37 /* 38 * Inspiration and ideas about this driver are from Erik Moe's Linux driver 39 * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some 40 * ideas dredged from the Solaris driver. 41 */ 42 43 /* 44 * Include header file appropriate for platform we're building on. 45 */ 46 #ifdef __NetBSD__ 47 #include <sys/cdefs.h> 48 __KERNEL_RCSID(0, "$NetBSD$"); 49 #include <dev/ic/isp_netbsd.h> 50 #endif 51 #ifdef __FreeBSD__ 52 #include <sys/cdefs.h> 53 __FBSDID("$FreeBSD$"); 54 #include <dev/isp/isp_freebsd.h> 55 #endif 56 #ifdef __OpenBSD__ 57 #include <dev/ic/isp_openbsd.h> 58 #endif 59 #ifdef __linux__ 60 #include "isp_linux.h" 61 #endif 62 #ifdef __svr4__ 63 #include "isp_solaris.h" 64 #endif 65 66 /* 67 * Local static data 68 */ 69 static const char notresp[] = "Unknown IOCB in RESPONSE Queue (type 0x%x) @ idx %d (next %d)"; 70 static const char bun[] = "bad underrun (count %d, resid %d, status %s)"; 71 static const char lipd[] = "Chan %d LIP destroyed %d active commands"; 72 static const char sacq[] = "unable to acquire scratch area"; 73 74 static const uint8_t alpa_map[] = { 75 0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda, 76 0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce, 77 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5, 78 0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3, 79 0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 80 0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b, 81 0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81, 82 0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73, 83 0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 84 0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56, 85 0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c, 86 0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c, 87 0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 88 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26, 89 0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17, 90 0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00 91 }; 92 93 /* 94 * Local function prototypes. 95 */ 96 static int isp_handle_control(ispsoftc_t *, isphdr_t *); 97 static void isp_handle_rpt_id_acq(ispsoftc_t *, isphdr_t *); 98 static void isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *); 99 static void isp_clear_portdb(ispsoftc_t *, int); 100 static void isp_mark_portdb(ispsoftc_t *, int); 101 static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int); 102 static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *); 103 static int isp_gethandles(ispsoftc_t *, int, uint16_t *, int *, int); 104 static void isp_dump_chip_portdb(ispsoftc_t *, int); 105 static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int); 106 static int isp_fclink_test(ispsoftc_t *, int, int); 107 static int isp_pdb_sync(ispsoftc_t *, int); 108 static int isp_scan_loop(ispsoftc_t *, int); 109 static int isp_gid_pt(ispsoftc_t *, int); 110 static int isp_scan_fabric(ispsoftc_t *, int); 111 static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *); 112 static int isp_register_fc4_type(ispsoftc_t *, int); 113 static int isp_register_fc4_features_24xx(ispsoftc_t *, int); 114 static int isp_register_port_name_24xx(ispsoftc_t *, int); 115 static int isp_register_node_name_24xx(ispsoftc_t *, int); 116 static uint16_t isp_next_handle(ispsoftc_t *, uint16_t *); 117 static int isp_fw_state(ispsoftc_t *, int); 118 static void isp_mboxcmd(ispsoftc_t *, mbreg_t *); 119 120 static void isp_setdfltfcparm(ispsoftc_t *, int); 121 static int isp_read_nvram(ispsoftc_t *, int); 122 static void isp_rd_2xxx_flash(ispsoftc_t *, uint32_t, uint32_t *); 123 static int isp_read_flthdr_2xxx(ispsoftc_t *); 124 static void isp_parse_flthdr_2xxx(ispsoftc_t *, uint8_t *); 125 static int isp_read_flt_2xxx(ispsoftc_t *); 126 static int isp_parse_flt_2xxx(ispsoftc_t *, uint8_t *); 127 static int isp_read_nvram_2400(ispsoftc_t *); 128 static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *); 129 130 static void 131 isp_change_fw_state(ispsoftc_t *isp, int chan, int state) 132 { 133 fcparam *fcp = FCPARAM(isp, chan); 134 135 if (fcp->isp_fwstate == state) 136 return; 137 isp_prt(isp, ISP_LOGCONFIG|ISP_LOG_SANCFG, 138 "Chan %d Firmware state <%s->%s>", chan, 139 isp_fc_fw_statename(fcp->isp_fwstate), isp_fc_fw_statename(state)); 140 fcp->isp_fwstate = state; 141 } 142 143 /* 144 * Reset Hardware. 145 * 146 * Hit the chip over the head, download new f/w if available and set it running. 147 * 148 * Locking done elsewhere. 149 */ 150 151 void 152 isp_reset(ispsoftc_t *isp, int do_load_defaults) 153 { 154 mbreg_t mbs; 155 char *buf; 156 uint64_t fwt; 157 uint32_t code_org, val; 158 int loaded_fw, loops, i, dodnld = 1; 159 const char *btype = "????"; 160 static const char dcrc[] = "Downloaded RISC Code Checksum Failure"; 161 162 isp->isp_state = ISP_NILSTATE; 163 ISP_DISABLE_INTS(isp); 164 165 /* 166 * Put the board into PAUSE mode (so we can read the SXP registers 167 * or write FPM/FBM registers). 168 */ 169 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT); 170 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT); 171 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE); 172 173 switch (isp->isp_type) { 174 case ISP_HA_FC_2400: 175 btype = "2422"; 176 break; 177 case ISP_HA_FC_2500: 178 btype = "2532"; 179 break; 180 case ISP_HA_FC_2600: 181 btype = "2600"; 182 break; 183 case ISP_HA_FC_2700: 184 btype = "2700"; 185 break; 186 case ISP_HA_FC_2800: 187 btype = "2800"; 188 break; 189 default: 190 break; 191 } 192 193 /* 194 * Stop DMA and wait for it to stop. 195 */ 196 ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4)); 197 for (loops = 0; loops < 100000; loops++) { 198 ISP_DELAY(10); 199 val = ISP_READ(isp, BIU2400_CSR); 200 if ((val & BIU2400_DMA_ACTIVE) == 0) { 201 break; 202 } 203 } 204 if (val & BIU2400_DMA_ACTIVE) 205 isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset"); 206 207 /* 208 * Hold it in SOFT_RESET and STOP state for 100us. 209 */ 210 ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4)); 211 ISP_DELAY(100); 212 for (loops = 0; loops < 10000; loops++) { 213 ISP_DELAY(5); 214 val = ISP_READ(isp, OUTMAILBOX0); 215 if (val != 0x4) 216 break; 217 } 218 switch (val) { 219 case 0x0: 220 break; 221 case 0x4: 222 isp_prt(isp, ISP_LOGERR, "The ROM code is busy after 50ms."); 223 return; 224 case 0xf: 225 isp_prt(isp, ISP_LOGERR, "Board configuration error."); 226 return; 227 default: 228 isp_prt(isp, ISP_LOGERR, "Unknown RISC Status Code 0x%x.", val); 229 return; 230 } 231 232 /* 233 * Reset RISC Processor 234 */ 235 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET); 236 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE); 237 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET); 238 239 /* 240 * Post-RISC Reset stuff. 241 */ 242 for (loops = 0; loops < 10000; loops++) { 243 ISP_DELAY(5); 244 val = ISP_READ(isp, OUTMAILBOX0); 245 if (val != 0x4) 246 break; 247 } 248 switch (val) { 249 case 0x0: 250 break; 251 case 0x4: 252 isp_prt(isp, ISP_LOGERR, "The ROM code is busy after 50ms."); 253 return; 254 case 0xf: 255 isp_prt(isp, ISP_LOGERR, "Board configuration error."); 256 return; 257 default: 258 isp_prt(isp, ISP_LOGERR, "Unknown RISC Status Code 0x%x.", val); 259 return; 260 } 261 262 isp->isp_reqidx = isp->isp_reqodx = 0; 263 isp->isp_resodx = 0; 264 isp->isp_atioodx = 0; 265 ISP_WRITE(isp, BIU2400_REQINP, 0); 266 ISP_WRITE(isp, BIU2400_REQOUTP, 0); 267 ISP_WRITE(isp, BIU2400_RSPINP, 0); 268 ISP_WRITE(isp, BIU2400_RSPOUTP, 0); 269 if (!IS_26XX(isp)) { 270 ISP_WRITE(isp, BIU2400_PRI_REQINP, 0); 271 ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0); 272 } 273 ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0); 274 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0); 275 276 /* 277 * Up until this point we've done everything by just reading or 278 * setting registers. From this point on we rely on at least *some* 279 * kind of firmware running in the card. 280 */ 281 282 /* 283 * Do some sanity checking by running a NOP command. 284 * If it succeeds, the ROM firmware is now running. 285 */ 286 MBSINIT(&mbs, MBOX_NO_OP, MBLOGALL, 0); 287 isp_mboxcmd(isp, &mbs); 288 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 289 isp_prt(isp, ISP_LOGERR, "NOP command failed (%x)", mbs.param[0]); 290 return; 291 } 292 293 /* 294 * Do some operational tests 295 */ 296 { 297 static const uint16_t patterns[MAX_MAILBOX] = { 298 0x0000, 0xdead, 0xbeef, 0xffff, 299 0xa5a5, 0x5a5a, 0x7f7f, 0x7ff7, 300 0x3421, 0xabcd, 0xdcba, 0xfeef, 301 0xbead, 0xdebe, 0x2222, 0x3333, 302 0x5555, 0x6666, 0x7777, 0xaaaa, 303 0xffff, 0xdddd, 0x9999, 0x1fbc, 304 0x6666, 0x6677, 0x1122, 0x33ff, 305 0x0000, 0x0001, 0x1000, 0x1010, 306 }; 307 int nmbox = ISP_NMBOX(isp); 308 MBSINIT(&mbs, MBOX_MAILBOX_REG_TEST, MBLOGALL, 0); 309 for (i = 1; i < nmbox; i++) { 310 mbs.param[i] = patterns[i]; 311 } 312 isp_mboxcmd(isp, &mbs); 313 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 314 return; 315 } 316 for (i = 1; i < nmbox; i++) { 317 if (mbs.param[i] != patterns[i]) { 318 isp_prt(isp, ISP_LOGERR, "Register Test Failed at Register %d: should have 0x%04x but got 0x%04x", i, patterns[i], mbs.param[i]); 319 return; 320 } 321 } 322 } 323 324 /* 325 * Download new Firmware, unless requested not to do so. 326 * This is made slightly trickier in some cases where the 327 * firmware of the ROM revision is newer than the revision 328 * compiled into the driver. So, where we used to compare 329 * versions of our f/w and the ROM f/w, now we just see 330 * whether we have f/w at all and whether a config flag 331 * has disabled our download. 332 */ 333 if ((isp->isp_mdvec->dv_ispfw == NULL) || (isp->isp_confopts & ISP_CFG_NORELOAD)) { 334 dodnld = 0; 335 } else { 336 337 /* 338 * Set up DMA for the request and response queues. 339 * We do this now so we can use the request queue 340 * for dma to load firmware from. 341 */ 342 if (ISP_MBOXDMASETUP(isp) != 0) { 343 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA"); 344 return; 345 } 346 } 347 348 code_org = ISP_CODE_ORG_2400; 349 loaded_fw = 0; 350 if (dodnld) { 351 const uint32_t *ptr = isp->isp_mdvec->dv_ispfw; 352 uint32_t la, wi, wl; 353 354 /* 355 * Keep loading until we run out of f/w. 356 */ 357 code_org = ptr[2]; /* 1st load address is our start addr */ 358 for (;;) { 359 isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], ptr[2]); 360 361 wi = 0; 362 la = ptr[2]; 363 wl = ptr[3]; 364 while (wi < ptr[3]) { 365 uint32_t *cp; 366 uint32_t nw; 367 368 nw = min(wl, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) / 4); 369 cp = isp->isp_rquest; 370 for (i = 0; i < nw; i++) 371 ISP_IOXPUT_32(isp, ptr[wi + i], &cp[i]); 372 MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1); 373 MBSINIT(&mbs, MBOX_LOAD_RISC_RAM, MBLOGALL, 0); 374 mbs.param[1] = la; 375 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); 376 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); 377 mbs.param[4] = nw >> 16; 378 mbs.param[5] = nw; 379 mbs.param[6] = DMA_WD3(isp->isp_rquest_dma); 380 mbs.param[7] = DMA_WD2(isp->isp_rquest_dma); 381 mbs.param[8] = la >> 16; 382 isp_prt(isp, ISP_LOGDEBUG0, "LOAD RISC RAM %u words at load address 0x%x", nw, la); 383 isp_mboxcmd(isp, &mbs); 384 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 385 isp_prt(isp, ISP_LOGERR, "F/W download failed"); 386 return; 387 } 388 la += nw; 389 wi += nw; 390 wl -= nw; 391 } 392 393 if (ptr[1] == 0) { 394 break; 395 } 396 ptr += ptr[3]; 397 } 398 loaded_fw = 1; 399 } else if (IS_26XX(isp)) { 400 isp_prt(isp, ISP_LOGDEBUG1, "loading firmware from flash"); 401 MBSINIT(&mbs, MBOX_LOAD_FLASH_FIRMWARE, MBLOGALL, 5000000); 402 mbs.ibitm = 0x01; 403 mbs.obitm = 0x07; 404 isp_mboxcmd(isp, &mbs); 405 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 406 isp_prt(isp, ISP_LOGERR, "Flash F/W load failed"); 407 return; 408 } 409 } else { 410 isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download"); 411 } 412 413 /* 414 * If we loaded firmware, verify its checksum 415 */ 416 if (loaded_fw) { 417 MBSINIT(&mbs, MBOX_VERIFY_CHECKSUM, MBLOGNONE, 0); 418 mbs.param[1] = code_org >> 16; 419 mbs.param[2] = code_org; 420 isp_mboxcmd(isp, &mbs); 421 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 422 isp_prt(isp, ISP_LOGERR, dcrc); 423 return; 424 } 425 } 426 427 /* 428 * Now start it rolling. 429 * 430 * If we didn't actually download f/w, 431 * we still need to (re)start it. 432 */ 433 MBSINIT(&mbs, MBOX_EXEC_FIRMWARE, MBLOGALL, 5000000); 434 mbs.param[1] = code_org >> 16; 435 mbs.param[2] = code_org; 436 if (!IS_26XX(isp)) 437 mbs.param[3] = loaded_fw ? 0 : 1; 438 isp_mboxcmd(isp, &mbs); 439 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) 440 return; 441 442 /* 443 * Ask the chip for the current firmware version. 444 * This should prove that the new firmware is working. 445 */ 446 MBSINIT(&mbs, MBOX_ABOUT_FIRMWARE, MBLOGALL, 5000000); 447 isp_mboxcmd(isp, &mbs); 448 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 449 return; 450 } 451 452 isp->isp_fwrev[0] = mbs.param[1]; 453 isp->isp_fwrev[1] = mbs.param[2]; 454 isp->isp_fwrev[2] = mbs.param[3]; 455 isp->isp_fwattr = mbs.param[6]; 456 isp->isp_fwattr |= ((uint64_t) mbs.param[15]) << 16; 457 if (isp->isp_fwattr & ISP2400_FW_ATTR_EXTNDED) { 458 isp->isp_fwattr |= 459 (((uint64_t) mbs.param[16]) << 32) | 460 (((uint64_t) mbs.param[17]) << 48); 461 } 462 463 isp_prt(isp, ISP_LOGCONFIG, "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d", 464 btype, isp->isp_revision, dodnld? "loaded" : "resident", isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]); 465 466 fwt = isp->isp_fwattr; 467 buf = FCPARAM(isp, 0)->isp_scanscratch; 468 ISP_SNPRINTF(buf, ISP_FC_SCRLEN, "Attributes:"); 469 if (fwt & ISP2400_FW_ATTR_CLASS2) { 470 fwt ^=ISP2400_FW_ATTR_CLASS2; 471 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s Class2", buf); 472 } 473 if (fwt & ISP2400_FW_ATTR_IP) { 474 fwt ^=ISP2400_FW_ATTR_IP; 475 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s IP", buf); 476 } 477 if (fwt & ISP2400_FW_ATTR_MULTIID) { 478 fwt ^=ISP2400_FW_ATTR_MULTIID; 479 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MultiID", buf); 480 } 481 if (fwt & ISP2400_FW_ATTR_SB2) { 482 fwt ^=ISP2400_FW_ATTR_SB2; 483 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SB2", buf); 484 } 485 if (fwt & ISP2400_FW_ATTR_T10CRC) { 486 fwt ^=ISP2400_FW_ATTR_T10CRC; 487 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s T10CRC", buf); 488 } 489 if (fwt & ISP2400_FW_ATTR_VI) { 490 fwt ^=ISP2400_FW_ATTR_VI; 491 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VI", buf); 492 } 493 if (fwt & ISP2400_FW_ATTR_MQ) { 494 fwt ^=ISP2400_FW_ATTR_MQ; 495 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MQ", buf); 496 } 497 if (fwt & ISP2400_FW_ATTR_MSIX) { 498 fwt ^=ISP2400_FW_ATTR_MSIX; 499 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MSIX", buf); 500 } 501 if (fwt & ISP2400_FW_ATTR_FCOE) { 502 fwt ^=ISP2400_FW_ATTR_FCOE; 503 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s FCOE", buf); 504 } 505 if (fwt & ISP2400_FW_ATTR_VP0) { 506 fwt ^= ISP2400_FW_ATTR_VP0; 507 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VP0_Decoupling", buf); 508 } 509 if (fwt & ISP2400_FW_ATTR_EXPFW) { 510 fwt ^= ISP2400_FW_ATTR_EXPFW; 511 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s (Experimental)", buf); 512 } 513 if (fwt & ISP2400_FW_ATTR_HOTFW) { 514 fwt ^= ISP2400_FW_ATTR_HOTFW; 515 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s HotFW", buf); 516 } 517 fwt &= ~ISP2400_FW_ATTR_EXTNDED; 518 if (fwt & ISP2400_FW_ATTR_EXTVP) { 519 fwt ^= ISP2400_FW_ATTR_EXTVP; 520 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ExtVP", buf); 521 } 522 if (fwt & ISP2400_FW_ATTR_VN2VN) { 523 fwt ^= ISP2400_FW_ATTR_VN2VN; 524 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VN2VN", buf); 525 } 526 if (fwt & ISP2400_FW_ATTR_EXMOFF) { 527 fwt ^= ISP2400_FW_ATTR_EXMOFF; 528 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s EXMOFF", buf); 529 } 530 if (fwt & ISP2400_FW_ATTR_NPMOFF) { 531 fwt ^= ISP2400_FW_ATTR_NPMOFF; 532 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NPMOFF", buf); 533 } 534 if (fwt & ISP2400_FW_ATTR_DIFCHOP) { 535 fwt ^= ISP2400_FW_ATTR_DIFCHOP; 536 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s DIFCHOP", buf); 537 } 538 if (fwt & ISP2400_FW_ATTR_SRIOV) { 539 fwt ^= ISP2400_FW_ATTR_SRIOV; 540 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SRIOV", buf); 541 } 542 if (fwt & ISP2400_FW_ATTR_ASICTMP) { 543 fwt ^= ISP2400_FW_ATTR_ASICTMP; 544 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ASICTMP", buf); 545 } 546 if (fwt & ISP2400_FW_ATTR_ATIOMQ) { 547 fwt ^= ISP2400_FW_ATTR_ATIOMQ; 548 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ATIOMQ", buf); 549 } 550 if (fwt) { 551 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s (unknown 0x%08x%08x)", buf, 552 (uint32_t) (fwt >> 32), (uint32_t) fwt); 553 } 554 isp_prt(isp, ISP_LOGCONFIG, "%s", buf); 555 556 /* 557 * For the maximum number of commands take free exchange control block 558 * buffer count reported by firmware, limiting it to the maximum of our 559 * hardcoded handle format (16K now) minus some management reserve. 560 */ 561 MBSINIT(&mbs, MBOX_GET_RESOURCE_COUNT, MBLOGALL, 0); 562 isp_mboxcmd(isp, &mbs); 563 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) 564 return; 565 isp->isp_maxcmds = MIN(mbs.param[3], ISP_HANDLE_MAX - ISP_HANDLE_RESERVE); 566 isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", isp->isp_maxcmds); 567 568 /* 569 * If we don't have Multi-ID f/w loaded, we need to restrict channels to one. 570 * Only make this check for non-SCSI cards (I'm not sure firmware attributes 571 * work for them). 572 */ 573 if (isp->isp_nchan > 1) { 574 if (!ISP_CAP_MULTI_ID(isp)) { 575 isp_prt(isp, ISP_LOGWARN, "non-MULTIID f/w loaded, " 576 "only can enable 1 of %d channels", isp->isp_nchan); 577 isp->isp_nchan = 1; 578 } else if (!ISP_CAP_VP0(isp)) { 579 isp_prt(isp, ISP_LOGWARN, "We can not use MULTIID " 580 "feature properly without VP0_Decoupling"); 581 isp->isp_nchan = 1; 582 } 583 } 584 585 /* 586 * Final DMA setup after we got isp_maxcmds. 587 */ 588 if (ISP_MBOXDMASETUP(isp) != 0) { 589 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA"); 590 return; 591 } 592 593 /* 594 * Setup interrupts. 595 */ 596 if (ISP_IRQSETUP(isp) != 0) { 597 isp_prt(isp, ISP_LOGERR, "Cannot setup IRQ"); 598 return; 599 } 600 ISP_ENABLE_INTS(isp); 601 602 for (i = 0; i < isp->isp_nchan; i++) 603 isp_change_fw_state(isp, i, FW_CONFIG_WAIT); 604 605 isp->isp_state = ISP_RESETSTATE; 606 607 /* 608 * We get some default values established. As a side 609 * effect, NVRAM is read here (unless overridden by 610 * a configuration flag). 611 */ 612 if (do_load_defaults) { 613 for (i = 0; i < isp->isp_nchan; i++) 614 isp_setdfltfcparm(isp, i); 615 } 616 } 617 618 /* 619 * Clean firmware shutdown. 620 */ 621 static int 622 isp_stop(ispsoftc_t *isp) 623 { 624 mbreg_t mbs; 625 626 isp->isp_state = ISP_NILSTATE; 627 MBSINIT(&mbs, MBOX_STOP_FIRMWARE, MBLOGALL, 500000); 628 mbs.param[1] = 0; 629 mbs.param[2] = 0; 630 mbs.param[3] = 0; 631 mbs.param[4] = 0; 632 mbs.param[5] = 0; 633 mbs.param[6] = 0; 634 mbs.param[7] = 0; 635 mbs.param[8] = 0; 636 isp_mboxcmd(isp, &mbs); 637 return (mbs.param[0] == MBOX_COMMAND_COMPLETE ? 0 : mbs.param[0]); 638 } 639 640 /* 641 * Hardware shutdown. 642 */ 643 void 644 isp_shutdown(ispsoftc_t *isp) 645 { 646 647 if (isp->isp_state >= ISP_RESETSTATE) 648 isp_stop(isp); 649 ISP_DISABLE_INTS(isp); 650 ISP_WRITE(isp, BIU2400_ICR, 0); 651 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE); 652 } 653 654 /* 655 * Initialize Parameters of Hardware to a known state. 656 * 657 * Locks are held before coming here. 658 */ 659 void 660 isp_init(ispsoftc_t *isp) 661 { 662 fcparam *fcp; 663 isp_icb_2400_t local, *icbp = &local; 664 mbreg_t mbs; 665 int chan; 666 int ownloopid = 0; 667 668 /* 669 * Check to see whether all channels have *some* kind of role 670 */ 671 for (chan = 0; chan < isp->isp_nchan; chan++) { 672 fcp = FCPARAM(isp, chan); 673 if (fcp->role != ISP_ROLE_NONE) { 674 break; 675 } 676 } 677 if (chan == isp->isp_nchan) { 678 isp_prt(isp, ISP_LOG_WARN1, "all %d channels with role 'none'", chan); 679 return; 680 } 681 682 isp->isp_state = ISP_INITSTATE; 683 684 /* 685 * Start with channel 0. 686 */ 687 fcp = FCPARAM(isp, 0); 688 689 /* 690 * Turn on LIP F8 async event (1) 691 */ 692 MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0); 693 mbs.param[1] = 1; 694 isp_mboxcmd(isp, &mbs); 695 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 696 return; 697 } 698 699 ISP_MEMZERO(icbp, sizeof (*icbp)); 700 icbp->icb_fwoptions1 = fcp->isp_fwoptions; 701 icbp->icb_fwoptions2 = fcp->isp_xfwoptions; 702 icbp->icb_fwoptions3 = fcp->isp_zfwoptions; 703 if (isp->isp_nchan > 1 && ISP_CAP_VP0(isp)) { 704 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE; 705 icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE; 706 } else { 707 if (fcp->role & ISP_ROLE_TARGET) 708 icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE; 709 else 710 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_TGT_ENABLE; 711 if (fcp->role & ISP_ROLE_INITIATOR) 712 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE; 713 else 714 icbp->icb_fwoptions1 |= ICB2400_OPT1_INI_DISABLE; 715 } 716 717 icbp->icb_version = ICB_VERSION1; 718 icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp); 719 if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) { 720 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN; 721 if (IS_28XX(isp)) 722 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN_28XX; 723 724 isp_prt(isp, ISP_LOGERR, 725 "bad frame length (%d) from NVRAM - using %d", 726 DEFAULT_FRAMESIZE(isp), icbp->icb_maxfrmlen); 727 } 728 729 if (!IS_26XX(isp)) 730 icbp->icb_execthrottle = 0xffff; 731 732 #ifdef ISP_TARGET_MODE 733 /* 734 * Set target exchange count. Take half if we are supporting both roles. 735 */ 736 if (icbp->icb_fwoptions1 & ICB2400_OPT1_TGT_ENABLE) { 737 if ((icbp->icb_fwoptions1 & ICB2400_OPT1_INI_DISABLE) == 0) 738 icbp->icb_xchgcnt = MIN(isp->isp_maxcmds / 2, ATPDPSIZE); 739 else 740 icbp->icb_xchgcnt = isp->isp_maxcmds; 741 } 742 #endif 743 744 ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0; 745 icbp->icb_hardaddr = fcp->isp_loopid; 746 if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) { 747 icbp->icb_hardaddr = 0; 748 ownloopid = 0; 749 } 750 751 if (ownloopid) 752 icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS; 753 754 if (isp->isp_confopts & ISP_CFG_NOFCTAPE) { 755 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_FCTAPE; 756 } 757 if (isp->isp_confopts & ISP_CFG_FCTAPE) { 758 icbp->icb_fwoptions2 |= ICB2400_OPT2_FCTAPE; 759 } 760 761 for (chan = 0; chan < isp->isp_nchan; chan++) { 762 if (icbp->icb_fwoptions2 & ICB2400_OPT2_FCTAPE) 763 FCPARAM(isp, chan)->fctape_enabled = 1; 764 else 765 FCPARAM(isp, chan)->fctape_enabled = 0; 766 } 767 768 switch (isp->isp_confopts & ISP_CFG_PORT_PREF) { 769 case ISP_CFG_LPORT_ONLY: 770 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK; 771 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY; 772 break; 773 case ISP_CFG_NPORT_ONLY: 774 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK; 775 icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY; 776 break; 777 case ISP_CFG_NPORT: 778 /* ISP_CFG_PTP_2_LOOP not available in 24XX/25XX */ 779 case ISP_CFG_LPORT: 780 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK; 781 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP; 782 break; 783 default: 784 /* Let NVRAM settings define it if they are sane */ 785 switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TOPO_MASK) { 786 case ICB2400_OPT2_LOOP_ONLY: 787 case ICB2400_OPT2_PTP_ONLY: 788 case ICB2400_OPT2_LOOP_2_PTP: 789 break; 790 default: 791 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK; 792 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP; 793 } 794 break; 795 } 796 797 switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) { 798 case ICB2400_OPT2_ZIO: 799 case ICB2400_OPT2_ZIO1: 800 icbp->icb_idelaytimer = 0; 801 break; 802 case 0: 803 break; 804 default: 805 isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field", icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK); 806 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK; 807 break; 808 } 809 810 if (IS_26XX(isp)) { 811 /* Use handshake to reduce global lock congestion. */ 812 icbp->icb_fwoptions2 |= ICB2400_OPT2_ENA_IHR; 813 icbp->icb_fwoptions2 |= ICB2400_OPT2_ENA_IHA; 814 } 815 816 if ((icbp->icb_fwoptions3 & ICB2400_OPT3_RSPSZ_MASK) == 0) { 817 icbp->icb_fwoptions3 |= ICB2400_OPT3_RSPSZ_24; 818 } 819 if (isp->isp_confopts & ISP_CFG_1GB) { 820 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK; 821 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_1GB; 822 } else if (isp->isp_confopts & ISP_CFG_2GB) { 823 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK; 824 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_2GB; 825 } else if (isp->isp_confopts & ISP_CFG_4GB) { 826 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK; 827 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_4GB; 828 } else if (isp->isp_confopts & ISP_CFG_8GB) { 829 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK; 830 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_8GB; 831 } else if (isp->isp_confopts & ISP_CFG_16GB) { 832 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK; 833 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_16GB; 834 } else if (isp->isp_confopts & ISP_CFG_32GB) { 835 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK; 836 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_32GB; 837 } else if (isp->isp_confopts & ISP_CFG_64GB) { 838 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK; 839 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_64GB; 840 } else { 841 switch (icbp->icb_fwoptions3 & ICB2400_OPT3_RATE_MASK) { 842 case ICB2400_OPT3_RATE_4GB: 843 case ICB2400_OPT3_RATE_8GB: 844 case ICB2400_OPT3_RATE_16GB: 845 case ICB2400_OPT3_RATE_32GB: 846 case ICB2400_OPT3_RATE_64GB: 847 case ICB2400_OPT3_RATE_AUTO: 848 break; 849 case ICB2400_OPT3_RATE_2GB: 850 if (isp->isp_type <= ISP_HA_FC_2500) 851 break; 852 /*FALLTHROUGH*/ 853 case ICB2400_OPT3_RATE_1GB: 854 if (isp->isp_type <= ISP_HA_FC_2400) 855 break; 856 /*FALLTHROUGH*/ 857 default: 858 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK; 859 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO; 860 break; 861 } 862 } 863 if (ownloopid == 0) { 864 icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID; 865 } 866 icbp->icb_logintime = ICB_LOGIN_TOV; 867 868 if (fcp->isp_wwnn && fcp->isp_wwpn) { 869 icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS; 870 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn); 871 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn); 872 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)), 873 ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn))); 874 } else if (fcp->isp_wwpn) { 875 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS; 876 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn); 877 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))); 878 } else { 879 isp_prt(isp, ISP_LOGERR, "No valid WWNs to use"); 880 return; 881 } 882 icbp->icb_rspnsin = isp->isp_resodx; 883 icbp->icb_rqstout = isp->isp_reqidx; 884 icbp->icb_retry_count = fcp->isp_retry_count; 885 886 icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp); 887 if (icbp->icb_rqstqlen < 8) { 888 isp_prt(isp, ISP_LOGERR, "bad request queue length %d", icbp->icb_rqstqlen); 889 return; 890 } 891 icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp); 892 if (icbp->icb_rsltqlen < 8) { 893 isp_prt(isp, ISP_LOGERR, "bad result queue length %d", 894 icbp->icb_rsltqlen); 895 return; 896 } 897 icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma); 898 icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma); 899 icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma); 900 icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma); 901 902 icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma); 903 icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma); 904 icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma); 905 icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma); 906 907 #ifdef ISP_TARGET_MODE 908 /* unconditionally set up the ATIO queue if we support target mode */ 909 icbp->icb_atio_in = isp->isp_atioodx; 910 icbp->icb_atioqlen = ATIO_QUEUE_LEN(isp); 911 if (icbp->icb_atioqlen < 8) { 912 isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d", icbp->icb_atioqlen); 913 return; 914 } 915 icbp->icb_atioqaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_atioq_dma); 916 icbp->icb_atioqaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_atioq_dma); 917 icbp->icb_atioqaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_atioq_dma); 918 icbp->icb_atioqaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_atioq_dma); 919 isp_prt(isp, ISP_LOGDEBUG0, "isp_init: atioq %04x%04x%04x%04x", DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma), 920 DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma)); 921 #endif 922 923 if (ISP_CAP_MSIX(isp) && isp->isp_nirq >= 2) { 924 icbp->icb_msixresp = 1; 925 if (IS_26XX(isp) && isp->isp_nirq >= 3) 926 icbp->icb_msixatio = 2; 927 } 928 929 isp_prt(isp, ISP_LOGDEBUG0, "isp_init: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3); 930 931 isp_prt(isp, ISP_LOGDEBUG0, "isp_init: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x", DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma), 932 DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma), DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma), 933 DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma)); 934 935 if (FC_SCRATCH_ACQUIRE(isp, 0)) { 936 isp_prt(isp, ISP_LOGERR, sacq); 937 return; 938 } 939 ISP_MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN); 940 isp_put_icb_2400(isp, icbp, fcp->isp_scratch); 941 if (isp->isp_dblev & ISP_LOGDEBUG1) { 942 isp_print_bytes(isp, "isp_init", 943 sizeof (*icbp), fcp->isp_scratch); 944 } 945 946 /* 947 * Now fill in information about any additional channels 948 */ 949 if (isp->isp_nchan > 1) { 950 isp_icb_2400_vpinfo_t vpinfo, *vdst; 951 vp_port_info_t pi, *pdst; 952 size_t amt = 0; 953 uint8_t *off; 954 955 vpinfo.vp_global_options = ICB2400_VPGOPT_GEN_RIDA; 956 if (ISP_CAP_VP0(isp)) { 957 vpinfo.vp_global_options |= ICB2400_VPGOPT_VP0_DECOUPLE; 958 vpinfo.vp_count = isp->isp_nchan; 959 chan = 0; 960 } else { 961 vpinfo.vp_count = isp->isp_nchan - 1; 962 chan = 1; 963 } 964 off = fcp->isp_scratch; 965 off += ICB2400_VPINFO_OFF; 966 vdst = (isp_icb_2400_vpinfo_t *) off; 967 isp_put_icb_2400_vpinfo(isp, &vpinfo, vdst); 968 amt = ICB2400_VPINFO_OFF + sizeof (isp_icb_2400_vpinfo_t); 969 for (; chan < isp->isp_nchan; chan++) { 970 fcparam *fcp2; 971 972 ISP_MEMZERO(&pi, sizeof (pi)); 973 fcp2 = FCPARAM(isp, chan); 974 if (fcp2->role != ISP_ROLE_NONE) { 975 pi.vp_port_options = ICB2400_VPOPT_ENABLED | 976 ICB2400_VPOPT_ENA_SNSLOGIN; 977 if (fcp2->role & ISP_ROLE_INITIATOR) 978 pi.vp_port_options |= ICB2400_VPOPT_INI_ENABLE; 979 if ((fcp2->role & ISP_ROLE_TARGET) == 0) 980 pi.vp_port_options |= ICB2400_VPOPT_TGT_DISABLE; 981 if (fcp2->isp_loopid < LOCAL_LOOP_LIM) { 982 pi.vp_port_loopid = fcp2->isp_loopid; 983 if (isp->isp_confopts & ISP_CFG_OWNLOOPID) 984 pi.vp_port_options |= ICB2400_VPOPT_HARD_ADDRESS; 985 } 986 987 } 988 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname, fcp2->isp_wwpn); 989 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename, fcp2->isp_wwnn); 990 off = fcp->isp_scratch; 991 if (ISP_CAP_VP0(isp)) 992 off += ICB2400_VPINFO_PORT_OFF(chan); 993 else 994 off += ICB2400_VPINFO_PORT_OFF(chan - 1); 995 pdst = (vp_port_info_t *) off; 996 isp_put_vp_port_info(isp, &pi, pdst); 997 amt += ICB2400_VPOPT_WRITE_SIZE; 998 } 999 if (isp->isp_dblev & ISP_LOGDEBUG1) { 1000 isp_print_bytes(isp, "isp_init", 1001 amt - ICB2400_VPINFO_OFF, 1002 (char *)fcp->isp_scratch + ICB2400_VPINFO_OFF); 1003 } 1004 } 1005 1006 /* 1007 * Init the firmware 1008 */ 1009 MBSINIT(&mbs, 0, MBLOGALL, 30000000); 1010 if (isp->isp_nchan > 1) { 1011 mbs.param[0] = MBOX_INIT_FIRMWARE_MULTI_ID; 1012 } else { 1013 mbs.param[0] = MBOX_INIT_FIRMWARE; 1014 } 1015 mbs.param[1] = 0; 1016 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 1017 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 1018 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 1019 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 1020 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)); 1021 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp), 0); 1022 isp_mboxcmd(isp, &mbs); 1023 FC_SCRATCH_RELEASE(isp, 0); 1024 1025 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1026 return; 1027 } 1028 1029 /* 1030 * Whatever happens, we're now committed to being here. 1031 */ 1032 isp->isp_state = ISP_RUNSTATE; 1033 } 1034 1035 static int 1036 isp_fc_enable_vp(ispsoftc_t *isp, int chan) 1037 { 1038 fcparam *fcp = FCPARAM(isp, chan); 1039 vp_modify_t vp; 1040 int retval; 1041 1042 /* Build a VP MODIFY command in memory */ 1043 ISP_MEMZERO(&vp, sizeof(vp)); 1044 vp.vp_mod_hdr.rqs_entry_type = RQSTYPE_VP_MODIFY; 1045 vp.vp_mod_hdr.rqs_entry_count = 1; 1046 vp.vp_mod_cnt = 1; 1047 vp.vp_mod_idx0 = chan; 1048 vp.vp_mod_cmd = VP_MODIFY_ENA; 1049 vp.vp_mod_ports[0].options = ICB2400_VPOPT_ENABLED | 1050 ICB2400_VPOPT_ENA_SNSLOGIN; 1051 if (fcp->role & ISP_ROLE_INITIATOR) 1052 vp.vp_mod_ports[0].options |= ICB2400_VPOPT_INI_ENABLE; 1053 if ((fcp->role & ISP_ROLE_TARGET) == 0) 1054 vp.vp_mod_ports[0].options |= ICB2400_VPOPT_TGT_DISABLE; 1055 if (fcp->isp_loopid < LOCAL_LOOP_LIM) { 1056 vp.vp_mod_ports[0].loopid = fcp->isp_loopid; 1057 if (isp->isp_confopts & ISP_CFG_OWNLOOPID) 1058 vp.vp_mod_ports[0].options |= ICB2400_VPOPT_HARD_ADDRESS; 1059 } 1060 MAKE_NODE_NAME_FROM_WWN(vp.vp_mod_ports[0].wwpn, fcp->isp_wwpn); 1061 MAKE_NODE_NAME_FROM_WWN(vp.vp_mod_ports[0].wwnn, fcp->isp_wwnn); 1062 1063 retval = isp_exec_entry_queue(isp, &vp, &vp, 5); 1064 if (retval != 0) { 1065 isp_prt(isp, ISP_LOGERR, "%s: VP_MODIFY of chan %d error %d", 1066 __func__, chan, retval); 1067 return (retval); 1068 } 1069 1070 if (vp.vp_mod_hdr.rqs_flags != 0 || vp.vp_mod_status != VP_STS_OK) { 1071 isp_prt(isp, ISP_LOGERR, 1072 "%s: VP_MODIFY of Chan %d failed with flags %x status %d", 1073 __func__, chan, vp.vp_mod_hdr.rqs_flags, vp.vp_mod_status); 1074 return (EIO); 1075 } 1076 return (0); 1077 } 1078 1079 static int 1080 isp_fc_disable_vp(ispsoftc_t *isp, int chan) 1081 { 1082 vp_ctrl_info_t vp; 1083 int retval; 1084 1085 /* Build a VP CTRL command in memory */ 1086 ISP_MEMZERO(&vp, sizeof(vp)); 1087 vp.vp_ctrl_hdr.rqs_entry_type = RQSTYPE_VP_CTRL; 1088 vp.vp_ctrl_hdr.rqs_entry_count = 1; 1089 if (ISP_CAP_VP0(isp)) { 1090 vp.vp_ctrl_status = 1; 1091 } else { 1092 vp.vp_ctrl_status = 0; 1093 chan--; /* VP0 can not be controlled in this case. */ 1094 } 1095 vp.vp_ctrl_command = VP_CTRL_CMD_DISABLE_VP_LOGO_ALL; 1096 vp.vp_ctrl_vp_count = 1; 1097 vp.vp_ctrl_idmap[chan / 16] |= (1 << chan % 16); 1098 1099 retval = isp_exec_entry_queue(isp, &vp, &vp, 5); 1100 if (retval != 0) { 1101 isp_prt(isp, ISP_LOGERR, "%s: VP_CTRL of chan %d error %d", 1102 __func__, chan, retval); 1103 return (retval); 1104 } 1105 1106 if (vp.vp_ctrl_hdr.rqs_flags != 0 || vp.vp_ctrl_status != 0) { 1107 isp_prt(isp, ISP_LOGERR, 1108 "%s: VP_CTRL of Chan %d failed with flags %x status %d %d", 1109 __func__, chan, vp.vp_ctrl_hdr.rqs_flags, 1110 vp.vp_ctrl_status, vp.vp_ctrl_index_fail); 1111 return (EIO); 1112 } 1113 return (0); 1114 } 1115 1116 static int 1117 isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role) 1118 { 1119 fcparam *fcp = FCPARAM(isp, chan); 1120 int i, was, res = 0; 1121 1122 if (chan >= isp->isp_nchan) { 1123 isp_prt(isp, ISP_LOGWARN, "%s: bad channel %d", __func__, chan); 1124 return (ENXIO); 1125 } 1126 if (fcp->role == new_role) 1127 return (0); 1128 for (was = 0, i = 0; i < isp->isp_nchan; i++) { 1129 if (FCPARAM(isp, i)->role != ISP_ROLE_NONE) 1130 was++; 1131 } 1132 if (was == 0 || (was == 1 && fcp->role != ISP_ROLE_NONE)) { 1133 fcp->role = new_role; 1134 return (isp_reinit(isp, 0)); 1135 } 1136 if (fcp->role != ISP_ROLE_NONE) { 1137 res = isp_fc_disable_vp(isp, chan); 1138 isp_clear_portdb(isp, chan); 1139 } 1140 fcp->role = new_role; 1141 if (fcp->role != ISP_ROLE_NONE) 1142 res = isp_fc_enable_vp(isp, chan); 1143 return (res); 1144 } 1145 1146 static void 1147 isp_clear_portdb(ispsoftc_t *isp, int chan) 1148 { 1149 fcparam *fcp = FCPARAM(isp, chan); 1150 fcportdb_t *lp; 1151 int i; 1152 1153 for (i = 0; i < MAX_FC_TARG; i++) { 1154 lp = &fcp->portdb[i]; 1155 switch (lp->state) { 1156 case FC_PORTDB_STATE_DEAD: 1157 case FC_PORTDB_STATE_CHANGED: 1158 case FC_PORTDB_STATE_VALID: 1159 lp->state = FC_PORTDB_STATE_NIL; 1160 isp_async(isp, ISPASYNC_DEV_GONE, chan, lp); 1161 break; 1162 case FC_PORTDB_STATE_NIL: 1163 case FC_PORTDB_STATE_NEW: 1164 lp->state = FC_PORTDB_STATE_NIL; 1165 break; 1166 case FC_PORTDB_STATE_ZOMBIE: 1167 break; 1168 default: 1169 panic("Don't know how to clear state %d\n", lp->state); 1170 } 1171 } 1172 } 1173 1174 static void 1175 isp_mark_portdb(ispsoftc_t *isp, int chan) 1176 { 1177 fcparam *fcp = FCPARAM(isp, chan); 1178 fcportdb_t *lp; 1179 int i; 1180 1181 for (i = 0; i < MAX_FC_TARG; i++) { 1182 lp = &fcp->portdb[i]; 1183 if (lp->state == FC_PORTDB_STATE_NIL) 1184 continue; 1185 if (lp->portid >= DOMAIN_CONTROLLER_BASE && 1186 lp->portid <= DOMAIN_CONTROLLER_END) 1187 continue; 1188 fcp->portdb[i].probational = 1; 1189 } 1190 } 1191 1192 /* 1193 * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards 1194 * or via FABRIC LOGIN/FABRIC LOGOUT for other cards. 1195 */ 1196 static int 1197 isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags) 1198 { 1199 isp_plogx_t pl; 1200 uint32_t sst, parm1; 1201 int retval, lev; 1202 const char *msg; 1203 char buf[64]; 1204 1205 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d PLOGX %s PortID 0x%06x nphdl 0x%x", 1206 chan, (flags & PLOGX_FLG_CMD_MASK) == PLOGX_FLG_CMD_PLOGI ? 1207 "Login":"Logout", portid, handle); 1208 1209 ISP_MEMZERO(&pl, sizeof(pl)); 1210 pl.plogx_header.rqs_entry_count = 1; 1211 pl.plogx_header.rqs_entry_type = RQSTYPE_LOGIN; 1212 pl.plogx_nphdl = handle; 1213 pl.plogx_vphdl = chan; 1214 pl.plogx_portlo = portid; 1215 pl.plogx_rspsz_porthi = (portid >> 16) & 0xff; 1216 pl.plogx_flags = flags; 1217 1218 retval = isp_exec_entry_queue(isp, &pl, &pl, 3 * ICB_LOGIN_TOV); 1219 if (retval != 0) { 1220 isp_prt(isp, ISP_LOGERR, "%s: PLOGX of chan %d error %d", 1221 __func__, chan, retval); 1222 return (retval); 1223 } 1224 1225 if (pl.plogx_status == PLOGX_STATUS_OK) { 1226 return (0); 1227 } else if (pl.plogx_status != PLOGX_STATUS_IOCBERR) { 1228 isp_prt(isp, ISP_LOGWARN, 1229 "status 0x%x on port login IOCB channel %d", 1230 pl.plogx_status, chan); 1231 return (-1); 1232 } 1233 1234 sst = pl.plogx_ioparm[0].lo16 | (pl.plogx_ioparm[0].hi16 << 16); 1235 parm1 = pl.plogx_ioparm[1].lo16 | (pl.plogx_ioparm[1].hi16 << 16); 1236 1237 retval = -1; 1238 lev = ISP_LOGERR; 1239 msg = NULL; 1240 1241 switch (sst) { 1242 case PLOGX_IOCBERR_NOLINK: 1243 msg = "no link"; 1244 break; 1245 case PLOGX_IOCBERR_NOIOCB: 1246 msg = "no IOCB buffer"; 1247 break; 1248 case PLOGX_IOCBERR_NOXGHG: 1249 msg = "no Exchange Control Block"; 1250 break; 1251 case PLOGX_IOCBERR_FAILED: 1252 ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff); 1253 msg = buf; 1254 break; 1255 case PLOGX_IOCBERR_NOFABRIC: 1256 msg = "no fabric"; 1257 break; 1258 case PLOGX_IOCBERR_NOTREADY: 1259 msg = "firmware not ready"; 1260 break; 1261 case PLOGX_IOCBERR_NOLOGIN: 1262 ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1); 1263 msg = buf; 1264 retval = MBOX_NOT_LOGGED_IN; 1265 break; 1266 case PLOGX_IOCBERR_REJECT: 1267 ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1); 1268 msg = buf; 1269 break; 1270 case PLOGX_IOCBERR_NOPCB: 1271 msg = "no PCB allocated"; 1272 break; 1273 case PLOGX_IOCBERR_EINVAL: 1274 ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1); 1275 msg = buf; 1276 break; 1277 case PLOGX_IOCBERR_PORTUSED: 1278 lev = ISP_LOG_SANCFG|ISP_LOG_WARN1; 1279 ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1); 1280 msg = buf; 1281 retval = MBOX_PORT_ID_USED | (parm1 << 16); 1282 break; 1283 case PLOGX_IOCBERR_HNDLUSED: 1284 lev = ISP_LOG_SANCFG|ISP_LOG_WARN1; 1285 ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1); 1286 msg = buf; 1287 retval = MBOX_LOOP_ID_USED; 1288 break; 1289 case PLOGX_IOCBERR_NOHANDLE: 1290 msg = "no handle allocated"; 1291 break; 1292 case PLOGX_IOCBERR_NOFLOGI: 1293 msg = "no FLOGI_ACC"; 1294 break; 1295 default: 1296 ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", pl.plogx_status, flags); 1297 msg = buf; 1298 break; 1299 } 1300 if (msg) { 1301 isp_prt(isp, lev, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s", 1302 chan, portid, handle, msg); 1303 } 1304 return (retval); 1305 } 1306 1307 static int 1308 isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb) 1309 { 1310 mbreg_t mbs; 1311 union { 1312 isp_pdb_24xx_t bill; 1313 } un; 1314 1315 MBSINIT(&mbs, MBOX_GET_PORT_DB, 1316 MBLOGALL & ~MBLOGMASK(MBOX_COMMAND_PARAM_ERROR), 250000); 1317 mbs.ibits = (1 << 9)|(1 << 10); 1318 mbs.param[1] = id; 1319 mbs.param[2] = DMA_WD1(isp->isp_iocb_dma); 1320 mbs.param[3] = DMA_WD0(isp->isp_iocb_dma); 1321 mbs.param[6] = DMA_WD3(isp->isp_iocb_dma); 1322 mbs.param[7] = DMA_WD2(isp->isp_iocb_dma); 1323 mbs.param[9] = chan; 1324 MEMORYBARRIER(isp, SYNC_IFORDEV, 0, sizeof(un), chan); 1325 1326 isp_mboxcmd(isp, &mbs); 1327 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) 1328 return (mbs.param[0] | (mbs.param[1] << 16)); 1329 1330 MEMORYBARRIER(isp, SYNC_IFORCPU, 0, sizeof(un), chan); 1331 isp_get_pdb_24xx(isp, isp->isp_iocb, &un.bill); 1332 pdb->handle = un.bill.pdb_handle; 1333 pdb->prli_word0 = un.bill.pdb_prli_svc0; 1334 pdb->prli_word3 = un.bill.pdb_prli_svc3; 1335 pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits); 1336 ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8); 1337 ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8); 1338 isp_prt(isp, ISP_LOGDEBUG0, 1339 "Chan %d handle 0x%x Port 0x%06x flags 0x%x curstate %x laststate %x", 1340 chan, id, pdb->portid, un.bill.pdb_flags, 1341 un.bill.pdb_curstate, un.bill.pdb_laststate); 1342 1343 if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE || un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) { 1344 mbs.param[0] = MBOX_NOT_LOGGED_IN; 1345 return (mbs.param[0]); 1346 } 1347 return (0); 1348 } 1349 1350 static int 1351 isp_gethandles(ispsoftc_t *isp, int chan, uint16_t *handles, int *num, int loop) 1352 { 1353 fcparam *fcp = FCPARAM(isp, chan); 1354 mbreg_t mbs; 1355 isp_pnhle_24xx_t el4, *elp4; 1356 int i, j; 1357 uint32_t p; 1358 1359 MBSINIT(&mbs, MBOX_GET_ID_LIST, MBLOGALL, 250000); 1360 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 1361 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 1362 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 1363 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 1364 mbs.param[8] = ISP_FC_SCRLEN; 1365 mbs.param[9] = chan; 1366 if (FC_SCRATCH_ACQUIRE(isp, chan)) { 1367 isp_prt(isp, ISP_LOGERR, sacq); 1368 return (-1); 1369 } 1370 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, ISP_FC_SCRLEN, chan); 1371 isp_mboxcmd(isp, &mbs); 1372 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1373 FC_SCRATCH_RELEASE(isp, chan); 1374 return (mbs.param[0] | (mbs.param[1] << 16)); 1375 } 1376 MEMORYBARRIER(isp, SYNC_SFORCPU, 0, ISP_FC_SCRLEN, chan); 1377 elp4 = fcp->isp_scratch; 1378 for (i = 0, j = 0; i < mbs.param[1] && j < *num; i++) { 1379 isp_get_pnhle_24xx(isp, &elp4[i], &el4); 1380 p = el4.pnhle_port_id_lo | (el4.pnhle_port_id_hi << 16); 1381 if (loop && (p >> 8) != (fcp->isp_portid >> 8)) 1382 continue; 1383 handles[j++] = el4.pnhle_handle; 1384 } 1385 *num = j; 1386 FC_SCRATCH_RELEASE(isp, chan); 1387 return (0); 1388 } 1389 1390 static void 1391 isp_dump_chip_portdb(ispsoftc_t *isp, int chan) 1392 { 1393 isp_pdb_t pdb; 1394 uint16_t nphdl; 1395 1396 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d chip port dump", chan); 1397 for (nphdl = 0; nphdl != NPH_MAX_2K; nphdl++) { 1398 if (isp_getpdb(isp, chan, nphdl, &pdb)) { 1399 continue; 1400 } 1401 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d Handle 0x%04x " 1402 "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x", 1403 chan, nphdl, pdb.portid, pdb.portname[0], pdb.portname[1], 1404 pdb.portname[2], pdb.portname[3], pdb.portname[4], 1405 pdb.portname[5], pdb.portname[6], pdb.portname[7]); 1406 } 1407 } 1408 1409 static uint64_t 1410 isp_get_wwn(ispsoftc_t *isp, int chan, int nphdl, int nodename) 1411 { 1412 uint64_t wwn = INI_NONE; 1413 mbreg_t mbs; 1414 1415 MBSINIT(&mbs, MBOX_GET_PORT_NAME, 1416 MBLOGALL & ~MBLOGMASK(MBOX_COMMAND_PARAM_ERROR), 500000); 1417 mbs.param[1] = nphdl; 1418 if (nodename) 1419 mbs.param[10] = 1; 1420 mbs.param[9] = chan; 1421 isp_mboxcmd(isp, &mbs); 1422 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1423 return (wwn); 1424 } 1425 wwn = (((uint64_t)(mbs.param[2] >> 8)) << 56) | 1426 (((uint64_t)(mbs.param[2] & 0xff))<< 48) | 1427 (((uint64_t)(mbs.param[3] >> 8)) << 40) | 1428 (((uint64_t)(mbs.param[3] & 0xff))<< 32) | 1429 (((uint64_t)(mbs.param[6] >> 8)) << 24) | 1430 (((uint64_t)(mbs.param[6] & 0xff))<< 16) | 1431 (((uint64_t)(mbs.param[7] >> 8)) << 8) | 1432 (((uint64_t)(mbs.param[7] & 0xff))); 1433 return (wwn); 1434 } 1435 1436 /* 1437 * Make sure we have good FC link. 1438 */ 1439 1440 static int 1441 isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay) 1442 { 1443 mbreg_t mbs; 1444 int i, r, topo; 1445 fcparam *fcp; 1446 isp_pdb_t pdb; 1447 NANOTIME_T hra, hrb; 1448 1449 fcp = FCPARAM(isp, chan); 1450 1451 if (fcp->isp_loopstate < LOOP_HAVE_LINK) 1452 return (-1); 1453 if (fcp->isp_loopstate >= LOOP_LTEST_DONE) 1454 return (0); 1455 1456 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test", chan); 1457 1458 /* 1459 * Wait up to N microseconds for F/W to go to a ready state. 1460 */ 1461 GET_NANOTIME(&hra); 1462 while (1) { 1463 isp_change_fw_state(isp, chan, isp_fw_state(isp, chan)); 1464 if (fcp->isp_fwstate == FW_READY) { 1465 break; 1466 } 1467 if (fcp->isp_loopstate < LOOP_HAVE_LINK) 1468 goto abort; 1469 GET_NANOTIME(&hrb); 1470 if ((NANOTIME_SUB(&hrb, &hra) / 1000 + 1000 >= usdelay)) 1471 break; 1472 ISP_SLEEP(isp, 1000); 1473 } 1474 if (fcp->isp_fwstate != FW_READY) { 1475 isp_prt(isp, ISP_LOG_SANCFG, 1476 "Chan %d Firmware is not ready (%s)", 1477 chan, isp_fc_fw_statename(fcp->isp_fwstate)); 1478 return (-1); 1479 } 1480 1481 /* 1482 * Get our Loop ID and Port ID. 1483 */ 1484 MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0); 1485 mbs.param[9] = chan; 1486 isp_mboxcmd(isp, &mbs); 1487 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1488 return (-1); 1489 } 1490 1491 topo = (int) mbs.param[6]; 1492 if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB) 1493 topo = TOPO_PTP_STUB; 1494 fcp->isp_topo = topo; 1495 fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16); 1496 1497 if (!TOPO_IS_FABRIC(fcp->isp_topo)) { 1498 fcp->isp_loopid = mbs.param[1] & 0xff; 1499 } else if (fcp->isp_topo != TOPO_F_PORT) { 1500 uint8_t alpa = fcp->isp_portid; 1501 1502 for (i = 0; alpa_map[i]; i++) { 1503 if (alpa_map[i] == alpa) 1504 break; 1505 } 1506 if (alpa_map[i]) 1507 fcp->isp_loopid = i; 1508 } 1509 1510 #if 0 1511 fcp->isp_loopstate = LOOP_HAVE_ADDR; 1512 #endif 1513 fcp->isp_loopstate = LOOP_TESTING_LINK; 1514 1515 if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) { 1516 r = isp_getpdb(isp, chan, NPH_FL_ID, &pdb); 1517 if (r != 0 || pdb.portid == 0) { 1518 isp_prt(isp, ISP_LOGWARN, 1519 "fabric topology, but cannot get info about fabric controller (0x%x)", r); 1520 fcp->isp_topo = TOPO_PTP_STUB; 1521 goto not_on_fabric; 1522 } 1523 1524 fcp->isp_fabric_params = mbs.param[7]; 1525 fcp->isp_sns_hdl = NPH_SNS_ID; 1526 r = isp_register_fc4_type(isp, chan); 1527 if (fcp->isp_loopstate < LOOP_TESTING_LINK) 1528 goto abort; 1529 if (r != 0) 1530 goto not_on_fabric; 1531 r = isp_register_fc4_features_24xx(isp, chan); 1532 if (fcp->isp_loopstate < LOOP_TESTING_LINK) 1533 goto abort; 1534 if (r != 0) 1535 goto not_on_fabric; 1536 r = isp_register_port_name_24xx(isp, chan); 1537 if (fcp->isp_loopstate < LOOP_TESTING_LINK) 1538 goto abort; 1539 if (r != 0) 1540 goto not_on_fabric; 1541 isp_register_node_name_24xx(isp, chan); 1542 if (fcp->isp_loopstate < LOOP_TESTING_LINK) 1543 goto abort; 1544 } 1545 1546 not_on_fabric: 1547 /* Get link speed. */ 1548 fcp->isp_gbspeed = 1; 1549 MBSINIT(&mbs, MBOX_GET_SET_DATA_RATE, MBLOGALL, 3000000); 1550 mbs.param[1] = MBGSD_GET_RATE; 1551 /* mbs.param[2] undefined if we're just getting rate */ 1552 isp_mboxcmd(isp, &mbs); 1553 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { 1554 if (mbs.param[1] == MBGSD_10GB) 1555 fcp->isp_gbspeed = 10; 1556 else if (mbs.param[1] == MBGSD_64GB) 1557 fcp->isp_gbspeed = 64; 1558 else if (mbs.param[1] == MBGSD_32GB) 1559 fcp->isp_gbspeed = 32; 1560 else if (mbs.param[1] == MBGSD_16GB) 1561 fcp->isp_gbspeed = 16; 1562 else if (mbs.param[1] == MBGSD_8GB) 1563 fcp->isp_gbspeed = 8; 1564 else if (mbs.param[1] == MBGSD_4GB) 1565 fcp->isp_gbspeed = 4; 1566 else if (mbs.param[1] == MBGSD_2GB) 1567 fcp->isp_gbspeed = 2; 1568 else if (mbs.param[1] == MBGSD_1GB) 1569 fcp->isp_gbspeed = 1; 1570 } 1571 1572 if (fcp->isp_loopstate < LOOP_TESTING_LINK) { 1573 abort: 1574 isp_prt(isp, ISP_LOG_SANCFG, 1575 "Chan %d FC link test aborted", chan); 1576 return (1); 1577 } 1578 fcp->isp_loopstate = LOOP_LTEST_DONE; 1579 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGCONFIG, 1580 "Chan %d WWPN %016jx WWNN %016jx", 1581 chan, (uintmax_t)fcp->isp_wwpn, (uintmax_t)fcp->isp_wwnn); 1582 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGCONFIG, 1583 "Chan %d %dGb %s PortID 0x%06x LoopID 0x%02x", 1584 chan, fcp->isp_gbspeed, isp_fc_toponame(fcp), fcp->isp_portid, 1585 fcp->isp_loopid); 1586 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test done", chan); 1587 return (0); 1588 } 1589 1590 /* 1591 * Complete the synchronization of our Port Database. 1592 * 1593 * At this point, we've scanned the local loop (if any) and the fabric 1594 * and performed fabric logins on all new devices. 1595 * 1596 * Our task here is to go through our port database removing any entities 1597 * that are still marked probational (issuing PLOGO for ones which we had 1598 * PLOGI'd into) or are dead, and notifying upper layers about new/changed 1599 * devices. 1600 */ 1601 static int 1602 isp_pdb_sync(ispsoftc_t *isp, int chan) 1603 { 1604 fcparam *fcp = FCPARAM(isp, chan); 1605 fcportdb_t *lp; 1606 uint16_t dbidx; 1607 1608 if (fcp->isp_loopstate < LOOP_FSCAN_DONE) 1609 return (-1); 1610 if (fcp->isp_loopstate >= LOOP_READY) 1611 return (0); 1612 1613 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync", chan); 1614 1615 fcp->isp_loopstate = LOOP_SYNCING_PDB; 1616 1617 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) { 1618 lp = &fcp->portdb[dbidx]; 1619 1620 if (lp->state == FC_PORTDB_STATE_NIL) 1621 continue; 1622 if (lp->probational && lp->state != FC_PORTDB_STATE_ZOMBIE) 1623 lp->state = FC_PORTDB_STATE_DEAD; 1624 switch (lp->state) { 1625 case FC_PORTDB_STATE_DEAD: 1626 lp->state = FC_PORTDB_STATE_NIL; 1627 isp_async(isp, ISPASYNC_DEV_GONE, chan, lp); 1628 if ((lp->portid & 0xffff00) != 0) { 1629 (void) isp_plogx(isp, chan, lp->handle, 1630 lp->portid, 1631 PLOGX_FLG_CMD_LOGO | 1632 PLOGX_FLG_IMPLICIT | 1633 PLOGX_FLG_FREE_NPHDL); 1634 } 1635 /* 1636 * Note that we might come out of this with our state 1637 * set to FC_PORTDB_STATE_ZOMBIE. 1638 */ 1639 break; 1640 case FC_PORTDB_STATE_NEW: 1641 lp->state = FC_PORTDB_STATE_VALID; 1642 isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp); 1643 break; 1644 case FC_PORTDB_STATE_CHANGED: 1645 lp->state = FC_PORTDB_STATE_VALID; 1646 isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp); 1647 lp->portid = lp->new_portid; 1648 lp->prli_word0 = lp->new_prli_word0; 1649 lp->prli_word3 = lp->new_prli_word3; 1650 break; 1651 case FC_PORTDB_STATE_VALID: 1652 isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp); 1653 break; 1654 case FC_PORTDB_STATE_ZOMBIE: 1655 break; 1656 default: 1657 isp_prt(isp, ISP_LOGWARN, 1658 "isp_pdb_sync: state %d for idx %d", 1659 lp->state, dbidx); 1660 isp_dump_portdb(isp, chan); 1661 } 1662 } 1663 1664 if (fcp->isp_loopstate < LOOP_SYNCING_PDB) { 1665 isp_prt(isp, ISP_LOG_SANCFG, 1666 "Chan %d FC PDB sync aborted", chan); 1667 return (1); 1668 } 1669 1670 fcp->isp_loopstate = LOOP_READY; 1671 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync done", chan); 1672 return (0); 1673 } 1674 1675 static void 1676 isp_pdb_add_update(ispsoftc_t *isp, int chan, isp_pdb_t *pdb) 1677 { 1678 fcportdb_t *lp; 1679 uint64_t wwnn, wwpn; 1680 1681 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb->nodename); 1682 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb->portname); 1683 1684 /* Search port database for the same WWPN. */ 1685 if (isp_find_pdb_by_wwpn(isp, chan, wwpn, &lp)) { 1686 if (!lp->probational) { 1687 isp_prt(isp, ISP_LOGERR, 1688 "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)", 1689 chan, lp->portid, lp->handle, 1690 FC_PORTDB_TGT(isp, chan, lp), lp->state); 1691 isp_dump_portdb(isp, chan); 1692 return; 1693 } 1694 lp->probational = 0; 1695 lp->node_wwn = wwnn; 1696 1697 /* Old device, nothing new. */ 1698 if (lp->portid == pdb->portid && 1699 lp->handle == pdb->handle && 1700 lp->prli_word3 == pdb->prli_word3 && 1701 ((pdb->prli_word0 & PRLI_WD0_EST_IMAGE_PAIR) == 1702 (lp->prli_word0 & PRLI_WD0_EST_IMAGE_PAIR))) { 1703 if (lp->state != FC_PORTDB_STATE_NEW) 1704 lp->state = FC_PORTDB_STATE_VALID; 1705 isp_prt(isp, ISP_LOG_SANCFG, 1706 "Chan %d Port 0x%06x@0x%04x is valid", 1707 chan, pdb->portid, pdb->handle); 1708 return; 1709 } 1710 1711 /* Something has changed. */ 1712 lp->state = FC_PORTDB_STATE_CHANGED; 1713 lp->handle = pdb->handle; 1714 lp->new_portid = pdb->portid; 1715 lp->new_prli_word0 = pdb->prli_word0; 1716 lp->new_prli_word3 = pdb->prli_word3; 1717 isp_prt(isp, ISP_LOG_SANCFG, 1718 "Chan %d Port 0x%06x@0x%04x is changed", 1719 chan, pdb->portid, pdb->handle); 1720 return; 1721 } 1722 1723 /* It seems like a new port. Find an empty slot for it. */ 1724 if (!isp_find_pdb_empty(isp, chan, &lp)) { 1725 isp_prt(isp, ISP_LOGERR, "Chan %d out of portdb entries", chan); 1726 return; 1727 } 1728 1729 ISP_MEMZERO(lp, sizeof (fcportdb_t)); 1730 lp->probational = 0; 1731 lp->state = FC_PORTDB_STATE_NEW; 1732 lp->portid = lp->new_portid = pdb->portid; 1733 lp->prli_word0 = lp->new_prli_word0 = pdb->prli_word0; 1734 lp->prli_word3 = lp->new_prli_word3 = pdb->prli_word3; 1735 lp->handle = pdb->handle; 1736 lp->port_wwn = wwpn; 1737 lp->node_wwn = wwnn; 1738 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Port 0x%06x@0x%04x is new", 1739 chan, pdb->portid, pdb->handle); 1740 } 1741 1742 /* 1743 * Scan local loop for devices. 1744 */ 1745 static int 1746 isp_scan_loop(ispsoftc_t *isp, int chan) 1747 { 1748 fcparam *fcp = FCPARAM(isp, chan); 1749 int idx, lim, r; 1750 isp_pdb_t pdb; 1751 uint16_t *handles; 1752 uint16_t handle; 1753 1754 if (fcp->isp_loopstate < LOOP_LTEST_DONE) 1755 return (-1); 1756 if (fcp->isp_loopstate >= LOOP_LSCAN_DONE) 1757 return (0); 1758 1759 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan", chan); 1760 fcp->isp_loopstate = LOOP_SCANNING_LOOP; 1761 if (TOPO_IS_FABRIC(fcp->isp_topo)) { 1762 isp_prt(isp, ISP_LOG_SANCFG, 1763 "Chan %d FC loop scan done (no loop)", chan); 1764 fcp->isp_loopstate = LOOP_LSCAN_DONE; 1765 return (0); 1766 } 1767 1768 handles = (uint16_t *)fcp->isp_scanscratch; 1769 lim = ISP_FC_SCRLEN / 2; 1770 r = isp_gethandles(isp, chan, handles, &lim, 1); 1771 if (r != 0) { 1772 isp_prt(isp, ISP_LOG_SANCFG, 1773 "Chan %d Getting list of handles failed with %x", chan, r); 1774 isp_prt(isp, ISP_LOG_SANCFG, 1775 "Chan %d FC loop scan done (bad)", chan); 1776 return (-1); 1777 } 1778 1779 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Got %d handles", 1780 chan, lim); 1781 1782 /* 1783 * Run through the list and get the port database info for each one. 1784 */ 1785 isp_mark_portdb(isp, chan); 1786 for (idx = 0; idx < lim; idx++) { 1787 handle = handles[idx]; 1788 1789 /* 1790 * Don't scan "special" ids. 1791 */ 1792 if (handle >= NPH_RESERVED) 1793 continue; 1794 1795 /* 1796 * Get the port database entity for this index. 1797 */ 1798 r = isp_getpdb(isp, chan, handle, &pdb); 1799 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) { 1800 abort: 1801 isp_prt(isp, ISP_LOG_SANCFG, 1802 "Chan %d FC loop scan aborted", chan); 1803 return (1); 1804 } 1805 if (r != 0) { 1806 isp_prt(isp, ISP_LOGDEBUG1, 1807 "Chan %d FC Scan Loop handle %d returned %x", 1808 chan, handle, r); 1809 continue; 1810 } 1811 1812 isp_pdb_add_update(isp, chan, &pdb); 1813 } 1814 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) 1815 goto abort; 1816 fcp->isp_loopstate = LOOP_LSCAN_DONE; 1817 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan done", chan); 1818 return (0); 1819 } 1820 1821 static int 1822 isp_ct_passthru(ispsoftc_t *isp, int chan, uint32_t cmd_bcnt, uint32_t rsp_bcnt) 1823 { 1824 fcparam *fcp = FCPARAM(isp, chan); 1825 isp_ct_pt_t pt; 1826 int retval; 1827 1828 if (isp->isp_dblev & ISP_LOGDEBUG1) 1829 isp_print_bytes(isp, "CT request", cmd_bcnt, fcp->isp_scratch); 1830 1831 /* 1832 * Build a Passthrough IOCB in memory. 1833 */ 1834 ISP_MEMZERO(&pt, sizeof(pt)); 1835 pt.ctp_header.rqs_entry_count = 1; 1836 pt.ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU; 1837 pt.ctp_nphdl = fcp->isp_sns_hdl; 1838 pt.ctp_cmd_cnt = 1; 1839 pt.ctp_vpidx = ISP_GET_VPIDX(isp, chan); 1840 pt.ctp_time = 10; 1841 pt.ctp_rsp_cnt = 1; 1842 pt.ctp_rsp_bcnt = rsp_bcnt; 1843 pt.ctp_cmd_bcnt = cmd_bcnt; 1844 pt.ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma); 1845 pt.ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma); 1846 pt.ctp_dataseg[0].ds_count = cmd_bcnt; 1847 pt.ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma); 1848 pt.ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma); 1849 pt.ctp_dataseg[1].ds_count = rsp_bcnt; 1850 1851 retval = isp_exec_entry_queue(isp, &pt, &pt, 2 * pt.ctp_time); 1852 if (retval != 0) { 1853 isp_prt(isp, ISP_LOGERR, "%s: CTP of chan %d error %d", 1854 __func__, chan, retval); 1855 return (retval); 1856 } 1857 1858 if (pt.ctp_status && pt.ctp_status != RQCS_DATA_UNDERRUN) { 1859 isp_prt(isp, ISP_LOGWARN, 1860 "Chan %d CT pass-through returned 0x%x", 1861 chan, pt.ctp_status); 1862 return (-1); 1863 } 1864 1865 if (isp->isp_dblev & ISP_LOGDEBUG1) 1866 isp_print_bytes(isp, "CT response", rsp_bcnt, fcp->isp_scratch); 1867 1868 return (0); 1869 } 1870 1871 /* 1872 * Scan the fabric for devices and add them to our port database. 1873 * 1874 * Use the GID_PT command to get list of all Nx_Port IDs SNS knows. 1875 * Use GFF_ID and GFT_ID to check port type (FCP) and features (target). 1876 * 1877 * We use CT Pass-through IOCB. 1878 */ 1879 #define GIDLEN ISP_FC_SCRLEN 1880 #define NGENT ((GIDLEN - 16) >> 2) 1881 1882 static int 1883 isp_gid_pt(ispsoftc_t *isp, int chan) 1884 { 1885 fcparam *fcp = FCPARAM(isp, chan); 1886 ct_hdr_t ct; 1887 uint8_t *scp = fcp->isp_scratch; 1888 1889 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GID_PT", chan); 1890 if (FC_SCRATCH_ACQUIRE(isp, chan)) { 1891 isp_prt(isp, ISP_LOGERR, sacq); 1892 return (-1); 1893 } 1894 1895 /* Build the CT command and execute via pass-through. */ 1896 ISP_MEMZERO(&ct, sizeof (ct)); 1897 ct.ct_revision = CT_REVISION; 1898 ct.ct_fcs_type = CT_FC_TYPE_FC; 1899 ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS; 1900 ct.ct_cmd_resp = SNS_GID_PT; 1901 ct.ct_bcnt_resid = (GIDLEN - 16) >> 2; 1902 isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp); 1903 scp[sizeof(ct)] = 0x7f; /* Port Type = Nx_Port */ 1904 scp[sizeof(ct)+1] = 0; /* Domain_ID = any */ 1905 scp[sizeof(ct)+2] = 0; /* Area_ID = any */ 1906 scp[sizeof(ct)+3] = 0; /* Flags = no Area_ID */ 1907 1908 if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), GIDLEN)) { 1909 FC_SCRATCH_RELEASE(isp, chan); 1910 return (-1); 1911 } 1912 1913 isp_get_gid_xx_response(isp, (sns_gid_xx_rsp_t *)scp, 1914 (sns_gid_xx_rsp_t *)fcp->isp_scanscratch, NGENT); 1915 FC_SCRATCH_RELEASE(isp, chan); 1916 return (0); 1917 } 1918 1919 static int 1920 isp_gff_id(ispsoftc_t *isp, int chan, uint32_t portid) 1921 { 1922 fcparam *fcp = FCPARAM(isp, chan); 1923 ct_hdr_t ct; 1924 uint32_t *rp; 1925 uint8_t *scp = fcp->isp_scratch; 1926 sns_gff_id_rsp_t rsp; 1927 int i, res = -1; 1928 1929 if (!fcp->isp_use_gff_id) /* User may block GFF_ID use. */ 1930 return (res); 1931 1932 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GFF_ID", chan); 1933 if (FC_SCRATCH_ACQUIRE(isp, chan)) { 1934 isp_prt(isp, ISP_LOGERR, sacq); 1935 return (res); 1936 } 1937 1938 /* Build the CT command and execute via pass-through. */ 1939 ISP_MEMZERO(&ct, sizeof (ct)); 1940 ct.ct_revision = CT_REVISION; 1941 ct.ct_fcs_type = CT_FC_TYPE_FC; 1942 ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS; 1943 ct.ct_cmd_resp = SNS_GFF_ID; 1944 ct.ct_bcnt_resid = (SNS_GFF_ID_RESP_SIZE - sizeof(ct)) / 4; 1945 isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp); 1946 rp = (uint32_t *) &scp[sizeof(ct)]; 1947 ISP_IOZPUT_32(isp, portid, rp); 1948 1949 if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), 1950 SNS_GFF_ID_RESP_SIZE)) { 1951 FC_SCRATCH_RELEASE(isp, chan); 1952 return (res); 1953 } 1954 1955 isp_get_gff_id_response(isp, (sns_gff_id_rsp_t *)scp, &rsp); 1956 if (rsp.snscb_cthdr.ct_cmd_resp == LS_ACC) { 1957 for (i = 0; i < 32; i++) { 1958 if (rsp.snscb_fc4_features[i] != 0) { 1959 res = 0; 1960 break; 1961 } 1962 } 1963 if (((rsp.snscb_fc4_features[FC4_SCSI / 8] >> 1964 ((FC4_SCSI % 8) * 4)) & 0x01) != 0) 1965 res = 1; 1966 /* Workaround for broken Brocade firmware. */ 1967 if (((ISP_SWAP32(isp, rsp.snscb_fc4_features[FC4_SCSI / 8]) >> 1968 ((FC4_SCSI % 8) * 4)) & 0x01) != 0) 1969 res = 1; 1970 } 1971 FC_SCRATCH_RELEASE(isp, chan); 1972 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GFF_ID result is %d", chan, res); 1973 return (res); 1974 } 1975 1976 static int 1977 isp_gft_id(ispsoftc_t *isp, int chan, uint32_t portid) 1978 { 1979 fcparam *fcp = FCPARAM(isp, chan); 1980 ct_hdr_t ct; 1981 uint32_t *rp; 1982 uint8_t *scp = fcp->isp_scratch; 1983 sns_gft_id_rsp_t rsp; 1984 int i, res = -1; 1985 1986 if (!fcp->isp_use_gft_id) /* User may block GFT_ID use. */ 1987 return (res); 1988 1989 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GFT_ID", chan); 1990 if (FC_SCRATCH_ACQUIRE(isp, chan)) { 1991 isp_prt(isp, ISP_LOGERR, sacq); 1992 return (res); 1993 } 1994 1995 /* Build the CT command and execute via pass-through. */ 1996 ISP_MEMZERO(&ct, sizeof (ct)); 1997 ct.ct_revision = CT_REVISION; 1998 ct.ct_fcs_type = CT_FC_TYPE_FC; 1999 ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS; 2000 ct.ct_cmd_resp = SNS_GFT_ID; 2001 ct.ct_bcnt_resid = (SNS_GFT_ID_RESP_SIZE - sizeof(ct)) / 4; 2002 isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp); 2003 rp = (uint32_t *) &scp[sizeof(ct)]; 2004 ISP_IOZPUT_32(isp, portid, rp); 2005 2006 if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), 2007 SNS_GFT_ID_RESP_SIZE)) { 2008 FC_SCRATCH_RELEASE(isp, chan); 2009 return (res); 2010 } 2011 2012 isp_get_gft_id_response(isp, (sns_gft_id_rsp_t *)scp, &rsp); 2013 if (rsp.snscb_cthdr.ct_cmd_resp == LS_ACC) { 2014 for (i = 0; i < 8; i++) { 2015 if (rsp.snscb_fc4_types[i] != 0) { 2016 res = 0; 2017 break; 2018 } 2019 } 2020 if (((rsp.snscb_fc4_types[FC4_SCSI / 32] >> 2021 (FC4_SCSI % 32)) & 0x01) != 0) 2022 res = 1; 2023 } 2024 FC_SCRATCH_RELEASE(isp, chan); 2025 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GFT_ID result is %d", chan, res); 2026 return (res); 2027 } 2028 2029 static int 2030 isp_scan_fabric(ispsoftc_t *isp, int chan) 2031 { 2032 fcparam *fcp = FCPARAM(isp, chan); 2033 fcportdb_t *lp; 2034 uint32_t portid; 2035 isp_pdb_t pdb; 2036 int portidx, portlim, r; 2037 sns_gid_xx_rsp_t *rs; 2038 2039 if (fcp->isp_loopstate < LOOP_LSCAN_DONE) 2040 return (-1); 2041 if (fcp->isp_loopstate >= LOOP_FSCAN_DONE) 2042 return (0); 2043 2044 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan", chan); 2045 fcp->isp_loopstate = LOOP_SCANNING_FABRIC; 2046 if (!TOPO_IS_FABRIC(fcp->isp_topo)) { 2047 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2048 isp_prt(isp, ISP_LOG_SANCFG, 2049 "Chan %d FC fabric scan done (no fabric)", chan); 2050 return (0); 2051 } 2052 2053 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) { 2054 abort: 2055 FC_SCRATCH_RELEASE(isp, chan); 2056 isp_prt(isp, ISP_LOG_SANCFG, 2057 "Chan %d FC fabric scan aborted", chan); 2058 return (1); 2059 } 2060 2061 /* 2062 * Make sure we still are logged into the fabric controller. 2063 */ 2064 r = isp_getpdb(isp, chan, NPH_FL_ID, &pdb); 2065 if ((r & 0xffff) == MBOX_NOT_LOGGED_IN) { 2066 isp_dump_chip_portdb(isp, chan); 2067 } 2068 if (r) { 2069 fcp->isp_loopstate = LOOP_LTEST_DONE; 2070 fail: 2071 isp_prt(isp, ISP_LOG_SANCFG, 2072 "Chan %d FC fabric scan done (bad)", chan); 2073 return (-1); 2074 } 2075 2076 /* Get list of port IDs from SNS. */ 2077 r = isp_gid_pt(isp, chan); 2078 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) 2079 goto abort; 2080 if (r > 0) { 2081 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2082 return (-1); 2083 } else if (r < 0) { 2084 fcp->isp_loopstate = LOOP_LTEST_DONE; /* try again */ 2085 return (-1); 2086 } 2087 2088 rs = (sns_gid_xx_rsp_t *) fcp->isp_scanscratch; 2089 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) 2090 goto abort; 2091 if (rs->snscb_cthdr.ct_cmd_resp != LS_ACC) { 2092 int level; 2093 /* FC-4 Type and Port Type not registered are not errors. */ 2094 if (rs->snscb_cthdr.ct_reason == 9 && 2095 (rs->snscb_cthdr.ct_explanation == 0x07 || 2096 rs->snscb_cthdr.ct_explanation == 0x0a)) { 2097 level = ISP_LOG_SANCFG; 2098 } else { 2099 level = ISP_LOGWARN; 2100 } 2101 isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_PT" 2102 " (Reason=0x%x Expl=0x%x)", chan, 2103 rs->snscb_cthdr.ct_reason, 2104 rs->snscb_cthdr.ct_explanation); 2105 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2106 return (-1); 2107 } 2108 2109 /* Check our buffer was big enough to get the full list. */ 2110 for (portidx = 0; portidx < NGENT-1; portidx++) { 2111 if (rs->snscb_ports[portidx].control & 0x80) 2112 break; 2113 } 2114 if ((rs->snscb_ports[portidx].control & 0x80) == 0) { 2115 isp_prt(isp, ISP_LOGWARN, 2116 "fabric too big for scratch area: increase ISP_FC_SCRLEN"); 2117 } 2118 portlim = portidx + 1; 2119 isp_prt(isp, ISP_LOG_SANCFG, 2120 "Chan %d Got %d ports back from name server", chan, portlim); 2121 2122 /* Go through the list and remove duplicate port ids. */ 2123 for (portidx = 0; portidx < portlim; portidx++) { 2124 int npidx; 2125 2126 portid = 2127 ((rs->snscb_ports[portidx].portid[0]) << 16) | 2128 ((rs->snscb_ports[portidx].portid[1]) << 8) | 2129 ((rs->snscb_ports[portidx].portid[2])); 2130 2131 for (npidx = portidx + 1; npidx < portlim; npidx++) { 2132 uint32_t new_portid = 2133 ((rs->snscb_ports[npidx].portid[0]) << 16) | 2134 ((rs->snscb_ports[npidx].portid[1]) << 8) | 2135 ((rs->snscb_ports[npidx].portid[2])); 2136 if (new_portid == portid) { 2137 break; 2138 } 2139 } 2140 2141 if (npidx < portlim) { 2142 rs->snscb_ports[npidx].portid[0] = 0; 2143 rs->snscb_ports[npidx].portid[1] = 0; 2144 rs->snscb_ports[npidx].portid[2] = 0; 2145 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d removing duplicate PortID 0x%06x entry from list", chan, portid); 2146 } 2147 } 2148 2149 /* 2150 * We now have a list of Port IDs for all FC4 SCSI devices 2151 * that the Fabric Name server knows about. 2152 * 2153 * For each entry on this list go through our port database looking 2154 * for probational entries- if we find one, then an old entry is 2155 * maybe still this one. We get some information to find out. 2156 * 2157 * Otherwise, it's a new fabric device, and we log into it 2158 * (unconditionally). After searching the entire database 2159 * again to make sure that we never ever ever ever have more 2160 * than one entry that has the same PortID or the same 2161 * WWNN/WWPN duple, we enter the device into our database. 2162 */ 2163 isp_mark_portdb(isp, chan); 2164 for (portidx = 0; portidx < portlim; portidx++) { 2165 portid = ((rs->snscb_ports[portidx].portid[0]) << 16) | 2166 ((rs->snscb_ports[portidx].portid[1]) << 8) | 2167 ((rs->snscb_ports[portidx].portid[2])); 2168 isp_prt(isp, ISP_LOG_SANCFG, 2169 "Chan %d Checking fabric port 0x%06x", chan, portid); 2170 if (portid == 0) { 2171 isp_prt(isp, ISP_LOG_SANCFG, 2172 "Chan %d Port at idx %d is zero", 2173 chan, portidx); 2174 continue; 2175 } 2176 if (portid == fcp->isp_portid) { 2177 isp_prt(isp, ISP_LOG_SANCFG, 2178 "Chan %d Port 0x%06x is our", chan, portid); 2179 continue; 2180 } 2181 2182 /* Now search the entire port database for the same portid. */ 2183 if (isp_find_pdb_by_portid(isp, chan, portid, &lp)) { 2184 if (!lp->probational) { 2185 isp_prt(isp, ISP_LOGERR, 2186 "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)", 2187 chan, lp->portid, lp->handle, 2188 FC_PORTDB_TGT(isp, chan, lp), lp->state); 2189 isp_dump_portdb(isp, chan); 2190 goto fail; 2191 } 2192 2193 if (lp->state == FC_PORTDB_STATE_ZOMBIE) 2194 goto relogin; 2195 2196 /* 2197 * See if we're still logged into it. 2198 * 2199 * If we aren't, mark it as a dead device and 2200 * leave the new portid in the database entry 2201 * for somebody further along to decide what to 2202 * do (policy choice). 2203 * 2204 * If we are, check to see if it's the same 2205 * device still (it should be). If for some 2206 * reason it isn't, mark it as a changed device 2207 * and leave the new portid and role in the 2208 * database entry for somebody further along to 2209 * decide what to do (policy choice). 2210 */ 2211 r = isp_getpdb(isp, chan, lp->handle, &pdb); 2212 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) 2213 goto abort; 2214 if (r != 0) { 2215 lp->state = FC_PORTDB_STATE_DEAD; 2216 isp_prt(isp, ISP_LOG_SANCFG, 2217 "Chan %d Port 0x%06x handle 0x%x is dead (%d)", 2218 chan, portid, lp->handle, r); 2219 goto relogin; 2220 } 2221 2222 isp_pdb_add_update(isp, chan, &pdb); 2223 continue; 2224 } 2225 2226 relogin: 2227 if ((fcp->role & ISP_ROLE_INITIATOR) == 0) { 2228 isp_prt(isp, ISP_LOG_SANCFG, 2229 "Chan %d Port 0x%06x is not logged in", chan, portid); 2230 continue; 2231 } 2232 2233 r = isp_gff_id(isp, chan, portid); 2234 if (r == 0) { 2235 isp_prt(isp, ISP_LOG_SANCFG, 2236 "Chan %d Port 0x%06x is not an FCP target", chan, portid); 2237 continue; 2238 } 2239 if (r < 0) 2240 r = isp_gft_id(isp, chan, portid); 2241 if (r == 0) { 2242 isp_prt(isp, ISP_LOG_SANCFG, 2243 "Chan %d Port 0x%06x is not FCP", chan, portid); 2244 continue; 2245 } 2246 2247 if (isp_login_device(isp, chan, portid, &pdb, 2248 &FCPARAM(isp, 0)->isp_lasthdl)) { 2249 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) 2250 goto abort; 2251 continue; 2252 } 2253 2254 isp_pdb_add_update(isp, chan, &pdb); 2255 } 2256 2257 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) 2258 goto abort; 2259 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2260 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan done", chan); 2261 return (0); 2262 } 2263 2264 /* 2265 * Find an unused handle and try and use to login to a port. 2266 */ 2267 static int 2268 isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint16_t *ohp) 2269 { 2270 int i, r; 2271 uint16_t handle; 2272 2273 handle = isp_next_handle(isp, ohp); 2274 for (i = 0; i < NPH_MAX_2K; i++) { 2275 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) 2276 return (-1); 2277 2278 /* Check if this handle is free. */ 2279 r = isp_getpdb(isp, chan, handle, p); 2280 if (r == 0) { 2281 if (p->portid != portid) { 2282 /* This handle is busy, try next one. */ 2283 handle = isp_next_handle(isp, ohp); 2284 continue; 2285 } 2286 break; 2287 } 2288 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) 2289 return (-1); 2290 2291 /* 2292 * Now try and log into the device 2293 */ 2294 r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI); 2295 if (r == 0) { 2296 break; 2297 } else if ((r & 0xffff) == MBOX_PORT_ID_USED) { 2298 /* 2299 * If we get here, then the firmwware still thinks we're logged into this device, but with a different 2300 * handle. We need to break that association. We used to try and just substitute the handle, but then 2301 * failed to get any data via isp_getpdb (below). 2302 */ 2303 if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL)) { 2304 isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16); 2305 } 2306 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) 2307 return (-1); 2308 r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI); 2309 if (r != 0) 2310 i = NPH_MAX_2K; 2311 break; 2312 } else if ((r & 0xffff) == MBOX_LOOP_ID_USED) { 2313 /* Try the next handle. */ 2314 handle = isp_next_handle(isp, ohp); 2315 } else { 2316 /* Give up. */ 2317 i = NPH_MAX_2K; 2318 break; 2319 } 2320 } 2321 2322 if (i == NPH_MAX_2K) { 2323 isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid); 2324 return (-1); 2325 } 2326 2327 /* 2328 * If we successfully logged into it, get the PDB for it 2329 * so we can crosscheck that it is still what we think it 2330 * is and that we also have the role it plays 2331 */ 2332 r = isp_getpdb(isp, chan, handle, p); 2333 if (r != 0) { 2334 isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle); 2335 return (-1); 2336 } 2337 2338 if (p->handle != handle || p->portid != portid) { 2339 isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)", 2340 chan, portid, handle, p->portid, p->handle); 2341 return (-1); 2342 } 2343 return (0); 2344 } 2345 2346 static int 2347 isp_register_fc4_type(ispsoftc_t *isp, int chan) 2348 { 2349 fcparam *fcp = FCPARAM(isp, chan); 2350 rft_id_t rp; 2351 ct_hdr_t *ct = &rp.rftid_hdr; 2352 uint8_t *scp = fcp->isp_scratch; 2353 2354 if (FC_SCRATCH_ACQUIRE(isp, chan)) { 2355 isp_prt(isp, ISP_LOGERR, sacq); 2356 return (-1); 2357 } 2358 2359 /* Build the CT command and execute via pass-through. */ 2360 ISP_MEMZERO(&rp, sizeof(rp)); 2361 ct->ct_revision = CT_REVISION; 2362 ct->ct_fcs_type = CT_FC_TYPE_FC; 2363 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS; 2364 ct->ct_cmd_resp = SNS_RFT_ID; 2365 ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2; 2366 rp.rftid_portid[0] = fcp->isp_portid >> 16; 2367 rp.rftid_portid[1] = fcp->isp_portid >> 8; 2368 rp.rftid_portid[2] = fcp->isp_portid; 2369 rp.rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f); 2370 isp_put_rft_id(isp, &rp, (rft_id_t *)scp); 2371 2372 if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) { 2373 FC_SCRATCH_RELEASE(isp, chan); 2374 return (-1); 2375 } 2376 2377 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct); 2378 FC_SCRATCH_RELEASE(isp, chan); 2379 if (ct->ct_cmd_resp == LS_RJT) { 2380 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "Chan %d Register FC4 Type rejected", chan); 2381 return (-1); 2382 } else if (ct->ct_cmd_resp == LS_ACC) { 2383 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Register FC4 Type accepted", chan); 2384 } else { 2385 isp_prt(isp, ISP_LOGWARN, "Chan %d Register FC4 Type: 0x%x", chan, ct->ct_cmd_resp); 2386 return (-1); 2387 } 2388 return (0); 2389 } 2390 2391 static int 2392 isp_register_fc4_features_24xx(ispsoftc_t *isp, int chan) 2393 { 2394 fcparam *fcp = FCPARAM(isp, chan); 2395 ct_hdr_t *ct; 2396 rff_id_t rp; 2397 uint8_t *scp = fcp->isp_scratch; 2398 2399 if (FC_SCRATCH_ACQUIRE(isp, chan)) { 2400 isp_prt(isp, ISP_LOGERR, sacq); 2401 return (-1); 2402 } 2403 2404 /* 2405 * Build the CT header and command in memory. 2406 */ 2407 ISP_MEMZERO(&rp, sizeof(rp)); 2408 ct = &rp.rffid_hdr; 2409 ct->ct_revision = CT_REVISION; 2410 ct->ct_fcs_type = CT_FC_TYPE_FC; 2411 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS; 2412 ct->ct_cmd_resp = SNS_RFF_ID; 2413 ct->ct_bcnt_resid = (sizeof (rff_id_t) - sizeof (ct_hdr_t)) >> 2; 2414 rp.rffid_portid[0] = fcp->isp_portid >> 16; 2415 rp.rffid_portid[1] = fcp->isp_portid >> 8; 2416 rp.rffid_portid[2] = fcp->isp_portid; 2417 rp.rffid_fc4features = 0; 2418 if (fcp->role & ISP_ROLE_TARGET) 2419 rp.rffid_fc4features |= 1; 2420 if (fcp->role & ISP_ROLE_INITIATOR) 2421 rp.rffid_fc4features |= 2; 2422 rp.rffid_fc4type = FC4_SCSI; 2423 isp_put_rff_id(isp, &rp, (rff_id_t *)scp); 2424 if (isp->isp_dblev & ISP_LOGDEBUG1) 2425 isp_print_bytes(isp, "CT request", sizeof(rft_id_t), scp); 2426 2427 if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) { 2428 FC_SCRATCH_RELEASE(isp, chan); 2429 return (-1); 2430 } 2431 2432 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct); 2433 FC_SCRATCH_RELEASE(isp, chan); 2434 if (ct->ct_cmd_resp == LS_RJT) { 2435 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, 2436 "Chan %d Register FC4 Features rejected", chan); 2437 return (-1); 2438 } else if (ct->ct_cmd_resp == LS_ACC) { 2439 isp_prt(isp, ISP_LOG_SANCFG, 2440 "Chan %d Register FC4 Features accepted", chan); 2441 } else { 2442 isp_prt(isp, ISP_LOGWARN, 2443 "Chan %d Register FC4 Features: 0x%x", chan, ct->ct_cmd_resp); 2444 return (-1); 2445 } 2446 return (0); 2447 } 2448 2449 static int 2450 isp_register_port_name_24xx(ispsoftc_t *isp, int chan) 2451 { 2452 fcparam *fcp = FCPARAM(isp, chan); 2453 ct_hdr_t *ct; 2454 rspn_id_t rp; 2455 uint8_t *scp = fcp->isp_scratch; 2456 int len; 2457 2458 if (FC_SCRATCH_ACQUIRE(isp, chan)) { 2459 isp_prt(isp, ISP_LOGERR, sacq); 2460 return (-1); 2461 } 2462 2463 /* 2464 * Build the CT header and command in memory. 2465 */ 2466 ISP_MEMZERO(&rp, sizeof(rp)); 2467 ct = &rp.rspnid_hdr; 2468 ct->ct_revision = CT_REVISION; 2469 ct->ct_fcs_type = CT_FC_TYPE_FC; 2470 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS; 2471 ct->ct_cmd_resp = SNS_RSPN_ID; 2472 rp.rspnid_portid[0] = fcp->isp_portid >> 16; 2473 rp.rspnid_portid[1] = fcp->isp_portid >> 8; 2474 rp.rspnid_portid[2] = fcp->isp_portid; 2475 rp.rspnid_length = 0; 2476 len = offsetof(rspn_id_t, rspnid_name); 2477 mtx_lock(&prison0.pr_mtx); 2478 rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length], 2479 "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD"); 2480 mtx_unlock(&prison0.pr_mtx); 2481 rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length], 2482 ":%s", device_get_nameunit(isp->isp_dev)); 2483 if (chan != 0) { 2484 rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length], 2485 "/%d", chan); 2486 } 2487 len += rp.rspnid_length; 2488 ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2; 2489 isp_put_rspn_id(isp, &rp, (rspn_id_t *)scp); 2490 2491 if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) { 2492 FC_SCRATCH_RELEASE(isp, chan); 2493 return (-1); 2494 } 2495 2496 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct); 2497 FC_SCRATCH_RELEASE(isp, chan); 2498 if (ct->ct_cmd_resp == LS_RJT) { 2499 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, 2500 "Chan %d Register Symbolic Port Name rejected", chan); 2501 return (-1); 2502 } else if (ct->ct_cmd_resp == LS_ACC) { 2503 isp_prt(isp, ISP_LOG_SANCFG, 2504 "Chan %d Register Symbolic Port Name accepted", chan); 2505 } else { 2506 isp_prt(isp, ISP_LOGWARN, 2507 "Chan %d Register Symbolic Port Name: 0x%x", chan, ct->ct_cmd_resp); 2508 return (-1); 2509 } 2510 return (0); 2511 } 2512 2513 static int 2514 isp_register_node_name_24xx(ispsoftc_t *isp, int chan) 2515 { 2516 fcparam *fcp = FCPARAM(isp, chan); 2517 ct_hdr_t *ct; 2518 rsnn_nn_t rp; 2519 uint8_t *scp = fcp->isp_scratch; 2520 int len; 2521 2522 if (FC_SCRATCH_ACQUIRE(isp, chan)) { 2523 isp_prt(isp, ISP_LOGERR, sacq); 2524 return (-1); 2525 } 2526 2527 /* 2528 * Build the CT header and command in memory. 2529 */ 2530 ISP_MEMZERO(&rp, sizeof(rp)); 2531 ct = &rp.rsnnnn_hdr; 2532 ct->ct_revision = CT_REVISION; 2533 ct->ct_fcs_type = CT_FC_TYPE_FC; 2534 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS; 2535 ct->ct_cmd_resp = SNS_RSNN_NN; 2536 MAKE_NODE_NAME_FROM_WWN(rp.rsnnnn_nodename, fcp->isp_wwnn); 2537 rp.rsnnnn_length = 0; 2538 len = offsetof(rsnn_nn_t, rsnnnn_name); 2539 mtx_lock(&prison0.pr_mtx); 2540 rp.rsnnnn_length += sprintf(&scp[len + rp.rsnnnn_length], 2541 "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD"); 2542 mtx_unlock(&prison0.pr_mtx); 2543 len += rp.rsnnnn_length; 2544 ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2; 2545 isp_put_rsnn_nn(isp, &rp, (rsnn_nn_t *)scp); 2546 2547 if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) { 2548 FC_SCRATCH_RELEASE(isp, chan); 2549 return (-1); 2550 } 2551 2552 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct); 2553 FC_SCRATCH_RELEASE(isp, chan); 2554 if (ct->ct_cmd_resp == LS_RJT) { 2555 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, 2556 "Chan %d Register Symbolic Node Name rejected", chan); 2557 return (-1); 2558 } else if (ct->ct_cmd_resp == LS_ACC) { 2559 isp_prt(isp, ISP_LOG_SANCFG, 2560 "Chan %d Register Symbolic Node Name accepted", chan); 2561 } else { 2562 isp_prt(isp, ISP_LOGWARN, 2563 "Chan %d Register Symbolic Node Name: 0x%x", chan, ct->ct_cmd_resp); 2564 return (-1); 2565 } 2566 return (0); 2567 } 2568 2569 static uint16_t 2570 isp_next_handle(ispsoftc_t *isp, uint16_t *ohp) 2571 { 2572 fcparam *fcp; 2573 int i, chan, wrap; 2574 uint16_t handle; 2575 2576 handle = *ohp; 2577 wrap = 0; 2578 2579 next: 2580 if (handle == NIL_HANDLE) { 2581 handle = 0; 2582 } else { 2583 handle++; 2584 if (handle > NPH_RESERVED - 1) { 2585 if (++wrap >= 2) { 2586 isp_prt(isp, ISP_LOGERR, "Out of port handles!"); 2587 return (NIL_HANDLE); 2588 } 2589 handle = 0; 2590 } 2591 } 2592 for (chan = 0; chan < isp->isp_nchan; chan++) { 2593 fcp = FCPARAM(isp, chan); 2594 if (fcp->role == ISP_ROLE_NONE) 2595 continue; 2596 for (i = 0; i < MAX_FC_TARG; i++) { 2597 if (fcp->portdb[i].state != FC_PORTDB_STATE_NIL && 2598 fcp->portdb[i].handle == handle) 2599 goto next; 2600 } 2601 } 2602 *ohp = handle; 2603 return (handle); 2604 } 2605 2606 /* 2607 * Start a command. Locking is assumed done in the caller. 2608 */ 2609 2610 int 2611 isp_start(XS_T *xs) 2612 { 2613 ispsoftc_t *isp; 2614 fcparam *fcp; 2615 uint32_t cdblen; 2616 ispreqt7_t local, *reqp = &local; 2617 void *qep; 2618 fcportdb_t *lp; 2619 int target, dmaresult; 2620 2621 XS_INITERR(xs); 2622 isp = XS_ISP(xs); 2623 2624 /* 2625 * Check command CDB length, etc.. We really are limited to 16 bytes 2626 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI, 2627 * but probably only if we're running fairly new firmware (we'll 2628 * let the old f/w choke on an extended command queue entry). 2629 */ 2630 2631 if (XS_CDBLEN(xs) > 16 || XS_CDBLEN(xs) == 0) { 2632 isp_prt(isp, ISP_LOGERR, "unsupported cdb length (%d, CDB[0]=0x%x)", XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff); 2633 XS_SETERR(xs, HBA_REQINVAL); 2634 return (CMD_COMPLETE); 2635 } 2636 2637 /* 2638 * Translate the target to device handle as appropriate, checking 2639 * for correct device state as well. 2640 */ 2641 target = XS_TGT(xs); 2642 fcp = FCPARAM(isp, XS_CHANNEL(xs)); 2643 2644 if ((fcp->role & ISP_ROLE_INITIATOR) == 0) { 2645 isp_prt(isp, ISP_LOG_WARN1, 2646 "%d.%d.%jx I am not an initiator", 2647 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs)); 2648 XS_SETERR(xs, HBA_SELTIMEOUT); 2649 return (CMD_COMPLETE); 2650 } 2651 2652 if (isp->isp_state != ISP_RUNSTATE) { 2653 isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE"); 2654 XS_SETERR(xs, HBA_BOTCH); 2655 return (CMD_COMPLETE); 2656 } 2657 2658 isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d", target); 2659 lp = &fcp->portdb[target]; 2660 if (target < 0 || target >= MAX_FC_TARG || 2661 lp->is_target == 0) { 2662 XS_SETERR(xs, HBA_SELTIMEOUT); 2663 return (CMD_COMPLETE); 2664 } 2665 if (fcp->isp_loopstate != LOOP_READY) { 2666 isp_prt(isp, ISP_LOGDEBUG1, 2667 "%d.%d.%jx loop is not ready", 2668 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs)); 2669 return (CMD_RQLATER); 2670 } 2671 if (lp->state == FC_PORTDB_STATE_ZOMBIE) { 2672 isp_prt(isp, ISP_LOGDEBUG1, 2673 "%d.%d.%jx target zombie", 2674 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs)); 2675 return (CMD_RQLATER); 2676 } 2677 if (lp->state != FC_PORTDB_STATE_VALID) { 2678 isp_prt(isp, ISP_LOGDEBUG1, 2679 "%d.%d.%jx bad db port state 0x%x", 2680 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs), lp->state); 2681 XS_SETERR(xs, HBA_SELTIMEOUT); 2682 return (CMD_COMPLETE); 2683 } 2684 2685 start_again: 2686 2687 qep = isp_getrqentry(isp); 2688 if (qep == NULL) { 2689 isp_prt(isp, ISP_LOG_WARN1, "Request Queue Overflow"); 2690 XS_SETERR(xs, HBA_BOTCH); 2691 return (CMD_EAGAIN); 2692 } 2693 XS_SETERR(xs, HBA_NOERROR); 2694 2695 /* 2696 * Now see if we need to synchronize the ISP with respect to anything. 2697 * We do dual duty here (cough) for synchronizing for buses other 2698 * than which we got here to send a command to. 2699 */ 2700 ISP_MEMZERO(reqp, QENTRY_LEN); 2701 if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) { 2702 isp_marker_24xx_t *m = (isp_marker_24xx_t *) reqp; 2703 m->mrk_header.rqs_entry_count = 1; 2704 m->mrk_header.rqs_entry_type = RQSTYPE_MARKER; 2705 m->mrk_modifier = SYNC_ALL; 2706 m->mrk_vphdl = XS_CHANNEL(xs); 2707 isp_put_marker_24xx(isp, m, qep); 2708 ISP_SYNC_REQUEST(isp); 2709 ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0); 2710 goto start_again; 2711 } 2712 2713 /* 2714 * NB: we do not support long CDBs (yet) 2715 */ 2716 cdblen = XS_CDBLEN(xs); 2717 if (cdblen > sizeof (reqp->req_cdb)) { 2718 isp_prt(isp, ISP_LOGERR, "Command Length %u too long for this chip", cdblen); 2719 XS_SETERR(xs, HBA_REQINVAL); 2720 return (CMD_COMPLETE); 2721 } 2722 2723 reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS; 2724 reqp->req_header.rqs_entry_count = 1; 2725 reqp->req_nphdl = lp->handle; 2726 reqp->req_time = XS_TIME(xs); 2727 be64enc(reqp->req_lun, CAM_EXTLUN_BYTE_SWIZZLE(XS_LUN(xs))); 2728 if (XS_XFRIN(xs)) 2729 reqp->req_alen_datadir = FCP_CMND_DATA_READ; 2730 else if (XS_XFROUT(xs)) 2731 reqp->req_alen_datadir = FCP_CMND_DATA_WRITE; 2732 if (XS_TAG_P(xs)) 2733 reqp->req_task_attribute = XS_TAG_TYPE(xs); 2734 else 2735 reqp->req_task_attribute = FCP_CMND_TASK_ATTR_SIMPLE; 2736 reqp->req_task_attribute |= (XS_PRIORITY(xs) << FCP_CMND_PRIO_SHIFT) & 2737 FCP_CMND_PRIO_MASK; 2738 if (FCPARAM(isp, XS_CHANNEL(xs))->fctape_enabled && (lp->prli_word3 & PRLI_WD3_RETRY)) { 2739 if (FCP_NEXT_CRN(isp, &reqp->req_crn, xs)) { 2740 isp_prt(isp, ISP_LOG_WARN1, 2741 "%d.%d.%jx cannot generate next CRN", 2742 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs)); 2743 XS_SETERR(xs, HBA_BOTCH); 2744 return (CMD_EAGAIN); 2745 } 2746 } 2747 ISP_MEMCPY(reqp->req_cdb, XS_CDBP(xs), cdblen); 2748 reqp->req_dl = XS_XFRLEN(xs); 2749 reqp->req_tidlo = lp->portid; 2750 reqp->req_tidhi = lp->portid >> 16; 2751 reqp->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs)); 2752 2753 /* Whew. Thankfully the same for type 7 requests */ 2754 reqp->req_handle = isp_allocate_handle(isp, xs, ISP_HANDLE_INITIATOR); 2755 if (reqp->req_handle == 0) { 2756 isp_prt(isp, ISP_LOG_WARN1, "out of xflist pointers"); 2757 XS_SETERR(xs, HBA_BOTCH); 2758 return (CMD_EAGAIN); 2759 } 2760 2761 /* 2762 * Set up DMA and/or do any platform dependent swizzling of the request entry 2763 * so that the Qlogic F/W understands what is being asked of it. 2764 * 2765 * The callee is responsible for adding all requests at this point. 2766 */ 2767 dmaresult = ISP_DMASETUP(isp, xs, reqp); 2768 if (dmaresult != 0) { 2769 isp_destroy_handle(isp, reqp->req_handle); 2770 /* 2771 * dmasetup sets actual error in packet, and 2772 * return what we were given to return. 2773 */ 2774 return (dmaresult); 2775 } 2776 isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "START cmd cdb[0]=0x%x datalen %ld", XS_CDBP(xs)[0], (long) XS_XFRLEN(xs)); 2777 return (0); 2778 } 2779 2780 /* 2781 * isp control 2782 * Locks (ints blocked) assumed held. 2783 */ 2784 2785 int 2786 isp_control(ispsoftc_t *isp, ispctl_t ctl, ...) 2787 { 2788 fcparam *fcp; 2789 fcportdb_t *lp; 2790 XS_T *xs; 2791 mbreg_t *mbr; 2792 int chan, tgt; 2793 uint32_t handle; 2794 va_list ap; 2795 uint8_t local[QENTRY_LEN]; 2796 2797 switch (ctl) { 2798 case ISPCTL_RESET_BUS: 2799 /* 2800 * Issue a bus reset. 2801 */ 2802 isp_prt(isp, ISP_LOGERR, "BUS RESET NOT IMPLEMENTED"); 2803 break; 2804 2805 case ISPCTL_RESET_DEV: 2806 { 2807 isp24xx_tmf_t *tmf; 2808 isp24xx_statusreq_t *sp; 2809 2810 va_start(ap, ctl); 2811 chan = va_arg(ap, int); 2812 tgt = va_arg(ap, int); 2813 va_end(ap); 2814 fcp = FCPARAM(isp, chan); 2815 2816 if (tgt < 0 || tgt >= MAX_FC_TARG) { 2817 isp_prt(isp, ISP_LOGWARN, "Chan %d trying to reset bad target %d", chan, tgt); 2818 break; 2819 } 2820 lp = &fcp->portdb[tgt]; 2821 if (lp->is_target == 0 || lp->state != FC_PORTDB_STATE_VALID) { 2822 isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt); 2823 break; 2824 } 2825 2826 tmf = (isp24xx_tmf_t *) local; 2827 ISP_MEMZERO(tmf, QENTRY_LEN); 2828 tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT; 2829 tmf->tmf_header.rqs_entry_count = 1; 2830 tmf->tmf_nphdl = lp->handle; 2831 tmf->tmf_delay = 2; 2832 tmf->tmf_timeout = 4; 2833 tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET; 2834 tmf->tmf_tidlo = lp->portid; 2835 tmf->tmf_tidhi = lp->portid >> 16; 2836 tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan); 2837 fcp->sendmarker = 1; 2838 isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid); 2839 2840 sp = (isp24xx_statusreq_t *) local; 2841 if (isp_exec_entry_mbox(isp, tmf, sp, 2 * tmf->tmf_timeout)) 2842 break; 2843 2844 if (sp->req_completion_status == 0) 2845 return (0); 2846 isp_prt(isp, ISP_LOGWARN, "Chan %d reset of target %d returned 0x%x", chan, tgt, sp->req_completion_status); 2847 break; 2848 } 2849 case ISPCTL_ABORT_CMD: 2850 { 2851 isp24xx_abrt_t *ab = (isp24xx_abrt_t *)&local; 2852 2853 va_start(ap, ctl); 2854 xs = va_arg(ap, XS_T *); 2855 va_end(ap); 2856 2857 tgt = XS_TGT(xs); 2858 chan = XS_CHANNEL(xs); 2859 2860 handle = isp_find_handle(isp, xs); 2861 if (handle == 0) { 2862 isp_prt(isp, ISP_LOGWARN, "cannot find handle for command to abort"); 2863 break; 2864 } 2865 2866 fcp = FCPARAM(isp, chan); 2867 if (tgt < 0 || tgt >= MAX_FC_TARG) { 2868 isp_prt(isp, ISP_LOGWARN, "Chan %d trying to abort bad target %d", chan, tgt); 2869 break; 2870 } 2871 lp = &fcp->portdb[tgt]; 2872 if (lp->is_target == 0 || lp->state != FC_PORTDB_STATE_VALID) { 2873 isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt); 2874 break; 2875 } 2876 isp_prt(isp, ISP_LOGALL, "Chan %d Abort Cmd for N-Port 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid); 2877 ISP_MEMZERO(ab, QENTRY_LEN); 2878 ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO; 2879 ab->abrt_header.rqs_entry_count = 1; 2880 ab->abrt_handle = lp->handle; 2881 ab->abrt_cmd_handle = handle; 2882 ab->abrt_tidlo = lp->portid; 2883 ab->abrt_tidhi = lp->portid >> 16; 2884 ab->abrt_vpidx = ISP_GET_VPIDX(isp, chan); 2885 2886 if (isp_exec_entry_mbox(isp, ab, ab, 5)) 2887 break; 2888 2889 if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY) 2890 return (0); 2891 isp_prt(isp, ISP_LOGWARN, "Chan %d handle %d abort returned 0x%x", chan, tgt, ab->abrt_nphdl); 2892 } 2893 case ISPCTL_FCLINK_TEST: 2894 { 2895 int usdelay; 2896 2897 va_start(ap, ctl); 2898 chan = va_arg(ap, int); 2899 usdelay = va_arg(ap, int); 2900 va_end(ap); 2901 if (usdelay == 0) 2902 usdelay = 250000; 2903 return (isp_fclink_test(isp, chan, usdelay)); 2904 } 2905 case ISPCTL_SCAN_FABRIC: 2906 2907 va_start(ap, ctl); 2908 chan = va_arg(ap, int); 2909 va_end(ap); 2910 return (isp_scan_fabric(isp, chan)); 2911 2912 case ISPCTL_SCAN_LOOP: 2913 2914 va_start(ap, ctl); 2915 chan = va_arg(ap, int); 2916 va_end(ap); 2917 return (isp_scan_loop(isp, chan)); 2918 2919 case ISPCTL_PDB_SYNC: 2920 2921 va_start(ap, ctl); 2922 chan = va_arg(ap, int); 2923 va_end(ap); 2924 return (isp_pdb_sync(isp, chan)); 2925 2926 case ISPCTL_SEND_LIP: 2927 break; 2928 2929 case ISPCTL_GET_PDB: 2930 { 2931 isp_pdb_t *pdb; 2932 va_start(ap, ctl); 2933 chan = va_arg(ap, int); 2934 tgt = va_arg(ap, int); 2935 pdb = va_arg(ap, isp_pdb_t *); 2936 va_end(ap); 2937 return (isp_getpdb(isp, chan, tgt, pdb)); 2938 } 2939 case ISPCTL_GET_NAMES: 2940 { 2941 uint64_t *wwnn, *wwnp; 2942 va_start(ap, ctl); 2943 chan = va_arg(ap, int); 2944 tgt = va_arg(ap, int); 2945 wwnn = va_arg(ap, uint64_t *); 2946 wwnp = va_arg(ap, uint64_t *); 2947 va_end(ap); 2948 if (wwnn == NULL && wwnp == NULL) { 2949 break; 2950 } 2951 if (wwnn) { 2952 *wwnn = isp_get_wwn(isp, chan, tgt, 1); 2953 if (*wwnn == INI_NONE) { 2954 break; 2955 } 2956 } 2957 if (wwnp) { 2958 *wwnp = isp_get_wwn(isp, chan, tgt, 0); 2959 if (*wwnp == INI_NONE) { 2960 break; 2961 } 2962 } 2963 return (0); 2964 } 2965 case ISPCTL_RUN_MBOXCMD: 2966 { 2967 va_start(ap, ctl); 2968 mbr = va_arg(ap, mbreg_t *); 2969 va_end(ap); 2970 isp_mboxcmd(isp, mbr); 2971 return (0); 2972 } 2973 case ISPCTL_PLOGX: 2974 { 2975 isp_plcmd_t *p; 2976 int r; 2977 2978 va_start(ap, ctl); 2979 p = va_arg(ap, isp_plcmd_t *); 2980 va_end(ap); 2981 2982 if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) { 2983 return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags)); 2984 } 2985 do { 2986 isp_next_handle(isp, &p->handle); 2987 r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags); 2988 if ((r & 0xffff) == MBOX_PORT_ID_USED) { 2989 p->handle = r >> 16; 2990 r = 0; 2991 break; 2992 } 2993 } while ((r & 0xffff) == MBOX_LOOP_ID_USED); 2994 return (r); 2995 } 2996 case ISPCTL_CHANGE_ROLE: 2997 { 2998 int role; 2999 3000 va_start(ap, ctl); 3001 chan = va_arg(ap, int); 3002 role = va_arg(ap, int); 3003 va_end(ap); 3004 return (isp_fc_change_role(isp, chan, role)); 3005 } 3006 default: 3007 isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl); 3008 break; 3009 3010 } 3011 return (-1); 3012 } 3013 3014 /* 3015 * Interrupt Service Routine(s). 3016 * 3017 * External (OS) framework has done the appropriate locking, 3018 * and the locking will be held throughout this function. 3019 */ 3020 3021 #ifdef ISP_TARGET_MODE 3022 void 3023 isp_intr_atioq(ispsoftc_t *isp) 3024 { 3025 void *addr; 3026 uint32_t iptr, optr, oop; 3027 3028 iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP); 3029 optr = isp->isp_atioodx; 3030 while (optr != iptr) { 3031 oop = optr; 3032 MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1); 3033 addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop); 3034 switch (((isphdr_t *)addr)->rqs_entry_type) { 3035 case RQSTYPE_NOTIFY: 3036 case RQSTYPE_ATIO: 3037 case RQSTYPE_NOTIFY_ACK: /* Can be set to ATIO queue.*/ 3038 case RQSTYPE_ABTS_RCVD: /* Can be set to ATIO queue.*/ 3039 (void) isp_target_notify(isp, addr, &oop, 3040 ATIO_QUEUE_LEN(isp)); 3041 break; 3042 case RQSTYPE_RPT_ID_ACQ: /* Can be set to ATIO queue.*/ 3043 default: 3044 isp_print_qentry(isp, "?ATIOQ entry?", oop, addr); 3045 break; 3046 } 3047 optr = ISP_NXT_QENTRY(oop, ATIO_QUEUE_LEN(isp)); 3048 } 3049 if (isp->isp_atioodx != optr) { 3050 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr); 3051 isp->isp_atioodx = optr; 3052 } 3053 } 3054 #endif 3055 3056 void 3057 isp_intr_mbox(ispsoftc_t *isp, uint16_t mbox0) 3058 { 3059 int i, obits; 3060 3061 if (!isp->isp_mboxbsy) { 3062 isp_prt(isp, ISP_LOGWARN, "mailbox 0x%x with no waiters", mbox0); 3063 return; 3064 } 3065 obits = isp->isp_obits; 3066 isp->isp_mboxtmp[0] = mbox0; 3067 for (i = 1; i < ISP_NMBOX(isp); i++) { 3068 if ((obits & (1 << i)) == 0) 3069 continue; 3070 isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i)); 3071 } 3072 isp->isp_mboxbsy = 0; 3073 } 3074 3075 void 3076 isp_intr_respq(ispsoftc_t *isp) 3077 { 3078 XS_T *xs, *cont_xs; 3079 uint8_t qe[QENTRY_LEN]; 3080 isp24xx_statusreq_t *sp = (isp24xx_statusreq_t *)qe; 3081 ispstatus_cont_t *scp = (ispstatus_cont_t *)qe; 3082 isphdr_t *hp; 3083 uint8_t *resp, *snsp, etype; 3084 uint16_t scsi_status; 3085 uint32_t iptr, cont = 0, cptr, optr, rlen, slen, totslen; 3086 #ifdef ISP_TARGET_MODE 3087 uint32_t sptr; 3088 #endif 3089 3090 /* 3091 * We can't be getting this now. 3092 */ 3093 if (isp->isp_state != ISP_RUNSTATE) { 3094 isp_prt(isp, ISP_LOGINFO, "respq interrupt when not ready"); 3095 return; 3096 } 3097 3098 iptr = ISP_READ(isp, BIU2400_RSPINP); 3099 optr = isp->isp_resodx; 3100 while (optr != iptr) { 3101 cptr = optr; 3102 #ifdef ISP_TARGET_MODE 3103 sptr = optr; 3104 #endif 3105 hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, cptr); 3106 optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp)); 3107 3108 /* 3109 * Synchronize our view of this response queue entry. 3110 */ 3111 MEMORYBARRIER(isp, SYNC_RESULT, cptr, QENTRY_LEN, -1); 3112 if (isp->isp_dblev & ISP_LOGDEBUG1) 3113 isp_print_qentry(isp, "Response Queue Entry", cptr, hp); 3114 isp_get_hdr(isp, hp, &sp->req_header); 3115 3116 /* 3117 * Log IOCBs rejected by the firmware. We can't really do 3118 * much more about them, since it just should not happen. 3119 */ 3120 if (sp->req_header.rqs_flags & RQSFLAG_BADTYPE) { 3121 isp_print_qentry(isp, "invalid entry type", cptr, hp); 3122 continue; 3123 } 3124 if (sp->req_header.rqs_flags & RQSFLAG_BADPARAM) { 3125 isp_print_qentry(isp, "invalid entry parameter", cptr, hp); 3126 continue; 3127 } 3128 if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) { 3129 isp_print_qentry(isp, "invalid entry count", cptr, hp); 3130 continue; 3131 } 3132 if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) { 3133 isp_print_qentry(isp, "invalid entry order", cptr, hp); 3134 continue; 3135 } 3136 3137 etype = sp->req_header.rqs_entry_type; 3138 3139 /* We expected Status Continuation, but got different IOCB. */ 3140 if (cont > 0 && etype != RQSTYPE_STATUS_CONT) { 3141 cont = 0; 3142 isp_done(cont_xs); 3143 } 3144 3145 if (isp_handle_control(isp, hp)) { 3146 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3147 continue; 3148 } 3149 3150 switch (etype) { 3151 case RQSTYPE_RESPONSE: 3152 isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp); 3153 break; 3154 case RQSTYPE_MARKER: 3155 isp_prt(isp, ISP_LOG_WARN1, "Marker Response"); 3156 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3157 continue; 3158 case RQSTYPE_STATUS_CONT: 3159 isp_get_cont_response(isp, (ispstatus_cont_t *)hp, scp); 3160 if (cont > 0) { 3161 slen = min(cont, sizeof(scp->req_sense_data)); 3162 XS_SENSE_APPEND(cont_xs, scp->req_sense_data, slen); 3163 cont -= slen; 3164 if (cont == 0) { 3165 isp_done(cont_xs); 3166 } else { 3167 isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN, 3168 "Expecting Status Continuations for %u bytes", 3169 cont); 3170 } 3171 } else { 3172 isp_prt(isp, ISP_LOG_WARN1, "Ignored Continuation Response"); 3173 } 3174 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3175 continue; 3176 #ifdef ISP_TARGET_MODE 3177 case RQSTYPE_NOTIFY_ACK: /* Can be set to ATIO queue. */ 3178 case RQSTYPE_CTIO7: 3179 case RQSTYPE_ABTS_RCVD: /* Can be set to ATIO queue. */ 3180 case RQSTYPE_ABTS_RSP: 3181 isp_target_notify(isp, hp, &cptr, RESULT_QUEUE_LEN(isp)); 3182 /* More then one IOCB could be consumed. */ 3183 while (sptr != cptr) { 3184 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3185 sptr = ISP_NXT_QENTRY(sptr, RESULT_QUEUE_LEN(isp)); 3186 hp = (isphdr_t *)ISP_QUEUE_ENTRY(isp->isp_result, sptr); 3187 } 3188 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3189 optr = ISP_NXT_QENTRY(cptr, RESULT_QUEUE_LEN(isp)); 3190 continue; 3191 #endif 3192 case RQSTYPE_RPT_ID_ACQ: /* Can be set to ATIO queue.*/ 3193 isp_handle_rpt_id_acq(isp, hp); 3194 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3195 continue; 3196 default: 3197 /* We don't know what was this -- log and skip. */ 3198 isp_prt(isp, ISP_LOGERR, notresp, etype, cptr, optr); 3199 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3200 continue; 3201 } 3202 3203 xs = isp_find_xs(isp, sp->req_handle); 3204 if (xs == NULL) { 3205 /* 3206 * Only whine if this isn't the expected fallout of 3207 * aborting the command or resetting the target. 3208 */ 3209 if (sp->req_completion_status != RQCS_ABORTED && 3210 sp->req_completion_status != RQCS_RESET_OCCURRED) 3211 isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", 3212 sp->req_handle, sp->req_completion_status); 3213 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3214 continue; 3215 } 3216 3217 resp = snsp = sp->req_rsp_sense; 3218 rlen = slen = totslen = 0; 3219 scsi_status = sp->req_scsi_status; 3220 if (scsi_status & RQCS_RV) { 3221 rlen = sp->req_response_len; 3222 snsp += rlen; 3223 } 3224 if (scsi_status & RQCS_SV) { 3225 totslen = sp->req_sense_len; 3226 slen = MIN(totslen, sizeof(sp->req_rsp_sense) - rlen); 3227 } 3228 *XS_STSP(xs) = scsi_status & 0xff; 3229 if (scsi_status & RQCS_RESID) 3230 XS_SET_RESID(xs, sp->req_fcp_residual); 3231 else 3232 XS_SET_RESID(xs, 0); 3233 3234 if (rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) { 3235 const char *ptr; 3236 char lb[64]; 3237 const char *rnames[10] = { 3238 "Task Management function complete", 3239 "FCP_DATA length different than FCP_BURST_LEN", 3240 "FCP_CMND fields invalid", 3241 "FCP_DATA parameter mismatch with FCP_DATA_RO", 3242 "Task Management function rejected", 3243 "Task Management function failed", 3244 NULL, 3245 NULL, 3246 "Task Management function succeeded", 3247 "Task Management function incorrect logical unit number", 3248 }; 3249 uint8_t code = resp[FCP_RSPNS_CODE_OFFSET]; 3250 if (code >= nitems(rnames) || rnames[code] == NULL) { 3251 ISP_SNPRINTF(lb, sizeof(lb), 3252 "Unknown FCP Response Code 0x%x", code); 3253 ptr = lb; 3254 } else { 3255 ptr = rnames[code]; 3256 } 3257 isp_xs_prt(isp, xs, ISP_LOGWARN, 3258 "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x", 3259 rlen, ptr, XS_CDBP(xs)[0] & 0xff); 3260 if (code != FCP_RSPNS_TMF_DONE && 3261 code != FCP_RSPNS_TMF_SUCCEEDED) 3262 XS_SETERR(xs, HBA_BOTCH); 3263 } 3264 isp_parse_status_24xx(isp, sp, xs); 3265 if (slen > 0) { 3266 XS_SAVE_SENSE(xs, snsp, slen); 3267 if (totslen > slen) { 3268 cont = totslen - slen; 3269 cont_xs = xs; 3270 isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN, 3271 "Expecting Status Continuations for %u bytes", 3272 cont); 3273 } 3274 } 3275 3276 ISP_DMAFREE(isp, xs); 3277 isp_destroy_handle(isp, sp->req_handle); 3278 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3279 3280 /* Complete command if we expect no Status Continuations. */ 3281 if (cont == 0) 3282 isp_done(xs); 3283 } 3284 3285 /* We haven't received all Status Continuations, but that is it. */ 3286 if (cont > 0) 3287 isp_done(cont_xs); 3288 3289 /* If we processed any IOCBs, let ISP know about it. */ 3290 if (optr != isp->isp_resodx) { 3291 ISP_WRITE(isp, BIU2400_RSPOUTP, optr); 3292 isp->isp_resodx = optr; 3293 } 3294 } 3295 3296 3297 void 3298 isp_intr_async(ispsoftc_t *isp, uint16_t mbox) 3299 { 3300 fcparam *fcp; 3301 uint16_t chan; 3302 3303 isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox); 3304 3305 switch (mbox) { 3306 case ASYNC_SYSTEM_ERROR: 3307 isp->isp_state = ISP_CRASHED; 3308 for (chan = 0; chan < isp->isp_nchan; chan++) { 3309 FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL; 3310 isp_change_fw_state(isp, chan, FW_CONFIG_WAIT); 3311 } 3312 /* 3313 * Were we waiting for a mailbox command to complete? 3314 * If so, it's dead, so wake up the waiter. 3315 */ 3316 if (isp->isp_mboxbsy) { 3317 isp->isp_obits = 1; 3318 isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR; 3319 isp->isp_mboxbsy = 0; 3320 } 3321 /* 3322 * It's up to the handler for isp_async to reinit stuff and 3323 * restart the firmware 3324 */ 3325 isp_async(isp, ISPASYNC_FW_CRASH); 3326 break; 3327 3328 case ASYNC_RQS_XFER_ERR: 3329 isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error"); 3330 break; 3331 3332 case ASYNC_RSP_XFER_ERR: 3333 isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error"); 3334 break; 3335 3336 case ASYNC_ATIO_XFER_ERR: 3337 isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error"); 3338 break; 3339 3340 case ASYNC_LIP_OCCURRED: 3341 case ASYNC_LIP_NOS_OLS_RECV: 3342 case ASYNC_LIP_ERROR: 3343 case ASYNC_PTPMODE: 3344 /* 3345 * These are broadcast events that have to be sent across 3346 * all active channels. 3347 */ 3348 for (chan = 0; chan < isp->isp_nchan; chan++) { 3349 fcp = FCPARAM(isp, chan); 3350 int topo = fcp->isp_topo; 3351 3352 if (fcp->role == ISP_ROLE_NONE) 3353 continue; 3354 if (fcp->isp_loopstate > LOOP_HAVE_LINK) 3355 fcp->isp_loopstate = LOOP_HAVE_LINK; 3356 ISP_SET_SENDMARKER(isp, chan, 1); 3357 isp_async(isp, ISPASYNC_LIP, chan); 3358 #ifdef ISP_TARGET_MODE 3359 isp_target_async(isp, chan, mbox); 3360 #endif 3361 /* 3362 * We've had problems with data corruption occurring on 3363 * commands that complete (with no apparent error) after 3364 * we receive a LIP. This has been observed mostly on 3365 * Local Loop topologies. To be safe, let's just mark 3366 * all active initiator commands as dead. 3367 */ 3368 if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) { 3369 int i, j; 3370 for (i = j = 0; i < ISP_HANDLE_NUM(isp); i++) { 3371 XS_T *xs; 3372 isp_hdl_t *hdp; 3373 3374 hdp = &isp->isp_xflist[i]; 3375 if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) { 3376 continue; 3377 } 3378 xs = hdp->cmd; 3379 if (XS_CHANNEL(xs) != chan) { 3380 continue; 3381 } 3382 j++; 3383 isp_prt(isp, ISP_LOG_WARN1, 3384 "%d.%d.%jx bus reset set at %s:%u", 3385 XS_CHANNEL(xs), XS_TGT(xs), 3386 (uintmax_t)XS_LUN(xs), 3387 __func__, __LINE__); 3388 XS_SETERR(xs, HBA_BUSRESET); 3389 } 3390 if (j) { 3391 isp_prt(isp, ISP_LOGERR, lipd, chan, j); 3392 } 3393 } 3394 } 3395 break; 3396 3397 case ASYNC_LOOP_UP: 3398 /* 3399 * This is a broadcast event that has to be sent across 3400 * all active channels. 3401 */ 3402 for (chan = 0; chan < isp->isp_nchan; chan++) { 3403 fcp = FCPARAM(isp, chan); 3404 if (fcp->role == ISP_ROLE_NONE) 3405 continue; 3406 fcp->isp_linkstate = 1; 3407 if (fcp->isp_loopstate < LOOP_HAVE_LINK) 3408 fcp->isp_loopstate = LOOP_HAVE_LINK; 3409 ISP_SET_SENDMARKER(isp, chan, 1); 3410 isp_async(isp, ISPASYNC_LOOP_UP, chan); 3411 #ifdef ISP_TARGET_MODE 3412 isp_target_async(isp, chan, mbox); 3413 #endif 3414 } 3415 break; 3416 3417 case ASYNC_LOOP_DOWN: 3418 /* 3419 * This is a broadcast event that has to be sent across 3420 * all active channels. 3421 */ 3422 for (chan = 0; chan < isp->isp_nchan; chan++) { 3423 fcp = FCPARAM(isp, chan); 3424 if (fcp->role == ISP_ROLE_NONE) 3425 continue; 3426 ISP_SET_SENDMARKER(isp, chan, 1); 3427 fcp->isp_linkstate = 0; 3428 fcp->isp_loopstate = LOOP_NIL; 3429 isp_async(isp, ISPASYNC_LOOP_DOWN, chan); 3430 #ifdef ISP_TARGET_MODE 3431 isp_target_async(isp, chan, mbox); 3432 #endif 3433 } 3434 break; 3435 3436 case ASYNC_LOOP_RESET: 3437 /* 3438 * This is a broadcast event that has to be sent across 3439 * all active channels. 3440 */ 3441 for (chan = 0; chan < isp->isp_nchan; chan++) { 3442 fcp = FCPARAM(isp, chan); 3443 if (fcp->role == ISP_ROLE_NONE) 3444 continue; 3445 ISP_SET_SENDMARKER(isp, chan, 1); 3446 if (fcp->isp_loopstate > LOOP_HAVE_LINK) 3447 fcp->isp_loopstate = LOOP_HAVE_LINK; 3448 isp_async(isp, ISPASYNC_LOOP_RESET, chan); 3449 #ifdef ISP_TARGET_MODE 3450 isp_target_async(isp, chan, mbox); 3451 #endif 3452 } 3453 break; 3454 3455 case ASYNC_PDB_CHANGED: 3456 { 3457 int echan, nphdl, nlstate, reason; 3458 3459 nphdl = ISP_READ(isp, OUTMAILBOX1); 3460 nlstate = ISP_READ(isp, OUTMAILBOX2); 3461 reason = ISP_READ(isp, OUTMAILBOX3) >> 8; 3462 if (ISP_CAP_MULTI_ID(isp)) { 3463 chan = ISP_READ(isp, OUTMAILBOX3) & 0xff; 3464 if (chan == 0xff || nphdl == NIL_HANDLE) { 3465 chan = 0; 3466 echan = isp->isp_nchan - 1; 3467 } else if (chan >= isp->isp_nchan) { 3468 break; 3469 } else { 3470 echan = chan; 3471 } 3472 } else { 3473 chan = echan = 0; 3474 } 3475 for (; chan <= echan; chan++) { 3476 fcp = FCPARAM(isp, chan); 3477 if (fcp->role == ISP_ROLE_NONE) 3478 continue; 3479 if (fcp->isp_loopstate > LOOP_LTEST_DONE) { 3480 if (nphdl != NIL_HANDLE && 3481 nphdl == fcp->isp_login_hdl && 3482 reason == PDB24XX_AE_OPN_2) 3483 continue; 3484 fcp->isp_loopstate = LOOP_LTEST_DONE; 3485 } else if (fcp->isp_loopstate < LOOP_HAVE_LINK) 3486 fcp->isp_loopstate = LOOP_HAVE_LINK; 3487 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, 3488 ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason); 3489 } 3490 break; 3491 } 3492 case ASYNC_CHANGE_NOTIFY: 3493 { 3494 int portid; 3495 3496 portid = ((ISP_READ(isp, OUTMAILBOX1) & 0xff) << 16) | 3497 ISP_READ(isp, OUTMAILBOX2); 3498 if (ISP_CAP_MULTI_ID(isp)) { 3499 chan = ISP_READ(isp, OUTMAILBOX3) & 0xff; 3500 if (chan >= isp->isp_nchan) 3501 break; 3502 } else { 3503 chan = 0; 3504 } 3505 fcp = FCPARAM(isp, chan); 3506 if (fcp->role == ISP_ROLE_NONE) 3507 break; 3508 if (fcp->isp_loopstate > LOOP_LTEST_DONE) 3509 fcp->isp_loopstate = LOOP_LTEST_DONE; 3510 else if (fcp->isp_loopstate < LOOP_HAVE_LINK) 3511 fcp->isp_loopstate = LOOP_HAVE_LINK; 3512 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, 3513 ISPASYNC_CHANGE_SNS, portid); 3514 break; 3515 } 3516 case ASYNC_ERR_LOGGING_DISABLED: 3517 isp_prt(isp, ISP_LOGWARN, "Error logging disabled (reason 0x%x)", 3518 ISP_READ(isp, OUTMAILBOX1)); 3519 break; 3520 case ASYNC_P2P_INIT_ERR: 3521 isp_prt(isp, ISP_LOGWARN, "P2P init error (reason 0x%x)", 3522 ISP_READ(isp, OUTMAILBOX1)); 3523 break; 3524 case ASYNC_RCV_ERR: 3525 isp_prt(isp, ISP_LOGWARN, "Receive Error"); 3526 break; 3527 case ASYNC_RJT_SENT: /* same as ASYNC_QFULL_SENT */ 3528 isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent"); 3529 break; 3530 case ASYNC_FW_RESTART_COMPLETE: 3531 isp_prt(isp, ISP_LOGDEBUG0, "FW restart complete"); 3532 break; 3533 case ASYNC_TEMPERATURE_ALERT: 3534 isp_prt(isp, ISP_LOGERR, "Temperature alert (subcode 0x%x)", 3535 ISP_READ(isp, OUTMAILBOX1)); 3536 break; 3537 case ASYNC_INTER_DRIVER_COMP: 3538 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication complete"); 3539 break; 3540 case ASYNC_INTER_DRIVER_NOTIFY: 3541 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication notification"); 3542 break; 3543 case ASYNC_INTER_DRIVER_TIME_EXT: 3544 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication time extended"); 3545 break; 3546 case ASYNC_TRANSCEIVER_INSERTION: 3547 isp_prt(isp, ISP_LOGDEBUG0, "Transceiver insertion (0x%x)", 3548 ISP_READ(isp, OUTMAILBOX1)); 3549 break; 3550 case ASYNC_TRANSCEIVER_REMOVAL: 3551 isp_prt(isp, ISP_LOGDEBUG0, "Transceiver removal"); 3552 break; 3553 case ASYNC_NIC_FW_STATE_CHANGE: 3554 isp_prt(isp, ISP_LOGDEBUG0, "NIC Firmware State Change"); 3555 break; 3556 case ASYNC_AUTOLOAD_FW_COMPLETE: 3557 isp_prt(isp, ISP_LOGDEBUG0, "Autoload FW init complete"); 3558 break; 3559 case ASYNC_AUTOLOAD_FW_FAILURE: 3560 isp_prt(isp, ISP_LOGERR, "Autoload FW init failure"); 3561 break; 3562 default: 3563 isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox); 3564 break; 3565 } 3566 } 3567 3568 /* 3569 * Handle completions with control handles by waking up waiting threads. 3570 */ 3571 static int 3572 isp_handle_control(ispsoftc_t *isp, isphdr_t *hp) 3573 { 3574 uint32_t hdl; 3575 void *ptr; 3576 3577 switch (hp->rqs_entry_type) { 3578 case RQSTYPE_RESPONSE: 3579 case RQSTYPE_MARKER: 3580 case RQSTYPE_NOTIFY_ACK: 3581 case RQSTYPE_CTIO7: 3582 case RQSTYPE_TSK_MGMT: 3583 case RQSTYPE_CT_PASSTHRU: 3584 case RQSTYPE_VP_MODIFY: 3585 case RQSTYPE_VP_CTRL: 3586 case RQSTYPE_ABORT_IO: 3587 case RQSTYPE_MBOX: 3588 case RQSTYPE_LOGIN: 3589 case RQSTYPE_ELS_PASSTHRU: 3590 ISP_IOXGET_32(isp, (uint32_t *)(hp + 1), hdl); 3591 if (ISP_H2HT(hdl) != ISP_HANDLE_CTRL) 3592 break; 3593 ptr = isp_find_xs(isp, hdl); 3594 if (ptr != NULL) { 3595 isp_destroy_handle(isp, hdl); 3596 memcpy(ptr, hp, QENTRY_LEN); 3597 wakeup(ptr); 3598 } 3599 return (1); 3600 } 3601 return (0); 3602 } 3603 3604 static void 3605 isp_handle_rpt_id_acq(ispsoftc_t *isp, isphdr_t *hp) 3606 { 3607 fcparam *fcp; 3608 isp_ridacq_t rid; 3609 int chan, c; 3610 uint32_t portid; 3611 3612 isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid); 3613 portid = (uint32_t)rid.ridacq_vp_port_hi << 16 | 3614 rid.ridacq_vp_port_lo; 3615 if (rid.ridacq_format == 0) { 3616 for (chan = 0; chan < isp->isp_nchan; chan++) { 3617 fcp = FCPARAM(isp, chan); 3618 if (fcp->role == ISP_ROLE_NONE) 3619 continue; 3620 c = (chan == 0) ? 127 : (chan - 1); 3621 if (rid.ridacq_map[c / 16] & (1 << (c % 16)) || 3622 chan == 0) { 3623 fcp->isp_loopstate = LOOP_HAVE_LINK; 3624 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, 3625 chan, ISPASYNC_CHANGE_OTHER); 3626 } else { 3627 fcp->isp_loopstate = LOOP_NIL; 3628 isp_async(isp, ISPASYNC_LOOP_DOWN, 3629 chan); 3630 } 3631 } 3632 } else { 3633 fcp = FCPARAM(isp, rid.ridacq_vp_index); 3634 if (rid.ridacq_vp_status == RIDACQ_STS_COMPLETE || 3635 rid.ridacq_vp_status == RIDACQ_STS_CHANGED) { 3636 fcp->isp_topo = (rid.ridacq_map[0] >> 9) & 0x7; 3637 fcp->isp_portid = portid; 3638 fcp->isp_loopstate = LOOP_HAVE_ADDR; 3639 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, 3640 rid.ridacq_vp_index, ISPASYNC_CHANGE_OTHER); 3641 } else { 3642 fcp->isp_loopstate = LOOP_NIL; 3643 isp_async(isp, ISPASYNC_LOOP_DOWN, 3644 rid.ridacq_vp_index); 3645 } 3646 } 3647 } 3648 3649 static void 3650 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs) 3651 { 3652 int ru_marked, sv_marked; 3653 int chan = XS_CHANNEL(xs); 3654 3655 switch (sp->req_completion_status) { 3656 case RQCS_COMPLETE: 3657 return; 3658 3659 case RQCS_DMA_ERROR: 3660 isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error"); 3661 if (XS_NOERR(xs)) 3662 XS_SETERR(xs, HBA_BOTCH); 3663 break; 3664 3665 case RQCS_TRANSPORT_ERROR: 3666 isp_xs_prt(isp, xs, ISP_LOGERR, "Transport Error"); 3667 if (XS_NOERR(xs)) 3668 XS_SETERR(xs, HBA_BOTCH); 3669 break; 3670 3671 case RQCS_RESET_OCCURRED: 3672 isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command"); 3673 FCPARAM(isp, chan)->sendmarker = 1; 3674 if (XS_NOERR(xs)) 3675 XS_SETERR(xs, HBA_BUSRESET); 3676 return; 3677 3678 case RQCS_ABORTED: 3679 isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted"); 3680 FCPARAM(isp, chan)->sendmarker = 1; 3681 if (XS_NOERR(xs)) 3682 XS_SETERR(xs, HBA_ABORTED); 3683 return; 3684 3685 case RQCS_TIMEOUT: 3686 isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out"); 3687 if (XS_NOERR(xs)) 3688 XS_SETERR(xs, HBA_CMDTIMEOUT); 3689 return; 3690 3691 case RQCS_DATA_OVERRUN: 3692 XS_SET_RESID(xs, sp->req_resid); 3693 isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun"); 3694 if (XS_NOERR(xs)) 3695 XS_SETERR(xs, HBA_DATAOVR); 3696 return; 3697 3698 case RQCS_DRE: /* data reassembly error */ 3699 isp_prt(isp, ISP_LOGERR, "Chan %d data reassembly error for target %d", chan, XS_TGT(xs)); 3700 if (XS_NOERR(xs)) 3701 XS_SETERR(xs, HBA_BOTCH); 3702 return; 3703 3704 case RQCS_TABORT: /* aborted by target */ 3705 isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS", chan, XS_TGT(xs)); 3706 if (XS_NOERR(xs)) 3707 XS_SETERR(xs, HBA_ABORTED); 3708 return; 3709 3710 case RQCS_DATA_UNDERRUN: 3711 ru_marked = (sp->req_scsi_status & RQCS_RU) != 0; 3712 /* 3713 * We can get an underrun w/o things being marked 3714 * if we got a non-zero status. 3715 */ 3716 sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0; 3717 if ((ru_marked == 0 && sv_marked == 0) || 3718 (sp->req_resid > XS_XFRLEN(xs))) { 3719 isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked"); 3720 if (XS_NOERR(xs)) 3721 XS_SETERR(xs, HBA_BOTCH); 3722 return; 3723 } 3724 XS_SET_RESID(xs, sp->req_resid); 3725 isp_xs_prt(isp, xs, ISP_LOG_WARN1, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff); 3726 return; 3727 3728 case RQCS_PORT_UNAVAILABLE: 3729 /* 3730 * No such port on the loop. Moral equivalent of SELTIMEO 3731 */ 3732 case RQCS_PORT_LOGGED_OUT: 3733 { 3734 const char *reason; 3735 uint8_t sts = sp->req_completion_status & 0xff; 3736 fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs)); 3737 fcportdb_t *lp; 3738 3739 /* 3740 * It was there (maybe)- treat as a selection timeout. 3741 */ 3742 if (sts == RQCS_PORT_UNAVAILABLE) { 3743 reason = "unavailable"; 3744 } else { 3745 reason = "logout"; 3746 } 3747 3748 isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d", 3749 chan, reason, XS_TGT(xs)); 3750 3751 /* XXX: Should we trigger rescan or FW announce change? */ 3752 3753 if (XS_NOERR(xs)) { 3754 lp = &fcp->portdb[XS_TGT(xs)]; 3755 if (lp->state == FC_PORTDB_STATE_ZOMBIE) { 3756 *XS_STSP(xs) = SCSI_BUSY; 3757 XS_SETERR(xs, HBA_TGTBSY); 3758 } else 3759 XS_SETERR(xs, HBA_SELTIMEOUT); 3760 } 3761 return; 3762 } 3763 case RQCS_PORT_CHANGED: 3764 isp_prt(isp, ISP_LOGWARN, "port changed for target %d chan %d", XS_TGT(xs), chan); 3765 if (XS_NOERR(xs)) { 3766 *XS_STSP(xs) = SCSI_BUSY; 3767 XS_SETERR(xs, HBA_TGTBSY); 3768 } 3769 return; 3770 3771 case RQCS_ENOMEM: /* f/w resource unavailable */ 3772 isp_prt(isp, ISP_LOGWARN, "f/w resource unavailable for target %d chan %d", XS_TGT(xs), chan); 3773 if (XS_NOERR(xs)) { 3774 *XS_STSP(xs) = SCSI_BUSY; 3775 XS_SETERR(xs, HBA_TGTBSY); 3776 } 3777 return; 3778 3779 case RQCS_TMO: /* task management overrun */ 3780 isp_prt(isp, ISP_LOGWARN, "command for target %d overlapped task management for chan %d", XS_TGT(xs), chan); 3781 if (XS_NOERR(xs)) { 3782 *XS_STSP(xs) = SCSI_BUSY; 3783 XS_SETERR(xs, HBA_TGTBSY); 3784 } 3785 return; 3786 3787 default: 3788 isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x on chan %d", sp->req_completion_status, chan); 3789 break; 3790 } 3791 if (XS_NOERR(xs)) 3792 XS_SETERR(xs, HBA_BOTCH); 3793 } 3794 3795 #define ISP_FC_IBITS(op) ((mbpfc[((op)<<3) + 0] << 24) | (mbpfc[((op)<<3) + 1] << 16) | (mbpfc[((op)<<3) + 2] << 8) | (mbpfc[((op)<<3) + 3])) 3796 #define ISP_FC_OBITS(op) ((mbpfc[((op)<<3) + 4] << 24) | (mbpfc[((op)<<3) + 5] << 16) | (mbpfc[((op)<<3) + 6] << 8) | (mbpfc[((op)<<3) + 7])) 3797 3798 #define ISP_FC_OPMAP(in0, out0) 0, 0, 0, in0, 0, 0, 0, out0 3799 #define ISP_FC_OPMAP_HALF(in1, in0, out1, out0) 0, 0, in1, in0, 0, 0, out1, out0 3800 #define ISP_FC_OPMAP_FULL(in3, in2, in1, in0, out3, out2, out1, out0) in3, in2, in1, in0, out3, out2, out1, out0 3801 static const uint32_t mbpfc[] = { 3802 ISP_FC_OPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */ 3803 ISP_FC_OPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */ 3804 ISP_FC_OPMAP_HALF(0x07, 0xff, 0x00, 0x1f), /* 0x02: MBOX_EXEC_FIRMWARE */ 3805 ISP_FC_OPMAP(0xdf, 0x01), /* 0x03: MBOX_DUMP_RAM */ 3806 ISP_FC_OPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */ 3807 ISP_FC_OPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */ 3808 ISP_FC_OPMAP_FULL(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff), /* 0x06: MBOX_MAILBOX_REG_TEST */ 3809 ISP_FC_OPMAP(0x07, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */ 3810 ISP_FC_OPMAP_FULL(0x0, 0x0, 0x0, 0x01, 0x0, 0x3, 0x80, 0x7f), /* 0x08: MBOX_ABOUT_FIRMWARE */ 3811 ISP_FC_OPMAP(0xdf, 0x01), /* 0x09: MBOX_LOAD_RISC_RAM_2100 */ 3812 ISP_FC_OPMAP(0xdf, 0x01), /* 0x0a: DUMP RAM */ 3813 ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x01), /* 0x0b: MBOX_LOAD_RISC_RAM */ 3814 ISP_FC_OPMAP(0x00, 0x00), /* 0x0c: */ 3815 ISP_FC_OPMAP_HALF(0x1, 0x0f, 0x0, 0x01), /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */ 3816 ISP_FC_OPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */ 3817 ISP_FC_OPMAP_HALF(0x1, 0x03, 0x0, 0x0d), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */ 3818 ISP_FC_OPMAP(0x1f, 0x11), /* 0x10: MBOX_INIT_REQ_QUEUE */ 3819 ISP_FC_OPMAP(0x2f, 0x21), /* 0x11: MBOX_INIT_RES_QUEUE */ 3820 ISP_FC_OPMAP(0x0f, 0x01), /* 0x12: MBOX_EXECUTE_IOCB */ 3821 ISP_FC_OPMAP(0x03, 0x03), /* 0x13: MBOX_WAKE_UP */ 3822 ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x03), /* 0x14: MBOX_STOP_FIRMWARE */ 3823 ISP_FC_OPMAP(0x4f, 0x01), /* 0x15: MBOX_ABORT */ 3824 ISP_FC_OPMAP(0x07, 0x01), /* 0x16: MBOX_ABORT_DEVICE */ 3825 ISP_FC_OPMAP(0x07, 0x01), /* 0x17: MBOX_ABORT_TARGET */ 3826 ISP_FC_OPMAP(0x03, 0x03), /* 0x18: MBOX_BUS_RESET */ 3827 ISP_FC_OPMAP(0x07, 0x05), /* 0x19: MBOX_STOP_QUEUE */ 3828 ISP_FC_OPMAP(0x07, 0x05), /* 0x1a: MBOX_START_QUEUE */ 3829 ISP_FC_OPMAP(0x07, 0x05), /* 0x1b: MBOX_SINGLE_STEP_QUEUE */ 3830 ISP_FC_OPMAP(0x07, 0x05), /* 0x1c: MBOX_ABORT_QUEUE */ 3831 ISP_FC_OPMAP(0x07, 0x03), /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */ 3832 ISP_FC_OPMAP(0x00, 0x00), /* 0x1e: */ 3833 ISP_FC_OPMAP(0x01, 0x07), /* 0x1f: MBOX_GET_FIRMWARE_STATUS */ 3834 ISP_FC_OPMAP_HALF(0x2, 0x01, 0x7e, 0xcf), /* 0x20: MBOX_GET_LOOP_ID */ 3835 ISP_FC_OPMAP(0x00, 0x00), /* 0x21: */ 3836 ISP_FC_OPMAP(0x03, 0x4b), /* 0x22: MBOX_GET_TIMEOUT_PARAMS */ 3837 ISP_FC_OPMAP(0x00, 0x00), /* 0x23: */ 3838 ISP_FC_OPMAP(0x00, 0x00), /* 0x24: */ 3839 ISP_FC_OPMAP(0x00, 0x00), /* 0x25: */ 3840 ISP_FC_OPMAP(0x00, 0x00), /* 0x26: */ 3841 ISP_FC_OPMAP(0x00, 0x00), /* 0x27: */ 3842 ISP_FC_OPMAP(0x01, 0x03), /* 0x28: MBOX_GET_FIRMWARE_OPTIONS */ 3843 ISP_FC_OPMAP(0x03, 0x07), /* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */ 3844 ISP_FC_OPMAP(0x00, 0x00), /* 0x2a: */ 3845 ISP_FC_OPMAP(0x00, 0x00), /* 0x2b: */ 3846 ISP_FC_OPMAP(0x00, 0x00), /* 0x2c: */ 3847 ISP_FC_OPMAP(0x00, 0x00), /* 0x2d: */ 3848 ISP_FC_OPMAP(0x00, 0x00), /* 0x2e: */ 3849 ISP_FC_OPMAP(0x00, 0x00), /* 0x2f: */ 3850 ISP_FC_OPMAP(0x00, 0x00), /* 0x30: */ 3851 ISP_FC_OPMAP(0x00, 0x00), /* 0x31: */ 3852 ISP_FC_OPMAP(0x4b, 0x4b), /* 0x32: MBOX_SET_TIMEOUT_PARAMS */ 3853 ISP_FC_OPMAP(0x00, 0x00), /* 0x33: */ 3854 ISP_FC_OPMAP(0x00, 0x00), /* 0x34: */ 3855 ISP_FC_OPMAP(0x00, 0x00), /* 0x35: */ 3856 ISP_FC_OPMAP(0x00, 0x00), /* 0x36: */ 3857 ISP_FC_OPMAP(0x00, 0x00), /* 0x37: */ 3858 ISP_FC_OPMAP(0x0f, 0x01), /* 0x38: MBOX_SET_FIRMWARE_OPTIONS */ 3859 ISP_FC_OPMAP(0x0f, 0x07), /* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */ 3860 ISP_FC_OPMAP(0x00, 0x00), /* 0x3a: */ 3861 ISP_FC_OPMAP(0x00, 0x00), /* 0x3b: */ 3862 ISP_FC_OPMAP(0x00, 0x00), /* 0x3c: */ 3863 ISP_FC_OPMAP(0x00, 0x00), /* 0x3d: */ 3864 ISP_FC_OPMAP(0x00, 0x00), /* 0x3e: */ 3865 ISP_FC_OPMAP(0x00, 0x00), /* 0x3f: */ 3866 ISP_FC_OPMAP(0x03, 0x01), /* 0x40: MBOX_LOOP_PORT_BYPASS */ 3867 ISP_FC_OPMAP(0x03, 0x01), /* 0x41: MBOX_LOOP_PORT_ENABLE */ 3868 ISP_FC_OPMAP_HALF(0x0, 0x01, 0x1f, 0xcf), /* 0x42: MBOX_GET_RESOURCE_COUNT */ 3869 ISP_FC_OPMAP(0x01, 0x01), /* 0x43: MBOX_REQUEST_OFFLINE_MODE */ 3870 ISP_FC_OPMAP(0x00, 0x00), /* 0x44: */ 3871 ISP_FC_OPMAP(0x00, 0x00), /* 0x45: */ 3872 ISP_FC_OPMAP(0x00, 0x00), /* 0x46: */ 3873 ISP_FC_OPMAP(0xcf, 0x03), /* 0x47: GET PORT_DATABASE ENHANCED */ 3874 ISP_FC_OPMAP(0xcf, 0x0f), /* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */ 3875 ISP_FC_OPMAP(0xcd, 0x01), /* 0x49: MBOX_GET_VP_DATABASE */ 3876 ISP_FC_OPMAP_HALF(0x2, 0xcd, 0x0, 0x01), /* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */ 3877 ISP_FC_OPMAP(0x00, 0x00), /* 0x4b: */ 3878 ISP_FC_OPMAP(0x00, 0x00), /* 0x4c: */ 3879 ISP_FC_OPMAP(0x00, 0x00), /* 0x4d: */ 3880 ISP_FC_OPMAP(0x00, 0x00), /* 0x4e: */ 3881 ISP_FC_OPMAP(0x00, 0x00), /* 0x4f: */ 3882 ISP_FC_OPMAP(0x00, 0x00), /* 0x50: */ 3883 ISP_FC_OPMAP(0x00, 0x00), /* 0x51: */ 3884 ISP_FC_OPMAP(0x00, 0x00), /* 0x52: */ 3885 ISP_FC_OPMAP(0x00, 0x00), /* 0x53: */ 3886 ISP_FC_OPMAP(0xcf, 0x01), /* 0x54: EXECUTE IOCB A64 */ 3887 ISP_FC_OPMAP(0x00, 0x00), /* 0x55: */ 3888 ISP_FC_OPMAP(0x00, 0x00), /* 0x56: */ 3889 ISP_FC_OPMAP(0x00, 0x00), /* 0x57: */ 3890 ISP_FC_OPMAP(0x00, 0x00), /* 0x58: */ 3891 ISP_FC_OPMAP(0x00, 0x00), /* 0x59: */ 3892 ISP_FC_OPMAP(0x00, 0x00), /* 0x5a: */ 3893 ISP_FC_OPMAP(0x03, 0x01), /* 0x5b: MBOX_DRIVER_HEARTBEAT */ 3894 ISP_FC_OPMAP(0xcf, 0x01), /* 0x5c: MBOX_FW_HEARTBEAT */ 3895 ISP_FC_OPMAP(0x07, 0x1f), /* 0x5d: MBOX_GET_SET_DATA_RATE */ 3896 ISP_FC_OPMAP(0x00, 0x00), /* 0x5e: */ 3897 ISP_FC_OPMAP(0x00, 0x00), /* 0x5f: */ 3898 ISP_FC_OPMAP(0xcf, 0x0f), /* 0x60: MBOX_INIT_FIRMWARE */ 3899 ISP_FC_OPMAP(0x00, 0x00), /* 0x61: */ 3900 ISP_FC_OPMAP(0x01, 0x01), /* 0x62: MBOX_INIT_LIP */ 3901 ISP_FC_OPMAP(0xcd, 0x03), /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */ 3902 ISP_FC_OPMAP(0xcf, 0x01), /* 0x64: MBOX_GET_PORT_DB */ 3903 ISP_FC_OPMAP(0x07, 0x01), /* 0x65: MBOX_CLEAR_ACA */ 3904 ISP_FC_OPMAP(0x07, 0x01), /* 0x66: MBOX_TARGET_RESET */ 3905 ISP_FC_OPMAP(0x07, 0x01), /* 0x67: MBOX_CLEAR_TASK_SET */ 3906 ISP_FC_OPMAP(0x07, 0x01), /* 0x68: MBOX_ABORT_TASK_SET */ 3907 ISP_FC_OPMAP_HALF(0x00, 0x01, 0x0f, 0x1f), /* 0x69: MBOX_GET_FW_STATE */ 3908 ISP_FC_OPMAP_HALF(0x6, 0x03, 0x0, 0xcf), /* 0x6a: MBOX_GET_PORT_NAME */ 3909 ISP_FC_OPMAP(0xcf, 0x01), /* 0x6b: MBOX_GET_LINK_STATUS */ 3910 ISP_FC_OPMAP(0x0f, 0x01), /* 0x6c: MBOX_INIT_LIP_RESET */ 3911 ISP_FC_OPMAP(0x00, 0x00), /* 0x6d: */ 3912 ISP_FC_OPMAP(0xcf, 0x03), /* 0x6e: MBOX_SEND_SNS */ 3913 ISP_FC_OPMAP(0x0f, 0x07), /* 0x6f: MBOX_FABRIC_LOGIN */ 3914 ISP_FC_OPMAP_HALF(0x02, 0x03, 0x00, 0x03), /* 0x70: MBOX_SEND_CHANGE_REQUEST */ 3915 ISP_FC_OPMAP(0x03, 0x03), /* 0x71: MBOX_FABRIC_LOGOUT */ 3916 ISP_FC_OPMAP(0x0f, 0x0f), /* 0x72: MBOX_INIT_LIP_LOGIN */ 3917 ISP_FC_OPMAP(0x00, 0x00), /* 0x73: */ 3918 ISP_FC_OPMAP(0x07, 0x01), /* 0x74: LOGIN LOOP PORT */ 3919 ISP_FC_OPMAP_HALF(0x03, 0xcf, 0x00, 0x07), /* 0x75: GET PORT/NODE NAME LIST */ 3920 ISP_FC_OPMAP(0x4f, 0x01), /* 0x76: SET VENDOR ID */ 3921 ISP_FC_OPMAP(0xcd, 0x01), /* 0x77: INITIALIZE IP MAILBOX */ 3922 ISP_FC_OPMAP(0x00, 0x00), /* 0x78: */ 3923 ISP_FC_OPMAP(0x00, 0x00), /* 0x79: */ 3924 ISP_FC_OPMAP(0x00, 0x00), /* 0x7a: */ 3925 ISP_FC_OPMAP(0x00, 0x00), /* 0x7b: */ 3926 ISP_FC_OPMAP_HALF(0x03, 0x4f, 0x00, 0x07), /* 0x7c: Get ID List */ 3927 ISP_FC_OPMAP(0xcf, 0x01), /* 0x7d: SEND LFA */ 3928 ISP_FC_OPMAP(0x0f, 0x01) /* 0x7e: LUN RESET */ 3929 }; 3930 #define MAX_FC_OPCODE 0x7e 3931 /* 3932 * Footnotes 3933 * 3934 * (1): this sets bits 21..16 in mailbox register #8, which we nominally 3935 * do not access at this time in the core driver. The caller is 3936 * responsible for setting this register first (Gross!). The assumption 3937 * is that we won't overflow. 3938 */ 3939 3940 static const char *fc_mbcmd_names[] = { 3941 "NO-OP", /* 00h */ 3942 "LOAD RAM", 3943 "EXEC FIRMWARE", 3944 "DUMP RAM", 3945 "WRITE RAM WORD", 3946 "READ RAM WORD", 3947 "MAILBOX REG TEST", 3948 "VERIFY CHECKSUM", 3949 "ABOUT FIRMWARE", 3950 "LOAD RAM (2100)", 3951 "DUMP RAM", 3952 "LOAD RISC RAM", 3953 "DUMP RISC RAM", 3954 "WRITE RAM WORD EXTENDED", 3955 "CHECK FIRMWARE", 3956 "READ RAM WORD EXTENDED", 3957 "INIT REQUEST QUEUE", /* 10h */ 3958 "INIT RESULT QUEUE", 3959 "EXECUTE IOCB", 3960 "WAKE UP", 3961 "STOP FIRMWARE", 3962 "ABORT", 3963 "ABORT DEVICE", 3964 "ABORT TARGET", 3965 "BUS RESET", 3966 "STOP QUEUE", 3967 "START QUEUE", 3968 "SINGLE STEP QUEUE", 3969 "ABORT QUEUE", 3970 "GET DEV QUEUE STATUS", 3971 NULL, 3972 "GET FIRMWARE STATUS", 3973 "GET LOOP ID", /* 20h */ 3974 NULL, 3975 "GET TIMEOUT PARAMS", 3976 NULL, 3977 NULL, 3978 NULL, 3979 NULL, 3980 NULL, 3981 "GET FIRMWARE OPTIONS", 3982 "GET PORT QUEUE PARAMS", 3983 "GENERATE SYSTEM ERROR", 3984 NULL, 3985 NULL, 3986 NULL, 3987 NULL, 3988 NULL, 3989 "WRITE SFP", /* 30h */ 3990 "READ SFP", 3991 "SET TIMEOUT PARAMS", 3992 NULL, 3993 NULL, 3994 NULL, 3995 NULL, 3996 NULL, 3997 "SET FIRMWARE OPTIONS", 3998 "SET PORT QUEUE PARAMS", 3999 NULL, 4000 "SET FC LED CONF", 4001 NULL, 4002 "RESTART NIC FIRMWARE", 4003 "ACCESS CONTROL", 4004 NULL, 4005 "LOOP PORT BYPASS", /* 40h */ 4006 "LOOP PORT ENABLE", 4007 "GET RESOURCE COUNT", 4008 "REQUEST NON PARTICIPATING MODE", 4009 "DIAGNOSTIC ECHO TEST", 4010 "DIAGNOSTIC LOOPBACK", 4011 NULL, 4012 "GET PORT DATABASE ENHANCED", 4013 "INIT FIRMWARE MULTI ID", 4014 "GET VP DATABASE", 4015 "GET VP DATABASE ENTRY", 4016 NULL, 4017 NULL, 4018 NULL, 4019 NULL, 4020 NULL, 4021 "GET FCF LIST", /* 50h */ 4022 "GET DCBX PARAMETERS", 4023 NULL, 4024 "HOST MEMORY COPY", 4025 "EXECUTE IOCB A64", 4026 NULL, 4027 NULL, 4028 "SEND RNID", 4029 NULL, 4030 "SET PARAMETERS", 4031 "GET PARAMETERS", 4032 "DRIVER HEARTBEAT", 4033 "FIRMWARE HEARTBEAT", 4034 "GET/SET DATA RATE", 4035 "SEND RNFT", 4036 NULL, 4037 "INIT FIRMWARE", /* 60h */ 4038 "GET INIT CONTROL BLOCK", 4039 "INIT LIP", 4040 "GET FC-AL POSITION MAP", 4041 "GET PORT DATABASE", 4042 "CLEAR ACA", 4043 "TARGET RESET", 4044 "CLEAR TASK SET", 4045 "ABORT TASK SET", 4046 "GET FW STATE", 4047 "GET PORT NAME", 4048 "GET LINK STATUS", 4049 "INIT LIP RESET", 4050 "GET LINK STATS & PRIVATE DATA CNTS", 4051 "SEND SNS", 4052 "FABRIC LOGIN", 4053 "SEND CHANGE REQUEST", /* 70h */ 4054 "FABRIC LOGOUT", 4055 "INIT LIP LOGIN", 4056 NULL, 4057 "LOGIN LOOP PORT", 4058 "GET PORT/NODE NAME LIST", 4059 "SET VENDOR ID", 4060 "INITIALIZE IP MAILBOX", 4061 NULL, 4062 NULL, 4063 "GET XGMAC STATS", 4064 NULL, 4065 "GET ID LIST", 4066 "SEND LFA", 4067 "LUN RESET" 4068 }; 4069 4070 static void 4071 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp) 4072 { 4073 const char *cname, *xname, *sname; 4074 char tname[16], mname[16]; 4075 unsigned int ibits, obits, box, opcode, t, to; 4076 4077 opcode = mbp->param[0]; 4078 if (opcode > MAX_FC_OPCODE) { 4079 mbp->param[0] = MBOX_INVALID_COMMAND; 4080 isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode); 4081 return; 4082 } 4083 cname = fc_mbcmd_names[opcode]; 4084 ibits = ISP_FC_IBITS(opcode); 4085 obits = ISP_FC_OBITS(opcode); 4086 if (cname == NULL) { 4087 cname = tname; 4088 ISP_SNPRINTF(tname, sizeof tname, "opcode %x", opcode); 4089 } 4090 isp_prt(isp, ISP_LOGDEBUG3, "Mailbox Command '%s'", cname); 4091 4092 /* 4093 * Pick up any additional bits that the caller might have set. 4094 */ 4095 ibits |= mbp->ibits; 4096 obits |= mbp->obits; 4097 4098 /* 4099 * Mask any bits that the caller wants us to mask 4100 */ 4101 ibits &= mbp->ibitm; 4102 obits &= mbp->obitm; 4103 4104 4105 if (ibits == 0 && obits == 0) { 4106 mbp->param[0] = MBOX_COMMAND_PARAM_ERROR; 4107 isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode); 4108 return; 4109 } 4110 4111 for (box = 0; box < ISP_NMBOX(isp); box++) { 4112 if (ibits & (1 << box)) { 4113 isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box, 4114 mbp->param[box]); 4115 ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]); 4116 } 4117 isp->isp_mboxtmp[box] = mbp->param[box] = 0; 4118 } 4119 4120 isp->isp_obits = obits; 4121 isp->isp_mboxbsy = 1; 4122 4123 /* 4124 * Set Host Interrupt condition so that RISC will pick up mailbox regs. 4125 */ 4126 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT); 4127 4128 /* 4129 * While we haven't finished the command, spin our wheels here. 4130 */ 4131 to = (mbp->timeout == 0) ? MBCMD_DEFAULT_TIMEOUT : mbp->timeout; 4132 for (t = 0; t < to; t += 100) { 4133 if (!isp->isp_mboxbsy) 4134 break; 4135 ISP_RUN_ISR(isp); 4136 if (!isp->isp_mboxbsy) 4137 break; 4138 ISP_DELAY(100); 4139 } 4140 4141 /* 4142 * Did the command time out? 4143 */ 4144 if (isp->isp_mboxbsy) { 4145 isp->isp_mboxbsy = 0; 4146 isp_prt(isp, ISP_LOGWARN, "Mailbox Command (0x%x) Timeout (%uus) (%s:%d)", 4147 opcode, to, mbp->func, mbp->lineno); 4148 mbp->param[0] = MBOX_TIMEOUT; 4149 goto out; 4150 } 4151 4152 /* 4153 * Copy back output registers. 4154 */ 4155 for (box = 0; box < ISP_NMBOX(isp); box++) { 4156 if (obits & (1 << box)) { 4157 mbp->param[box] = isp->isp_mboxtmp[box]; 4158 isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box, 4159 mbp->param[box]); 4160 } 4161 } 4162 4163 out: 4164 if (mbp->logval == 0 || mbp->param[0] == MBOX_COMMAND_COMPLETE) 4165 return; 4166 4167 if ((mbp->param[0] & 0xbfe0) == 0 && 4168 (mbp->logval & MBLOGMASK(mbp->param[0])) == 0) 4169 return; 4170 4171 xname = NULL; 4172 sname = ""; 4173 switch (mbp->param[0]) { 4174 case MBOX_INVALID_COMMAND: 4175 xname = "INVALID COMMAND"; 4176 break; 4177 case MBOX_HOST_INTERFACE_ERROR: 4178 xname = "HOST INTERFACE ERROR"; 4179 break; 4180 case MBOX_TEST_FAILED: 4181 xname = "TEST FAILED"; 4182 break; 4183 case MBOX_COMMAND_ERROR: 4184 xname = "COMMAND ERROR"; 4185 ISP_SNPRINTF(mname, sizeof(mname), " subcode 0x%x", 4186 mbp->param[1]); 4187 sname = mname; 4188 break; 4189 case MBOX_COMMAND_PARAM_ERROR: 4190 xname = "COMMAND PARAMETER ERROR"; 4191 break; 4192 case MBOX_PORT_ID_USED: 4193 xname = "PORT ID ALREADY IN USE"; 4194 break; 4195 case MBOX_LOOP_ID_USED: 4196 xname = "LOOP ID ALREADY IN USE"; 4197 break; 4198 case MBOX_ALL_IDS_USED: 4199 xname = "ALL LOOP IDS IN USE"; 4200 break; 4201 case MBOX_NOT_LOGGED_IN: 4202 xname = "NOT LOGGED IN"; 4203 break; 4204 case MBOX_LINK_DOWN_ERROR: 4205 xname = "LINK DOWN ERROR"; 4206 break; 4207 case MBOX_LOOPBACK_ERROR: 4208 xname = "LOOPBACK ERROR"; 4209 break; 4210 case MBOX_CHECKSUM_ERROR: 4211 xname = "CHECKSUM ERROR"; 4212 break; 4213 case MBOX_INVALID_PRODUCT_KEY: 4214 xname = "INVALID PRODUCT KEY"; 4215 break; 4216 case MBOX_REGS_BUSY: 4217 xname = "REGISTERS BUSY"; 4218 break; 4219 case MBOX_TIMEOUT: 4220 xname = "TIMEOUT"; 4221 break; 4222 default: 4223 ISP_SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]); 4224 xname = mname; 4225 break; 4226 } 4227 if (xname) { 4228 isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s%s)", 4229 cname, xname, sname); 4230 } 4231 } 4232 4233 static int 4234 isp_fw_state(ispsoftc_t *isp, int chan) 4235 { 4236 mbreg_t mbs; 4237 4238 MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0); 4239 isp_mboxcmd(isp, &mbs); 4240 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) 4241 return (mbs.param[1]); 4242 return (FW_ERROR); 4243 } 4244 4245 static void 4246 isp_setdfltfcparm(ispsoftc_t *isp, int chan) 4247 { 4248 fcparam *fcp = FCPARAM(isp, chan); 4249 4250 /* 4251 * Establish some default parameters. 4252 */ 4253 fcp->role = DEFAULT_ROLE(isp, chan); 4254 fcp->isp_retry_delay = ICB_DFLT_RDELAY; 4255 fcp->isp_retry_count = ICB_DFLT_RCOUNT; 4256 fcp->isp_loopid = DEFAULT_LOOPID(isp, chan); 4257 fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan); 4258 fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan); 4259 fcp->isp_fwoptions = 0; 4260 fcp->isp_xfwoptions = 0; 4261 fcp->isp_zfwoptions = 0; 4262 fcp->isp_lasthdl = NIL_HANDLE; 4263 fcp->isp_login_hdl = NIL_HANDLE; 4264 4265 fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS; 4266 fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS; 4267 if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) 4268 fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX; 4269 fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS; 4270 fcp->isp_xfwoptions |= ICB2400_OPT2_LOOP_2_PTP; 4271 fcp->isp_zfwoptions |= ICB2400_OPT3_RATE_AUTO; 4272 4273 /* 4274 * Now try and read NVRAM unless told to not do so. 4275 * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram. 4276 */ 4277 if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) { 4278 int i, j = 0; 4279 /* 4280 * Give a couple of tries at reading NVRAM. 4281 */ 4282 for (i = 0; i < 2; i++) { 4283 j = isp_read_nvram(isp, chan); 4284 if (j == 0) { 4285 break; 4286 } 4287 } 4288 if (j) { 4289 isp->isp_confopts |= ISP_CFG_NONVRAM; 4290 } 4291 } 4292 4293 fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan); 4294 fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan); 4295 isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s", 4296 chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn), 4297 (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn), 4298 isp_class3_roles[fcp->role]); 4299 } 4300 4301 /* 4302 * Re-initialize the ISP and complete all orphaned commands 4303 * with a 'botched' notice. The reset/init routines should 4304 * not disturb an already active list of commands. 4305 */ 4306 4307 int 4308 isp_reinit(ispsoftc_t *isp, int do_load_defaults) 4309 { 4310 int i, res = 0; 4311 4312 if (isp->isp_state > ISP_RESETSTATE) 4313 isp_stop(isp); 4314 if (isp->isp_state != ISP_RESETSTATE) 4315 isp_reset(isp, do_load_defaults); 4316 if (isp->isp_state != ISP_RESETSTATE) { 4317 res = EIO; 4318 isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__); 4319 goto cleanup; 4320 } 4321 4322 isp_init(isp); 4323 if (isp->isp_state > ISP_RESETSTATE && 4324 isp->isp_state != ISP_RUNSTATE) { 4325 res = EIO; 4326 isp_prt(isp, ISP_LOGERR, "%s: cannot init card", __func__); 4327 ISP_DISABLE_INTS(isp); 4328 } 4329 4330 cleanup: 4331 isp_clear_commands(isp); 4332 for (i = 0; i < isp->isp_nchan; i++) 4333 isp_clear_portdb(isp, i); 4334 return (res); 4335 } 4336 4337 /* 4338 * NVRAM Routines 4339 */ 4340 static int 4341 isp_read_nvram(ispsoftc_t *isp, int bus) 4342 { 4343 fcparam *fcp = FCPARAM(isp, 0); 4344 int r = 0; 4345 4346 if (isp->isp_type != ISP_HA_FC_2600) { 4347 if (IS_28XX(isp)) { 4348 fcp->flash_data_addr = ISP28XX_BASE_ADDR; 4349 fcp->flt_region_flt = ISP28XX_FLT_ADDR; 4350 } else if (IS_27XX(isp)) { 4351 fcp->flash_data_addr = ISP27XX_BASE_ADDR; 4352 fcp->flt_region_flt = ISP27XX_FLT_ADDR; 4353 } else if (IS_25XX(isp)) { 4354 fcp->flash_data_addr = ISP25XX_BASE_ADDR; 4355 fcp->flt_region_flt = ISP25XX_FLT_ADDR; 4356 } else { 4357 fcp->flash_data_addr = ISP24XX_BASE_ADDR; 4358 fcp->flt_region_flt = ISP24XX_FLT_ADDR; 4359 } 4360 fcp->flt_length = 0; 4361 r = isp_read_flthdr_2xxx(isp); 4362 if (r == 0) { 4363 isp_read_flt_2xxx(isp); 4364 } else { /* fallback to hardcoded NVRAM address */ 4365 if (IS_28XX(isp)) { 4366 fcp->flt_region_nvram = 0x300000; 4367 } else if (IS_27XX(isp)) { 4368 fcp->flash_data_addr = 0x7fe7c000; 4369 fcp->flt_region_nvram = 0; 4370 } else if (IS_25XX(isp)) { 4371 fcp->flt_region_nvram = 0x48000; 4372 } else { 4373 fcp->flash_data_addr = 0x7ffe0000; 4374 fcp->flt_region_nvram = 0; 4375 } 4376 fcp->flt_region_nvram += ISP2400_NVRAM_PORT_ADDR(isp->isp_port); 4377 } 4378 } else { 4379 fcp->flash_data_addr = 0x7fe7c000; 4380 fcp->flt_region_nvram = 0; 4381 fcp->flt_region_nvram += ISP2400_NVRAM_PORT_ADDR(isp->isp_port); 4382 } 4383 return (isp_read_nvram_2400(isp)); 4384 } 4385 4386 static void 4387 isp_rd_2xxx_flash(ispsoftc_t *isp, uint32_t addr, uint32_t *rp) 4388 { 4389 fcparam *fcp = FCPARAM(isp, 0); 4390 int loops = 0; 4391 uint32_t base = fcp->flash_data_addr; 4392 uint32_t tmp = 0; 4393 4394 ISP_WRITE(isp, BIU2400_FLASH_ADDR, base + addr); 4395 for (loops = 0; loops < 5000; loops++) { 4396 ISP_DELAY(10); 4397 tmp = ISP_READ(isp, BIU2400_FLASH_ADDR); 4398 if ((tmp & (1U << 31)) != 0) { 4399 break; 4400 } 4401 } 4402 if (tmp & (1U << 31)) { 4403 *rp = ISP_READ(isp, BIU2400_FLASH_DATA); 4404 ISP_SWIZZLE_NVRAM_LONG(isp, rp); 4405 } else { 4406 *rp = 0xffffffff; 4407 } 4408 } 4409 4410 static int 4411 isp_read_flthdr_2xxx(ispsoftc_t *isp) 4412 { 4413 fcparam *fcp = FCPARAM(isp, 0); 4414 int retval = 0; 4415 uint32_t addr, lwrds, *dptr; 4416 uint16_t csum; 4417 uint8_t flthdr_data[FLT_HEADER_SIZE]; 4418 4419 addr = fcp->flt_region_flt; 4420 dptr = (uint32_t *) flthdr_data; 4421 4422 isp_prt(isp, ISP_LOGDEBUG0, 4423 "FLTL[DEF]: 0x%x", addr); 4424 for (lwrds = 0; lwrds < FLT_HEADER_SIZE >> 2; lwrds++) { 4425 isp_rd_2xxx_flash(isp, addr++, dptr++); 4426 } 4427 dptr = (uint32_t *) flthdr_data; 4428 for (csum = 0, lwrds = 0; lwrds < FLT_HEADER_SIZE >> 4; lwrds++) { 4429 uint16_t tmp; 4430 ISP_IOXGET_16(isp, &dptr[lwrds], tmp); 4431 csum += tmp; 4432 } 4433 if (csum != 0) { 4434 retval = -1; 4435 goto out; 4436 } 4437 isp_parse_flthdr_2xxx(isp, flthdr_data); 4438 out: 4439 return (retval); 4440 } 4441 4442 static void 4443 isp_parse_flthdr_2xxx(ispsoftc_t *isp, uint8_t *flthdr_data) 4444 { 4445 fcparam *fcp = FCPARAM(isp, 0); 4446 uint16_t ver, csum; 4447 4448 ver = le16toh((uint16_t) (ISP2XXX_FLT_VERSION(flthdr_data))); 4449 fcp->flt_length = le16toh((uint16_t) (ISP2XXX_FLT_LENGTH(flthdr_data))); 4450 csum = le16toh((uint16_t) (ISP2XXX_FLT_CSUM(flthdr_data))); 4451 4452 if ((fcp->flt_length == 0) || 4453 (fcp->flt_length > (FLT_HEADER_SIZE + FLT_REGIONS_SIZE))) { 4454 isp_prt(isp, ISP_LOGERR, 4455 "FLT[DEF]: Invalid length=0x%x(%d)", 4456 fcp->flt_length, fcp->flt_length); 4457 } 4458 isp_prt(isp, ISP_LOGDEBUG0, 4459 "FLT[DEF]: version=0x%x length=0x%x(%d) checksum=0x%x", 4460 ver, fcp->flt_length, fcp->flt_length, csum); 4461 } 4462 4463 static int 4464 isp_read_flt_2xxx(ispsoftc_t *isp) 4465 { 4466 fcparam *fcp = FCPARAM(isp, 0); 4467 int retval = 0; 4468 int len = fcp->flt_length - FLT_HEADER_SIZE; 4469 uint32_t addr, lwrds, *dptr; 4470 uint8_t flt_data[len]; 4471 fcp->flt_region_entries = len / FLT_REGION_SIZE; 4472 4473 addr = fcp->flt_region_flt + (FLT_HEADER_SIZE >> 2); 4474 dptr = (uint32_t *) flt_data; 4475 isp_prt(isp, ISP_LOGDEBUG0, "FLT[DEF]: regions=%d", 4476 fcp->flt_region_entries); 4477 for (lwrds = 0; lwrds < len >> 2; lwrds++) { 4478 isp_rd_2xxx_flash(isp, addr++, dptr++); 4479 } 4480 retval = isp_parse_flt_2xxx(isp, flt_data); 4481 return (retval); 4482 } 4483 4484 static int 4485 isp_parse_flt_2xxx(ispsoftc_t *isp, uint8_t *flt_data) 4486 { 4487 fcparam *fcp = FCPARAM(isp, 0); 4488 int count; 4489 struct flt_region region[fcp->flt_region_entries]; 4490 4491 for (count = 0; count < fcp->flt_region_entries; count++) { 4492 region[count].code = 4493 le16toh((uint16_t) (ISP2XXX_FLT_REG_CODE(flt_data, count))); 4494 region[count].attribute = 4495 (uint8_t) (ISP2XXX_FLT_REG_ATTR(flt_data, count)); 4496 region[count].reserved = 4497 (uint8_t) (ISP2XXX_FLT_REG_RES(flt_data, count)); 4498 region[count].size = 4499 le32toh((uint32_t) (ISP2XXX_FLT_REG_SIZE(flt_data, count)) >> 2); 4500 region[count].start = 4501 le32toh((uint32_t) (ISP2XXX_FLT_REG_START(flt_data, count)) >> 2); 4502 region[count].end = 4503 le32toh((uint32_t) (ISP2XXX_FLT_REG_END(flt_data, count)) >> 2); 4504 4505 isp_prt(isp, ISP_LOGDEBUG0, 4506 "FLT[0x%x]: start=0x%x end=0x%x size=0x%x attribute=0x%x", 4507 region[count].code, region[count].start, region[count].end, 4508 region[count].size, region[count].attribute); 4509 4510 switch (region[count].code) { 4511 case FLT_REG_FW: 4512 fcp->flt_region_fw = region[count].start; 4513 break; 4514 case FLT_REG_BOOT_CODE: 4515 fcp->flt_region_boot = region[count].start; 4516 break; 4517 case FLT_REG_VPD_0: 4518 fcp->flt_region_vpd_nvram = region[count].start; 4519 if (isp->isp_port == 0) 4520 fcp->flt_region_vpd = region[count].start; 4521 break; 4522 case FLT_REG_VPD_1: 4523 if (isp->isp_port == 1) 4524 fcp->flt_region_vpd = region[count].start; 4525 break; 4526 case FLT_REG_VPD_2: 4527 if (!IS_27XX(isp)) 4528 break; 4529 if (isp->isp_port == 2) 4530 fcp->flt_region_vpd = region[count].start; 4531 break; 4532 case FLT_REG_VPD_3: 4533 if (!IS_27XX(isp)) 4534 break; 4535 if (isp->isp_port == 3) 4536 fcp->flt_region_vpd = region[count].start; 4537 break; 4538 case FLT_REG_NVRAM_0: 4539 if (isp->isp_port == 0) 4540 fcp->flt_region_nvram = region[count].start; 4541 break; 4542 case FLT_REG_NVRAM_1: 4543 if (isp->isp_port == 1) 4544 fcp->flt_region_nvram = region[count].start; 4545 break; 4546 case FLT_REG_NVRAM_2: 4547 if (!IS_27XX(isp)) 4548 break; 4549 if (isp->isp_port == 2) 4550 fcp->flt_region_nvram = region[count].start; 4551 break; 4552 case FLT_REG_NVRAM_3: 4553 if (!IS_27XX(isp)) 4554 break; 4555 if (isp->isp_port == 3) 4556 fcp->flt_region_nvram = region[count].start; 4557 break; 4558 case FLT_REG_FDT: 4559 fcp->flt_region_fdt = region[count].start; 4560 break; 4561 case FLT_REG_FLT: 4562 fcp->flt_region_flt = region[count].start; 4563 break; 4564 case FLT_REG_NPIV_CONF_0: 4565 if (isp->isp_port == 0) 4566 fcp->flt_region_npiv_conf = region[count].start; 4567 break; 4568 case FLT_REG_NPIV_CONF_1: 4569 if (isp->isp_port == 1) 4570 fcp->flt_region_npiv_conf = region[count].start; 4571 break; 4572 case FLT_REG_GOLD_FW: 4573 fcp->flt_region_gold_fw = region[count].start; 4574 break; 4575 case FLT_REG_FCP_PRIO_0: 4576 if (isp->isp_port == 0) 4577 fcp->flt_region_fcp_prio = region[count].start; 4578 break; 4579 case FLT_REG_FCP_PRIO_1: 4580 if (isp->isp_port == 1) 4581 fcp->flt_region_fcp_prio = region[count].start; 4582 break; 4583 case FLT_REG_IMG_PRI_27XX: 4584 if (IS_27XX(isp)) 4585 fcp->flt_region_img_status_pri = region[count].start; 4586 break; 4587 case FLT_REG_IMG_SEC_27XX: 4588 if (IS_27XX(isp)) 4589 fcp->flt_region_img_status_sec = region[count].start; 4590 break; 4591 case FLT_REG_FW_SEC_27XX: 4592 if (IS_27XX(isp)) 4593 fcp->flt_region_fw_sec = region[count].start; 4594 break; 4595 case FLT_REG_BOOTLOAD_SEC_27XX: 4596 if (IS_27XX(isp)) 4597 fcp->flt_region_boot_sec = region[count].start; 4598 break; 4599 case FLT_REG_AUX_IMG_PRI_28XX: 4600 if (IS_27XX(isp)) 4601 fcp->flt_region_aux_img_status_pri = region[count].start; 4602 break; 4603 case FLT_REG_AUX_IMG_SEC_28XX: 4604 if (IS_27XX(isp)) 4605 fcp->flt_region_aux_img_status_sec = region[count].start; 4606 break; 4607 case FLT_REG_NVRAM_SEC_28XX_0: 4608 if (IS_27XX(isp)) 4609 if (isp->isp_port == 0) 4610 fcp->flt_region_nvram_sec = region[count].start; 4611 break; 4612 case FLT_REG_NVRAM_SEC_28XX_1: 4613 if (IS_27XX(isp)) 4614 if (isp->isp_port == 1) 4615 fcp->flt_region_nvram_sec = region[count].start; 4616 break; 4617 case FLT_REG_NVRAM_SEC_28XX_2: 4618 if (IS_27XX(isp)) 4619 if (isp->isp_port == 2) 4620 fcp->flt_region_nvram_sec = region[count].start; 4621 break; 4622 case FLT_REG_NVRAM_SEC_28XX_3: 4623 if (IS_27XX(isp)) 4624 if (isp->isp_port == 3) 4625 fcp->flt_region_nvram_sec = region[count].start; 4626 break; 4627 case FLT_REG_VPD_SEC_27XX_0: 4628 case FLT_REG_VPD_SEC_28XX_0: 4629 if (IS_27XX(isp)) { 4630 fcp->flt_region_vpd_nvram_sec = region[count].start; 4631 if (isp->isp_port == 0) 4632 fcp->flt_region_vpd_sec = region[count].start; 4633 } 4634 break; 4635 case FLT_REG_VPD_SEC_27XX_1: 4636 case FLT_REG_VPD_SEC_28XX_1: 4637 if (IS_27XX(isp)) 4638 if (isp->isp_port == 1) 4639 fcp->flt_region_vpd_sec = region[count].start; 4640 break; 4641 case FLT_REG_VPD_SEC_27XX_2: 4642 case FLT_REG_VPD_SEC_28XX_2: 4643 if (IS_27XX(isp)) 4644 if (isp->isp_port == 2) 4645 fcp->flt_region_vpd_sec = region[count].start; 4646 break; 4647 case FLT_REG_VPD_SEC_27XX_3: 4648 case FLT_REG_VPD_SEC_28XX_3: 4649 if (IS_27XX(isp)) 4650 if (isp->isp_port == 3) 4651 fcp->flt_region_vpd_sec = region[count].start; 4652 break; 4653 } 4654 } 4655 isp_prt(isp, ISP_LOGDEBUG0, 4656 "FLT[FLT]: boot=0x%x fw=0x%x vpd_nvram=0x%x vpd=0x%x nvram 0x%x " 4657 "fdt=0x%x flt=0x%x npiv=0x%x fcp_prif_cfg=0x%x", 4658 fcp->flt_region_boot, fcp->flt_region_fw, fcp->flt_region_vpd_nvram, 4659 fcp->flt_region_vpd, fcp->flt_region_nvram, fcp->flt_region_fdt, 4660 fcp->flt_region_flt, fcp->flt_region_npiv_conf, 4661 fcp->flt_region_fcp_prio); 4662 4663 return (0); 4664 } 4665 4666 static int 4667 isp_read_nvram_2400(ispsoftc_t *isp) 4668 { 4669 fcparam *fcp = FCPARAM(isp, 0); 4670 int retval = 0; 4671 uint32_t addr, csum, lwrds, *dptr; 4672 uint8_t nvram_data[ISP2400_NVRAM_SIZE]; 4673 4674 addr = fcp->flt_region_nvram; 4675 dptr = (uint32_t *) nvram_data; 4676 for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) { 4677 isp_rd_2xxx_flash(isp, addr++, dptr++); 4678 } 4679 if (nvram_data[0] != 'I' || nvram_data[1] != 'S' || 4680 nvram_data[2] != 'P') { 4681 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)", 4682 nvram_data[0], nvram_data[1], nvram_data[2]); 4683 retval = -1; 4684 goto out; 4685 } 4686 dptr = (uint32_t *) nvram_data; 4687 for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) { 4688 uint32_t tmp; 4689 ISP_IOXGET_32(isp, &dptr[lwrds], tmp); 4690 csum += tmp; 4691 } 4692 if (csum != 0) { 4693 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum"); 4694 retval = -1; 4695 goto out; 4696 } 4697 isp_parse_nvram_2400(isp, nvram_data); 4698 out: 4699 return (retval); 4700 } 4701 4702 static void 4703 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data) 4704 { 4705 fcparam *fcp = FCPARAM(isp, 0); 4706 uint64_t wwn; 4707 4708 isp_prt(isp, ISP_LOGDEBUG0, 4709 "NVRAM 0x%08x%08x 0x%08x%08x maxframelen %d", 4710 (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32), 4711 (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)), 4712 (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32), 4713 (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)), 4714 ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data)); 4715 isp_prt(isp, ISP_LOGDEBUG0, 4716 "NVRAM loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", 4717 ISP2400_NVRAM_HARDLOOPID(nvram_data), 4718 ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data), 4719 ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data), 4720 ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data)); 4721 4722 wwn = ISP2400_NVRAM_PORT_NAME(nvram_data); 4723 fcp->isp_wwpn_nvram = wwn; 4724 4725 wwn = ISP2400_NVRAM_NODE_NAME(nvram_data); 4726 if (wwn) { 4727 if ((wwn >> 60) != 2 && (wwn >> 60) != 5) { 4728 wwn = 0; 4729 } 4730 } 4731 if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) { 4732 wwn = fcp->isp_wwpn_nvram; 4733 wwn &= ~((uint64_t) 0xfff << 48); 4734 } 4735 fcp->isp_wwnn_nvram = wwn; 4736 4737 if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) { 4738 DEFAULT_FRAMESIZE(isp) = 4739 ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data); 4740 } 4741 if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) { 4742 fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data); 4743 } 4744 fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data); 4745 fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data); 4746 fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data); 4747 } 4748