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