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