1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2009-2020 Alexander Motin <mav@FreeBSD.org> 5 * Copyright (c) 1997-2009 by Matthew Jacob 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 32 /* 33 * Machine and OS Independent (well, as best as possible) 34 * code for the Qlogic ISP SCSI and FC-SCSI adapters. 35 */ 36 37 /* 38 * Inspiration and ideas about this driver are from Erik Moe's Linux driver 39 * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some 40 * ideas dredged from the Solaris driver. 41 */ 42 43 /* 44 * Include header file appropriate for platform we're building on. 45 */ 46 #ifdef __NetBSD__ 47 #include <sys/cdefs.h> 48 __KERNEL_RCSID(0, "$NetBSD$"); 49 #include <dev/ic/isp_netbsd.h> 50 #endif 51 #ifdef __FreeBSD__ 52 #include <sys/param.h> 53 #include <sys/cdefs.h> 54 #include <sys/firmware.h> 55 #include <dev/isp/isp_freebsd.h> 56 #endif 57 #ifdef __OpenBSD__ 58 #include <dev/ic/isp_openbsd.h> 59 #endif 60 #ifdef __linux__ 61 #include "isp_linux.h" 62 #endif 63 #ifdef __svr4__ 64 #include "isp_solaris.h" 65 #endif 66 67 /* 68 * Local static data 69 */ 70 static const char notresp[] = "Unknown IOCB in RESPONSE Queue (type 0x%x) @ idx %d (next %d)"; 71 static const char bun[] = "bad underrun (count %d, resid %d, status %s)"; 72 static const char lipd[] = "Chan %d LIP destroyed %d active commands"; 73 static const char sacq[] = "unable to acquire scratch area"; 74 75 static const uint8_t alpa_map[] = { 76 0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda, 77 0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce, 78 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5, 79 0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3, 80 0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 81 0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b, 82 0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81, 83 0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73, 84 0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 85 0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56, 86 0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c, 87 0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c, 88 0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 89 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26, 90 0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17, 91 0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00 92 }; 93 94 /* 95 * Local function prototypes. 96 */ 97 static int isp_handle_control(ispsoftc_t *, isphdr_t *); 98 static void isp_handle_rpt_id_acq(ispsoftc_t *, isphdr_t *); 99 static void isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *); 100 static void isp_clear_portdb(ispsoftc_t *, int); 101 static void isp_mark_portdb(ispsoftc_t *, int); 102 static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int); 103 static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *); 104 static int isp_gethandles(ispsoftc_t *, int, uint16_t *, int *, int); 105 static void isp_dump_chip_portdb(ispsoftc_t *, int); 106 static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int); 107 static int isp_fclink_test(ispsoftc_t *, int, int); 108 static int isp_pdb_sync(ispsoftc_t *, int); 109 static int isp_scan_loop(ispsoftc_t *, int); 110 static int isp_gid_pt(ispsoftc_t *, int); 111 static int isp_scan_fabric(ispsoftc_t *, int); 112 static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *); 113 static int isp_register_fc4_type(ispsoftc_t *, int); 114 static int isp_register_fc4_features_24xx(ispsoftc_t *, int); 115 static int isp_register_port_name_24xx(ispsoftc_t *, int); 116 static int isp_register_node_name_24xx(ispsoftc_t *, int); 117 static uint16_t isp_next_handle(ispsoftc_t *, uint16_t *); 118 static int isp_fw_state(ispsoftc_t *, int); 119 static void isp_mboxcmd(ispsoftc_t *, mbreg_t *); 120 121 static void isp_get_flash_addrs(ispsoftc_t *); 122 static void isp_setdfltfcparm(ispsoftc_t *, int); 123 static int isp_read_flash_dword(ispsoftc_t *, uint32_t, uint32_t *); 124 static int isp_read_flash_data(ispsoftc_t *, uint32_t *, uint32_t, uint32_t); 125 static void isp_rd_2xxx_flash(ispsoftc_t *, uint32_t, uint32_t *); 126 static int isp_read_flthdr_2xxx(ispsoftc_t *); 127 static void isp_parse_flthdr_2xxx(ispsoftc_t *, uint8_t *); 128 static int isp_read_flt_2xxx(ispsoftc_t *); 129 static int isp_parse_flt_2xxx(ispsoftc_t *, uint8_t *); 130 static int isp_read_nvram(ispsoftc_t *); 131 static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *); 132 133 static void isp_print_image(ispsoftc_t *, char *, struct isp_image_status *); 134 static bool isp_check_aux_image_status_signature(struct isp_image_status *); 135 static bool isp_check_image_status_signature(struct isp_image_status *); 136 static unsigned long isp_image_status_checksum(struct isp_image_status *); 137 static void isp_component_status(struct active_regions *, struct isp_image_status *); 138 static int isp_compare_image_generation(ispsoftc_t *, struct isp_image_status *, struct isp_image_status *); 139 static void isp_get_aux_images(ispsoftc_t *, struct active_regions *); 140 static void isp_get_active_image(ispsoftc_t *, struct active_regions *); 141 static bool isp_risc_firmware_invalid(ispsoftc_t *, uint32_t *); 142 static int isp_load_ram(ispsoftc_t *, uint32_t *, uint32_t, uint32_t); 143 static int isp_load_risc_flash(ispsoftc_t *, uint32_t *, uint32_t); 144 static int isp_load_risc(ispsoftc_t *, uint32_t *); 145 146 static void 147 isp_change_fw_state(ispsoftc_t *isp, int chan, int state) 148 { 149 fcparam *fcp = FCPARAM(isp, chan); 150 151 if (fcp->isp_fwstate == state) 152 return; 153 isp_prt(isp, ISP_LOGCONFIG|ISP_LOG_SANCFG, 154 "Chan %d Firmware state <%s->%s>", chan, 155 isp_fc_fw_statename(fcp->isp_fwstate), isp_fc_fw_statename(state)); 156 fcp->isp_fwstate = state; 157 } 158 159 static void 160 isp_get_flash_addrs(ispsoftc_t *isp) 161 { 162 fcparam *fcp = FCPARAM(isp, 0); 163 int r = 0; 164 165 if (IS_28XX(isp)) { 166 fcp->flash_data_addr = ISP28XX_BASE_ADDR; 167 fcp->flt_region_flt = ISP28XX_FLT_ADDR; 168 } else if (IS_26XX(isp)) { /* 26xx and 27xx are identical */ 169 fcp->flash_data_addr = ISP27XX_BASE_ADDR; 170 fcp->flt_region_flt = ISP27XX_FLT_ADDR; 171 } else if (IS_25XX(isp)) { 172 fcp->flash_data_addr = ISP25XX_BASE_ADDR; 173 fcp->flt_region_flt = ISP25XX_FLT_ADDR; 174 } else { 175 fcp->flash_data_addr = ISP24XX_BASE_ADDR; 176 fcp->flt_region_flt = ISP24XX_FLT_ADDR; 177 } 178 fcp->flt_length = 0; 179 r = isp_read_flthdr_2xxx(isp); 180 if (r == 0) { 181 isp_read_flt_2xxx(isp); 182 } else { /* fallback to hardcoded NVRAM address */ 183 if (IS_28XX(isp)) { 184 fcp->flt_region_nvram = 0x300000; 185 } else if (IS_26XX(isp)) { 186 fcp->flash_data_addr = 0x7fe7c000; 187 fcp->flt_region_nvram = 0; 188 } else if (IS_25XX(isp)) { 189 fcp->flt_region_nvram = 0x48000; 190 } else { 191 fcp->flash_data_addr = 0x7ffe0000; 192 fcp->flt_region_nvram = 0; 193 } 194 fcp->flt_region_nvram += ISP2400_NVRAM_PORT_ADDR(isp->isp_port); 195 } 196 } 197 198 /* 199 * Reset Hardware. 200 * 201 * Hit the chip over the head, download new f/w if available and set it running. 202 * 203 * Locking done elsewhere. 204 */ 205 206 void 207 isp_reset(ispsoftc_t *isp, int do_load_defaults) 208 { 209 mbreg_t mbs; 210 char *buf; 211 uint16_t fwt; 212 uint32_t code_org, val; 213 int loaded_fw, loops, i, dodnld = 1; 214 const char *btype = "????"; 215 static const char dcrc[] = "Downloaded RISC Code Checksum Failure"; 216 217 isp->isp_state = ISP_NILSTATE; 218 ISP_DISABLE_INTS(isp); 219 220 /* 221 * Put the board into PAUSE mode (so we can read the SXP registers 222 * or write FPM/FBM registers). 223 */ 224 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT); 225 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT); 226 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE); 227 228 switch (isp->isp_type) { 229 case ISP_HA_FC_2400: 230 btype = "2422"; 231 break; 232 case ISP_HA_FC_2500: 233 btype = "2532"; 234 break; 235 case ISP_HA_FC_2600: 236 btype = "2600"; 237 break; 238 case ISP_HA_FC_2700: 239 btype = "2700"; 240 break; 241 case ISP_HA_FC_2800: 242 btype = "2800"; 243 break; 244 default: 245 break; 246 } 247 248 /* 249 * Stop DMA and wait for it to stop. 250 */ 251 ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4)); 252 for (loops = 0; loops < 100000; loops++) { 253 ISP_DELAY(10); 254 val = ISP_READ(isp, BIU2400_CSR); 255 if ((val & BIU2400_DMA_ACTIVE) == 0) { 256 break; 257 } 258 } 259 if (val & BIU2400_DMA_ACTIVE) 260 isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset"); 261 262 /* 263 * Hold it in SOFT_RESET and STOP state for 100us. 264 */ 265 ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4)); 266 ISP_DELAY(100); 267 for (loops = 0; loops < 10000; loops++) { 268 ISP_DELAY(5); 269 val = ISP_READ(isp, OUTMAILBOX0); 270 if (val != 0x4) 271 break; 272 } 273 switch (val) { 274 case 0x0: 275 break; 276 case 0x4: 277 isp_prt(isp, ISP_LOGERR, "The ROM code is busy after 50ms."); 278 return; 279 case 0xf: 280 isp_prt(isp, ISP_LOGERR, "Board configuration error."); 281 return; 282 default: 283 isp_prt(isp, ISP_LOGERR, "Unknown RISC Status Code 0x%x.", val); 284 return; 285 } 286 287 /* 288 * Reset RISC Processor 289 */ 290 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET); 291 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE); 292 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET); 293 294 /* 295 * Post-RISC Reset stuff. 296 */ 297 for (loops = 0; loops < 10000; loops++) { 298 ISP_DELAY(5); 299 val = ISP_READ(isp, OUTMAILBOX0); 300 if (val != 0x4) 301 break; 302 } 303 switch (val) { 304 case 0x0: 305 break; 306 case 0x4: 307 isp_prt(isp, ISP_LOGERR, "The ROM code is busy after 50ms."); 308 return; 309 case 0xf: 310 isp_prt(isp, ISP_LOGERR, "Board configuration error."); 311 return; 312 default: 313 isp_prt(isp, ISP_LOGERR, "Unknown RISC Status Code 0x%x.", val); 314 return; 315 } 316 317 isp->isp_reqidx = isp->isp_reqodx = 0; 318 isp->isp_resodx = 0; 319 isp->isp_atioodx = 0; 320 ISP_WRITE(isp, BIU2400_REQINP, 0); 321 ISP_WRITE(isp, BIU2400_REQOUTP, 0); 322 ISP_WRITE(isp, BIU2400_RSPINP, 0); 323 ISP_WRITE(isp, BIU2400_RSPOUTP, 0); 324 if (!IS_26XX(isp)) { 325 ISP_WRITE(isp, BIU2400_PRI_REQINP, 0); 326 ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0); 327 } 328 ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0); 329 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0); 330 331 /* 332 * Up until this point we've done everything by just reading or 333 * setting registers. From this point on we rely on at least *some* 334 * kind of firmware running in the card. 335 */ 336 337 /* 338 * Do some sanity checking by running a NOP command. 339 * If it succeeds, the ROM firmware is now running. 340 */ 341 MBSINIT(&mbs, MBOX_NO_OP, MBLOGALL, 0); 342 isp_mboxcmd(isp, &mbs); 343 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 344 isp_prt(isp, ISP_LOGERR, "NOP command failed (%x)", mbs.param[0]); 345 return; 346 } 347 348 /* 349 * Do some operational tests 350 */ 351 { 352 static const uint16_t patterns[MAX_MAILBOX] = { 353 0x0000, 0xdead, 0xbeef, 0xffff, 354 0xa5a5, 0x5a5a, 0x7f7f, 0x7ff7, 355 0x3421, 0xabcd, 0xdcba, 0xfeef, 356 0xbead, 0xdebe, 0x2222, 0x3333, 357 0x5555, 0x6666, 0x7777, 0xaaaa, 358 0xffff, 0xdddd, 0x9999, 0x1fbc, 359 0x6666, 0x6677, 0x1122, 0x33ff, 360 0x0000, 0x0001, 0x1000, 0x1010, 361 }; 362 int nmbox = ISP_NMBOX(isp); 363 MBSINIT(&mbs, MBOX_MAILBOX_REG_TEST, MBLOGALL, 0); 364 for (i = 1; i < nmbox; i++) { 365 mbs.param[i] = patterns[i]; 366 } 367 isp_mboxcmd(isp, &mbs); 368 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 369 return; 370 } 371 for (i = 1; i < nmbox; i++) { 372 if (mbs.param[i] != patterns[i]) { 373 isp_prt(isp, ISP_LOGERR, "Register Test Failed at Register %d: should have 0x%04x but got 0x%04x", i, patterns[i], mbs.param[i]); 374 return; 375 } 376 } 377 } 378 379 /* 380 * Early setup DMA for the request and response queues. 381 * We do this now so we can use the request queue 382 * for dma to load firmware from. 383 */ 384 385 if (ISP_MBOXDMASETUP(isp) != 0) { 386 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA"); 387 return; 388 } 389 390 /* 391 * FW load priority 392 * For 27xx and newer: 393 * Load ispfw(4) firmware unless requested not to do so. 394 * Request (active) flash firmware information. Compare 395 * version numbers of ispfw(4) and flash firmware. Load 396 * the highest version into RAM of the adapter. 397 * If loading ispfw(4) is disabled or loading it failed 398 * (eg. no firmware available) we just load firmware from 399 * flash. If this fails for whatever reason we fallback 400 * to let the adapter MBOX_LOAD_FLASH_FIRMWARE by itself 401 * followed by MBOX_EXEC_FIRMWARE and hope the best to 402 * get it up and running. 403 * 404 * For 26xx and older: 405 * Load ispfw(4) firmware unless requested not to do so 406 * and load it into RAM of the adapter. If loading 407 * ispfw(4) is disabled or loading it failed (eg. no 408 * firmware available) we just let the adapter 409 * MBOX_EXEC_FIRMWARE to start the flash firmware. 410 * For the 26xx a preceding MBOX_LOAD_FLASH_FIRMWARE 411 * is required. 412 */ 413 414 fcparam *fcp = FCPARAM(isp, 0); 415 416 /* read FLT to get flash region addresses */ 417 isp_get_flash_addrs(isp); 418 419 /* set informational sysctl(8) to sane value */ 420 snprintf(fcp->fw_version_ispfw, sizeof(fcp->fw_version_ispfw), 421 "not loaded"); 422 snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash), 423 "not loaded"); 424 snprintf(fcp->fw_version_run, sizeof(fcp->fw_version_run), 425 "not loaded"); 426 427 428 /* Try to load ispfw(4) first */ 429 if (!(isp->isp_confopts & ISP_CFG_NORELOAD)) { 430 char fwname[32]; 431 snprintf(fwname, sizeof(fwname), "isp_%04x", isp->isp_did); 432 isp->isp_osinfo.ispfw = firmware_get(fwname); 433 if (isp->isp_osinfo.ispfw != NULL) { 434 isp->isp_mdvec->dv_ispfw = isp->isp_osinfo.ispfw->data; 435 const uint32_t *ispfwptr = isp->isp_mdvec->dv_ispfw; 436 for (i = 0; i < 4; i++) 437 fcp->fw_ispfwrev[i] = ispfwptr[4 + i]; 438 isp_prt(isp, ISP_LOGCONFIG, 439 "Loaded ispfw(4) firmware %s", fwname); 440 snprintf(fcp->fw_version_ispfw, 441 sizeof(fcp->fw_version_ispfw), 442 "%u.%u.%u", fcp->fw_ispfwrev[0], 443 fcp->fw_ispfwrev[1], fcp->fw_ispfwrev[2]); 444 isp_prt(isp, ISP_LOGCONFIG, 445 "Firmware revision (ispfw) %u.%u.%u (%x).", 446 fcp->fw_ispfwrev[0], fcp->fw_ispfwrev[1], 447 fcp->fw_ispfwrev[2], fcp->fw_ispfwrev[3]); 448 } else { 449 isp_prt(isp, ISP_LOGDEBUG0, 450 "Unable to load ispfw(4) firmware %s", fwname); 451 } 452 } 453 454 loaded_fw = 0; 455 dodnld = 0; 456 457 if (IS_27XX(isp)) { 458 switch (isp_load_risc(isp, 0)) { 459 case ISP_ABORTED: 460 /* 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 } 3092 case ISPCTL_FCLINK_TEST: 3093 { 3094 int usdelay; 3095 3096 va_start(ap, ctl); 3097 chan = va_arg(ap, int); 3098 usdelay = va_arg(ap, int); 3099 va_end(ap); 3100 if (usdelay == 0) 3101 usdelay = 250000; 3102 return (isp_fclink_test(isp, chan, usdelay)); 3103 } 3104 case ISPCTL_SCAN_FABRIC: 3105 3106 va_start(ap, ctl); 3107 chan = va_arg(ap, int); 3108 va_end(ap); 3109 return (isp_scan_fabric(isp, chan)); 3110 3111 case ISPCTL_SCAN_LOOP: 3112 3113 va_start(ap, ctl); 3114 chan = va_arg(ap, int); 3115 va_end(ap); 3116 return (isp_scan_loop(isp, chan)); 3117 3118 case ISPCTL_PDB_SYNC: 3119 3120 va_start(ap, ctl); 3121 chan = va_arg(ap, int); 3122 va_end(ap); 3123 return (isp_pdb_sync(isp, chan)); 3124 3125 case ISPCTL_SEND_LIP: 3126 break; 3127 3128 case ISPCTL_GET_PDB: 3129 { 3130 isp_pdb_t *pdb; 3131 va_start(ap, ctl); 3132 chan = va_arg(ap, int); 3133 tgt = va_arg(ap, int); 3134 pdb = va_arg(ap, isp_pdb_t *); 3135 va_end(ap); 3136 return (isp_getpdb(isp, chan, tgt, pdb)); 3137 } 3138 case ISPCTL_GET_NAMES: 3139 { 3140 uint64_t *wwnn, *wwnp; 3141 va_start(ap, ctl); 3142 chan = va_arg(ap, int); 3143 tgt = va_arg(ap, int); 3144 wwnn = va_arg(ap, uint64_t *); 3145 wwnp = va_arg(ap, uint64_t *); 3146 va_end(ap); 3147 if (wwnn == NULL && wwnp == NULL) { 3148 break; 3149 } 3150 if (wwnn) { 3151 *wwnn = isp_get_wwn(isp, chan, tgt, 1); 3152 if (*wwnn == INI_NONE) { 3153 break; 3154 } 3155 } 3156 if (wwnp) { 3157 *wwnp = isp_get_wwn(isp, chan, tgt, 0); 3158 if (*wwnp == INI_NONE) { 3159 break; 3160 } 3161 } 3162 return (0); 3163 } 3164 case ISPCTL_RUN_MBOXCMD: 3165 { 3166 va_start(ap, ctl); 3167 mbr = va_arg(ap, mbreg_t *); 3168 va_end(ap); 3169 isp_mboxcmd(isp, mbr); 3170 return (0); 3171 } 3172 case ISPCTL_PLOGX: 3173 { 3174 isp_plcmd_t *p; 3175 int r; 3176 3177 va_start(ap, ctl); 3178 p = va_arg(ap, isp_plcmd_t *); 3179 va_end(ap); 3180 3181 if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) { 3182 return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags)); 3183 } 3184 do { 3185 isp_next_handle(isp, &p->handle); 3186 r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags); 3187 if ((r & 0xffff) == MBOX_PORT_ID_USED) { 3188 p->handle = r >> 16; 3189 r = 0; 3190 break; 3191 } 3192 } while ((r & 0xffff) == MBOX_LOOP_ID_USED); 3193 return (r); 3194 } 3195 case ISPCTL_CHANGE_ROLE: 3196 { 3197 int role; 3198 3199 va_start(ap, ctl); 3200 chan = va_arg(ap, int); 3201 role = va_arg(ap, int); 3202 va_end(ap); 3203 return (isp_fc_change_role(isp, chan, role)); 3204 } 3205 default: 3206 isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl); 3207 break; 3208 3209 } 3210 return (-1); 3211 } 3212 3213 /* 3214 * Interrupt Service Routine(s). 3215 * 3216 * External (OS) framework has done the appropriate locking, 3217 * and the locking will be held throughout this function. 3218 */ 3219 3220 #ifdef ISP_TARGET_MODE 3221 void 3222 isp_intr_atioq(ispsoftc_t *isp) 3223 { 3224 void *addr; 3225 uint32_t iptr, optr, oop; 3226 3227 iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP); 3228 optr = isp->isp_atioodx; 3229 while (optr != iptr) { 3230 oop = optr; 3231 MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1); 3232 addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop); 3233 switch (((isphdr_t *)addr)->rqs_entry_type) { 3234 case RQSTYPE_NOTIFY: 3235 case RQSTYPE_ATIO: 3236 case RQSTYPE_NOTIFY_ACK: /* Can be set to ATIO queue.*/ 3237 case RQSTYPE_ABTS_RCVD: /* Can be set to ATIO queue.*/ 3238 (void) isp_target_notify(isp, addr, &oop, 3239 ATIO_QUEUE_LEN(isp)); 3240 break; 3241 case RQSTYPE_RPT_ID_ACQ: /* Can be set to ATIO queue.*/ 3242 default: 3243 isp_print_qentry(isp, "?ATIOQ entry?", oop, addr); 3244 break; 3245 } 3246 optr = ISP_NXT_QENTRY(oop, ATIO_QUEUE_LEN(isp)); 3247 } 3248 if (isp->isp_atioodx != optr) { 3249 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr); 3250 isp->isp_atioodx = optr; 3251 } 3252 } 3253 #endif 3254 3255 void 3256 isp_intr_mbox(ispsoftc_t *isp, uint16_t mbox0) 3257 { 3258 int i, obits; 3259 3260 if (!isp->isp_mboxbsy) { 3261 isp_prt(isp, ISP_LOGWARN, "mailbox 0x%x with no waiters", mbox0); 3262 return; 3263 } 3264 obits = isp->isp_obits; 3265 isp->isp_mboxtmp[0] = mbox0; 3266 for (i = 1; i < ISP_NMBOX(isp); i++) { 3267 if ((obits & (1 << i)) == 0) 3268 continue; 3269 isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i)); 3270 } 3271 isp->isp_mboxbsy = 0; 3272 } 3273 3274 void 3275 isp_intr_respq(ispsoftc_t *isp) 3276 { 3277 XS_T *xs, *cont_xs; 3278 uint8_t qe[QENTRY_LEN]; 3279 isp24xx_statusreq_t *sp = (isp24xx_statusreq_t *)qe; 3280 ispstatus_cont_t *scp = (ispstatus_cont_t *)qe; 3281 isphdr_t *hp; 3282 uint8_t *resp, *snsp, etype; 3283 uint16_t scsi_status; 3284 uint32_t iptr, cont = 0, cptr, optr, rlen, slen, totslen; 3285 #ifdef ISP_TARGET_MODE 3286 uint32_t sptr; 3287 #endif 3288 3289 /* 3290 * We can't be getting this now. 3291 */ 3292 if (isp->isp_state != ISP_RUNSTATE) { 3293 isp_prt(isp, ISP_LOGINFO, "respq interrupt when not ready"); 3294 return; 3295 } 3296 3297 iptr = ISP_READ(isp, BIU2400_RSPINP); 3298 optr = isp->isp_resodx; 3299 while (optr != iptr) { 3300 cptr = optr; 3301 #ifdef ISP_TARGET_MODE 3302 sptr = optr; 3303 #endif 3304 hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, cptr); 3305 optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp)); 3306 3307 /* 3308 * Synchronize our view of this response queue entry. 3309 */ 3310 MEMORYBARRIER(isp, SYNC_RESULT, cptr, QENTRY_LEN, -1); 3311 if (isp->isp_dblev & ISP_LOGDEBUG1) 3312 isp_print_qentry(isp, "Response Queue Entry", cptr, hp); 3313 isp_get_hdr(isp, hp, &sp->req_header); 3314 3315 /* 3316 * Log IOCBs rejected by the firmware. We can't really do 3317 * much more about them, since it just should not happen. 3318 */ 3319 if (sp->req_header.rqs_flags & RQSFLAG_BADTYPE) { 3320 isp_print_qentry(isp, "invalid entry type", cptr, hp); 3321 continue; 3322 } 3323 if (sp->req_header.rqs_flags & RQSFLAG_BADPARAM) { 3324 isp_print_qentry(isp, "invalid entry parameter", cptr, hp); 3325 continue; 3326 } 3327 if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) { 3328 isp_print_qentry(isp, "invalid entry count", cptr, hp); 3329 continue; 3330 } 3331 if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) { 3332 isp_print_qentry(isp, "invalid entry order", cptr, hp); 3333 continue; 3334 } 3335 3336 etype = sp->req_header.rqs_entry_type; 3337 3338 /* We expected Status Continuation, but got different IOCB. */ 3339 if (cont > 0 && etype != RQSTYPE_STATUS_CONT) { 3340 cont = 0; 3341 isp_done(cont_xs); 3342 } 3343 3344 if (isp_handle_control(isp, hp)) { 3345 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3346 continue; 3347 } 3348 3349 switch (etype) { 3350 case RQSTYPE_RESPONSE: 3351 isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp); 3352 break; 3353 case RQSTYPE_MARKER: 3354 isp_prt(isp, ISP_LOG_WARN1, "Marker Response"); 3355 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3356 continue; 3357 case RQSTYPE_STATUS_CONT: 3358 isp_get_cont_response(isp, (ispstatus_cont_t *)hp, scp); 3359 if (cont > 0) { 3360 slen = min(cont, sizeof(scp->req_sense_data)); 3361 XS_SENSE_APPEND(cont_xs, scp->req_sense_data, slen); 3362 cont -= slen; 3363 if (cont == 0) { 3364 isp_done(cont_xs); 3365 } else { 3366 isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN, 3367 "Expecting Status Continuations for %u bytes", 3368 cont); 3369 } 3370 } else { 3371 isp_prt(isp, ISP_LOG_WARN1, "Ignored Continuation Response"); 3372 } 3373 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3374 continue; 3375 #ifdef ISP_TARGET_MODE 3376 case RQSTYPE_NOTIFY_ACK: /* Can be set to ATIO queue. */ 3377 case RQSTYPE_CTIO7: 3378 case RQSTYPE_ABTS_RCVD: /* Can be set to ATIO queue. */ 3379 case RQSTYPE_ABTS_RSP: 3380 isp_target_notify(isp, hp, &cptr, RESULT_QUEUE_LEN(isp)); 3381 /* More then one IOCB could be consumed. */ 3382 while (sptr != cptr) { 3383 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3384 sptr = ISP_NXT_QENTRY(sptr, RESULT_QUEUE_LEN(isp)); 3385 hp = (isphdr_t *)ISP_QUEUE_ENTRY(isp->isp_result, sptr); 3386 } 3387 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3388 optr = ISP_NXT_QENTRY(cptr, RESULT_QUEUE_LEN(isp)); 3389 continue; 3390 #endif 3391 case RQSTYPE_RPT_ID_ACQ: /* Can be set to ATIO queue.*/ 3392 isp_handle_rpt_id_acq(isp, hp); 3393 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3394 continue; 3395 default: 3396 /* We don't know what was this -- log and skip. */ 3397 isp_prt(isp, ISP_LOGERR, notresp, etype, cptr, optr); 3398 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3399 continue; 3400 } 3401 3402 xs = isp_find_xs(isp, sp->req_handle); 3403 if (xs == NULL) { 3404 /* 3405 * Only whine if this isn't the expected fallout of 3406 * aborting the command or resetting the target. 3407 */ 3408 if (sp->req_completion_status != RQCS_ABORTED && 3409 sp->req_completion_status != RQCS_RESET_OCCURRED) 3410 isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", 3411 sp->req_handle, sp->req_completion_status); 3412 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3413 continue; 3414 } 3415 3416 resp = snsp = sp->req_rsp_sense; 3417 rlen = slen = totslen = 0; 3418 scsi_status = sp->req_scsi_status; 3419 if (scsi_status & RQCS_RV) { 3420 rlen = sp->req_response_len; 3421 snsp += rlen; 3422 } 3423 if (scsi_status & RQCS_SV) { 3424 totslen = sp->req_sense_len; 3425 slen = MIN(totslen, sizeof(sp->req_rsp_sense) - rlen); 3426 } 3427 *XS_STSP(xs) = scsi_status & 0xff; 3428 if (scsi_status & RQCS_RESID) 3429 XS_SET_RESID(xs, sp->req_fcp_residual); 3430 else 3431 XS_SET_RESID(xs, 0); 3432 3433 if (rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) { 3434 const char *ptr; 3435 char lb[64]; 3436 const char *rnames[10] = { 3437 "Task Management function complete", 3438 "FCP_DATA length different than FCP_BURST_LEN", 3439 "FCP_CMND fields invalid", 3440 "FCP_DATA parameter mismatch with FCP_DATA_RO", 3441 "Task Management function rejected", 3442 "Task Management function failed", 3443 NULL, 3444 NULL, 3445 "Task Management function succeeded", 3446 "Task Management function incorrect logical unit number", 3447 }; 3448 uint8_t code = resp[FCP_RSPNS_CODE_OFFSET]; 3449 if (code >= nitems(rnames) || rnames[code] == NULL) { 3450 ISP_SNPRINTF(lb, sizeof(lb), 3451 "Unknown FCP Response Code 0x%x", code); 3452 ptr = lb; 3453 } else { 3454 ptr = rnames[code]; 3455 } 3456 isp_xs_prt(isp, xs, ISP_LOGWARN, 3457 "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x", 3458 rlen, ptr, XS_CDBP(xs)[0] & 0xff); 3459 if (code != FCP_RSPNS_TMF_DONE && 3460 code != FCP_RSPNS_TMF_SUCCEEDED) 3461 XS_SETERR(xs, HBA_BOTCH); 3462 } 3463 isp_parse_status_24xx(isp, sp, xs); 3464 if (slen > 0) { 3465 XS_SAVE_SENSE(xs, snsp, slen); 3466 if (totslen > slen) { 3467 cont = totslen - slen; 3468 cont_xs = xs; 3469 isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN, 3470 "Expecting Status Continuations for %u bytes", 3471 cont); 3472 } 3473 } 3474 3475 ISP_DMAFREE(isp, xs); 3476 isp_destroy_handle(isp, sp->req_handle); 3477 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ 3478 3479 /* Complete command if we expect no Status Continuations. */ 3480 if (cont == 0) 3481 isp_done(xs); 3482 } 3483 3484 /* We haven't received all Status Continuations, but that is it. */ 3485 if (cont > 0) 3486 isp_done(cont_xs); 3487 3488 /* If we processed any IOCBs, let ISP know about it. */ 3489 if (optr != isp->isp_resodx) { 3490 ISP_WRITE(isp, BIU2400_RSPOUTP, optr); 3491 isp->isp_resodx = optr; 3492 } 3493 } 3494 3495 3496 void 3497 isp_intr_async(ispsoftc_t *isp, uint16_t mbox) 3498 { 3499 fcparam *fcp; 3500 uint16_t chan; 3501 3502 isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox); 3503 3504 switch (mbox) { 3505 case ASYNC_SYSTEM_ERROR: 3506 isp->isp_state = ISP_CRASHED; 3507 for (chan = 0; chan < isp->isp_nchan; chan++) { 3508 FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL; 3509 isp_change_fw_state(isp, chan, FW_CONFIG_WAIT); 3510 } 3511 /* 3512 * Were we waiting for a mailbox command to complete? 3513 * If so, it's dead, so wake up the waiter. 3514 */ 3515 if (isp->isp_mboxbsy) { 3516 isp->isp_obits = 1; 3517 isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR; 3518 isp->isp_mboxbsy = 0; 3519 } 3520 /* 3521 * It's up to the handler for isp_async to reinit stuff and 3522 * restart the firmware 3523 */ 3524 isp_async(isp, ISPASYNC_FW_CRASH); 3525 break; 3526 3527 case ASYNC_RQS_XFER_ERR: 3528 isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error"); 3529 break; 3530 3531 case ASYNC_RSP_XFER_ERR: 3532 isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error"); 3533 break; 3534 3535 case ASYNC_ATIO_XFER_ERR: 3536 isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error"); 3537 break; 3538 3539 case ASYNC_LIP_OCCURRED: 3540 case ASYNC_LIP_NOS_OLS_RECV: 3541 case ASYNC_LIP_ERROR: 3542 case ASYNC_PTPMODE: 3543 /* 3544 * These are broadcast events that have to be sent across 3545 * all active channels. 3546 */ 3547 for (chan = 0; chan < isp->isp_nchan; chan++) { 3548 fcp = FCPARAM(isp, chan); 3549 int topo = fcp->isp_topo; 3550 3551 if (fcp->role == ISP_ROLE_NONE) 3552 continue; 3553 if (fcp->isp_loopstate > LOOP_HAVE_LINK) 3554 fcp->isp_loopstate = LOOP_HAVE_LINK; 3555 ISP_SET_SENDMARKER(isp, chan, 1); 3556 isp_async(isp, ISPASYNC_LIP, chan); 3557 #ifdef ISP_TARGET_MODE 3558 isp_target_async(isp, chan, mbox); 3559 #endif 3560 /* 3561 * We've had problems with data corruption occurring on 3562 * commands that complete (with no apparent error) after 3563 * we receive a LIP. This has been observed mostly on 3564 * Local Loop topologies. To be safe, let's just mark 3565 * all active initiator commands as dead. 3566 */ 3567 if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) { 3568 int i, j; 3569 for (i = j = 0; i < ISP_HANDLE_NUM(isp); i++) { 3570 XS_T *xs; 3571 isp_hdl_t *hdp; 3572 3573 hdp = &isp->isp_xflist[i]; 3574 if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) { 3575 continue; 3576 } 3577 xs = hdp->cmd; 3578 if (XS_CHANNEL(xs) != chan) { 3579 continue; 3580 } 3581 j++; 3582 isp_prt(isp, ISP_LOG_WARN1, 3583 "%d.%d.%jx bus reset set at %s:%u", 3584 XS_CHANNEL(xs), XS_TGT(xs), 3585 (uintmax_t)XS_LUN(xs), 3586 __func__, __LINE__); 3587 XS_SETERR(xs, HBA_BUSRESET); 3588 } 3589 if (j) { 3590 isp_prt(isp, ISP_LOGERR, lipd, chan, j); 3591 } 3592 } 3593 } 3594 break; 3595 3596 case ASYNC_LOOP_UP: 3597 /* 3598 * This is a broadcast event that has to be sent across 3599 * all active channels. 3600 */ 3601 for (chan = 0; chan < isp->isp_nchan; chan++) { 3602 fcp = FCPARAM(isp, chan); 3603 if (fcp->role == ISP_ROLE_NONE) 3604 continue; 3605 fcp->isp_linkstate = 1; 3606 if (fcp->isp_loopstate < LOOP_HAVE_LINK) 3607 fcp->isp_loopstate = LOOP_HAVE_LINK; 3608 ISP_SET_SENDMARKER(isp, chan, 1); 3609 isp_async(isp, ISPASYNC_LOOP_UP, chan); 3610 #ifdef ISP_TARGET_MODE 3611 isp_target_async(isp, chan, mbox); 3612 #endif 3613 } 3614 break; 3615 3616 case ASYNC_LOOP_DOWN: 3617 /* 3618 * This is a broadcast event that has to be sent across 3619 * all active channels. 3620 */ 3621 for (chan = 0; chan < isp->isp_nchan; chan++) { 3622 fcp = FCPARAM(isp, chan); 3623 if (fcp->role == ISP_ROLE_NONE) 3624 continue; 3625 ISP_SET_SENDMARKER(isp, chan, 1); 3626 fcp->isp_linkstate = 0; 3627 fcp->isp_loopstate = LOOP_NIL; 3628 isp_async(isp, ISPASYNC_LOOP_DOWN, chan); 3629 #ifdef ISP_TARGET_MODE 3630 isp_target_async(isp, chan, mbox); 3631 #endif 3632 } 3633 break; 3634 3635 case ASYNC_LOOP_RESET: 3636 /* 3637 * This is a broadcast event that has to be sent across 3638 * all active channels. 3639 */ 3640 for (chan = 0; chan < isp->isp_nchan; chan++) { 3641 fcp = FCPARAM(isp, chan); 3642 if (fcp->role == ISP_ROLE_NONE) 3643 continue; 3644 ISP_SET_SENDMARKER(isp, chan, 1); 3645 if (fcp->isp_loopstate > LOOP_HAVE_LINK) 3646 fcp->isp_loopstate = LOOP_HAVE_LINK; 3647 isp_async(isp, ISPASYNC_LOOP_RESET, chan); 3648 #ifdef ISP_TARGET_MODE 3649 isp_target_async(isp, chan, mbox); 3650 #endif 3651 } 3652 break; 3653 3654 case ASYNC_PDB_CHANGED: 3655 { 3656 int echan, nphdl, nlstate, reason; 3657 3658 nphdl = ISP_READ(isp, OUTMAILBOX1); 3659 nlstate = ISP_READ(isp, OUTMAILBOX2); 3660 reason = ISP_READ(isp, OUTMAILBOX3) >> 8; 3661 if (ISP_CAP_MULTI_ID(isp)) { 3662 chan = ISP_READ(isp, OUTMAILBOX3) & 0xff; 3663 if (chan == 0xff || nphdl == NIL_HANDLE) { 3664 chan = 0; 3665 echan = isp->isp_nchan - 1; 3666 } else if (chan >= isp->isp_nchan) { 3667 break; 3668 } else { 3669 echan = chan; 3670 } 3671 } else { 3672 chan = echan = 0; 3673 } 3674 for (; chan <= echan; chan++) { 3675 fcp = FCPARAM(isp, chan); 3676 if (fcp->role == ISP_ROLE_NONE) 3677 continue; 3678 if (fcp->isp_loopstate > LOOP_LTEST_DONE) { 3679 if (nphdl != NIL_HANDLE && 3680 nphdl == fcp->isp_login_hdl && 3681 reason == PDB24XX_AE_OPN_2) 3682 continue; 3683 fcp->isp_loopstate = LOOP_LTEST_DONE; 3684 } else if (fcp->isp_loopstate < LOOP_HAVE_LINK) 3685 fcp->isp_loopstate = LOOP_HAVE_LINK; 3686 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, 3687 ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason); 3688 } 3689 break; 3690 } 3691 case ASYNC_CHANGE_NOTIFY: 3692 { 3693 int portid; 3694 3695 portid = ((ISP_READ(isp, OUTMAILBOX1) & 0xff) << 16) | 3696 ISP_READ(isp, OUTMAILBOX2); 3697 if (ISP_CAP_MULTI_ID(isp)) { 3698 chan = ISP_READ(isp, OUTMAILBOX3) & 0xff; 3699 if (chan >= isp->isp_nchan) 3700 break; 3701 } else { 3702 chan = 0; 3703 } 3704 fcp = FCPARAM(isp, chan); 3705 if (fcp->role == ISP_ROLE_NONE) 3706 break; 3707 if (fcp->isp_loopstate > LOOP_LTEST_DONE) 3708 fcp->isp_loopstate = LOOP_LTEST_DONE; 3709 else if (fcp->isp_loopstate < LOOP_HAVE_LINK) 3710 fcp->isp_loopstate = LOOP_HAVE_LINK; 3711 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, 3712 ISPASYNC_CHANGE_SNS, portid); 3713 break; 3714 } 3715 case ASYNC_ERR_LOGGING_DISABLED: 3716 isp_prt(isp, ISP_LOGWARN, "Error logging disabled (reason 0x%x)", 3717 ISP_READ(isp, OUTMAILBOX1)); 3718 break; 3719 case ASYNC_P2P_INIT_ERR: 3720 isp_prt(isp, ISP_LOGWARN, "P2P init error (reason 0x%x)", 3721 ISP_READ(isp, OUTMAILBOX1)); 3722 break; 3723 case ASYNC_RCV_ERR: 3724 isp_prt(isp, ISP_LOGWARN, "Receive Error"); 3725 break; 3726 case ASYNC_RJT_SENT: /* same as ASYNC_QFULL_SENT */ 3727 isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent"); 3728 break; 3729 case ASYNC_FW_RESTART_COMPLETE: 3730 isp_prt(isp, ISP_LOGDEBUG0, "FW restart complete"); 3731 break; 3732 case ASYNC_TEMPERATURE_ALERT: 3733 isp_prt(isp, ISP_LOGERR, "Temperature alert (subcode 0x%x)", 3734 ISP_READ(isp, OUTMAILBOX1)); 3735 break; 3736 case ASYNC_INTER_DRIVER_COMP: 3737 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication complete"); 3738 break; 3739 case ASYNC_INTER_DRIVER_NOTIFY: 3740 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication notification"); 3741 break; 3742 case ASYNC_INTER_DRIVER_TIME_EXT: 3743 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication time extended"); 3744 break; 3745 case ASYNC_TRANSCEIVER_INSERTION: 3746 isp_prt(isp, ISP_LOGDEBUG0, "Transceiver insertion (0x%x)", 3747 ISP_READ(isp, OUTMAILBOX1)); 3748 break; 3749 case ASYNC_TRANSCEIVER_REMOVAL: 3750 isp_prt(isp, ISP_LOGDEBUG0, "Transceiver removal"); 3751 break; 3752 case ASYNC_NIC_FW_STATE_CHANGE: 3753 isp_prt(isp, ISP_LOGDEBUG0, "NIC Firmware State Change"); 3754 break; 3755 case ASYNC_AUTOLOAD_FW_COMPLETE: 3756 isp_prt(isp, ISP_LOGDEBUG0, "Autoload FW init complete"); 3757 break; 3758 case ASYNC_AUTOLOAD_FW_FAILURE: 3759 isp_prt(isp, ISP_LOGERR, "Autoload FW init failure"); 3760 break; 3761 default: 3762 isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox); 3763 break; 3764 } 3765 } 3766 3767 /* 3768 * Handle completions with control handles by waking up waiting threads. 3769 */ 3770 static int 3771 isp_handle_control(ispsoftc_t *isp, isphdr_t *hp) 3772 { 3773 uint32_t hdl; 3774 void *ptr; 3775 3776 switch (hp->rqs_entry_type) { 3777 case RQSTYPE_RESPONSE: 3778 case RQSTYPE_MARKER: 3779 case RQSTYPE_NOTIFY_ACK: 3780 case RQSTYPE_CTIO7: 3781 case RQSTYPE_TSK_MGMT: 3782 case RQSTYPE_CT_PASSTHRU: 3783 case RQSTYPE_VP_MODIFY: 3784 case RQSTYPE_VP_CTRL: 3785 case RQSTYPE_ABORT_IO: 3786 case RQSTYPE_MBOX: 3787 case RQSTYPE_LOGIN: 3788 case RQSTYPE_ELS_PASSTHRU: 3789 ISP_IOXGET_32(isp, (uint32_t *)(hp + 1), hdl); 3790 if (ISP_H2HT(hdl) != ISP_HANDLE_CTRL) 3791 break; 3792 ptr = isp_find_xs(isp, hdl); 3793 if (ptr != NULL) { 3794 isp_destroy_handle(isp, hdl); 3795 memcpy(ptr, hp, QENTRY_LEN); 3796 wakeup(ptr); 3797 } 3798 return (1); 3799 } 3800 return (0); 3801 } 3802 3803 static void 3804 isp_handle_rpt_id_acq(ispsoftc_t *isp, isphdr_t *hp) 3805 { 3806 fcparam *fcp; 3807 isp_ridacq_t rid; 3808 int chan, c; 3809 uint32_t portid; 3810 3811 isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid); 3812 portid = (uint32_t)rid.ridacq_vp_port_hi << 16 | 3813 rid.ridacq_vp_port_lo; 3814 if (rid.ridacq_format == 0) { 3815 for (chan = 0; chan < isp->isp_nchan; chan++) { 3816 fcp = FCPARAM(isp, chan); 3817 if (fcp->role == ISP_ROLE_NONE) 3818 continue; 3819 c = (chan == 0) ? 127 : (chan - 1); 3820 if (rid.ridacq_map[c / 16] & (1 << (c % 16)) || 3821 chan == 0) { 3822 fcp->isp_loopstate = LOOP_HAVE_LINK; 3823 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, 3824 chan, ISPASYNC_CHANGE_OTHER); 3825 } else { 3826 fcp->isp_loopstate = LOOP_NIL; 3827 isp_async(isp, ISPASYNC_LOOP_DOWN, 3828 chan); 3829 } 3830 } 3831 } else { 3832 fcp = FCPARAM(isp, rid.ridacq_vp_index); 3833 if (rid.ridacq_vp_status == RIDACQ_STS_COMPLETE || 3834 rid.ridacq_vp_status == RIDACQ_STS_CHANGED) { 3835 fcp->isp_topo = (rid.ridacq_map[0] >> 9) & 0x7; 3836 fcp->isp_portid = portid; 3837 fcp->isp_loopstate = LOOP_HAVE_ADDR; 3838 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, 3839 rid.ridacq_vp_index, ISPASYNC_CHANGE_OTHER); 3840 } else { 3841 fcp->isp_loopstate = LOOP_NIL; 3842 isp_async(isp, ISPASYNC_LOOP_DOWN, 3843 rid.ridacq_vp_index); 3844 } 3845 } 3846 } 3847 3848 static void 3849 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs) 3850 { 3851 int ru_marked, sv_marked; 3852 int chan = XS_CHANNEL(xs); 3853 3854 switch (sp->req_completion_status) { 3855 case RQCS_COMPLETE: 3856 return; 3857 3858 case RQCS_DMA_ERROR: 3859 isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error"); 3860 if (XS_NOERR(xs)) 3861 XS_SETERR(xs, HBA_BOTCH); 3862 break; 3863 3864 case RQCS_TRANSPORT_ERROR: 3865 isp_xs_prt(isp, xs, ISP_LOGERR, "Transport Error"); 3866 if (XS_NOERR(xs)) 3867 XS_SETERR(xs, HBA_BOTCH); 3868 break; 3869 3870 case RQCS_RESET_OCCURRED: 3871 isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command"); 3872 FCPARAM(isp, chan)->sendmarker = 1; 3873 if (XS_NOERR(xs)) 3874 XS_SETERR(xs, HBA_BUSRESET); 3875 return; 3876 3877 case RQCS_ABORTED: 3878 isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted"); 3879 FCPARAM(isp, chan)->sendmarker = 1; 3880 if (XS_NOERR(xs)) 3881 XS_SETERR(xs, HBA_ABORTED); 3882 return; 3883 3884 case RQCS_TIMEOUT: 3885 isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out"); 3886 if (XS_NOERR(xs)) 3887 XS_SETERR(xs, HBA_CMDTIMEOUT); 3888 return; 3889 3890 case RQCS_DATA_OVERRUN: 3891 XS_SET_RESID(xs, sp->req_resid); 3892 isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun"); 3893 if (XS_NOERR(xs)) 3894 XS_SETERR(xs, HBA_DATAOVR); 3895 return; 3896 3897 case RQCS_DRE: /* data reassembly error */ 3898 isp_prt(isp, ISP_LOGERR, "Chan %d data reassembly error for target %d", chan, XS_TGT(xs)); 3899 if (XS_NOERR(xs)) 3900 XS_SETERR(xs, HBA_BOTCH); 3901 return; 3902 3903 case RQCS_TABORT: /* aborted by target */ 3904 isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS", chan, XS_TGT(xs)); 3905 if (XS_NOERR(xs)) 3906 XS_SETERR(xs, HBA_ABORTED); 3907 return; 3908 3909 case RQCS_DATA_UNDERRUN: 3910 ru_marked = (sp->req_scsi_status & RQCS_RU) != 0; 3911 /* 3912 * We can get an underrun w/o things being marked 3913 * if we got a non-zero status. 3914 */ 3915 sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0; 3916 if ((ru_marked == 0 && sv_marked == 0) || 3917 (sp->req_resid > XS_XFRLEN(xs))) { 3918 isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked"); 3919 if (XS_NOERR(xs)) 3920 XS_SETERR(xs, HBA_BOTCH); 3921 return; 3922 } 3923 XS_SET_RESID(xs, sp->req_resid); 3924 isp_xs_prt(isp, xs, ISP_LOG_WARN1, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff); 3925 return; 3926 3927 case RQCS_PORT_UNAVAILABLE: 3928 /* 3929 * No such port on the loop. Moral equivalent of SELTIMEO 3930 */ 3931 case RQCS_PORT_LOGGED_OUT: 3932 { 3933 const char *reason; 3934 uint8_t sts = sp->req_completion_status & 0xff; 3935 fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs)); 3936 fcportdb_t *lp; 3937 3938 /* 3939 * It was there (maybe)- treat as a selection timeout. 3940 */ 3941 if (sts == RQCS_PORT_UNAVAILABLE) { 3942 reason = "unavailable"; 3943 } else { 3944 reason = "logout"; 3945 } 3946 3947 isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d", 3948 chan, reason, XS_TGT(xs)); 3949 3950 /* XXX: Should we trigger rescan or FW announce change? */ 3951 3952 if (XS_NOERR(xs)) { 3953 lp = &fcp->portdb[XS_TGT(xs)]; 3954 if (lp->state == FC_PORTDB_STATE_ZOMBIE) { 3955 *XS_STSP(xs) = SCSI_BUSY; 3956 XS_SETERR(xs, HBA_TGTBSY); 3957 } else 3958 XS_SETERR(xs, HBA_SELTIMEOUT); 3959 } 3960 return; 3961 } 3962 case RQCS_PORT_CHANGED: 3963 isp_prt(isp, ISP_LOGWARN, "port changed for target %d chan %d", XS_TGT(xs), chan); 3964 if (XS_NOERR(xs)) { 3965 *XS_STSP(xs) = SCSI_BUSY; 3966 XS_SETERR(xs, HBA_TGTBSY); 3967 } 3968 return; 3969 3970 case RQCS_ENOMEM: /* f/w resource unavailable */ 3971 isp_prt(isp, ISP_LOGWARN, "f/w resource unavailable for target %d chan %d", XS_TGT(xs), chan); 3972 if (XS_NOERR(xs)) { 3973 *XS_STSP(xs) = SCSI_BUSY; 3974 XS_SETERR(xs, HBA_TGTBSY); 3975 } 3976 return; 3977 3978 case RQCS_TMO: /* task management overrun */ 3979 isp_prt(isp, ISP_LOGWARN, "command for target %d overlapped task management for chan %d", XS_TGT(xs), chan); 3980 if (XS_NOERR(xs)) { 3981 *XS_STSP(xs) = SCSI_BUSY; 3982 XS_SETERR(xs, HBA_TGTBSY); 3983 } 3984 return; 3985 3986 default: 3987 isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x on chan %d", sp->req_completion_status, chan); 3988 break; 3989 } 3990 if (XS_NOERR(xs)) 3991 XS_SETERR(xs, HBA_BOTCH); 3992 } 3993 3994 #define ISP_FC_IBITS(op) ((mbpfc[((op)<<3) + 0] << 24) | (mbpfc[((op)<<3) + 1] << 16) | (mbpfc[((op)<<3) + 2] << 8) | (mbpfc[((op)<<3) + 3])) 3995 #define ISP_FC_OBITS(op) ((mbpfc[((op)<<3) + 4] << 24) | (mbpfc[((op)<<3) + 5] << 16) | (mbpfc[((op)<<3) + 6] << 8) | (mbpfc[((op)<<3) + 7])) 3996 3997 #define ISP_FC_OPMAP(in0, out0) 0, 0, 0, in0, 0, 0, 0, out0 3998 #define ISP_FC_OPMAP_HALF(in1, in0, out1, out0) 0, 0, in1, in0, 0, 0, out1, out0 3999 #define ISP_FC_OPMAP_FULL(in3, in2, in1, in0, out3, out2, out1, out0) in3, in2, in1, in0, out3, out2, out1, out0 4000 static const uint32_t mbpfc[] = { 4001 ISP_FC_OPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */ 4002 ISP_FC_OPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */ 4003 ISP_FC_OPMAP_HALF(0x07, 0xff, 0x00, 0x1f), /* 0x02: MBOX_EXEC_FIRMWARE */ 4004 ISP_FC_OPMAP(0x01, 0x07), /* 0x03: MBOX_LOAD_FLASH_FIRMWARE */ 4005 ISP_FC_OPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */ 4006 ISP_FC_OPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */ 4007 ISP_FC_OPMAP_FULL(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff), /* 0x06: MBOX_MAILBOX_REG_TEST */ 4008 ISP_FC_OPMAP(0x07, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */ 4009 ISP_FC_OPMAP_FULL(0x0, 0x0, 0x0, 0x01, 0x0, 0x3, 0x80, 0x7f), /* 0x08: MBOX_ABOUT_FIRMWARE */ 4010 ISP_FC_OPMAP(0xdf, 0x01), /* 0x09: MBOX_LOAD_RISC_RAM_2100 */ 4011 ISP_FC_OPMAP(0xdf, 0x01), /* 0x0a: MBOX_DUMP_RISC_RAM_2100 */ 4012 ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x01), /* 0x0b: MBOX_LOAD_RISC_RAM */ 4013 ISP_FC_OPMAP(0x00, 0x00), /* 0x0c: */ 4014 ISP_FC_OPMAP_HALF(0x1, 0x0f, 0x0, 0x01), /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */ 4015 ISP_FC_OPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */ 4016 ISP_FC_OPMAP_HALF(0x1, 0x03, 0x0, 0x0d), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */ 4017 ISP_FC_OPMAP(0x1f, 0x11), /* 0x10: MBOX_INIT_REQ_QUEUE */ 4018 ISP_FC_OPMAP(0x2f, 0x21), /* 0x11: MBOX_INIT_RES_QUEUE */ 4019 ISP_FC_OPMAP(0x0f, 0x01), /* 0x12: MBOX_EXECUTE_IOCB */ 4020 ISP_FC_OPMAP(0x03, 0x03), /* 0x13: MBOX_WAKE_UP */ 4021 ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x03), /* 0x14: MBOX_STOP_FIRMWARE */ 4022 ISP_FC_OPMAP(0x4f, 0x01), /* 0x15: MBOX_ABORT */ 4023 ISP_FC_OPMAP(0x07, 0x01), /* 0x16: MBOX_ABORT_DEVICE */ 4024 ISP_FC_OPMAP(0x07, 0x01), /* 0x17: MBOX_ABORT_TARGET */ 4025 ISP_FC_OPMAP(0x03, 0x03), /* 0x18: MBOX_BUS_RESET */ 4026 ISP_FC_OPMAP(0x07, 0x05), /* 0x19: MBOX_STOP_QUEUE */ 4027 ISP_FC_OPMAP(0x07, 0x05), /* 0x1a: MBOX_START_QUEUE */ 4028 ISP_FC_OPMAP(0x07, 0x05), /* 0x1b: MBOX_SINGLE_STEP_QUEUE */ 4029 ISP_FC_OPMAP(0x07, 0x05), /* 0x1c: MBOX_ABORT_QUEUE */ 4030 ISP_FC_OPMAP(0x07, 0x03), /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */ 4031 ISP_FC_OPMAP(0x00, 0x00), /* 0x1e: */ 4032 ISP_FC_OPMAP(0x01, 0x07), /* 0x1f: MBOX_GET_FIRMWARE_STATUS */ 4033 ISP_FC_OPMAP_HALF(0x2, 0x01, 0x7e, 0xcf), /* 0x20: MBOX_GET_LOOP_ID */ 4034 ISP_FC_OPMAP(0x00, 0x00), /* 0x21: */ 4035 ISP_FC_OPMAP(0x03, 0x4b), /* 0x22: MBOX_GET_TIMEOUT_PARAMS */ 4036 ISP_FC_OPMAP(0x00, 0x00), /* 0x23: */ 4037 ISP_FC_OPMAP(0x00, 0x00), /* 0x24: */ 4038 ISP_FC_OPMAP(0x00, 0x00), /* 0x25: */ 4039 ISP_FC_OPMAP(0x00, 0x00), /* 0x26: */ 4040 ISP_FC_OPMAP(0x00, 0x00), /* 0x27: */ 4041 ISP_FC_OPMAP(0x01, 0x03), /* 0x28: MBOX_GET_FIRMWARE_OPTIONS */ 4042 ISP_FC_OPMAP(0x03, 0x07), /* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */ 4043 ISP_FC_OPMAP(0x00, 0x00), /* 0x2a: */ 4044 ISP_FC_OPMAP(0x00, 0x00), /* 0x2b: */ 4045 ISP_FC_OPMAP(0x00, 0x00), /* 0x2c: */ 4046 ISP_FC_OPMAP(0x00, 0x00), /* 0x2d: */ 4047 ISP_FC_OPMAP(0x00, 0x00), /* 0x2e: */ 4048 ISP_FC_OPMAP(0x00, 0x00), /* 0x2f: */ 4049 ISP_FC_OPMAP(0x00, 0x00), /* 0x30: */ 4050 ISP_FC_OPMAP(0x00, 0x00), /* 0x31: */ 4051 ISP_FC_OPMAP(0x4b, 0x4b), /* 0x32: MBOX_SET_TIMEOUT_PARAMS */ 4052 ISP_FC_OPMAP(0x00, 0x00), /* 0x33: */ 4053 ISP_FC_OPMAP(0x00, 0x00), /* 0x34: */ 4054 ISP_FC_OPMAP(0x00, 0x00), /* 0x35: */ 4055 ISP_FC_OPMAP(0x00, 0x00), /* 0x36: */ 4056 ISP_FC_OPMAP(0x00, 0x00), /* 0x37: */ 4057 ISP_FC_OPMAP(0x0f, 0x01), /* 0x38: MBOX_SET_FIRMWARE_OPTIONS */ 4058 ISP_FC_OPMAP(0x0f, 0x07), /* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */ 4059 ISP_FC_OPMAP(0x00, 0x00), /* 0x3a: */ 4060 ISP_FC_OPMAP(0x00, 0x00), /* 0x3b: */ 4061 ISP_FC_OPMAP(0x00, 0x00), /* 0x3c: */ 4062 ISP_FC_OPMAP(0x00, 0x00), /* 0x3d: */ 4063 ISP_FC_OPMAP(0x00, 0x00), /* 0x3e: */ 4064 ISP_FC_OPMAP(0x00, 0x00), /* 0x3f: */ 4065 ISP_FC_OPMAP(0x03, 0x01), /* 0x40: MBOX_LOOP_PORT_BYPASS */ 4066 ISP_FC_OPMAP(0x03, 0x01), /* 0x41: MBOX_LOOP_PORT_ENABLE */ 4067 ISP_FC_OPMAP_HALF(0x0, 0x01, 0x1f, 0xcf), /* 0x42: MBOX_GET_RESOURCE_COUNT */ 4068 ISP_FC_OPMAP(0x01, 0x01), /* 0x43: MBOX_REQUEST_OFFLINE_MODE */ 4069 ISP_FC_OPMAP(0x00, 0x00), /* 0x44: */ 4070 ISP_FC_OPMAP(0x00, 0x00), /* 0x45: */ 4071 ISP_FC_OPMAP(0x00, 0x00), /* 0x46: */ 4072 ISP_FC_OPMAP(0xcf, 0x03), /* 0x47: GET PORT_DATABASE ENHANCED */ 4073 ISP_FC_OPMAP(0xcf, 0x0f), /* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */ 4074 ISP_FC_OPMAP(0xcd, 0x01), /* 0x49: MBOX_GET_VP_DATABASE */ 4075 ISP_FC_OPMAP_HALF(0x2, 0xcd, 0x0, 0x01), /* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */ 4076 ISP_FC_OPMAP(0x00, 0x00), /* 0x4b: */ 4077 ISP_FC_OPMAP(0x00, 0x00), /* 0x4c: */ 4078 ISP_FC_OPMAP(0x00, 0x00), /* 0x4d: */ 4079 ISP_FC_OPMAP(0x00, 0x00), /* 0x4e: */ 4080 ISP_FC_OPMAP(0x00, 0x00), /* 0x4f: */ 4081 ISP_FC_OPMAP(0x00, 0x00), /* 0x50: */ 4082 ISP_FC_OPMAP(0x00, 0x00), /* 0x51: */ 4083 ISP_FC_OPMAP(0x00, 0x00), /* 0x52: */ 4084 ISP_FC_OPMAP(0x00, 0x00), /* 0x53: */ 4085 ISP_FC_OPMAP(0xcf, 0x01), /* 0x54: EXECUTE IOCB A64 */ 4086 ISP_FC_OPMAP(0x00, 0x00), /* 0x55: */ 4087 ISP_FC_OPMAP(0x00, 0x00), /* 0x56: */ 4088 ISP_FC_OPMAP(0x00, 0x00), /* 0x57: */ 4089 ISP_FC_OPMAP(0x00, 0x00), /* 0x58: */ 4090 ISP_FC_OPMAP(0x00, 0x00), /* 0x59: */ 4091 ISP_FC_OPMAP(0x00, 0x00), /* 0x5a: */ 4092 ISP_FC_OPMAP(0x03, 0x01), /* 0x5b: MBOX_DRIVER_HEARTBEAT */ 4093 ISP_FC_OPMAP(0xcf, 0x01), /* 0x5c: MBOX_FW_HEARTBEAT */ 4094 ISP_FC_OPMAP(0x07, 0x1f), /* 0x5d: MBOX_GET_SET_DATA_RATE */ 4095 ISP_FC_OPMAP(0x00, 0x00), /* 0x5e: */ 4096 ISP_FC_OPMAP(0x00, 0x00), /* 0x5f: */ 4097 ISP_FC_OPMAP(0xcf, 0x0f), /* 0x60: MBOX_INIT_FIRMWARE */ 4098 ISP_FC_OPMAP(0x00, 0x00), /* 0x61: */ 4099 ISP_FC_OPMAP(0x01, 0x01), /* 0x62: MBOX_INIT_LIP */ 4100 ISP_FC_OPMAP(0xcd, 0x03), /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */ 4101 ISP_FC_OPMAP(0xcf, 0x01), /* 0x64: MBOX_GET_PORT_DB */ 4102 ISP_FC_OPMAP(0x07, 0x01), /* 0x65: MBOX_CLEAR_ACA */ 4103 ISP_FC_OPMAP(0x07, 0x01), /* 0x66: MBOX_TARGET_RESET */ 4104 ISP_FC_OPMAP(0x07, 0x01), /* 0x67: MBOX_CLEAR_TASK_SET */ 4105 ISP_FC_OPMAP(0x07, 0x01), /* 0x68: MBOX_ABORT_TASK_SET */ 4106 ISP_FC_OPMAP_HALF(0x00, 0x01, 0x0f, 0x1f), /* 0x69: MBOX_GET_FW_STATE */ 4107 ISP_FC_OPMAP_HALF(0x6, 0x03, 0x0, 0xcf), /* 0x6a: MBOX_GET_PORT_NAME */ 4108 ISP_FC_OPMAP(0xcf, 0x01), /* 0x6b: MBOX_GET_LINK_STATUS */ 4109 ISP_FC_OPMAP(0x0f, 0x01), /* 0x6c: MBOX_INIT_LIP_RESET */ 4110 ISP_FC_OPMAP(0x00, 0x00), /* 0x6d: */ 4111 ISP_FC_OPMAP(0xcf, 0x03), /* 0x6e: MBOX_SEND_SNS */ 4112 ISP_FC_OPMAP(0x0f, 0x07), /* 0x6f: MBOX_FABRIC_LOGIN */ 4113 ISP_FC_OPMAP_HALF(0x02, 0x03, 0x00, 0x03), /* 0x70: MBOX_SEND_CHANGE_REQUEST */ 4114 ISP_FC_OPMAP(0x03, 0x03), /* 0x71: MBOX_FABRIC_LOGOUT */ 4115 ISP_FC_OPMAP(0x0f, 0x0f), /* 0x72: MBOX_INIT_LIP_LOGIN */ 4116 ISP_FC_OPMAP(0x00, 0x00), /* 0x73: */ 4117 ISP_FC_OPMAP(0x07, 0x01), /* 0x74: LOGIN LOOP PORT */ 4118 ISP_FC_OPMAP_HALF(0x03, 0xcf, 0x00, 0x07), /* 0x75: GET PORT/NODE NAME LIST */ 4119 ISP_FC_OPMAP(0x4f, 0x01), /* 0x76: SET VENDOR ID */ 4120 ISP_FC_OPMAP(0xcd, 0x01), /* 0x77: INITIALIZE IP MAILBOX */ 4121 ISP_FC_OPMAP(0x00, 0x00), /* 0x78: */ 4122 ISP_FC_OPMAP(0x00, 0x00), /* 0x79: */ 4123 ISP_FC_OPMAP(0x00, 0x00), /* 0x7a: */ 4124 ISP_FC_OPMAP(0x00, 0x00), /* 0x7b: */ 4125 ISP_FC_OPMAP_HALF(0x03, 0x4f, 0x00, 0x07), /* 0x7c: Get ID List */ 4126 ISP_FC_OPMAP(0xcf, 0x01), /* 0x7d: SEND LFA */ 4127 ISP_FC_OPMAP(0x0f, 0x01) /* 0x7e: LUN RESET */ 4128 }; 4129 #define MAX_FC_OPCODE 0x7e 4130 /* 4131 * Footnotes 4132 * 4133 * (1): this sets bits 21..16 in mailbox register #8, which we nominally 4134 * do not access at this time in the core driver. The caller is 4135 * responsible for setting this register first (Gross!). The assumption 4136 * is that we won't overflow. 4137 */ 4138 4139 static const char *fc_mbcmd_names[] = { 4140 "NO-OP", /* 00h */ 4141 "LOAD RAM", 4142 "EXEC FIRMWARE", 4143 "LOAD FLASH FIRMWARE", 4144 "WRITE RAM WORD", 4145 "READ RAM WORD", 4146 "MAILBOX REG TEST", 4147 "VERIFY CHECKSUM", 4148 "ABOUT FIRMWARE", 4149 "LOAD RAM (2100)", 4150 "DUMP RAM (2100)", 4151 "LOAD RISC RAM", 4152 "DUMP RISC RAM", 4153 "WRITE RAM WORD EXTENDED", 4154 "CHECK FIRMWARE", 4155 "READ RAM WORD EXTENDED", 4156 "INIT REQUEST QUEUE", /* 10h */ 4157 "INIT RESULT QUEUE", 4158 "EXECUTE IOCB", 4159 "WAKE UP", 4160 "STOP FIRMWARE", 4161 "ABORT", 4162 "ABORT DEVICE", 4163 "ABORT TARGET", 4164 "BUS RESET", 4165 "STOP QUEUE", 4166 "START QUEUE", 4167 "SINGLE STEP QUEUE", 4168 "ABORT QUEUE", 4169 "GET DEV QUEUE STATUS", 4170 NULL, 4171 "GET FIRMWARE STATUS", 4172 "GET LOOP ID", /* 20h */ 4173 NULL, 4174 "GET TIMEOUT PARAMS", 4175 NULL, 4176 NULL, 4177 NULL, 4178 NULL, 4179 NULL, 4180 "GET FIRMWARE OPTIONS", 4181 "GET PORT QUEUE PARAMS", 4182 "GENERATE SYSTEM ERROR", 4183 NULL, 4184 NULL, 4185 NULL, 4186 NULL, 4187 NULL, 4188 "WRITE SFP", /* 30h */ 4189 "READ SFP", 4190 "SET TIMEOUT PARAMS", 4191 NULL, 4192 NULL, 4193 NULL, 4194 NULL, 4195 NULL, 4196 "SET FIRMWARE OPTIONS", 4197 "SET PORT QUEUE PARAMS", 4198 NULL, 4199 "SET FC LED CONF", 4200 NULL, 4201 "RESTART NIC FIRMWARE", 4202 "ACCESS CONTROL", 4203 NULL, 4204 "LOOP PORT BYPASS", /* 40h */ 4205 "LOOP PORT ENABLE", 4206 "GET RESOURCE COUNT", 4207 "REQUEST NON PARTICIPATING MODE", 4208 "DIAGNOSTIC ECHO TEST", 4209 "DIAGNOSTIC LOOPBACK", 4210 NULL, 4211 "GET PORT DATABASE ENHANCED", 4212 "INIT FIRMWARE MULTI ID", 4213 "GET VP DATABASE", 4214 "GET VP DATABASE ENTRY", 4215 NULL, 4216 NULL, 4217 NULL, 4218 NULL, 4219 NULL, 4220 "GET FCF LIST", /* 50h */ 4221 "GET DCBX PARAMETERS", 4222 NULL, 4223 "HOST MEMORY COPY", 4224 "EXECUTE IOCB A64", 4225 NULL, 4226 NULL, 4227 "SEND RNID", 4228 NULL, 4229 "SET PARAMETERS", 4230 "GET PARAMETERS", 4231 "DRIVER HEARTBEAT", 4232 "FIRMWARE HEARTBEAT", 4233 "GET/SET DATA RATE", 4234 "SEND RNFT", 4235 NULL, 4236 "INIT FIRMWARE", /* 60h */ 4237 "GET INIT CONTROL BLOCK", 4238 "INIT LIP", 4239 "GET FC-AL POSITION MAP", 4240 "GET PORT DATABASE", 4241 "CLEAR ACA", 4242 "TARGET RESET", 4243 "CLEAR TASK SET", 4244 "ABORT TASK SET", 4245 "GET FW STATE", 4246 "GET PORT NAME", 4247 "GET LINK STATUS", 4248 "INIT LIP RESET", 4249 "GET LINK STATS & PRIVATE DATA CNTS", 4250 "SEND SNS", 4251 "FABRIC LOGIN", 4252 "SEND CHANGE REQUEST", /* 70h */ 4253 "FABRIC LOGOUT", 4254 "INIT LIP LOGIN", 4255 NULL, 4256 "LOGIN LOOP PORT", 4257 "GET PORT/NODE NAME LIST", 4258 "SET VENDOR ID", 4259 "INITIALIZE IP MAILBOX", 4260 NULL, 4261 NULL, 4262 "GET XGMAC STATS", 4263 NULL, 4264 "GET ID LIST", 4265 "SEND LFA", 4266 "LUN RESET" 4267 }; 4268 4269 static void 4270 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp) 4271 { 4272 const char *cname, *xname, *sname; 4273 char tname[16], mname[16]; 4274 unsigned int ibits, obits, box, opcode, t, to; 4275 4276 opcode = mbp->param[0]; 4277 if (opcode > MAX_FC_OPCODE) { 4278 mbp->param[0] = MBOX_INVALID_COMMAND; 4279 isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode); 4280 return; 4281 } 4282 cname = fc_mbcmd_names[opcode]; 4283 ibits = ISP_FC_IBITS(opcode); 4284 obits = ISP_FC_OBITS(opcode); 4285 if (cname == NULL) { 4286 cname = tname; 4287 ISP_SNPRINTF(tname, sizeof(tname), "opcode %x", opcode); 4288 } 4289 isp_prt(isp, ISP_LOGDEBUG3, "Mailbox Command '%s'", cname); 4290 4291 /* 4292 * Pick up any additional bits that the caller might have set. 4293 */ 4294 ibits |= mbp->ibits; 4295 obits |= mbp->obits; 4296 4297 /* 4298 * Mask any bits that the caller wants us to mask 4299 */ 4300 ibits &= mbp->ibitm; 4301 obits &= mbp->obitm; 4302 4303 4304 if (ibits == 0 && obits == 0) { 4305 mbp->param[0] = MBOX_COMMAND_PARAM_ERROR; 4306 isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode); 4307 return; 4308 } 4309 4310 for (box = 0; box < ISP_NMBOX(isp); box++) { 4311 if (ibits & (1 << box)) { 4312 isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box, 4313 mbp->param[box]); 4314 ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]); 4315 } 4316 isp->isp_mboxtmp[box] = mbp->param[box] = 0; 4317 } 4318 4319 isp->isp_obits = obits; 4320 isp->isp_mboxbsy = 1; 4321 4322 /* 4323 * Set Host Interrupt condition so that RISC will pick up mailbox regs. 4324 */ 4325 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT); 4326 4327 /* 4328 * While we haven't finished the command, spin our wheels here. 4329 */ 4330 to = (mbp->timeout == 0) ? MBCMD_DEFAULT_TIMEOUT : mbp->timeout; 4331 for (t = 0; t < to; t += 100) { 4332 if (!isp->isp_mboxbsy) 4333 break; 4334 ISP_RUN_ISR(isp); 4335 if (!isp->isp_mboxbsy) 4336 break; 4337 ISP_DELAY(100); 4338 } 4339 4340 /* 4341 * Did the command time out? 4342 */ 4343 if (isp->isp_mboxbsy) { 4344 isp->isp_mboxbsy = 0; 4345 isp_prt(isp, ISP_LOGWARN, "Mailbox Command (0x%x) Timeout (%uus) (%s:%d)", 4346 opcode, to, mbp->func, mbp->lineno); 4347 mbp->param[0] = MBOX_TIMEOUT; 4348 goto out; 4349 } 4350 4351 /* 4352 * Copy back output registers. 4353 */ 4354 for (box = 0; box < ISP_NMBOX(isp); box++) { 4355 if (obits & (1 << box)) { 4356 mbp->param[box] = isp->isp_mboxtmp[box]; 4357 isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box, 4358 mbp->param[box]); 4359 } 4360 } 4361 4362 out: 4363 if (mbp->logval == 0 || mbp->param[0] == MBOX_COMMAND_COMPLETE) 4364 return; 4365 4366 if ((mbp->param[0] & 0xbfe0) == 0 && 4367 (mbp->logval & MBLOGMASK(mbp->param[0])) == 0) 4368 return; 4369 4370 xname = NULL; 4371 sname = ""; 4372 switch (mbp->param[0]) { 4373 case MBOX_INVALID_COMMAND: 4374 xname = "INVALID COMMAND"; 4375 break; 4376 case MBOX_HOST_INTERFACE_ERROR: 4377 xname = "HOST INTERFACE ERROR"; 4378 break; 4379 case MBOX_TEST_FAILED: 4380 xname = "TEST FAILED"; 4381 break; 4382 case MBOX_COMMAND_ERROR: 4383 xname = "COMMAND ERROR"; 4384 ISP_SNPRINTF(mname, sizeof(mname), " subcode 0x%x", 4385 mbp->param[1]); 4386 sname = mname; 4387 break; 4388 case MBOX_COMMAND_PARAM_ERROR: 4389 xname = "COMMAND PARAMETER ERROR"; 4390 break; 4391 case MBOX_PORT_ID_USED: 4392 xname = "PORT ID ALREADY IN USE"; 4393 break; 4394 case MBOX_LOOP_ID_USED: 4395 xname = "LOOP ID ALREADY IN USE"; 4396 break; 4397 case MBOX_ALL_IDS_USED: 4398 xname = "ALL LOOP IDS IN USE"; 4399 break; 4400 case MBOX_NOT_LOGGED_IN: 4401 xname = "NOT LOGGED IN"; 4402 break; 4403 case MBOX_LINK_DOWN_ERROR: 4404 xname = "LINK DOWN ERROR"; 4405 break; 4406 case MBOX_LOOPBACK_ERROR: 4407 xname = "LOOPBACK ERROR"; 4408 break; 4409 case MBOX_CHECKSUM_ERROR: 4410 xname = "CHECKSUM ERROR"; 4411 break; 4412 case MBOX_INVALID_PRODUCT_KEY: 4413 xname = "INVALID PRODUCT KEY"; 4414 break; 4415 case MBOX_REGS_BUSY: 4416 xname = "REGISTERS BUSY"; 4417 break; 4418 case MBOX_TIMEOUT: 4419 xname = "TIMEOUT"; 4420 break; 4421 default: 4422 ISP_SNPRINTF(mname, sizeof(mname), "error 0x%x", mbp->param[0]); 4423 xname = mname; 4424 break; 4425 } 4426 if (xname) { 4427 isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s%s)", 4428 cname, xname, sname); 4429 } 4430 } 4431 4432 static int 4433 isp_fw_state(ispsoftc_t *isp, int chan) 4434 { 4435 mbreg_t mbs; 4436 4437 MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0); 4438 isp_mboxcmd(isp, &mbs); 4439 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) 4440 return (mbs.param[1]); 4441 return (FW_ERROR); 4442 } 4443 4444 static void 4445 isp_setdfltfcparm(ispsoftc_t *isp, int chan) 4446 { 4447 fcparam *fcp = FCPARAM(isp, chan); 4448 4449 /* 4450 * Establish some default parameters. 4451 */ 4452 fcp->role = DEFAULT_ROLE(isp, chan); 4453 fcp->isp_retry_delay = ICB_DFLT_RDELAY; 4454 fcp->isp_retry_count = ICB_DFLT_RCOUNT; 4455 fcp->isp_loopid = DEFAULT_LOOPID(isp, chan); 4456 fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan); 4457 fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan); 4458 fcp->isp_fwoptions = 0; 4459 fcp->isp_xfwoptions = 0; 4460 fcp->isp_zfwoptions = 0; 4461 fcp->isp_lasthdl = NIL_HANDLE; 4462 fcp->isp_login_hdl = NIL_HANDLE; 4463 4464 fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS; 4465 fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS; 4466 if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) 4467 fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX; 4468 fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS; 4469 fcp->isp_xfwoptions |= ICB2400_OPT2_LOOP_2_PTP; 4470 fcp->isp_zfwoptions |= ICB2400_OPT3_RATE_AUTO; 4471 4472 /* 4473 * Now try and read NVRAM unless told to not do so. 4474 * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram. 4475 */ 4476 if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) { 4477 int i, j = 0; 4478 /* 4479 * Give a couple of tries at reading NVRAM. 4480 */ 4481 for (i = 0; i < 2; i++) { 4482 j = isp_read_nvram(isp); 4483 if (j == 0) { 4484 break; 4485 } 4486 } 4487 if (j) { 4488 isp->isp_confopts |= ISP_CFG_NONVRAM; 4489 } 4490 } 4491 4492 fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan); 4493 fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan); 4494 isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s", 4495 chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn), 4496 (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn), 4497 isp_class3_roles[fcp->role]); 4498 } 4499 4500 /* 4501 * Re-initialize the ISP and complete all orphaned commands 4502 * with a 'botched' notice. The reset/init routines should 4503 * not disturb an already active list of commands. 4504 */ 4505 4506 int 4507 isp_reinit(ispsoftc_t *isp, int do_load_defaults) 4508 { 4509 int i, res = 0; 4510 4511 if (isp->isp_state > ISP_RESETSTATE) 4512 isp_stop(isp); 4513 if (isp->isp_state != ISP_RESETSTATE) 4514 isp_reset(isp, do_load_defaults); 4515 if (isp->isp_state != ISP_RESETSTATE) { 4516 res = EIO; 4517 isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__); 4518 goto cleanup; 4519 } 4520 4521 isp_init(isp); 4522 if (isp->isp_state > ISP_RESETSTATE && 4523 isp->isp_state != ISP_RUNSTATE) { 4524 res = EIO; 4525 isp_prt(isp, ISP_LOGERR, "%s: cannot init card", __func__); 4526 ISP_DISABLE_INTS(isp); 4527 } 4528 4529 cleanup: 4530 isp_clear_commands(isp); 4531 for (i = 0; i < isp->isp_nchan; i++) 4532 isp_clear_portdb(isp, i); 4533 return (res); 4534 } 4535 4536 /* 4537 * NVRAM Routines 4538 */ 4539 static inline uint32_t 4540 flash_data_addr(ispsoftc_t *isp, uint32_t faddr) 4541 { 4542 fcparam *fcp = FCPARAM(isp, 0); 4543 4544 return (fcp->flash_data_addr + faddr); 4545 } 4546 4547 static int 4548 isp_read_flash_dword(ispsoftc_t *isp, uint32_t addr, uint32_t *data) 4549 { 4550 int loops = 0; 4551 4552 ISP_WRITE(isp, BIU2400_FLASH_ADDR, addr & ~0x80000000); 4553 for (loops = 0; loops < 30000; loops++) { 4554 if (ISP_READ(isp, BIU2400_FLASH_ADDR & 0x80000000)) { 4555 *data = ISP_READ(isp, BIU2400_FLASH_DATA); 4556 return (ISP_SUCCESS); 4557 } 4558 ISP_DELAY(10); 4559 } 4560 isp_prt(isp, ISP_LOGERR, 4561 "Flash read dword at 0x%x timeout.", addr); 4562 *data = 0xffffffff; 4563 return (ISP_FUNCTION_TIMEOUT); 4564 } 4565 4566 static int 4567 isp_read_flash_data(ispsoftc_t *isp, uint32_t *dwptr, uint32_t faddr, uint32_t dwords) 4568 { 4569 int loops = 0; 4570 int rval = ISP_SUCCESS; 4571 4572 /* Dword reads to flash. */ 4573 faddr = flash_data_addr(isp, faddr); 4574 for (loops = 0; loops < dwords; loops++, faddr++, dwptr++) { 4575 rval = isp_read_flash_dword(isp, faddr, dwptr); 4576 if (rval != ISP_SUCCESS) 4577 break; 4578 *dwptr = htole32(*dwptr); 4579 } 4580 4581 return (rval); 4582 } 4583 4584 static void 4585 isp_rd_2xxx_flash(ispsoftc_t *isp, uint32_t addr, uint32_t *rp) 4586 { 4587 fcparam *fcp = FCPARAM(isp, 0); 4588 int loops = 0; 4589 uint32_t base = fcp->flash_data_addr; 4590 4591 ISP_WRITE(isp, BIU2400_FLASH_ADDR, (base + addr) & ~0x80000000); 4592 for (loops = 0; loops < 30000; loops++) { 4593 ISP_DELAY(10); 4594 if (ISP_READ(isp, BIU2400_FLASH_ADDR & 0x80000000)) { 4595 *rp = ISP_READ(isp, BIU2400_FLASH_DATA); 4596 ISP_SWIZZLE_NVRAM_LONG(isp, rp); 4597 return; 4598 } 4599 } 4600 isp_prt(isp, ISP_LOGERR, 4601 "Flash read dword at 0x%x timeout.", (base + addr)); 4602 *rp = 0xffffffff; 4603 } 4604 4605 static int 4606 isp_read_flthdr_2xxx(ispsoftc_t *isp) 4607 { 4608 fcparam *fcp = FCPARAM(isp, 0); 4609 int retval = 0; 4610 uint32_t addr, lwrds, *dptr; 4611 uint16_t csum; 4612 uint8_t flthdr_data[FLT_HEADER_SIZE]; 4613 4614 addr = fcp->flt_region_flt; 4615 dptr = (uint32_t *) flthdr_data; 4616 4617 isp_prt(isp, ISP_LOGDEBUG0, "FLTL[DEF]: 0x%x", addr); 4618 for (lwrds = 0; lwrds < FLT_HEADER_SIZE >> 2; lwrds++) { 4619 isp_rd_2xxx_flash(isp, addr++, dptr++); 4620 } 4621 dptr = (uint32_t *) flthdr_data; 4622 for (csum = 0, lwrds = 0; lwrds < FLT_HEADER_SIZE >> 4; lwrds++) { 4623 uint16_t tmp; 4624 ISP_IOXGET_16(isp, &dptr[lwrds], tmp); 4625 csum += tmp; 4626 } 4627 if (csum != 0) { 4628 retval = -1; 4629 goto out; 4630 } 4631 isp_parse_flthdr_2xxx(isp, flthdr_data); 4632 out: 4633 return (retval); 4634 } 4635 4636 static void 4637 isp_parse_flthdr_2xxx(ispsoftc_t *isp, uint8_t *flthdr_data) 4638 { 4639 fcparam *fcp = FCPARAM(isp, 0); 4640 uint16_t ver, csum; 4641 4642 ver = le16toh((uint16_t) (ISP2XXX_FLT_VERSION(flthdr_data))); 4643 fcp->flt_length = le16toh((uint16_t) (ISP2XXX_FLT_LENGTH(flthdr_data))); 4644 csum = le16toh((uint16_t) (ISP2XXX_FLT_CSUM(flthdr_data))); 4645 4646 if ((fcp->flt_length == 0) || 4647 (fcp->flt_length > (FLT_HEADER_SIZE + FLT_REGIONS_SIZE))) { 4648 isp_prt(isp, ISP_LOGERR, 4649 "FLT[DEF]: Invalid length=0x%x(%d)", 4650 fcp->flt_length, fcp->flt_length); 4651 } 4652 isp_prt(isp, ISP_LOGDEBUG0, 4653 "FLT[DEF]: version=0x%x length=0x%x(%d) checksum=0x%x", 4654 ver, fcp->flt_length, fcp->flt_length, csum); 4655 } 4656 4657 static int 4658 isp_read_flt_2xxx(ispsoftc_t *isp) 4659 { 4660 fcparam *fcp = FCPARAM(isp, 0); 4661 int retval = 0; 4662 int len = fcp->flt_length - FLT_HEADER_SIZE; 4663 uint32_t addr, lwrds, *dptr; 4664 uint8_t flt_data[len]; 4665 fcp->flt_region_entries = len / FLT_REGION_SIZE; 4666 4667 addr = fcp->flt_region_flt + (FLT_HEADER_SIZE >> 2); 4668 dptr = (uint32_t *) flt_data; 4669 isp_prt(isp, ISP_LOGDEBUG0, "FLT[DEF]: regions=%d", 4670 fcp->flt_region_entries); 4671 for (lwrds = 0; lwrds < len >> 2; lwrds++) { 4672 isp_rd_2xxx_flash(isp, addr++, dptr++); 4673 } 4674 retval = isp_parse_flt_2xxx(isp, flt_data); 4675 return (retval); 4676 } 4677 4678 static int 4679 isp_parse_flt_2xxx(ispsoftc_t *isp, uint8_t *flt_data) 4680 { 4681 fcparam *fcp = FCPARAM(isp, 0); 4682 int count; 4683 struct flt_region region[fcp->flt_region_entries]; 4684 4685 for (count = 0; count < fcp->flt_region_entries; count++) { 4686 region[count].code = 4687 le16toh((uint16_t) (ISP2XXX_FLT_REG_CODE(flt_data, count))); 4688 region[count].attribute = 4689 (uint8_t) (ISP2XXX_FLT_REG_ATTR(flt_data, count)); 4690 region[count].reserved = 4691 (uint8_t) (ISP2XXX_FLT_REG_RES(flt_data, count)); 4692 region[count].size = 4693 le32toh((uint32_t) (ISP2XXX_FLT_REG_SIZE(flt_data, count)) >> 2); 4694 region[count].start = 4695 le32toh((uint32_t) (ISP2XXX_FLT_REG_START(flt_data, count)) >> 2); 4696 region[count].end = 4697 le32toh((uint32_t) (ISP2XXX_FLT_REG_END(flt_data, count)) >> 2); 4698 4699 isp_prt(isp, ISP_LOGDEBUG0, 4700 "FLT[0x%x]: start=0x%x end=0x%x size=0x%x attribute=0x%x", 4701 region[count].code, region[count].start, region[count].end, 4702 region[count].size, region[count].attribute); 4703 4704 switch (region[count].code) { 4705 case FLT_REG_FW: 4706 fcp->flt_region_fw = region[count].start; 4707 break; 4708 case FLT_REG_BOOT_CODE: 4709 fcp->flt_region_boot = region[count].start; 4710 break; 4711 case FLT_REG_VPD_0: 4712 fcp->flt_region_vpd_nvram = region[count].start; 4713 if (isp->isp_port == 0) 4714 fcp->flt_region_vpd = region[count].start; 4715 break; 4716 case FLT_REG_VPD_1: 4717 if (isp->isp_port == 1) 4718 fcp->flt_region_vpd = region[count].start; 4719 break; 4720 case FLT_REG_VPD_2: 4721 if (!IS_27XX(isp)) 4722 break; 4723 if (isp->isp_port == 2) 4724 fcp->flt_region_vpd = region[count].start; 4725 break; 4726 case FLT_REG_VPD_3: 4727 if (!IS_27XX(isp)) 4728 break; 4729 if (isp->isp_port == 3) 4730 fcp->flt_region_vpd = region[count].start; 4731 break; 4732 case FLT_REG_NVRAM_0: 4733 if (isp->isp_port == 0) 4734 fcp->flt_region_nvram = region[count].start; 4735 break; 4736 case FLT_REG_NVRAM_1: 4737 if (isp->isp_port == 1) 4738 fcp->flt_region_nvram = region[count].start; 4739 break; 4740 case FLT_REG_NVRAM_2: 4741 if (!IS_27XX(isp)) 4742 break; 4743 if (isp->isp_port == 2) 4744 fcp->flt_region_nvram = region[count].start; 4745 break; 4746 case FLT_REG_NVRAM_3: 4747 if (!IS_27XX(isp)) 4748 break; 4749 if (isp->isp_port == 3) 4750 fcp->flt_region_nvram = region[count].start; 4751 break; 4752 case FLT_REG_FDT: 4753 fcp->flt_region_fdt = region[count].start; 4754 break; 4755 case FLT_REG_FLT: 4756 fcp->flt_region_flt = region[count].start; 4757 break; 4758 case FLT_REG_NPIV_CONF_0: 4759 if (isp->isp_port == 0) 4760 fcp->flt_region_npiv_conf = region[count].start; 4761 break; 4762 case FLT_REG_NPIV_CONF_1: 4763 if (isp->isp_port == 1) 4764 fcp->flt_region_npiv_conf = region[count].start; 4765 break; 4766 case FLT_REG_GOLD_FW: 4767 fcp->flt_region_gold_fw = region[count].start; 4768 break; 4769 case FLT_REG_FCP_PRIO_0: 4770 if (isp->isp_port == 0) 4771 fcp->flt_region_fcp_prio = region[count].start; 4772 break; 4773 case FLT_REG_FCP_PRIO_1: 4774 if (isp->isp_port == 1) 4775 fcp->flt_region_fcp_prio = region[count].start; 4776 break; 4777 case FLT_REG_IMG_PRI_27XX: 4778 if (IS_27XX(isp)) 4779 fcp->flt_region_img_status_pri = region[count].start; 4780 break; 4781 case FLT_REG_IMG_SEC_27XX: 4782 if (IS_27XX(isp)) 4783 fcp->flt_region_img_status_sec = region[count].start; 4784 break; 4785 case FLT_REG_FW_SEC_27XX: 4786 if (IS_27XX(isp)) 4787 fcp->flt_region_fw_sec = region[count].start; 4788 break; 4789 case FLT_REG_BOOTLOAD_SEC_27XX: 4790 if (IS_27XX(isp)) 4791 fcp->flt_region_boot_sec = region[count].start; 4792 break; 4793 case FLT_REG_AUX_IMG_PRI_28XX: 4794 if (IS_27XX(isp)) 4795 fcp->flt_region_aux_img_status_pri = region[count].start; 4796 break; 4797 case FLT_REG_AUX_IMG_SEC_28XX: 4798 if (IS_27XX(isp)) 4799 fcp->flt_region_aux_img_status_sec = region[count].start; 4800 break; 4801 case FLT_REG_NVRAM_SEC_28XX_0: 4802 if (IS_27XX(isp)) 4803 if (isp->isp_port == 0) 4804 fcp->flt_region_nvram_sec = region[count].start; 4805 break; 4806 case FLT_REG_NVRAM_SEC_28XX_1: 4807 if (IS_27XX(isp)) 4808 if (isp->isp_port == 1) 4809 fcp->flt_region_nvram_sec = region[count].start; 4810 break; 4811 case FLT_REG_NVRAM_SEC_28XX_2: 4812 if (IS_27XX(isp)) 4813 if (isp->isp_port == 2) 4814 fcp->flt_region_nvram_sec = region[count].start; 4815 break; 4816 case FLT_REG_NVRAM_SEC_28XX_3: 4817 if (IS_27XX(isp)) 4818 if (isp->isp_port == 3) 4819 fcp->flt_region_nvram_sec = region[count].start; 4820 break; 4821 case FLT_REG_VPD_SEC_27XX_0: 4822 case FLT_REG_VPD_SEC_28XX_0: 4823 if (IS_27XX(isp)) { 4824 fcp->flt_region_vpd_nvram_sec = region[count].start; 4825 if (isp->isp_port == 0) 4826 fcp->flt_region_vpd_sec = region[count].start; 4827 } 4828 break; 4829 case FLT_REG_VPD_SEC_27XX_1: 4830 case FLT_REG_VPD_SEC_28XX_1: 4831 if (IS_27XX(isp)) 4832 if (isp->isp_port == 1) 4833 fcp->flt_region_vpd_sec = region[count].start; 4834 break; 4835 case FLT_REG_VPD_SEC_27XX_2: 4836 case FLT_REG_VPD_SEC_28XX_2: 4837 if (IS_27XX(isp)) 4838 if (isp->isp_port == 2) 4839 fcp->flt_region_vpd_sec = region[count].start; 4840 break; 4841 case FLT_REG_VPD_SEC_27XX_3: 4842 case FLT_REG_VPD_SEC_28XX_3: 4843 if (IS_27XX(isp)) 4844 if (isp->isp_port == 3) 4845 fcp->flt_region_vpd_sec = region[count].start; 4846 break; 4847 } 4848 } 4849 isp_prt(isp, ISP_LOGCONFIG, 4850 "FLT[FLT]: boot=0x%x fw=0x%x vpd_nvram=0x%x vpd=0x%x nvram=0x%x " 4851 "fdt=0x%x flt=0x%x npiv=0x%x fcp_prif_cfg=0x%x", 4852 fcp->flt_region_boot, fcp->flt_region_fw, fcp->flt_region_vpd_nvram, 4853 fcp->flt_region_vpd, fcp->flt_region_nvram, fcp->flt_region_fdt, 4854 fcp->flt_region_flt, fcp->flt_region_npiv_conf, 4855 fcp->flt_region_fcp_prio); 4856 4857 return (0); 4858 } 4859 4860 static void 4861 isp_print_image(ispsoftc_t *isp, char *name, struct isp_image_status *image_status) 4862 { 4863 isp_prt(isp, ISP_LOGDEBUG0, 4864 "%s %s: mask=0x%02x gen=0x%04x ver=%u.%u map=0x%01x sum=0x%08x sig=0x%08x", 4865 name, "status", 4866 image_status->image_status_mask, 4867 le16toh(image_status->generation), 4868 image_status->ver_major, 4869 image_status->ver_minor, 4870 image_status->bitmap, 4871 le32toh(image_status->checksum), 4872 le32toh(image_status->signature)); 4873 } 4874 4875 static bool 4876 isp_check_aux_image_status_signature(struct isp_image_status *image_status) 4877 { 4878 unsigned long signature = le32toh(image_status->signature); 4879 4880 return (signature != ISP28XX_AUX_IMG_STATUS_SIGN); 4881 } 4882 4883 static bool 4884 isp_check_image_status_signature(struct isp_image_status *image_status) 4885 { 4886 unsigned long signature = le32toh(image_status->signature); 4887 4888 return ((signature != ISP27XX_IMG_STATUS_SIGN) && 4889 (signature != ISP28XX_IMG_STATUS_SIGN)); 4890 } 4891 4892 static unsigned long 4893 isp_image_status_checksum(struct isp_image_status *image_status) 4894 { 4895 uint32_t *p = (uint32_t *)image_status; 4896 unsigned int n = sizeof(*image_status) / sizeof(*p); 4897 uint32_t sum = 0; 4898 4899 for ( ; n--; p++) 4900 sum += le32toh(*((uint32_t *)(p))); 4901 4902 return (sum); 4903 } 4904 4905 static inline unsigned int 4906 isp_component_bitmask(struct isp_image_status *aux, unsigned int bitmask) 4907 { 4908 return (aux->bitmap & bitmask ? 4909 ISP27XX_SECONDARY_IMAGE : ISP27XX_PRIMARY_IMAGE); 4910 } 4911 4912 static void 4913 isp_component_status(struct active_regions *active_regions, struct isp_image_status *aux) 4914 { 4915 active_regions->aux.board_config = 4916 isp_component_bitmask(aux, ISP28XX_AUX_IMG_BOARD_CONFIG); 4917 4918 active_regions->aux.vpd_nvram = 4919 isp_component_bitmask(aux, ISP28XX_AUX_IMG_VPD_NVRAM); 4920 4921 active_regions->aux.npiv_config_0_1 = 4922 isp_component_bitmask(aux, ISP28XX_AUX_IMG_NPIV_CONFIG_0_1); 4923 4924 active_regions->aux.npiv_config_2_3 = 4925 isp_component_bitmask(aux, ISP28XX_AUX_IMG_NPIV_CONFIG_2_3); 4926 4927 active_regions->aux.nvme_params = 4928 isp_component_bitmask(aux, ISP28XX_AUX_IMG_NVME_PARAMS); 4929 } 4930 4931 static int 4932 isp_compare_image_generation(ispsoftc_t *isp, 4933 struct isp_image_status *pri_image_status, 4934 struct isp_image_status *sec_image_status) 4935 { 4936 /* calculate generation delta as uint16 (this accounts for wrap) */ 4937 int16_t delta = 4938 le16toh(pri_image_status->generation) - 4939 le16toh(sec_image_status->generation); 4940 4941 isp_prt(isp, ISP_LOGDEBUG0, "generation delta = %d", delta); 4942 4943 return (delta); 4944 } 4945 4946 static void 4947 isp_get_aux_images(ispsoftc_t *isp, struct active_regions *active_regions) 4948 { 4949 fcparam *fcp = FCPARAM(isp, 0); 4950 struct isp_image_status pri_aux_image_status, sec_aux_image_status; 4951 bool valid_pri_image = false, valid_sec_image = false; 4952 bool active_pri_image = false, active_sec_image = false; 4953 4954 if (!fcp->flt_region_aux_img_status_pri) { 4955 isp_prt(isp, ISP_LOGWARN, 4956 "Primary aux image not addressed"); 4957 goto check_sec_image; 4958 } 4959 4960 isp_read_flash_data(isp, (uint32_t *)&pri_aux_image_status, 4961 fcp->flt_region_aux_img_status_pri, 4962 sizeof(pri_aux_image_status) >> 2); 4963 isp_print_image(isp, "Primary aux image", &pri_aux_image_status); 4964 4965 if (isp_check_aux_image_status_signature(&pri_aux_image_status)) { 4966 isp_prt(isp, ISP_LOGERR, 4967 "Primary aux image signature (0x%x) not valid", 4968 le32toh(pri_aux_image_status.signature)); 4969 goto check_sec_image; 4970 } 4971 4972 if (isp_image_status_checksum(&pri_aux_image_status)) { 4973 isp_prt(isp, ISP_LOGERR, 4974 "Primary aux image checksum failed"); 4975 goto check_sec_image; 4976 } 4977 4978 valid_pri_image = true; 4979 4980 if (pri_aux_image_status.image_status_mask & 1) { 4981 isp_prt(isp, ISP_LOGCONFIG, 4982 "Primary aux image is active"); 4983 active_pri_image = true; 4984 } 4985 4986 check_sec_image: 4987 if (!fcp->flt_region_aux_img_status_sec) { 4988 isp_prt(isp, ISP_LOGWARN, 4989 "Secondary aux image not addressed"); 4990 goto check_valid_image; 4991 } 4992 4993 isp_read_flash_data(isp, (uint32_t *)&sec_aux_image_status, 4994 fcp->flt_region_aux_img_status_sec, 4995 sizeof(sec_aux_image_status) >> 2); 4996 isp_print_image(isp, "Secondary aux image", &sec_aux_image_status); 4997 4998 if (isp_check_aux_image_status_signature(&sec_aux_image_status)) { 4999 isp_prt(isp, ISP_LOGERR, 5000 "Secondary aux image signature (0x%x) not valid", 5001 le32toh(sec_aux_image_status.signature)); 5002 goto check_valid_image; 5003 } 5004 5005 if (isp_image_status_checksum(&sec_aux_image_status)) { 5006 isp_prt(isp, ISP_LOGERR, 5007 "Secondary aux image checksum failed"); 5008 goto check_valid_image; 5009 } 5010 5011 valid_sec_image = true; 5012 5013 if (sec_aux_image_status.image_status_mask & 1) { 5014 isp_prt(isp, ISP_LOGCONFIG, 5015 "Secondary aux image is active"); 5016 active_sec_image = true; 5017 } 5018 5019 check_valid_image: 5020 if (valid_pri_image && active_pri_image && 5021 valid_sec_image && active_sec_image) { 5022 if (isp_compare_image_generation(isp, &pri_aux_image_status, 5023 &sec_aux_image_status) >= 0) { 5024 isp_component_status(active_regions, 5025 &pri_aux_image_status); 5026 } else { 5027 isp_component_status(active_regions, 5028 &sec_aux_image_status); 5029 } 5030 } else if (valid_pri_image && active_pri_image) { 5031 isp_component_status(active_regions, &pri_aux_image_status); 5032 } else if (valid_sec_image && active_sec_image) { 5033 isp_component_status(active_regions, &sec_aux_image_status); 5034 } 5035 5036 isp_prt(isp, ISP_LOGDEBUG0, 5037 "aux images active: BCFG=%u VPD/NVR=%u NPIV0/1=%u NPIV2/3=%u, NVME=%u", 5038 active_regions->aux.board_config, 5039 active_regions->aux.vpd_nvram, 5040 active_regions->aux.npiv_config_0_1, 5041 active_regions->aux.npiv_config_2_3, 5042 active_regions->aux.nvme_params); 5043 } 5044 5045 static void 5046 isp_get_active_image(ispsoftc_t *isp, struct active_regions * active_regions) 5047 { 5048 fcparam *fcp = FCPARAM(isp, 0); 5049 struct isp_image_status pri_image_status, sec_image_status; 5050 bool valid_pri_image = false, valid_sec_image = false; 5051 bool active_pri_image = false, active_sec_image = false; 5052 5053 if (!fcp->flt_region_img_status_pri) { 5054 isp_prt(isp, ISP_LOGWARN, 5055 "Primary image not addressed"); 5056 goto check_sec_image; 5057 } 5058 5059 if (isp_read_flash_data(isp, (uint32_t *) &pri_image_status, 5060 fcp->flt_region_img_status_pri, sizeof(pri_image_status) >> 2) != 5061 ISP_SUCCESS) 5062 goto check_sec_image; 5063 5064 isp_print_image(isp, "Primary image", &pri_image_status); 5065 5066 if (isp_check_image_status_signature(&pri_image_status)) { 5067 isp_prt(isp, ISP_LOGERR, 5068 "Primary image signature (0x%x) not valid", 5069 le32toh(pri_image_status.signature)); 5070 goto check_sec_image; 5071 } 5072 5073 if (isp_image_status_checksum(&pri_image_status)) { 5074 isp_prt(isp, ISP_LOGERR, 5075 "Primary image checksum failed"); 5076 goto check_sec_image; 5077 } 5078 5079 valid_pri_image = true; 5080 5081 if (pri_image_status.image_status_mask & 1) { 5082 isp_prt(isp, ISP_LOGCONFIG, 5083 "Primary image is active"); 5084 active_pri_image = true; 5085 } 5086 5087 check_sec_image: 5088 if (!fcp->flt_region_img_status_sec) { 5089 isp_prt(isp, ISP_LOGWARN, 5090 "Secondary image not addressed"); 5091 return; 5092 } 5093 5094 if (isp_read_flash_data(isp, (uint32_t *) &sec_image_status, 5095 fcp->flt_region_img_status_sec, sizeof(sec_image_status) >> 2) != 5096 ISP_SUCCESS) 5097 return; 5098 5099 isp_print_image(isp, "Secondary image", &sec_image_status); 5100 5101 if (isp_check_image_status_signature(&sec_image_status)) { 5102 isp_prt(isp, ISP_LOGERR, 5103 "Secondary image signature (0x%x) not valid", 5104 le32toh(sec_image_status.signature)); 5105 } 5106 5107 if (isp_image_status_checksum(&sec_image_status)) { 5108 isp_prt(isp, ISP_LOGERR, 5109 "Secondary image checksum failed"); 5110 goto check_valid_image; 5111 } 5112 5113 valid_sec_image = true; 5114 5115 if (sec_image_status.image_status_mask & 1) { 5116 isp_prt(isp, ISP_LOGCONFIG, 5117 "Secondary image is active"); 5118 active_sec_image = true; 5119 } 5120 5121 check_valid_image: 5122 if (valid_pri_image && active_pri_image) 5123 active_regions->global = ISP27XX_PRIMARY_IMAGE; 5124 5125 if (valid_sec_image && active_sec_image) { 5126 if (!active_regions->global || 5127 isp_compare_image_generation(isp, 5128 &pri_image_status, &sec_image_status) < 0) { 5129 active_regions->global = ISP27XX_SECONDARY_IMAGE; 5130 } 5131 } 5132 5133 isp_prt(isp, ISP_LOGDEBUG0, "active image %s (%u)", 5134 active_regions->global == ISP27XX_DEFAULT_IMAGE ? 5135 "default (boot/fw)" : 5136 active_regions->global == ISP27XX_PRIMARY_IMAGE ? 5137 "primary" : 5138 active_regions->global == ISP27XX_SECONDARY_IMAGE ? 5139 "secondary" : "invalid", 5140 active_regions->global); 5141 } 5142 5143 static bool isp_risc_firmware_invalid(ispsoftc_t *isp, uint32_t *dword) 5144 { 5145 return ((dword[4] | dword[5] | dword[6] | dword[7]) == 0 || 5146 (~dword[4] | ~dword[5] | ~dword[6] | ~dword[7]) == 0); 5147 } 5148 5149 static int 5150 isp_load_ram(ispsoftc_t *isp, uint32_t *data, uint32_t risc_addr, 5151 uint32_t risc_code_size) 5152 { 5153 mbreg_t mbs; 5154 int rval = ISP_SUCCESS; 5155 5156 MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1); 5157 MBSINIT(&mbs, MBOX_LOAD_RISC_RAM, MBLOGALL, 0); 5158 mbs.param[1] = risc_addr; 5159 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); 5160 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); 5161 mbs.param[4] = risc_code_size >> 16; 5162 mbs.param[5] = risc_code_size; 5163 mbs.param[6] = DMA_WD3(isp->isp_rquest_dma); 5164 mbs.param[7] = DMA_WD2(isp->isp_rquest_dma); 5165 mbs.param[8] = risc_addr >> 16; 5166 isp_prt(isp, ISP_LOGDEBUG0, 5167 "LOAD RISC RAM %u (0x%x) words at load address 0x%x", 5168 risc_code_size, risc_code_size, risc_addr); 5169 isp_mboxcmd(isp, &mbs); 5170 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 5171 isp_prt(isp, ISP_LOGERR, "F/W download failed"); 5172 rval = ISP_FUNCTION_FAILED; 5173 } 5174 5175 return (rval); 5176 } 5177 5178 static int 5179 isp_load_risc_flash(ispsoftc_t *isp, uint32_t *srisc_addr, uint32_t faddr) 5180 { 5181 fcparam *fcp = FCPARAM(isp, 0); 5182 int rval = ISP_SUCCESS; 5183 unsigned int segments, fragment; 5184 unsigned long i; 5185 unsigned int j; 5186 unsigned long dlen; 5187 uint32_t *dcode; 5188 uint32_t risc_addr, risc_size = 0; 5189 5190 isp_prt(isp, ISP_LOGDEBUG0, 5191 "Accessing flash firmware at 0x%x.", faddr); 5192 5193 dcode = isp->isp_rquest; 5194 isp_read_flash_data(isp, dcode, faddr, 8); 5195 if (isp_risc_firmware_invalid(isp, dcode)) { 5196 snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash), 5197 "invalid"); 5198 isp_prt(isp, ISP_LOGERR, 5199 "Unable to verify the integrity of flash firmware image."); 5200 isp_prt(isp, ISP_LOGERR, 5201 "Firmware data: 0x%08x 0x%08x 0x%08x 0x%08x.", 5202 dcode[0], dcode[1], dcode[2], dcode[3]); 5203 return (ISP_FUNCTION_FAILED); 5204 } else { 5205 for (i = 0; i < 4; i++) 5206 fcp->fw_flashrev[i] = be32toh(dcode[4 + i]); 5207 snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash), 5208 "%u.%u.%u", fcp->fw_flashrev[0], fcp->fw_flashrev[1], 5209 fcp->fw_flashrev[2]); 5210 isp_prt(isp, ISP_LOGCONFIG, 5211 "Firmware revision (flash) %u.%u.%u (%x).", 5212 fcp->fw_flashrev[0], fcp->fw_flashrev[1], 5213 fcp->fw_flashrev[2], fcp->fw_flashrev[3]); 5214 5215 /* If ispfw(4) is loaded compare versions and use the newest */ 5216 if (isp->isp_osinfo.ispfw != NULL) { 5217 if (ISP_FW_NEWER_THANX(fcp->fw_ispfwrev, fcp->fw_flashrev)) { 5218 isp_prt(isp, ISP_LOGCONFIG, 5219 "Loading RISC with newer ispfw(4) firmware"); 5220 return (ISP_ABORTED); 5221 } 5222 isp_prt(isp, ISP_LOGCONFIG, 5223 "Loading RISC with newer flash firmware"); 5224 } 5225 } 5226 5227 dcode = isp->isp_rquest; 5228 segments = ISP_RISC_CODE_SEGMENTS; 5229 for (j = 0; j < segments; j++) { 5230 isp_prt(isp, ISP_LOGDEBUG0, "Loading segment %u", j); 5231 isp_read_flash_data(isp, dcode, faddr, 10); 5232 risc_addr = be32toh(dcode[2]); 5233 risc_size = be32toh(dcode[3]); 5234 5235 dlen = min(risc_size, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) / 4); 5236 for (fragment = 0; risc_size; fragment++) { 5237 if (dlen > risc_size) 5238 dlen = risc_size; 5239 5240 isp_prt(isp, ISP_LOGDEBUG0, 5241 "Loading fragment %u: 0x%x <- 0x%x (0x%lx dwords)", 5242 fragment, risc_addr, faddr, dlen); 5243 isp_read_flash_data(isp, dcode, faddr, dlen); 5244 for (i = 0; i < dlen; i++) { 5245 dcode[i] = bswap32(dcode[i]); 5246 } 5247 5248 rval = isp_load_ram(isp, dcode, risc_addr, dlen); 5249 if (rval) { 5250 isp_prt(isp, ISP_LOGERR, 5251 "Failed to load firmware fragment %u.", 5252 fragment); 5253 return (ISP_FUNCTION_FAILED); 5254 } 5255 5256 faddr += dlen; 5257 risc_addr += dlen; 5258 risc_size -= dlen; 5259 } 5260 } 5261 5262 return (rval); 5263 } 5264 5265 static int 5266 isp_load_risc(ispsoftc_t *isp, uint32_t *srisc_addr) 5267 { 5268 fcparam *fcp = FCPARAM(isp, 0); 5269 int rval = ISP_SUCCESS; 5270 struct active_regions active_regions = { }; 5271 5272 /* 5273 * Starting with 27xx there is a primary and secondary firmware region 5274 * in flash. All older controllers just have one firmware region. 5275 */ 5276 if (!IS_27XX(isp)) 5277 goto try_primary_fw; 5278 5279 isp_get_active_image(isp, &active_regions); 5280 5281 if (active_regions.global != ISP27XX_SECONDARY_IMAGE) 5282 goto try_primary_fw; 5283 5284 isp_prt(isp, ISP_LOGCONFIG, 5285 "Loading secondary firmware image."); 5286 rval = isp_load_risc_flash(isp, srisc_addr, fcp->flt_region_fw_sec); 5287 return (rval); 5288 5289 try_primary_fw: 5290 isp_prt(isp, ISP_LOGCONFIG, 5291 "Loading primary firmware image."); 5292 rval = isp_load_risc_flash(isp, srisc_addr, fcp->flt_region_fw); 5293 return (rval); 5294 } 5295 5296 static int 5297 isp_read_nvram(ispsoftc_t *isp) 5298 { 5299 fcparam *fcp = FCPARAM(isp, 0); 5300 int retval = 0; 5301 uint32_t addr, csum, lwrds, *dptr; 5302 uint8_t nvram_data[ISP2400_NVRAM_SIZE]; 5303 struct active_regions active_regions = { }; 5304 5305 if (IS_27XX(isp)) 5306 isp_get_aux_images(isp, &active_regions); 5307 5308 addr = fcp->flt_region_nvram; 5309 5310 if (IS_28XX(isp)) { 5311 if (active_regions.aux.vpd_nvram == ISP27XX_SECONDARY_IMAGE) 5312 addr = fcp->flt_region_nvram_sec; 5313 5314 isp_prt(isp, ISP_LOGCONFIG, "Loading %s NVRAM image", 5315 active_regions.aux.vpd_nvram == ISP27XX_PRIMARY_IMAGE ? 5316 "primary" : "secondary"); 5317 } 5318 5319 dptr = (uint32_t *) nvram_data; 5320 for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) { 5321 isp_rd_2xxx_flash(isp, addr++, dptr++); 5322 } 5323 if (nvram_data[0] != 'I' || nvram_data[1] != 'S' || 5324 nvram_data[2] != 'P') { 5325 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)", 5326 nvram_data[0], nvram_data[1], nvram_data[2]); 5327 retval = -1; 5328 goto out; 5329 } 5330 dptr = (uint32_t *) nvram_data; 5331 for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) { 5332 uint32_t tmp; 5333 ISP_IOXGET_32(isp, &dptr[lwrds], tmp); 5334 csum += tmp; 5335 } 5336 if (csum != 0) { 5337 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum"); 5338 retval = -1; 5339 goto out; 5340 } 5341 isp_parse_nvram_2400(isp, nvram_data); 5342 out: 5343 return (retval); 5344 } 5345 5346 static void 5347 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data) 5348 { 5349 fcparam *fcp = FCPARAM(isp, 0); 5350 uint64_t wwn; 5351 5352 isp_prt(isp, ISP_LOGDEBUG0, 5353 "NVRAM 0x%08x%08x 0x%08x%08x maxframelen %d", 5354 (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32), 5355 (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)), 5356 (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32), 5357 (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)), 5358 ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data)); 5359 isp_prt(isp, ISP_LOGDEBUG0, 5360 "NVRAM loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", 5361 ISP2400_NVRAM_HARDLOOPID(nvram_data), 5362 ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data), 5363 ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data), 5364 ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data)); 5365 5366 wwn = ISP2400_NVRAM_PORT_NAME(nvram_data); 5367 fcp->isp_wwpn_nvram = wwn; 5368 5369 wwn = ISP2400_NVRAM_NODE_NAME(nvram_data); 5370 if (wwn) { 5371 if ((wwn >> 60) != 2 && (wwn >> 60) != 5) { 5372 wwn = 0; 5373 } 5374 } 5375 if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) { 5376 wwn = fcp->isp_wwpn_nvram; 5377 wwn &= ~((uint64_t) 0xfff << 48); 5378 } 5379 fcp->isp_wwnn_nvram = wwn; 5380 5381 if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) { 5382 DEFAULT_FRAMESIZE(isp) = 5383 ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data); 5384 } 5385 if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) { 5386 fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data); 5387 } 5388 fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data); 5389 fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data); 5390 fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data); 5391 } 5392