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