Lines Matching +full:isp +full:- +full:0
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2009-2020 Alexander Motin <mav@FreeBSD.org>
5 * Copyright (c) 1997-2009 by Matthew Jacob
34 * code for the Qlogic ISP SCSI and FC-SCSI adapters.
48 __KERNEL_RCSID(0, "$NetBSD$");
55 #include <dev/isp/isp_freebsd.h>
70 static const char notresp[] = "Unknown IOCB in RESPONSE Queue (type 0x%x) @ idx %d (next %d)";
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
147 isp_change_fw_state(ispsoftc_t *isp, int chan, int state)
149 fcparam *fcp = FCPARAM(isp, chan);
151 if (fcp->isp_fwstate == state)
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;
160 isp_get_flash_addrs(ispsoftc_t *isp)
162 fcparam *fcp = FCPARAM(isp, 0);
163 int r = 0;
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;
175 fcp->flash_data_addr = ISP24XX_BASE_ADDR;
176 fcp->flt_region_flt = ISP24XX_FLT_ADDR;
178 fcp->flt_length = 0;
179 r = isp_read_flthdr_2xxx(isp);
180 if (r == 0) {
181 isp_read_flt_2xxx(isp);
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;
191 fcp->flash_data_addr = 0x7ffe0000;
192 fcp->flt_region_nvram = 0;
194 fcp->flt_region_nvram += ISP2400_NVRAM_PORT_ADDR(isp->isp_port);
207 isp_reset(ispsoftc_t *isp, int do_load_defaults)
217 isp->isp_state = ISP_NILSTATE;
218 ISP_DISABLE_INTS(isp);
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);
228 switch (isp->isp_type) {
251 ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
252 for (loops = 0; loops < 100000; loops++) {
254 val = ISP_READ(isp, BIU2400_CSR);
255 if ((val & BIU2400_DMA_ACTIVE) == 0) {
260 isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
265 ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
267 for (loops = 0; loops < 10000; loops++) {
269 val = ISP_READ(isp, OUTMAILBOX0);
270 if (val != 0x4)
274 case 0x0:
276 case 0x4:
277 isp_prt(isp, ISP_LOGERR, "The ROM code is busy after 50ms.");
279 case 0xf:
280 isp_prt(isp, ISP_LOGERR, "Board configuration error.");
283 isp_prt(isp, ISP_LOGERR, "Unknown RISC Status Code 0x%x.", val);
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);
295 * Post-RISC Reset stuff.
297 for (loops = 0; loops < 10000; loops++) {
299 val = ISP_READ(isp, OUTMAILBOX0);
300 if (val != 0x4)
304 case 0x0:
306 case 0x4:
307 isp_prt(isp, ISP_LOGERR, "The ROM code is busy after 50ms.");
309 case 0xf:
310 isp_prt(isp, ISP_LOGERR, "Board configuration error.");
313 isp_prt(isp, ISP_LOGERR, "Unknown RISC Status Code 0x%x.", val);
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);
328 ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
329 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
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]);
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,
362 int nmbox = ISP_NMBOX(isp);
363 MBSINIT(&mbs, MBOX_MAILBOX_REG_TEST, MBLOGALL, 0);
367 isp_mboxcmd(isp, &mbs);
368 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
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]);
385 if (ISP_MBOXDMASETUP(isp) != 0) {
386 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
414 fcparam *fcp = FCPARAM(isp, 0);
417 isp_get_flash_addrs(isp);
420 snprintf(fcp->fw_version_ispfw, sizeof(fcp->fw_version_ispfw),
422 snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
424 snprintf(fcp->fw_version_run, sizeof(fcp->fw_version_run),
429 if (!(isp->isp_confopts & ISP_CFG_NORELOAD)) {
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,
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,
446 fcp->fw_ispfwrev[0], fcp->fw_ispfwrev[1],
447 fcp->fw_ispfwrev[2], fcp->fw_ispfwrev[3]);
449 isp_prt(isp, ISP_LOGDEBUG0,
454 loaded_fw = 0;
455 dodnld = 0;
457 if (IS_27XX(isp)) {
458 switch (isp_load_risc(isp, 0)) {
475 if (isp->isp_osinfo.ispfw != NULL)
481 if (isp->isp_osinfo.ispfw != NULL)
487 const uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
493 isp_prt(isp, ISP_LOGDEBUG2,
494 "Load 0x%x words of code at load address 0x%x",
497 wi = 0;
504 nw = min(wl, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) / 4);
505 cp = isp->isp_rquest;
506 for (i = 0; i < nw; i++)
507 ISP_IOXPUT_32(isp, ptr[wi + i], &cp[i]);
508 if (isp_load_ram(isp, cp, la, nw) != 0) {
509 isp_prt(isp, ISP_LOGERR,
515 wl -= nw;
518 if (ptr[1] == 0) {
525 if (isp->isp_osinfo.ispfw != NULL)
526 firmware_put(isp->isp_osinfo.ispfw, FIRMWARE_UNLOAD);
528 isp_prt(isp, ISP_LOGCONFIG,
534 MBSINIT(&mbs, MBOX_VERIFY_CHECKSUM, MBLOGNONE, 0);
537 isp_mboxcmd(isp, &mbs);
538 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
539 isp_prt(isp, ISP_LOGERR, "%s: 0x%x", dcrc,
543 } else if (IS_26XX(isp)) {
544 isp_prt(isp, ISP_LOGCONFIG,
547 isp_mboxcmd(isp, &mbs);
548 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
549 isp_prt(isp, ISP_LOGERR, "Flash F/W load failed");
563 if (!IS_26XX(isp))
564 mbs.param[3] = loaded_fw ? 0 : 1;
565 mbs.param[4] = 0;
566 if (IS_27XX(isp))
567 mbs.param[4] |= 0x08; /* NVME_ENABLE_FLAG */
568 mbs.param[11] = 0;
569 isp_mboxcmd(isp, &mbs);
570 if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
572 fcp->fw_ability_mask = (mbs.param[3] << 16) | mbs.param[2];
573 isp_prt(isp, ISP_LOGDEBUG0, "Firmware ability mask: 0x%x",
574 fcp->fw_ability_mask);
575 if (IS_26XX(isp)) {
576 fcp->max_supported_speed = mbs.param[2] & (0x1 | 0x2);
577 isp_prt(isp, ISP_LOGINFO, "Maximum supported speed: %s",
578 fcp->max_supported_speed == 0 ? "16Gbit/s" :
579 fcp->max_supported_speed == 1 ? "32Gbit/s" :
580 fcp->max_supported_speed == 2 ? "64Gbit/s" : "unknown");
582 if (IS_28XX(isp) && (mbs.param[5] & 0x400)) {
583 isp_prt(isp, ISP_LOGINFO,
592 isp_mboxcmd(isp, &mbs);
593 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
597 isp->isp_fwrev[0] = mbs.param[1];
598 isp->isp_fwrev[1] = mbs.param[2];
599 isp->isp_fwrev[2] = mbs.param[3];
600 isp->isp_fwattr = mbs.param[6];
601 isp->isp_fwattr_h = mbs.param[15];
602 if (isp->isp_fwattr & ISP_FW_ATTR_EXTNDED) {
603 isp->isp_fwattr_ext[0] = mbs.param[16];
604 isp->isp_fwattr_ext[1] = mbs.param[17];
607 isp_prt(isp, ISP_LOGCONFIG, "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
608 btype, isp->isp_revision, dodnld ? "loaded" : "resident",
609 isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
610 snprintf(fcp->fw_version_run, sizeof(fcp->fw_version_run),
611 "%u.%u.%u", isp->isp_fwrev[0], isp->isp_fwrev[1],
612 isp->isp_fwrev[2]);
613 if (!dodnld && !IS_26XX(isp))
614 snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
615 "%s", fcp->fw_version_run);
617 fwt = isp->isp_fwattr;
618 buf = FCPARAM(isp, 0)->isp_scanscratch;
622 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s Class2", buf);
626 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s IP", buf);
630 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MultiID", buf);
634 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SB2", buf);
638 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s T10CRC", buf);
642 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VI", buf);
646 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MQ", buf);
650 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MSIX", buf);
654 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s FCOE", buf);
658 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VP0_Decoupling", buf);
662 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s (Experimental)", buf);
666 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s HotFW", buf);
670 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf),
671 "%s (unknown 0x%04x)", buf, fwt);
673 isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
675 fwt = isp->isp_fwattr_h;
676 buf = FCPARAM(isp, 0)->isp_scanscratch;
680 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ExtVP", buf);
684 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VN2VN", buf);
688 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s EXMOFF", buf);
692 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NPMOFF", buf);
696 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s DIFCHOP", buf);
700 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SRIOV", buf);
704 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NVMe", buf);
708 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NVMe(updated)", buf);
712 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NVMe(first burst)", buf);
715 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf),
716 "%s (unknown 0x%04x)", buf, fwt);
718 isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
720 fwt = isp->isp_fwattr_ext[0];
721 buf = FCPARAM(isp, 0)->isp_scanscratch;
725 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ASICTMP", buf);
729 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ATIOMQ", buf);
733 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s EDIF", buf);
737 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SCM", buf);
741 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NVMe-2", buf);
744 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf),
745 "%s (unknown 0x%04x)", buf, fwt);
747 isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
749 fwt = isp->isp_fwattr_ext[1];
750 buf = FCPARAM(isp, 0)->isp_scanscratch;
753 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf),
754 "%s (unknown 0x%04x)", buf, fwt);
756 isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
763 MBSINIT(&mbs, MBOX_GET_RESOURCE_COUNT, MBLOGALL, 0);
764 isp_mboxcmd(isp, &mbs);
765 if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
767 isp->isp_maxcmds = MIN(mbs.param[3], ISP_HANDLE_MAX - ISP_HANDLE_RESERVE);
768 isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", isp->isp_maxcmds);
771 * If we don't have Multi-ID f/w loaded, we need to restrict channels to one.
772 * Only make this check for non-SCSI cards (I'm not sure firmware attributes
775 if (isp->isp_nchan > 1) {
776 if (!ISP_CAP_MULTI_ID(isp)) {
777 isp_prt(isp, ISP_LOGWARN, "non-MULTIID f/w loaded, "
778 "only can enable 1 of %d channels", isp->isp_nchan);
779 isp->isp_nchan = 1;
780 } else if (!ISP_CAP_VP0(isp)) {
781 isp_prt(isp, ISP_LOGWARN, "We can not use MULTIID "
783 isp->isp_nchan = 1;
790 if (ISP_MBOXDMASETUP(isp) != 0) {
791 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
798 if (ISP_IRQSETUP(isp) != 0) {
799 isp_prt(isp, ISP_LOGERR, "Cannot setup IRQ");
802 ISP_ENABLE_INTS(isp);
804 for (i = 0; i < isp->isp_nchan; i++)
805 isp_change_fw_state(isp, i, FW_CONFIG_WAIT);
807 isp->isp_state = ISP_RESETSTATE;
815 for (i = 0; i < isp->isp_nchan; i++)
816 isp_setdfltfcparm(isp, i);
824 isp_stop(ispsoftc_t *isp)
828 isp->isp_state = ISP_NILSTATE;
830 mbs.param[1] = 0;
831 mbs.param[2] = 0;
832 mbs.param[3] = 0;
833 mbs.param[4] = 0;
834 mbs.param[5] = 0;
835 mbs.param[6] = 0;
836 mbs.param[7] = 0;
837 mbs.param[8] = 0;
838 isp_mboxcmd(isp, &mbs);
839 return (mbs.param[0] == MBOX_COMMAND_COMPLETE ? 0 : mbs.param[0]);
846 isp_shutdown(ispsoftc_t *isp)
849 if (isp->isp_state >= ISP_RESETSTATE)
850 isp_stop(isp);
851 ISP_DISABLE_INTS(isp);
852 ISP_WRITE(isp, BIU2400_ICR, 0);
853 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
862 isp_init(ispsoftc_t *isp)
868 int ownloopid = 0;
873 for (chan = 0; chan < isp->isp_nchan; chan++) {
874 fcp = FCPARAM(isp, chan);
875 if (fcp->role != ISP_ROLE_NONE) {
879 if (chan == isp->isp_nchan) {
880 isp_prt(isp, ISP_LOG_WARN1, "all %d channels with role 'none'", chan);
884 isp->isp_state = ISP_INITSTATE;
887 * Start with channel 0.
889 fcp = FCPARAM(isp, 0);
894 MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
896 isp_mboxcmd(isp, &mbs);
897 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
902 icbp->icb_fwoptions1 = fcp->isp_fwoptions;
903 icbp->icb_fwoptions2 = fcp->isp_xfwoptions;
904 icbp->icb_fwoptions3 = fcp->isp_zfwoptions;
905 if (isp->isp_nchan > 1 && ISP_CAP_VP0(isp)) {
906 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
907 icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
909 if (fcp->role & ISP_ROLE_TARGET)
910 icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
912 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_TGT_ENABLE;
913 if (fcp->role & ISP_ROLE_INITIATOR)
914 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
916 icbp->icb_fwoptions1 |= ICB2400_OPT1_INI_DISABLE;
919 icbp->icb_version = ICB_VERSION1;
920 icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
921 if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
922 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
923 if (IS_28XX(isp))
924 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN_28XX;
926 isp_prt(isp, ISP_LOGERR,
927 "bad frame length (%d) from NVRAM - using %d",
928 DEFAULT_FRAMESIZE(isp), icbp->icb_maxfrmlen);
931 if (!IS_26XX(isp))
932 icbp->icb_execthrottle = 0xffff;
938 if (icbp->icb_fwoptions1 & ICB2400_OPT1_TGT_ENABLE) {
939 if ((icbp->icb_fwoptions1 & ICB2400_OPT1_INI_DISABLE) == 0)
940 icbp->icb_xchgcnt = MIN(isp->isp_maxcmds / 2, ATPDPSIZE);
942 icbp->icb_xchgcnt = isp->isp_maxcmds;
946 ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
947 icbp->icb_hardaddr = fcp->isp_loopid;
948 if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
949 icbp->icb_hardaddr = 0;
950 ownloopid = 0;
954 icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
956 if (isp->isp_confopts & ISP_CFG_NOFCTAPE) {
957 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_FCTAPE;
959 if (isp->isp_confopts & ISP_CFG_FCTAPE) {
960 icbp->icb_fwoptions2 |= ICB2400_OPT2_FCTAPE;
963 for (chan = 0; chan < isp->isp_nchan; chan++) {
964 if (icbp->icb_fwoptions2 & ICB2400_OPT2_FCTAPE)
965 FCPARAM(isp, chan)->fctape_enabled = 1;
967 FCPARAM(isp, chan)->fctape_enabled = 0;
970 switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
972 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
973 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY;
976 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
977 icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY;
982 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
983 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
987 switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TOPO_MASK) {
993 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
994 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
999 switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) {
1002 icbp->icb_idelaytimer = 0;
1004 case 0:
1007 isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field", icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
1008 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK;
1012 if (IS_26XX(isp)) {
1014 icbp->icb_fwoptions2 |= ICB2400_OPT2_ENA_IHR;
1015 icbp->icb_fwoptions2 |= ICB2400_OPT2_ENA_IHA;
1018 if ((icbp->icb_fwoptions3 & ICB2400_OPT3_RSPSZ_MASK) == 0) {
1019 icbp->icb_fwoptions3 |= ICB2400_OPT3_RSPSZ_24;
1021 if (isp->isp_confopts & ISP_CFG_1GB) {
1022 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1023 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_1GB;
1024 } else if (isp->isp_confopts & ISP_CFG_2GB) {
1025 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1026 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_2GB;
1027 } else if (isp->isp_confopts & ISP_CFG_4GB) {
1028 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1029 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_4GB;
1030 } else if (isp->isp_confopts & ISP_CFG_8GB) {
1031 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1032 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_8GB;
1033 } else if (isp->isp_confopts & ISP_CFG_16GB) {
1034 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1035 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_16GB;
1036 } else if (isp->isp_confopts & ISP_CFG_32GB) {
1037 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1038 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_32GB;
1039 } else if (isp->isp_confopts & ISP_CFG_64GB) {
1040 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1041 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_64GB;
1043 switch (icbp->icb_fwoptions3 & ICB2400_OPT3_RATE_MASK) {
1052 if (isp->isp_type <= ISP_HA_FC_2500)
1056 if (isp->isp_type <= ISP_HA_FC_2400)
1060 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1061 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
1065 if (ownloopid == 0) {
1066 icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID;
1068 icbp->icb_logintime = ICB_LOGIN_TOV;
1070 if (fcp->isp_wwnn && fcp->isp_wwpn) {
1071 icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
1072 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1073 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
1074 isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node 0x%08x%08x Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwnn >> 32)), ((uint32_t) (fcp->isp_wwnn)),
1075 ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
1076 } else if (fcp->isp_wwpn) {
1077 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS;
1078 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1079 isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node to be same as Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
1081 isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
1084 icbp->icb_rspnsin = isp->isp_resodx;
1085 icbp->icb_rqstout = isp->isp_reqidx;
1086 icbp->icb_retry_count = fcp->isp_retry_count;
1088 icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
1089 if (icbp->icb_rqstqlen < 8) {
1090 isp_prt(isp, ISP_LOGERR, "bad request queue length %d", icbp->icb_rqstqlen);
1093 icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
1094 if (icbp->icb_rsltqlen < 8) {
1095 isp_prt(isp, ISP_LOGERR, "bad result queue length %d",
1096 icbp->icb_rsltqlen);
1099 icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1100 icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1101 icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1102 icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
1104 icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1105 icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1106 icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1107 icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
1111 icbp->icb_atio_in = isp->isp_atioodx;
1112 icbp->icb_atioqlen = ATIO_QUEUE_LEN(isp);
1113 if (icbp->icb_atioqlen < 8) {
1114 isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d", icbp->icb_atioqlen);
1117 icbp->icb_atioqaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_atioq_dma);
1118 icbp->icb_atioqaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_atioq_dma);
1119 icbp->icb_atioqaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_atioq_dma);
1120 icbp->icb_atioqaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_atioq_dma);
1121 isp_prt(isp, ISP_LOGDEBUG0, "isp_init: atioq %04x%04x%04x%04x", DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma),
1122 DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma));
1125 if (ISP_CAP_MSIX(isp) && isp->isp_nirq >= 2) {
1126 icbp->icb_msixresp = 1;
1127 if (IS_26XX(isp) && isp->isp_nirq >= 3)
1128 icbp->icb_msixatio = 2;
1131 isp_prt(isp, ISP_LOGDEBUG0, "isp_init: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3);
1133 isp_prt(isp, ISP_LOGDEBUG0, "isp_init: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x", DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma),
1134 DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma), DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
1135 DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
1137 if (FC_SCRATCH_ACQUIRE(isp, 0)) {
1138 isp_prt(isp, ISP_LOGERR, sacq);
1141 ISP_MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
1142 isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
1143 if (isp->isp_dblev & ISP_LOGDEBUG1) {
1144 isp_print_bytes(isp, "isp_init",
1145 sizeof (*icbp), fcp->isp_scratch);
1151 if (isp->isp_nchan > 1) {
1154 size_t amt = 0;
1158 if (ISP_CAP_VP0(isp)) {
1160 vpinfo.vp_count = isp->isp_nchan;
1161 chan = 0;
1163 vpinfo.vp_count = isp->isp_nchan - 1;
1166 off = fcp->isp_scratch;
1169 isp_put_icb_2400_vpinfo(isp, &vpinfo, vdst);
1171 for (; chan < isp->isp_nchan; chan++) {
1175 fcp2 = FCPARAM(isp, chan);
1176 if (fcp2->role != ISP_ROLE_NONE) {
1179 if (fcp2->role & ISP_ROLE_INITIATOR)
1181 if ((fcp2->role & ISP_ROLE_TARGET) == 0)
1183 if (fcp2->isp_loopid < LOCAL_LOOP_LIM) {
1184 pi.vp_port_loopid = fcp2->isp_loopid;
1185 if (isp->isp_confopts & ISP_CFG_OWNLOOPID)
1190 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname, fcp2->isp_wwpn);
1191 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename, fcp2->isp_wwnn);
1192 off = fcp->isp_scratch;
1193 if (ISP_CAP_VP0(isp))
1196 off += ICB2400_VPINFO_PORT_OFF(chan - 1);
1198 isp_put_vp_port_info(isp, &pi, pdst);
1201 if (isp->isp_dblev & ISP_LOGDEBUG1) {
1202 isp_print_bytes(isp, "isp_init",
1203 amt - ICB2400_VPINFO_OFF,
1204 (char *)fcp->isp_scratch + ICB2400_VPINFO_OFF);
1211 MBSINIT(&mbs, 0, MBLOGALL, 30000000);
1212 if (isp->isp_nchan > 1) {
1213 mbs.param[0] = MBOX_INIT_FIRMWARE_MULTI_ID;
1215 mbs.param[0] = MBOX_INIT_FIRMWARE;
1217 mbs.param[1] = 0;
1218 mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1219 mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1220 mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1221 mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1222 isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %04x%04x%04x%04x", DMA_WD3(fcp->isp_scdma), DMA_WD2(fcp->isp_scdma), DMA_WD1(fcp->isp_scdma), DMA_WD0(fcp->isp_scdma));
1223 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp), 0);
1224 isp_mboxcmd(isp, &mbs);
1225 FC_SCRATCH_RELEASE(isp, 0);
1227 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1234 isp->isp_state = ISP_RUNSTATE;
1238 isp_fc_enable_vp(ispsoftc_t *isp, int chan)
1240 fcparam *fcp = FCPARAM(isp, chan);
1251 vp.vp_mod_ports[0].options = ICB2400_VPOPT_ENABLED |
1253 if (fcp->role & ISP_ROLE_INITIATOR)
1254 vp.vp_mod_ports[0].options |= ICB2400_VPOPT_INI_ENABLE;
1255 if ((fcp->role & ISP_ROLE_TARGET) == 0)
1256 vp.vp_mod_ports[0].options |= ICB2400_VPOPT_TGT_DISABLE;
1257 if (fcp->isp_loopid < LOCAL_LOOP_LIM) {
1258 vp.vp_mod_ports[0].loopid = fcp->isp_loopid;
1259 if (isp->isp_confopts & ISP_CFG_OWNLOOPID)
1260 vp.vp_mod_ports[0].options |= ICB2400_VPOPT_HARD_ADDRESS;
1262 MAKE_NODE_NAME_FROM_WWN(vp.vp_mod_ports[0].wwpn, fcp->isp_wwpn);
1263 MAKE_NODE_NAME_FROM_WWN(vp.vp_mod_ports[0].wwnn, fcp->isp_wwnn);
1265 retval = isp_exec_entry_queue(isp, &vp, &vp, 5);
1266 if (retval != 0) {
1267 isp_prt(isp, ISP_LOGERR, "%s: VP_MODIFY of chan %d error %d",
1272 if (vp.vp_mod_hdr.rqs_flags != 0 || vp.vp_mod_status != VP_STS_OK) {
1273 isp_prt(isp, ISP_LOGERR,
1278 return (0);
1282 isp_fc_disable_vp(ispsoftc_t *isp, int chan)
1291 if (ISP_CAP_VP0(isp)) {
1294 vp.vp_ctrl_status = 0;
1295 chan--; /* VP0 can not be controlled in this case. */
1301 retval = isp_exec_entry_queue(isp, &vp, &vp, 5);
1302 if (retval != 0) {
1303 isp_prt(isp, ISP_LOGERR, "%s: VP_CTRL of chan %d error %d",
1308 if (vp.vp_ctrl_hdr.rqs_flags != 0 || vp.vp_ctrl_status != 0) {
1309 isp_prt(isp, ISP_LOGERR,
1315 return (0);
1319 isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role)
1321 fcparam *fcp = FCPARAM(isp, chan);
1322 int i, was, res = 0;
1324 if (chan >= isp->isp_nchan) {
1325 isp_prt(isp, ISP_LOGWARN, "%s: bad channel %d", __func__, chan);
1328 if (fcp->role == new_role)
1329 return (0);
1330 for (was = 0, i = 0; i < isp->isp_nchan; i++) {
1331 if (FCPARAM(isp, i)->role != ISP_ROLE_NONE)
1334 if (was == 0 || (was == 1 && fcp->role != ISP_ROLE_NONE)) {
1335 fcp->role = new_role;
1336 return (isp_reinit(isp, 0));
1338 if (fcp->role != ISP_ROLE_NONE) {
1339 res = isp_fc_disable_vp(isp, chan);
1340 isp_clear_portdb(isp, chan);
1342 fcp->role = new_role;
1343 if (fcp->role != ISP_ROLE_NONE)
1344 res = isp_fc_enable_vp(isp, chan);
1349 isp_clear_portdb(ispsoftc_t *isp, int chan)
1351 fcparam *fcp = FCPARAM(isp, chan);
1355 for (i = 0; i < MAX_FC_TARG; i++) {
1356 lp = &fcp->portdb[i];
1357 switch (lp->state) {
1361 lp->state = FC_PORTDB_STATE_NIL;
1362 isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
1366 lp->state = FC_PORTDB_STATE_NIL;
1371 panic("Don't know how to clear state %d\n", lp->state);
1377 isp_mark_portdb(ispsoftc_t *isp, int chan)
1379 fcparam *fcp = FCPARAM(isp, chan);
1383 for (i = 0; i < MAX_FC_TARG; i++) {
1384 lp = &fcp->portdb[i];
1385 if (lp->state == FC_PORTDB_STATE_NIL)
1387 if (lp->portid >= DOMAIN_CONTROLLER_BASE &&
1388 lp->portid <= DOMAIN_CONTROLLER_END)
1390 fcp->portdb[i].probational = 1;
1399 isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags)
1407 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d PLOGX %s PortID 0x%06x nphdl 0x%x",
1417 pl.plogx_rspsz_porthi = (portid >> 16) & 0xff;
1420 retval = isp_exec_entry_queue(isp, &pl, &pl, 3 * ICB_LOGIN_TOV);
1421 if (retval != 0) {
1422 isp_prt(isp, ISP_LOGERR, "%s: PLOGX of chan %d error %d",
1428 return (0);
1430 isp_prt(isp, ISP_LOGWARN,
1431 "status 0x%x on port login IOCB channel %d",
1433 return (-1);
1436 sst = pl.plogx_ioparm[0].lo16 | (pl.plogx_ioparm[0].hi16 << 16);
1439 retval = -1;
1454 ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff);
1464 ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1);
1469 ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1);
1476 ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1);
1481 ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1);
1487 ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1);
1503 isp_prt(isp, lev, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s",
1510 isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb)
1521 mbs.param[2] = DMA_WD1(isp->isp_iocb_dma);
1522 mbs.param[3] = DMA_WD0(isp->isp_iocb_dma);
1523 mbs.param[6] = DMA_WD3(isp->isp_iocb_dma);
1524 mbs.param[7] = DMA_WD2(isp->isp_iocb_dma);
1526 MEMORYBARRIER(isp, SYNC_IFORDEV, 0, sizeof(un), chan);
1528 isp_mboxcmd(isp, &mbs);
1529 if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
1530 return (mbs.param[0] | (mbs.param[1] << 16));
1532 MEMORYBARRIER(isp, SYNC_IFORCPU, 0, sizeof(un), chan);
1533 isp_get_pdb_24xx(isp, isp->isp_iocb, &un.bill);
1534 pdb->handle = un.bill.pdb_handle;
1535 pdb->prli_word0 = un.bill.pdb_prli_svc0;
1536 pdb->prli_word3 = un.bill.pdb_prli_svc3;
1537 pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
1538 ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
1539 ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
1540 isp_prt(isp, ISP_LOGDEBUG0,
1541 "Chan %d handle 0x%x Port 0x%06x flags 0x%x curstate %x laststate %x",
1542 chan, id, pdb->portid, un.bill.pdb_flags,
1554 mbs.param[0] = MBOX_NOT_LOGGED_IN;
1555 return (mbs.param[0]);
1557 return (0);
1561 isp_gethandles(ispsoftc_t *isp, int chan, uint16_t *handles, int *num, int loop)
1563 fcparam *fcp = FCPARAM(isp, chan);
1570 mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1571 mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1572 mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1573 mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1576 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
1577 isp_prt(isp, ISP_LOGERR, sacq);
1578 return (-1);
1580 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, ISP_FC_SCRLEN, chan);
1581 isp_mboxcmd(isp, &mbs);
1582 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1583 FC_SCRATCH_RELEASE(isp, chan);
1584 return (mbs.param[0] | (mbs.param[1] << 16));
1586 MEMORYBARRIER(isp, SYNC_SFORCPU, 0, ISP_FC_SCRLEN, chan);
1587 elp4 = fcp->isp_scratch;
1588 for (i = 0, j = 0; i < mbs.param[1] && j < *num; i++) {
1589 isp_get_pnhle_24xx(isp, &elp4[i], &el4);
1591 if (loop && (p >> 8) != (fcp->isp_portid >> 8))
1596 FC_SCRATCH_RELEASE(isp, chan);
1597 return (0);
1601 isp_dump_chip_portdb(ispsoftc_t *isp, int chan)
1606 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d chip port dump", chan);
1607 for (nphdl = 0; nphdl != NPH_MAX_2K; nphdl++) {
1608 if (isp_getpdb(isp, chan, nphdl, &pdb)) {
1611 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d Handle 0x%04x "
1612 "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x",
1613 chan, nphdl, pdb.portid, pdb.portname[0], pdb.portname[1],
1620 isp_get_wwn(ispsoftc_t *isp, int chan, int nphdl, int nodename)
1631 isp_mboxcmd(isp, &mbs);
1632 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1636 (((uint64_t)(mbs.param[2] & 0xff))<< 48) |
1638 (((uint64_t)(mbs.param[3] & 0xff))<< 32) |
1640 (((uint64_t)(mbs.param[6] & 0xff))<< 16) |
1642 (((uint64_t)(mbs.param[7] & 0xff)));
1651 isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
1659 fcp = FCPARAM(isp, chan);
1661 if (fcp->isp_loopstate < LOOP_HAVE_LINK)
1662 return (-1);
1663 if (fcp->isp_loopstate >= LOOP_LTEST_DONE)
1664 return (0);
1666 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test", chan);
1673 isp_change_fw_state(isp, chan, isp_fw_state(isp, chan));
1674 if (fcp->isp_fwstate == FW_READY) {
1677 if (fcp->isp_loopstate < LOOP_HAVE_LINK)
1682 ISP_SLEEP(isp, 1000);
1684 if (fcp->isp_fwstate != FW_READY) {
1685 isp_prt(isp, ISP_LOG_SANCFG,
1687 chan, isp_fc_fw_statename(fcp->isp_fwstate));
1688 return (-1);
1694 MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0);
1696 isp_mboxcmd(isp, &mbs);
1697 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1698 return (-1);
1704 fcp->isp_topo = topo;
1705 fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
1707 if (!TOPO_IS_FABRIC(fcp->isp_topo)) {
1708 fcp->isp_loopid = mbs.param[1] & 0xff;
1709 } else if (fcp->isp_topo != TOPO_F_PORT) {
1710 uint8_t alpa = fcp->isp_portid;
1712 for (i = 0; alpa_map[i]; i++) {
1717 fcp->isp_loopid = i;
1720 #if 0
1721 fcp->isp_loopstate = LOOP_HAVE_ADDR;
1723 fcp->isp_loopstate = LOOP_TESTING_LINK;
1725 if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
1726 r = isp_getpdb(isp, chan, NPH_FL_ID, &pdb);
1727 if (r != 0 || pdb.portid == 0) {
1728 isp_prt(isp, ISP_LOGWARN,
1729 "fabric topology, but cannot get info about fabric controller (0x%x)", r);
1730 fcp->isp_topo = TOPO_PTP_STUB;
1734 fcp->isp_fabric_params = mbs.param[7];
1735 fcp->isp_sns_hdl = NPH_SNS_ID;
1736 r = isp_register_fc4_type(isp, chan);
1737 if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1739 if (r != 0)
1741 r = isp_register_fc4_features_24xx(isp, chan);
1742 if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1744 if (r != 0)
1746 r = isp_register_port_name_24xx(isp, chan);
1747 if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1749 if (r != 0)
1751 isp_register_node_name_24xx(isp, chan);
1752 if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1758 fcp->isp_gbspeed = 1;
1762 isp_mboxcmd(isp, &mbs);
1763 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1765 fcp->isp_gbspeed = 10;
1767 fcp->isp_gbspeed = 64;
1769 fcp->isp_gbspeed = 32;
1771 fcp->isp_gbspeed = 16;
1773 fcp->isp_gbspeed = 8;
1775 fcp->isp_gbspeed = 4;
1777 fcp->isp_gbspeed = 2;
1779 fcp->isp_gbspeed = 1;
1782 if (fcp->isp_loopstate < LOOP_TESTING_LINK) {
1784 isp_prt(isp, ISP_LOG_SANCFG,
1788 fcp->isp_loopstate = LOOP_LTEST_DONE;
1789 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGCONFIG,
1791 chan, (uintmax_t)fcp->isp_wwpn, (uintmax_t)fcp->isp_wwnn);
1792 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGCONFIG,
1793 "Chan %d %dGb %s PortID 0x%06x LoopID 0x%02x",
1794 chan, fcp->isp_gbspeed, isp_fc_toponame(fcp), fcp->isp_portid,
1795 fcp->isp_loopid);
1796 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test done", chan);
1797 return (0);
1812 isp_pdb_sync(ispsoftc_t *isp, int chan)
1814 fcparam *fcp = FCPARAM(isp, chan);
1818 if (fcp->isp_loopstate < LOOP_FSCAN_DONE)
1819 return (-1);
1820 if (fcp->isp_loopstate >= LOOP_READY)
1821 return (0);
1823 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync", chan);
1825 fcp->isp_loopstate = LOOP_SYNCING_PDB;
1827 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
1828 lp = &fcp->portdb[dbidx];
1830 if (lp->state == FC_PORTDB_STATE_NIL)
1832 if (lp->probational && lp->state != FC_PORTDB_STATE_ZOMBIE)
1833 lp->state = FC_PORTDB_STATE_DEAD;
1834 switch (lp->state) {
1836 lp->state = FC_PORTDB_STATE_NIL;
1837 isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
1838 if ((lp->portid & 0xffff00) != 0) {
1839 (void) isp_plogx(isp, chan, lp->handle,
1840 lp->portid,
1851 lp->state = FC_PORTDB_STATE_VALID;
1852 isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
1855 lp->state = FC_PORTDB_STATE_VALID;
1856 isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
1857 lp->portid = lp->new_portid;
1858 lp->prli_word0 = lp->new_prli_word0;
1859 lp->prli_word3 = lp->new_prli_word3;
1862 isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
1867 isp_prt(isp, ISP_LOGWARN,
1869 lp->state, dbidx);
1870 isp_dump_portdb(isp, chan);
1874 if (fcp->isp_loopstate < LOOP_SYNCING_PDB) {
1875 isp_prt(isp, ISP_LOG_SANCFG,
1880 fcp->isp_loopstate = LOOP_READY;
1881 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync done", chan);
1882 return (0);
1886 isp_pdb_add_update(ispsoftc_t *isp, int chan, isp_pdb_t *pdb)
1891 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb->nodename);
1892 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb->portname);
1895 if (isp_find_pdb_by_wwpn(isp, chan, wwpn, &lp)) {
1896 if (!lp->probational) {
1897 isp_prt(isp, ISP_LOGERR,
1898 "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)",
1899 chan, lp->portid, lp->handle,
1900 FC_PORTDB_TGT(isp, chan, lp), lp->state);
1901 isp_dump_portdb(isp, chan);
1904 lp->probational = 0;
1905 lp->node_wwn = wwnn;
1908 if (lp->portid == pdb->portid &&
1909 lp->handle == pdb->handle &&
1910 lp->prli_word3 == pdb->prli_word3 &&
1911 ((pdb->prli_word0 & PRLI_WD0_EST_IMAGE_PAIR) ==
1912 (lp->prli_word0 & PRLI_WD0_EST_IMAGE_PAIR))) {
1913 if (lp->state != FC_PORTDB_STATE_NEW)
1914 lp->state = FC_PORTDB_STATE_VALID;
1915 isp_prt(isp, ISP_LOG_SANCFG,
1916 "Chan %d Port 0x%06x@0x%04x is valid",
1917 chan, pdb->portid, pdb->handle);
1922 lp->state = FC_PORTDB_STATE_CHANGED;
1923 lp->handle = pdb->handle;
1924 lp->new_portid = pdb->portid;
1925 lp->new_prli_word0 = pdb->prli_word0;
1926 lp->new_prli_word3 = pdb->prli_word3;
1927 isp_prt(isp, ISP_LOG_SANCFG,
1928 "Chan %d Port 0x%06x@0x%04x is changed",
1929 chan, pdb->portid, pdb->handle);
1934 if (!isp_find_pdb_empty(isp, chan, &lp)) {
1935 isp_prt(isp, ISP_LOGERR, "Chan %d out of portdb entries", chan);
1940 lp->probational = 0;
1941 lp->state = FC_PORTDB_STATE_NEW;
1942 lp->portid = lp->new_portid = pdb->portid;
1943 lp->prli_word0 = lp->new_prli_word0 = pdb->prli_word0;
1944 lp->prli_word3 = lp->new_prli_word3 = pdb->prli_word3;
1945 lp->handle = pdb->handle;
1946 lp->port_wwn = wwpn;
1947 lp->node_wwn = wwnn;
1948 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Port 0x%06x@0x%04x is new",
1949 chan, pdb->portid, pdb->handle);
1956 isp_scan_loop(ispsoftc_t *isp, int chan)
1958 fcparam *fcp = FCPARAM(isp, chan);
1964 if (fcp->isp_loopstate < LOOP_LTEST_DONE)
1965 return (-1);
1966 if (fcp->isp_loopstate >= LOOP_LSCAN_DONE)
1967 return (0);
1969 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan", chan);
1970 fcp->isp_loopstate = LOOP_SCANNING_LOOP;
1971 if (TOPO_IS_FABRIC(fcp->isp_topo)) {
1972 isp_prt(isp, ISP_LOG_SANCFG,
1974 fcp->isp_loopstate = LOOP_LSCAN_DONE;
1975 return (0);
1978 handles = (uint16_t *)fcp->isp_scanscratch;
1980 r = isp_gethandles(isp, chan, handles, &lim, 1);
1981 if (r != 0) {
1982 isp_prt(isp, ISP_LOG_SANCFG,
1984 isp_prt(isp, ISP_LOG_SANCFG,
1986 return (-1);
1989 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Got %d handles",
1995 isp_mark_portdb(isp, chan);
1996 for (idx = 0; idx < lim; idx++) {
2008 r = isp_getpdb(isp, chan, handle, &pdb);
2009 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2011 isp_prt(isp, ISP_LOG_SANCFG,
2015 if (r != 0) {
2016 isp_prt(isp, ISP_LOGDEBUG1,
2022 isp_pdb_add_update(isp, chan, &pdb);
2024 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
2026 fcp->isp_loopstate = LOOP_LSCAN_DONE;
2027 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan done", chan);
2028 return (0);
2032 isp_ct_passthru(ispsoftc_t *isp, int chan, uint32_t cmd_bcnt, uint32_t rsp_bcnt)
2034 fcparam *fcp = FCPARAM(isp, chan);
2038 if (isp->isp_dblev & ISP_LOGDEBUG1)
2039 isp_print_bytes(isp, "CT request", cmd_bcnt, fcp->isp_scratch);
2047 pt.ctp_nphdl = fcp->isp_sns_hdl;
2049 pt.ctp_vpidx = ISP_GET_VPIDX(isp, chan);
2054 pt.ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma);
2055 pt.ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma);
2056 pt.ctp_dataseg[0].ds_count = cmd_bcnt;
2057 pt.ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma);
2058 pt.ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma);
2061 retval = isp_exec_entry_queue(isp, &pt, &pt, 2 * pt.ctp_time);
2062 if (retval != 0) {
2063 isp_prt(isp, ISP_LOGERR, "%s: CTP of chan %d error %d",
2069 isp_prt(isp, ISP_LOGWARN,
2070 "Chan %d CT pass-through returned 0x%x",
2072 return (-1);
2075 if (isp->isp_dblev & ISP_LOGDEBUG1)
2076 isp_print_bytes(isp, "CT response", rsp_bcnt, fcp->isp_scratch);
2078 return (0);
2087 * We use CT Pass-through IOCB.
2090 #define NGENT ((GIDLEN - 16) >> 2)
2093 isp_gid_pt(ispsoftc_t *isp, int chan)
2095 fcparam *fcp = FCPARAM(isp, chan);
2097 uint8_t *scp = fcp->isp_scratch;
2099 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GID_PT", chan);
2100 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2101 isp_prt(isp, ISP_LOGERR, sacq);
2102 return (-1);
2105 /* Build the CT command and execute via pass-through. */
2111 ct.ct_bcnt_resid = (GIDLEN - 16) >> 2;
2112 isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp);
2113 scp[sizeof(ct)] = 0x7f; /* Port Type = Nx_Port */
2114 scp[sizeof(ct)+1] = 0; /* Domain_ID = any */
2115 scp[sizeof(ct)+2] = 0; /* Area_ID = any */
2116 scp[sizeof(ct)+3] = 0; /* Flags = no Area_ID */
2118 if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), GIDLEN)) {
2119 FC_SCRATCH_RELEASE(isp, chan);
2120 return (-1);
2123 isp_get_gid_xx_response(isp, (sns_gid_xx_rsp_t *)scp,
2124 (sns_gid_xx_rsp_t *)fcp->isp_scanscratch, NGENT);
2125 FC_SCRATCH_RELEASE(isp, chan);
2126 return (0);
2130 isp_gff_id(ispsoftc_t *isp, int chan, uint32_t portid)
2132 fcparam *fcp = FCPARAM(isp, chan);
2135 uint8_t *scp = fcp->isp_scratch;
2137 int i, res = -1;
2139 if (!fcp->isp_use_gff_id) /* User may block GFF_ID use. */
2142 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GFF_ID", chan);
2143 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2144 isp_prt(isp, ISP_LOGERR, sacq);
2148 /* Build the CT command and execute via pass-through. */
2154 ct.ct_bcnt_resid = (SNS_GFF_ID_RESP_SIZE - sizeof(ct)) / 4;
2155 isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp);
2157 ISP_IOZPUT_32(isp, portid, rp);
2159 if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t),
2161 FC_SCRATCH_RELEASE(isp, chan);
2165 isp_get_gff_id_response(isp, (sns_gff_id_rsp_t *)scp, &rsp);
2167 for (i = 0; i < 32; i++) {
2168 if (rsp.snscb_fc4_features[i] != 0) {
2169 res = 0;
2174 ((FC4_SCSI % 8) * 4)) & 0x01) != 0)
2177 if (((ISP_SWAP32(isp, rsp.snscb_fc4_features[FC4_SCSI / 8]) >>
2178 ((FC4_SCSI % 8) * 4)) & 0x01) != 0)
2181 FC_SCRATCH_RELEASE(isp, chan);
2182 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GFF_ID result is %d", chan, res);
2187 isp_gft_id(ispsoftc_t *isp, int chan, uint32_t portid)
2189 fcparam *fcp = FCPARAM(isp, chan);
2192 uint8_t *scp = fcp->isp_scratch;
2194 int i, res = -1;
2196 if (!fcp->isp_use_gft_id) /* User may block GFT_ID use. */
2199 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GFT_ID", chan);
2200 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2201 isp_prt(isp, ISP_LOGERR, sacq);
2205 /* Build the CT command and execute via pass-through. */
2211 ct.ct_bcnt_resid = (SNS_GFT_ID_RESP_SIZE - sizeof(ct)) / 4;
2212 isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp);
2214 ISP_IOZPUT_32(isp, portid, rp);
2216 if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t),
2218 FC_SCRATCH_RELEASE(isp, chan);
2222 isp_get_gft_id_response(isp, (sns_gft_id_rsp_t *)scp, &rsp);
2224 for (i = 0; i < 8; i++) {
2225 if (rsp.snscb_fc4_types[i] != 0) {
2226 res = 0;
2231 (FC4_SCSI % 32)) & 0x01) != 0)
2234 FC_SCRATCH_RELEASE(isp, chan);
2235 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GFT_ID result is %d", chan, res);
2240 isp_scan_fabric(ispsoftc_t *isp, int chan)
2242 fcparam *fcp = FCPARAM(isp, chan);
2249 if (fcp->isp_loopstate < LOOP_LSCAN_DONE)
2250 return (-1);
2251 if (fcp->isp_loopstate >= LOOP_FSCAN_DONE)
2252 return (0);
2254 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan", chan);
2255 fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
2256 if (!TOPO_IS_FABRIC(fcp->isp_topo)) {
2257 fcp->isp_loopstate = LOOP_FSCAN_DONE;
2258 isp_prt(isp, ISP_LOG_SANCFG,
2260 return (0);
2263 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
2265 FC_SCRATCH_RELEASE(isp, chan);
2266 isp_prt(isp, ISP_LOG_SANCFG,
2274 r = isp_getpdb(isp, chan, NPH_FL_ID, &pdb);
2275 if ((r & 0xffff) == MBOX_NOT_LOGGED_IN) {
2276 isp_dump_chip_portdb(isp, chan);
2279 fcp->isp_loopstate = LOOP_LTEST_DONE;
2281 isp_prt(isp, ISP_LOG_SANCFG,
2283 return (-1);
2287 r = isp_gid_pt(isp, chan);
2288 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2290 if (r > 0) {
2291 fcp->isp_loopstate = LOOP_FSCAN_DONE;
2292 return (-1);
2293 } else if (r < 0) {
2294 fcp->isp_loopstate = LOOP_LTEST_DONE; /* try again */
2295 return (-1);
2298 rs = (sns_gid_xx_rsp_t *) fcp->isp_scanscratch;
2299 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2301 if (rs->snscb_cthdr.ct_cmd_resp != LS_ACC) {
2303 /* FC-4 Type and Port Type not registered are not errors. */
2304 if (rs->snscb_cthdr.ct_reason == 9 &&
2305 (rs->snscb_cthdr.ct_explanation == 0x07 ||
2306 rs->snscb_cthdr.ct_explanation == 0x0a)) {
2311 isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_PT"
2312 " (Reason=0x%x Expl=0x%x)", chan,
2313 rs->snscb_cthdr.ct_reason,
2314 rs->snscb_cthdr.ct_explanation);
2315 fcp->isp_loopstate = LOOP_FSCAN_DONE;
2316 return (-1);
2320 for (portidx = 0; portidx < NGENT-1; portidx++) {
2321 if (rs->snscb_ports[portidx].control & 0x80)
2324 if ((rs->snscb_ports[portidx].control & 0x80) == 0) {
2325 isp_prt(isp, ISP_LOGWARN,
2329 isp_prt(isp, ISP_LOG_SANCFG,
2333 for (portidx = 0; portidx < portlim; portidx++) {
2337 ((rs->snscb_ports[portidx].portid[0]) << 16) |
2338 ((rs->snscb_ports[portidx].portid[1]) << 8) |
2339 ((rs->snscb_ports[portidx].portid[2]));
2343 ((rs->snscb_ports[npidx].portid[0]) << 16) |
2344 ((rs->snscb_ports[npidx].portid[1]) << 8) |
2345 ((rs->snscb_ports[npidx].portid[2]));
2352 rs->snscb_ports[npidx].portid[0] = 0;
2353 rs->snscb_ports[npidx].portid[1] = 0;
2354 rs->snscb_ports[npidx].portid[2] = 0;
2355 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d removing duplicate PortID 0x%06x entry from list", chan, portid);
2364 * for probational entries- if we find one, then an old entry is
2373 isp_mark_portdb(isp, chan);
2374 for (portidx = 0; portidx < portlim; portidx++) {
2375 portid = ((rs->snscb_ports[portidx].portid[0]) << 16) |
2376 ((rs->snscb_ports[portidx].portid[1]) << 8) |
2377 ((rs->snscb_ports[portidx].portid[2]));
2378 isp_prt(isp, ISP_LOG_SANCFG,
2379 "Chan %d Checking fabric port 0x%06x", chan, portid);
2380 if (portid == 0) {
2381 isp_prt(isp, ISP_LOG_SANCFG,
2386 if (portid == fcp->isp_portid) {
2387 isp_prt(isp, ISP_LOG_SANCFG,
2388 "Chan %d Port 0x%06x is our", chan, portid);
2393 if (isp_find_pdb_by_portid(isp, chan, portid, &lp)) {
2394 if (!lp->probational) {
2395 isp_prt(isp, ISP_LOGERR,
2396 "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)",
2397 chan, lp->portid, lp->handle,
2398 FC_PORTDB_TGT(isp, chan, lp), lp->state);
2399 isp_dump_portdb(isp, chan);
2403 if (lp->state == FC_PORTDB_STATE_ZOMBIE)
2421 r = isp_getpdb(isp, chan, lp->handle, &pdb);
2422 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2424 if (r != 0) {
2425 lp->state = FC_PORTDB_STATE_DEAD;
2426 isp_prt(isp, ISP_LOG_SANCFG,
2427 "Chan %d Port 0x%06x handle 0x%x is dead (%d)",
2428 chan, portid, lp->handle, r);
2432 isp_pdb_add_update(isp, chan, &pdb);
2437 if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
2438 isp_prt(isp, ISP_LOG_SANCFG,
2439 "Chan %d Port 0x%06x is not logged in", chan, portid);
2443 r = isp_gff_id(isp, chan, portid);
2444 if (r == 0) {
2445 isp_prt(isp, ISP_LOG_SANCFG,
2446 "Chan %d Port 0x%06x is not an FCP target", chan, portid);
2449 if (r < 0)
2450 r = isp_gft_id(isp, chan, portid);
2451 if (r == 0) {
2452 isp_prt(isp, ISP_LOG_SANCFG,
2453 "Chan %d Port 0x%06x is not FCP", chan, portid);
2457 if (isp_login_device(isp, chan, portid, &pdb,
2458 &FCPARAM(isp, 0)->isp_lasthdl)) {
2459 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2464 isp_pdb_add_update(isp, chan, &pdb);
2467 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2469 fcp->isp_loopstate = LOOP_FSCAN_DONE;
2470 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan done", chan);
2471 return (0);
2478 isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
2483 handle = isp_next_handle(isp, ohp);
2484 for (i = 0; i < NPH_MAX_2K; i++) {
2485 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
2486 return (-1);
2489 r = isp_getpdb(isp, chan, handle, p);
2490 if (r == 0) {
2491 if (p->portid != portid) {
2493 handle = isp_next_handle(isp, ohp);
2498 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
2499 return (-1);
2504 r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
2505 if (r == 0) {
2507 } else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
2513 if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL)) {
2514 isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16);
2516 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
2517 return (-1);
2518 r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
2519 if (r != 0)
2522 } else if ((r & 0xffff) == MBOX_LOOP_ID_USED) {
2524 handle = isp_next_handle(isp, ohp);
2533 isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid);
2534 return (-1);
2542 r = isp_getpdb(isp, chan, handle, p);
2543 if (r != 0) {
2544 isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
2545 return (-1);
2548 if (p->handle != handle || p->portid != portid) {
2549 isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
2550 chan, portid, handle, p->portid, p->handle);
2551 return (-1);
2553 return (0);
2557 isp_register_fc4_type(ispsoftc_t *isp, int chan)
2559 fcparam *fcp = FCPARAM(isp, chan);
2562 uint8_t *scp = fcp->isp_scratch;
2564 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2565 isp_prt(isp, ISP_LOGERR, sacq);
2566 return (-1);
2569 /* Build the CT command and execute via pass-through. */
2571 ct->ct_revision = CT_REVISION;
2572 ct->ct_fcs_type = CT_FC_TYPE_FC;
2573 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2574 ct->ct_cmd_resp = SNS_RFT_ID;
2575 ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
2576 rp.rftid_portid[0] = fcp->isp_portid >> 16;
2577 rp.rftid_portid[1] = fcp->isp_portid >> 8;
2578 rp.rftid_portid[2] = fcp->isp_portid;
2579 rp.rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
2580 isp_put_rft_id(isp, &rp, (rft_id_t *)scp);
2582 if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) {
2583 FC_SCRATCH_RELEASE(isp, chan);
2584 return (-1);
2587 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2588 FC_SCRATCH_RELEASE(isp, chan);
2589 if (ct->ct_cmd_resp == LS_RJT) {
2590 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "Chan %d Register FC4 Type rejected", chan);
2591 return (-1);
2592 } else if (ct->ct_cmd_resp == LS_ACC) {
2593 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Register FC4 Type accepted", chan);
2595 isp_prt(isp, ISP_LOGWARN, "Chan %d Register FC4 Type: 0x%x", chan, ct->ct_cmd_resp);
2596 return (-1);
2598 return (0);
2602 isp_register_fc4_features_24xx(ispsoftc_t *isp, int chan)
2604 fcparam *fcp = FCPARAM(isp, chan);
2607 uint8_t *scp = fcp->isp_scratch;
2609 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2610 isp_prt(isp, ISP_LOGERR, sacq);
2611 return (-1);
2619 ct->ct_revision = CT_REVISION;
2620 ct->ct_fcs_type = CT_FC_TYPE_FC;
2621 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2622 ct->ct_cmd_resp = SNS_RFF_ID;
2623 ct->ct_bcnt_resid = (sizeof (rff_id_t) - sizeof (ct_hdr_t)) >> 2;
2624 rp.rffid_portid[0] = fcp->isp_portid >> 16;
2625 rp.rffid_portid[1] = fcp->isp_portid >> 8;
2626 rp.rffid_portid[2] = fcp->isp_portid;
2627 rp.rffid_fc4features = 0;
2628 if (fcp->role & ISP_ROLE_TARGET)
2630 if (fcp->role & ISP_ROLE_INITIATOR)
2633 isp_put_rff_id(isp, &rp, (rff_id_t *)scp);
2634 if (isp->isp_dblev & ISP_LOGDEBUG1)
2635 isp_print_bytes(isp, "CT request", sizeof(rft_id_t), scp);
2637 if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) {
2638 FC_SCRATCH_RELEASE(isp, chan);
2639 return (-1);
2642 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2643 FC_SCRATCH_RELEASE(isp, chan);
2644 if (ct->ct_cmd_resp == LS_RJT) {
2645 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
2647 return (-1);
2648 } else if (ct->ct_cmd_resp == LS_ACC) {
2649 isp_prt(isp, ISP_LOG_SANCFG,
2652 isp_prt(isp, ISP_LOGWARN,
2653 "Chan %d Register FC4 Features: 0x%x", chan, ct->ct_cmd_resp);
2654 return (-1);
2656 return (0);
2660 isp_register_port_name_24xx(ispsoftc_t *isp, int chan)
2662 fcparam *fcp = FCPARAM(isp, chan);
2665 uint8_t *scp = fcp->isp_scratch;
2668 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2669 isp_prt(isp, ISP_LOGERR, sacq);
2670 return (-1);
2678 ct->ct_revision = CT_REVISION;
2679 ct->ct_fcs_type = CT_FC_TYPE_FC;
2680 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2681 ct->ct_cmd_resp = SNS_RSPN_ID;
2682 rp.rspnid_portid[0] = fcp->isp_portid >> 16;
2683 rp.rspnid_portid[1] = fcp->isp_portid >> 8;
2684 rp.rspnid_portid[2] = fcp->isp_portid;
2685 rp.rspnid_length = 0;
2689 "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD");
2692 ":%s", device_get_nameunit(isp->isp_dev));
2693 if (chan != 0) {
2698 ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2;
2699 isp_put_rspn_id(isp, &rp, (rspn_id_t *)scp);
2701 if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) {
2702 FC_SCRATCH_RELEASE(isp, chan);
2703 return (-1);
2706 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2707 FC_SCRATCH_RELEASE(isp, chan);
2708 if (ct->ct_cmd_resp == LS_RJT) {
2709 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
2711 return (-1);
2712 } else if (ct->ct_cmd_resp == LS_ACC) {
2713 isp_prt(isp, ISP_LOG_SANCFG,
2716 isp_prt(isp, ISP_LOGWARN,
2717 "Chan %d Register Symbolic Port Name: 0x%x", chan, ct->ct_cmd_resp);
2718 return (-1);
2720 return (0);
2724 isp_register_node_name_24xx(ispsoftc_t *isp, int chan)
2726 fcparam *fcp = FCPARAM(isp, chan);
2729 uint8_t *scp = fcp->isp_scratch;
2732 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2733 isp_prt(isp, ISP_LOGERR, sacq);
2734 return (-1);
2742 ct->ct_revision = CT_REVISION;
2743 ct->ct_fcs_type = CT_FC_TYPE_FC;
2744 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2745 ct->ct_cmd_resp = SNS_RSNN_NN;
2746 MAKE_NODE_NAME_FROM_WWN(rp.rsnnnn_nodename, fcp->isp_wwnn);
2747 rp.rsnnnn_length = 0;
2751 "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD");
2754 ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2;
2755 isp_put_rsnn_nn(isp, &rp, (rsnn_nn_t *)scp);
2757 if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) {
2758 FC_SCRATCH_RELEASE(isp, chan);
2759 return (-1);
2762 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2763 FC_SCRATCH_RELEASE(isp, chan);
2764 if (ct->ct_cmd_resp == LS_RJT) {
2765 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
2767 return (-1);
2768 } else if (ct->ct_cmd_resp == LS_ACC) {
2769 isp_prt(isp, ISP_LOG_SANCFG,
2772 isp_prt(isp, ISP_LOGWARN,
2773 "Chan %d Register Symbolic Node Name: 0x%x", chan, ct->ct_cmd_resp);
2774 return (-1);
2776 return (0);
2780 isp_next_handle(ispsoftc_t *isp, uint16_t *ohp)
2787 wrap = 0;
2791 handle = 0;
2794 if (handle > NPH_RESERVED - 1) {
2796 isp_prt(isp, ISP_LOGERR, "Out of port handles!");
2799 handle = 0;
2802 for (chan = 0; chan < isp->isp_nchan; chan++) {
2803 fcp = FCPARAM(isp, chan);
2804 if (fcp->role == ISP_ROLE_NONE)
2806 for (i = 0; i < MAX_FC_TARG; i++) {
2807 if (fcp->portdb[i].state != FC_PORTDB_STATE_NIL &&
2808 fcp->portdb[i].handle == handle)
2823 ispsoftc_t *isp;
2832 isp = XS_ISP(xs);
2841 if (XS_CDBLEN(xs) > 16 || XS_CDBLEN(xs) == 0) {
2842 isp_prt(isp, ISP_LOGERR, "unsupported cdb length (%d, CDB[0]=0x%x)", XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
2852 fcp = FCPARAM(isp, XS_CHANNEL(xs));
2854 if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
2855 isp_prt(isp, ISP_LOG_WARN1,
2862 if (isp->isp_state != ISP_RUNSTATE) {
2863 isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
2868 isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d", target);
2869 lp = &fcp->portdb[target];
2870 if (target < 0 || target >= MAX_FC_TARG ||
2871 lp->is_target == 0) {
2875 if (fcp->isp_loopstate != LOOP_READY) {
2876 isp_prt(isp, ISP_LOGDEBUG1,
2881 if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
2882 isp_prt(isp, ISP_LOGDEBUG1,
2887 if (lp->state != FC_PORTDB_STATE_VALID) {
2888 isp_prt(isp, ISP_LOGDEBUG1,
2889 "%d.%d.%jx bad db port state 0x%x",
2890 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs), lp->state);
2897 qep = isp_getrqentry(isp);
2899 isp_prt(isp, ISP_LOG_WARN1, "Request Queue Overflow");
2906 * Now see if we need to synchronize the ISP with respect to anything.
2911 if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) {
2913 m->mrk_header.rqs_entry_count = 1;
2914 m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
2915 m->mrk_modifier = SYNC_ALL;
2916 m->mrk_vphdl = XS_CHANNEL(xs);
2917 isp_put_marker_24xx(isp, m, qep);
2918 ISP_SYNC_REQUEST(isp);
2919 ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0);
2927 if (cdblen > sizeof (reqp->req_cdb)) {
2928 isp_prt(isp, ISP_LOGERR, "Command Length %u too long for this chip", cdblen);
2933 reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
2934 reqp->req_header.rqs_entry_count = 1;
2935 reqp->req_nphdl = lp->handle;
2936 reqp->req_time = XS_TIME(xs);
2937 be64enc(reqp->req_lun, CAM_EXTLUN_BYTE_SWIZZLE(XS_LUN(xs)));
2939 reqp->req_alen_datadir = FCP_CMND_DATA_READ;
2941 reqp->req_alen_datadir = FCP_CMND_DATA_WRITE;
2943 reqp->req_task_attribute = XS_TAG_TYPE(xs);
2945 reqp->req_task_attribute = FCP_CMND_TASK_ATTR_SIMPLE;
2946 reqp->req_task_attribute |= (XS_PRIORITY(xs) << FCP_CMND_PRIO_SHIFT) &
2948 if (FCPARAM(isp, XS_CHANNEL(xs))->fctape_enabled && (lp->prli_word3 & PRLI_WD3_RETRY)) {
2949 if (FCP_NEXT_CRN(isp, &reqp->req_crn, xs)) {
2950 isp_prt(isp, ISP_LOG_WARN1,
2957 ISP_MEMCPY(reqp->req_cdb, XS_CDBP(xs), cdblen);
2958 reqp->req_dl = XS_XFRLEN(xs);
2959 reqp->req_tidlo = lp->portid;
2960 reqp->req_tidhi = lp->portid >> 16;
2961 reqp->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs));
2964 reqp->req_handle = isp_allocate_handle(isp, xs, ISP_HANDLE_INITIATOR);
2965 if (reqp->req_handle == 0) {
2966 isp_prt(isp, ISP_LOG_WARN1, "out of xflist pointers");
2977 dmaresult = ISP_DMASETUP(isp, xs, reqp);
2978 if (dmaresult != 0) {
2979 isp_destroy_handle(isp, reqp->req_handle);
2986 isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "START cmd cdb[0]=0x%x datalen %ld", XS_CDBP(xs)[0], (long) XS_XFRLEN(xs));
2987 return (0);
2991 * isp control
2996 isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
3012 isp_prt(isp, ISP_LOGERR, "BUS RESET NOT IMPLEMENTED");
3024 fcp = FCPARAM(isp, chan);
3026 if (tgt < 0 || tgt >= MAX_FC_TARG) {
3027 isp_prt(isp, ISP_LOGWARN, "Chan %d trying to reset bad target %d", chan, tgt);
3030 lp = &fcp->portdb[tgt];
3031 if (lp->is_target == 0 || lp->state != FC_PORTDB_STATE_VALID) {
3032 isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
3038 tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
3039 tmf->tmf_header.rqs_entry_count = 1;
3040 tmf->tmf_nphdl = lp->handle;
3041 tmf->tmf_delay = 2;
3042 tmf->tmf_timeout = 4;
3043 tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
3044 tmf->tmf_tidlo = lp->portid;
3045 tmf->tmf_tidhi = lp->portid >> 16;
3046 tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
3047 fcp->sendmarker = 1;
3048 isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
3051 if (isp_exec_entry_mbox(isp, tmf, sp, 2 * tmf->tmf_timeout))
3054 if (sp->req_completion_status == 0)
3055 return (0);
3056 isp_prt(isp, ISP_LOGWARN, "Chan %d reset of target %d returned 0x%x", chan, tgt, sp->req_completion_status);
3070 handle = isp_find_handle(isp, xs);
3071 if (handle == 0) {
3072 isp_prt(isp, ISP_LOGWARN, "cannot find handle for command to abort");
3076 fcp = FCPARAM(isp, chan);
3077 if (tgt < 0 || tgt >= MAX_FC_TARG) {
3078 isp_prt(isp, ISP_LOGWARN, "Chan %d trying to abort bad target %d", chan, tgt);
3081 lp = &fcp->portdb[tgt];
3082 if (lp->is_target == 0 || lp->state != FC_PORTDB_STATE_VALID) {
3083 isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
3086 isp_prt(isp, ISP_LOGALL, "Chan %d Abort Cmd for N-Port 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
3088 ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
3089 ab->abrt_header.rqs_entry_count = 1;
3090 ab->abrt_handle = lp->handle;
3091 ab->abrt_cmd_handle = handle;
3092 ab->abrt_tidlo = lp->portid;
3093 ab->abrt_tidhi = lp->portid >> 16;
3094 ab->abrt_vpidx = ISP_GET_VPIDX(isp, chan);
3096 if (isp_exec_entry_mbox(isp, ab, ab, 5))
3099 if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY)
3100 return (0);
3101 isp_prt(isp, ISP_LOGWARN, "Chan %d handle %d abort returned 0x%x", chan, tgt, ab->abrt_nphdl);
3112 if (usdelay == 0)
3114 return (isp_fclink_test(isp, chan, usdelay));
3121 return (isp_scan_fabric(isp, chan));
3128 return (isp_scan_loop(isp, chan));
3135 return (isp_pdb_sync(isp, chan));
3148 return (isp_getpdb(isp, chan, tgt, pdb));
3163 *wwnn = isp_get_wwn(isp, chan, tgt, 1);
3169 *wwnp = isp_get_wwn(isp, chan, tgt, 0);
3174 return (0);
3181 isp_mboxcmd(isp, mbr);
3182 return (0);
3193 if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
3194 return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags));
3197 isp_next_handle(isp, &p->handle);
3198 r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags);
3199 if ((r & 0xffff) == MBOX_PORT_ID_USED) {
3200 p->handle = r >> 16;
3201 r = 0;
3204 } while ((r & 0xffff) == MBOX_LOOP_ID_USED);
3215 return (isp_fc_change_role(isp, chan, role));
3218 isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
3222 return (-1);
3234 isp_intr_atioq(ispsoftc_t *isp)
3239 iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
3240 optr = isp->isp_atioodx;
3243 MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1);
3244 addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
3245 switch (((isphdr_t *)addr)->rqs_entry_type) {
3250 (void) isp_target_notify(isp, addr, &oop,
3251 ATIO_QUEUE_LEN(isp));
3255 isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
3258 optr = ISP_NXT_QENTRY(oop, ATIO_QUEUE_LEN(isp));
3260 if (isp->isp_atioodx != optr) {
3261 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
3262 isp->isp_atioodx = optr;
3268 isp_intr_mbox(ispsoftc_t *isp, uint16_t mbox0)
3272 if (!isp->isp_mboxbsy) {
3273 isp_prt(isp, ISP_LOGWARN, "mailbox 0x%x with no waiters", mbox0);
3276 obits = isp->isp_obits;
3277 isp->isp_mboxtmp[0] = mbox0;
3278 for (i = 1; i < ISP_NMBOX(isp); i++) {
3279 if ((obits & (1 << i)) == 0)
3281 isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
3283 isp->isp_mboxbsy = 0;
3287 isp_intr_respq(ispsoftc_t *isp)
3296 uint32_t iptr, cont = 0, cptr, optr, rlen, slen, totslen;
3304 if (isp->isp_state != ISP_RUNSTATE) {
3305 isp_prt(isp, ISP_LOGINFO, "respq interrupt when not ready");
3309 iptr = ISP_READ(isp, BIU2400_RSPINP);
3310 optr = isp->isp_resodx;
3316 hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, cptr);
3317 optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
3322 MEMORYBARRIER(isp, SYNC_RESULT, cptr, QENTRY_LEN, -1);
3323 if (isp->isp_dblev & ISP_LOGDEBUG1)
3324 isp_print_qentry(isp, "Response Queue Entry", cptr, hp);
3325 isp_get_hdr(isp, hp, &sp->req_header);
3331 if (sp->req_header.rqs_flags & RQSFLAG_BADTYPE) {
3332 isp_print_qentry(isp, "invalid entry type", cptr, hp);
3335 if (sp->req_header.rqs_flags & RQSFLAG_BADPARAM) {
3336 isp_print_qentry(isp, "invalid entry parameter", cptr, hp);
3339 if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
3340 isp_print_qentry(isp, "invalid entry count", cptr, hp);
3343 if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
3344 isp_print_qentry(isp, "invalid entry order", cptr, hp);
3348 etype = sp->req_header.rqs_entry_type;
3351 if (cont > 0 && etype != RQSTYPE_STATUS_CONT) {
3352 cont = 0;
3356 if (isp_handle_control(isp, hp)) {
3363 isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp);
3366 isp_prt(isp, ISP_LOG_WARN1, "Marker Response");
3370 isp_get_cont_response(isp, (ispstatus_cont_t *)hp, scp);
3371 if (cont > 0) {
3372 slen = min(cont, sizeof(scp->req_sense_data));
3373 XS_SENSE_APPEND(cont_xs, scp->req_sense_data, slen);
3374 cont -= slen;
3375 if (cont == 0) {
3378 isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN,
3383 isp_prt(isp, ISP_LOG_WARN1, "Ignored Continuation Response");
3392 isp_target_notify(isp, hp, &cptr, RESULT_QUEUE_LEN(isp));
3396 sptr = ISP_NXT_QENTRY(sptr, RESULT_QUEUE_LEN(isp));
3397 hp = (isphdr_t *)ISP_QUEUE_ENTRY(isp->isp_result, sptr);
3400 optr = ISP_NXT_QENTRY(cptr, RESULT_QUEUE_LEN(isp));
3404 isp_handle_rpt_id_acq(isp, hp);
3408 /* We don't know what was this -- log and skip. */
3409 isp_prt(isp, ISP_LOGERR, notresp, etype, cptr, optr);
3414 xs = isp_find_xs(isp, sp->req_handle);
3420 if (sp->req_completion_status != RQCS_ABORTED &&
3421 sp->req_completion_status != RQCS_RESET_OCCURRED)
3422 isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)",
3423 sp->req_handle, sp->req_completion_status);
3428 resp = snsp = sp->req_rsp_sense;
3429 rlen = slen = totslen = 0;
3430 scsi_status = sp->req_scsi_status;
3432 rlen = sp->req_response_len;
3436 totslen = sp->req_sense_len;
3437 slen = MIN(totslen, sizeof(sp->req_rsp_sense) - rlen);
3439 *XS_STSP(xs) = scsi_status & 0xff;
3441 XS_SET_RESID(xs, sp->req_fcp_residual);
3443 XS_SET_RESID(xs, 0);
3445 if (rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
3463 "Unknown FCP Response Code 0x%x", code);
3468 isp_xs_prt(isp, xs, ISP_LOGWARN,
3469 "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x",
3470 rlen, ptr, XS_CDBP(xs)[0] & 0xff);
3475 isp_parse_status_24xx(isp, sp, xs);
3476 if (slen > 0) {
3479 cont = totslen - slen;
3481 isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN,
3487 ISP_DMAFREE(isp, xs);
3488 isp_destroy_handle(isp, sp->req_handle);
3492 if (cont == 0)
3497 if (cont > 0)
3500 /* If we processed any IOCBs, let ISP know about it. */
3501 if (optr != isp->isp_resodx) {
3502 ISP_WRITE(isp, BIU2400_RSPOUTP, optr);
3503 isp->isp_resodx = optr;
3509 isp_intr_async(ispsoftc_t *isp, uint16_t mbox)
3514 isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
3518 isp->isp_state = ISP_CRASHED;
3519 for (chan = 0; chan < isp->isp_nchan; chan++) {
3520 FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
3521 isp_change_fw_state(isp, chan, FW_CONFIG_WAIT);
3527 if (isp->isp_mboxbsy) {
3528 isp->isp_obits = 1;
3529 isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
3530 isp->isp_mboxbsy = 0;
3536 isp_async(isp, ISPASYNC_FW_CRASH);
3540 isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
3544 isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
3548 isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
3559 for (chan = 0; chan < isp->isp_nchan; chan++) {
3560 fcp = FCPARAM(isp, chan);
3561 int topo = fcp->isp_topo;
3563 if (fcp->role == ISP_ROLE_NONE)
3565 if (fcp->isp_loopstate > LOOP_HAVE_LINK)
3566 fcp->isp_loopstate = LOOP_HAVE_LINK;
3567 ISP_SET_SENDMARKER(isp, chan, 1);
3568 isp_async(isp, ISPASYNC_LIP, chan);
3570 isp_target_async(isp, chan, mbox);
3581 for (i = j = 0; i < ISP_HANDLE_NUM(isp); i++) {
3585 hdp = &isp->isp_xflist[i];
3586 if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) {
3589 xs = hdp->cmd;
3594 isp_prt(isp, ISP_LOG_WARN1,
3602 isp_prt(isp, ISP_LOGERR, lipd, chan, j);
3613 for (chan = 0; chan < isp->isp_nchan; chan++) {
3614 fcp = FCPARAM(isp, chan);
3615 if (fcp->role == ISP_ROLE_NONE)
3617 fcp->isp_linkstate = 1;
3618 if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3619 fcp->isp_loopstate = LOOP_HAVE_LINK;
3620 ISP_SET_SENDMARKER(isp, chan, 1);
3621 isp_async(isp, ISPASYNC_LOOP_UP, chan);
3623 isp_target_async(isp, chan, mbox);
3633 for (chan = 0; chan < isp->isp_nchan; chan++) {
3634 fcp = FCPARAM(isp, chan);
3635 if (fcp->role == ISP_ROLE_NONE)
3637 ISP_SET_SENDMARKER(isp, chan, 1);
3638 fcp->isp_linkstate = 0;
3639 fcp->isp_loopstate = LOOP_NIL;
3640 isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
3642 isp_target_async(isp, chan, mbox);
3652 for (chan = 0; chan < isp->isp_nchan; chan++) {
3653 fcp = FCPARAM(isp, chan);
3654 if (fcp->role == ISP_ROLE_NONE)
3656 ISP_SET_SENDMARKER(isp, chan, 1);
3657 if (fcp->isp_loopstate > LOOP_HAVE_LINK)
3658 fcp->isp_loopstate = LOOP_HAVE_LINK;
3659 isp_async(isp, ISPASYNC_LOOP_RESET, chan);
3661 isp_target_async(isp, chan, mbox);
3670 nphdl = ISP_READ(isp, OUTMAILBOX1);
3671 nlstate = ISP_READ(isp, OUTMAILBOX2);
3672 reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
3673 if (ISP_CAP_MULTI_ID(isp)) {
3674 chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;
3675 if (chan == 0xff || nphdl == NIL_HANDLE) {
3676 chan = 0;
3677 echan = isp->isp_nchan - 1;
3678 } else if (chan >= isp->isp_nchan) {
3684 chan = echan = 0;
3687 fcp = FCPARAM(isp, chan);
3688 if (fcp->role == ISP_ROLE_NONE)
3690 if (fcp->isp_loopstate > LOOP_LTEST_DONE) {
3692 nphdl == fcp->isp_login_hdl &&
3695 fcp->isp_loopstate = LOOP_LTEST_DONE;
3696 } else if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3697 fcp->isp_loopstate = LOOP_HAVE_LINK;
3698 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
3707 portid = ((ISP_READ(isp, OUTMAILBOX1) & 0xff) << 16) |
3708 ISP_READ(isp, OUTMAILBOX2);
3709 if (ISP_CAP_MULTI_ID(isp)) {
3710 chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;
3711 if (chan >= isp->isp_nchan)
3714 chan = 0;
3716 fcp = FCPARAM(isp, chan);
3717 if (fcp->role == ISP_ROLE_NONE)
3719 if (fcp->isp_loopstate > LOOP_LTEST_DONE)
3720 fcp->isp_loopstate = LOOP_LTEST_DONE;
3721 else if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3722 fcp->isp_loopstate = LOOP_HAVE_LINK;
3723 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
3728 isp_prt(isp, ISP_LOGWARN, "Error logging disabled (reason 0x%x)",
3729 ISP_READ(isp, OUTMAILBOX1));
3732 isp_prt(isp, ISP_LOGWARN, "P2P init error (reason 0x%x)",
3733 ISP_READ(isp, OUTMAILBOX1));
3736 isp_prt(isp, ISP_LOGWARN, "Receive Error");
3739 isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
3742 isp_prt(isp, ISP_LOGDEBUG0, "FW restart complete");
3745 isp_prt(isp, ISP_LOGERR, "Temperature alert (subcode 0x%x)",
3746 ISP_READ(isp, OUTMAILBOX1));
3749 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication complete");
3752 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication notification");
3755 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication time extended");
3758 isp_prt(isp, ISP_LOGDEBUG0, "Transceiver insertion (0x%x)",
3759 ISP_READ(isp, OUTMAILBOX1));
3762 isp_prt(isp, ISP_LOGDEBUG0, "Transceiver removal");
3765 isp_prt(isp, ISP_LOGDEBUG0, "NIC Firmware State Change");
3768 isp_prt(isp, ISP_LOGDEBUG0, "Autoload FW init complete");
3771 isp_prt(isp, ISP_LOGERR, "Autoload FW init failure");
3774 isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
3783 isp_handle_control(ispsoftc_t *isp, isphdr_t *hp)
3788 switch (hp->rqs_entry_type) {
3801 ISP_IOXGET_32(isp, (uint32_t *)(hp + 1), hdl);
3804 ptr = isp_find_xs(isp, hdl);
3806 isp_destroy_handle(isp, hdl);
3812 return (0);
3816 isp_handle_rpt_id_acq(ispsoftc_t *isp, isphdr_t *hp)
3823 isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
3826 if (rid.ridacq_format == 0) {
3827 for (chan = 0; chan < isp->isp_nchan; chan++) {
3828 fcp = FCPARAM(isp, chan);
3829 if (fcp->role == ISP_ROLE_NONE)
3831 c = (chan == 0) ? 127 : (chan - 1);
3833 chan == 0) {
3834 fcp->isp_loopstate = LOOP_HAVE_LINK;
3835 isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
3838 fcp->isp_loopstate = LOOP_NIL;
3839 isp_async(isp, ISPASYNC_LOOP_DOWN,
3844 fcp = FCPARAM(isp, rid.ridacq_vp_index);
3847 fcp->isp_topo = (rid.ridacq_map[0] >> 9) & 0x7;
3848 fcp->isp_portid = portid;
3849 fcp->isp_loopstate = LOOP_HAVE_ADDR;
3850 isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
3853 fcp->isp_loopstate = LOOP_NIL;
3854 isp_async(isp, ISPASYNC_LOOP_DOWN,
3861 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs)
3866 switch (sp->req_completion_status) {
3871 isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error");
3877 isp_xs_prt(isp, xs, ISP_LOGERR, "Transport Error");
3883 isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command");
3884 FCPARAM(isp, chan)->sendmarker = 1;
3890 isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
3891 FCPARAM(isp, chan)->sendmarker = 1;
3897 isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out");
3903 XS_SET_RESID(xs, sp->req_resid);
3904 isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun");
3910 isp_prt(isp, ISP_LOGERR, "Chan %d data reassembly error for target %d", chan, XS_TGT(xs));
3916 isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS", chan, XS_TGT(xs));
3922 ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
3925 * if we got a non-zero status.
3927 sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
3928 if ((ru_marked == 0 && sv_marked == 0) ||
3929 (sp->req_resid > XS_XFRLEN(xs))) {
3930 isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
3935 XS_SET_RESID(xs, sp->req_resid);
3936 isp_xs_prt(isp, xs, ISP_LOG_WARN1, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff);
3946 uint8_t sts = sp->req_completion_status & 0xff;
3947 fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
3951 * It was there (maybe)- treat as a selection timeout.
3959 isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d",
3965 lp = &fcp->portdb[XS_TGT(xs)];
3966 if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
3975 isp_prt(isp, ISP_LOGWARN, "port changed for target %d chan %d", XS_TGT(xs), chan);
3983 isp_prt(isp, ISP_LOGWARN, "f/w resource unavailable for target %d chan %d", XS_TGT(xs), chan);
3991 isp_prt(isp, ISP_LOGWARN, "command for target %d overlapped task management for chan %d", XS_TGT(xs), chan);
3999 isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x on chan %d", sp->req_completion_status, chan);
4006 #define ISP_FC_IBITS(op) ((mbpfc[((op)<<3) + 0] << 24) | (mbpfc[((op)<<3) + 1] << 16) | (mbpfc[((op)<<3) + 2] << 8) | (mbpfc[((op)<<3) + 3]))
4009 #define ISP_FC_OPMAP(in0, out0) 0, 0, 0, in0, 0, 0, 0, out0
4010 #define ISP_FC_OPMAP_HALF(in1, in0, out1, out0) 0, 0, in1, in0, 0, 0, out1, out0
4013 ISP_FC_OPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */
4014 ISP_FC_OPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */
4015 ISP_FC_OPMAP_HALF(0x07, 0xff, 0x00, 0x1f), /* 0x02: MBOX_EXEC_FIRMWARE */
4016 ISP_FC_OPMAP(0x01, 0x07), /* 0x03: MBOX_LOAD_FLASH_FIRMWARE */
4017 ISP_FC_OPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */
4018 ISP_FC_OPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */
4019 ISP_FC_OPMAP_FULL(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff), /* 0x06: MBOX_MAILBOX_REG_TEST */
4020 ISP_FC_OPMAP(0x07, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */
4021 ISP_FC_OPMAP_FULL(0x0, 0x0, 0x0, 0x01, 0x0, 0x3, 0x80, 0x7f), /* 0x08: MBOX_ABOUT_FIRMWARE */
4022 ISP_FC_OPMAP(0xdf, 0x01), /* 0x09: MBOX_LOAD_RISC_RAM_2100 */
4023 ISP_FC_OPMAP(0xdf, 0x01), /* 0x0a: MBOX_DUMP_RISC_RAM_2100 */
4024 ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x01), /* 0x0b: MBOX_LOAD_RISC_RAM */
4025 ISP_FC_OPMAP(0x00, 0x00), /* 0x0c: */
4026 ISP_FC_OPMAP_HALF(0x1, 0x0f, 0x0, 0x01), /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
4027 ISP_FC_OPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */
4028 ISP_FC_OPMAP_HALF(0x1, 0x03, 0x0, 0x0d), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
4029 ISP_FC_OPMAP(0x1f, 0x11), /* 0x10: MBOX_INIT_REQ_QUEUE */
4030 ISP_FC_OPMAP(0x2f, 0x21), /* 0x11: MBOX_INIT_RES_QUEUE */
4031 ISP_FC_OPMAP(0x0f, 0x01), /* 0x12: MBOX_EXECUTE_IOCB */
4032 ISP_FC_OPMAP(0x03, 0x03), /* 0x13: MBOX_WAKE_UP */
4033 ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x03), /* 0x14: MBOX_STOP_FIRMWARE */
4034 ISP_FC_OPMAP(0x4f, 0x01), /* 0x15: MBOX_ABORT */
4035 ISP_FC_OPMAP(0x07, 0x01), /* 0x16: MBOX_ABORT_DEVICE */
4036 ISP_FC_OPMAP(0x07, 0x01), /* 0x17: MBOX_ABORT_TARGET */
4037 ISP_FC_OPMAP(0x03, 0x03), /* 0x18: MBOX_BUS_RESET */
4038 ISP_FC_OPMAP(0x07, 0x05), /* 0x19: MBOX_STOP_QUEUE */
4039 ISP_FC_OPMAP(0x07, 0x05), /* 0x1a: MBOX_START_QUEUE */
4040 ISP_FC_OPMAP(0x07, 0x05), /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
4041 ISP_FC_OPMAP(0x07, 0x05), /* 0x1c: MBOX_ABORT_QUEUE */
4042 ISP_FC_OPMAP(0x07, 0x03), /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
4043 ISP_FC_OPMAP(0x00, 0x00), /* 0x1e: */
4044 ISP_FC_OPMAP(0x01, 0x07), /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
4045 ISP_FC_OPMAP_HALF(0x2, 0x01, 0x7e, 0xcf), /* 0x20: MBOX_GET_LOOP_ID */
4046 ISP_FC_OPMAP(0x00, 0x00), /* 0x21: */
4047 ISP_FC_OPMAP(0x03, 0x4b), /* 0x22: MBOX_GET_TIMEOUT_PARAMS */
4048 ISP_FC_OPMAP(0x00, 0x00), /* 0x23: */
4049 ISP_FC_OPMAP(0x00, 0x00), /* 0x24: */
4050 ISP_FC_OPMAP(0x00, 0x00), /* 0x25: */
4051 ISP_FC_OPMAP(0x00, 0x00), /* 0x26: */
4052 ISP_FC_OPMAP(0x00, 0x00), /* 0x27: */
4053 ISP_FC_OPMAP(0x01, 0x03), /* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
4054 ISP_FC_OPMAP(0x03, 0x07), /* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
4055 ISP_FC_OPMAP(0x00, 0x00), /* 0x2a: */
4056 ISP_FC_OPMAP(0x00, 0x00), /* 0x2b: */
4057 ISP_FC_OPMAP(0x00, 0x00), /* 0x2c: */
4058 ISP_FC_OPMAP(0x00, 0x00), /* 0x2d: */
4059 ISP_FC_OPMAP(0x00, 0x00), /* 0x2e: */
4060 ISP_FC_OPMAP(0x00, 0x00), /* 0x2f: */
4061 ISP_FC_OPMAP(0x00, 0x00), /* 0x30: */
4062 ISP_FC_OPMAP(0x00, 0x00), /* 0x31: */
4063 ISP_FC_OPMAP(0x4b, 0x4b), /* 0x32: MBOX_SET_TIMEOUT_PARAMS */
4064 ISP_FC_OPMAP(0x00, 0x00), /* 0x33: */
4065 ISP_FC_OPMAP(0x00, 0x00), /* 0x34: */
4066 ISP_FC_OPMAP(0x00, 0x00), /* 0x35: */
4067 ISP_FC_OPMAP(0x00, 0x00), /* 0x36: */
4068 ISP_FC_OPMAP(0x00, 0x00), /* 0x37: */
4069 ISP_FC_OPMAP(0x0f, 0x01), /* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
4070 ISP_FC_OPMAP(0x0f, 0x07), /* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
4071 ISP_FC_OPMAP(0x00, 0x00), /* 0x3a: */
4072 ISP_FC_OPMAP(0x00, 0x00), /* 0x3b: */
4073 ISP_FC_OPMAP(0x00, 0x00), /* 0x3c: */
4074 ISP_FC_OPMAP(0x00, 0x00), /* 0x3d: */
4075 ISP_FC_OPMAP(0x00, 0x00), /* 0x3e: */
4076 ISP_FC_OPMAP(0x00, 0x00), /* 0x3f: */
4077 ISP_FC_OPMAP(0x03, 0x01), /* 0x40: MBOX_LOOP_PORT_BYPASS */
4078 ISP_FC_OPMAP(0x03, 0x01), /* 0x41: MBOX_LOOP_PORT_ENABLE */
4079 ISP_FC_OPMAP_HALF(0x0, 0x01, 0x1f, 0xcf), /* 0x42: MBOX_GET_RESOURCE_COUNT */
4080 ISP_FC_OPMAP(0x01, 0x01), /* 0x43: MBOX_REQUEST_OFFLINE_MODE */
4081 ISP_FC_OPMAP(0x00, 0x00), /* 0x44: */
4082 ISP_FC_OPMAP(0x00, 0x00), /* 0x45: */
4083 ISP_FC_OPMAP(0x00, 0x00), /* 0x46: */
4084 ISP_FC_OPMAP(0xcf, 0x03), /* 0x47: GET PORT_DATABASE ENHANCED */
4085 ISP_FC_OPMAP(0xcf, 0x0f), /* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */
4086 ISP_FC_OPMAP(0xcd, 0x01), /* 0x49: MBOX_GET_VP_DATABASE */
4087 ISP_FC_OPMAP_HALF(0x2, 0xcd, 0x0, 0x01), /* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */
4088 ISP_FC_OPMAP(0x00, 0x00), /* 0x4b: */
4089 ISP_FC_OPMAP(0x00, 0x00), /* 0x4c: */
4090 ISP_FC_OPMAP(0x00, 0x00), /* 0x4d: */
4091 ISP_FC_OPMAP(0x00, 0x00), /* 0x4e: */
4092 ISP_FC_OPMAP(0x00, 0x00), /* 0x4f: */
4093 ISP_FC_OPMAP(0x00, 0x00), /* 0x50: */
4094 ISP_FC_OPMAP(0x00, 0x00), /* 0x51: */
4095 ISP_FC_OPMAP(0x00, 0x00), /* 0x52: */
4096 ISP_FC_OPMAP(0x00, 0x00), /* 0x53: */
4097 ISP_FC_OPMAP(0xcf, 0x01), /* 0x54: EXECUTE IOCB A64 */
4098 ISP_FC_OPMAP(0x00, 0x00), /* 0x55: */
4099 ISP_FC_OPMAP(0x00, 0x00), /* 0x56: */
4100 ISP_FC_OPMAP(0x00, 0x00), /* 0x57: */
4101 ISP_FC_OPMAP(0x00, 0x00), /* 0x58: */
4102 ISP_FC_OPMAP(0x00, 0x00), /* 0x59: */
4103 ISP_FC_OPMAP(0x00, 0x00), /* 0x5a: */
4104 ISP_FC_OPMAP(0x03, 0x01), /* 0x5b: MBOX_DRIVER_HEARTBEAT */
4105 ISP_FC_OPMAP(0xcf, 0x01), /* 0x5c: MBOX_FW_HEARTBEAT */
4106 ISP_FC_OPMAP(0x07, 0x1f), /* 0x5d: MBOX_GET_SET_DATA_RATE */
4107 ISP_FC_OPMAP(0x00, 0x00), /* 0x5e: */
4108 ISP_FC_OPMAP(0x00, 0x00), /* 0x5f: */
4109 ISP_FC_OPMAP(0xcf, 0x0f), /* 0x60: MBOX_INIT_FIRMWARE */
4110 ISP_FC_OPMAP(0x00, 0x00), /* 0x61: */
4111 ISP_FC_OPMAP(0x01, 0x01), /* 0x62: MBOX_INIT_LIP */
4112 ISP_FC_OPMAP(0xcd, 0x03), /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
4113 ISP_FC_OPMAP(0xcf, 0x01), /* 0x64: MBOX_GET_PORT_DB */
4114 ISP_FC_OPMAP(0x07, 0x01), /* 0x65: MBOX_CLEAR_ACA */
4115 ISP_FC_OPMAP(0x07, 0x01), /* 0x66: MBOX_TARGET_RESET */
4116 ISP_FC_OPMAP(0x07, 0x01), /* 0x67: MBOX_CLEAR_TASK_SET */
4117 ISP_FC_OPMAP(0x07, 0x01), /* 0x68: MBOX_ABORT_TASK_SET */
4118 ISP_FC_OPMAP_HALF(0x00, 0x01, 0x0f, 0x1f), /* 0x69: MBOX_GET_FW_STATE */
4119 ISP_FC_OPMAP_HALF(0x6, 0x03, 0x0, 0xcf), /* 0x6a: MBOX_GET_PORT_NAME */
4120 ISP_FC_OPMAP(0xcf, 0x01), /* 0x6b: MBOX_GET_LINK_STATUS */
4121 ISP_FC_OPMAP(0x0f, 0x01), /* 0x6c: MBOX_INIT_LIP_RESET */
4122 ISP_FC_OPMAP(0x00, 0x00), /* 0x6d: */
4123 ISP_FC_OPMAP(0xcf, 0x03), /* 0x6e: MBOX_SEND_SNS */
4124 ISP_FC_OPMAP(0x0f, 0x07), /* 0x6f: MBOX_FABRIC_LOGIN */
4125 ISP_FC_OPMAP_HALF(0x02, 0x03, 0x00, 0x03), /* 0x70: MBOX_SEND_CHANGE_REQUEST */
4126 ISP_FC_OPMAP(0x03, 0x03), /* 0x71: MBOX_FABRIC_LOGOUT */
4127 ISP_FC_OPMAP(0x0f, 0x0f), /* 0x72: MBOX_INIT_LIP_LOGIN */
4128 ISP_FC_OPMAP(0x00, 0x00), /* 0x73: */
4129 ISP_FC_OPMAP(0x07, 0x01), /* 0x74: LOGIN LOOP PORT */
4130 ISP_FC_OPMAP_HALF(0x03, 0xcf, 0x00, 0x07), /* 0x75: GET PORT/NODE NAME LIST */
4131 ISP_FC_OPMAP(0x4f, 0x01), /* 0x76: SET VENDOR ID */
4132 ISP_FC_OPMAP(0xcd, 0x01), /* 0x77: INITIALIZE IP MAILBOX */
4133 ISP_FC_OPMAP(0x00, 0x00), /* 0x78: */
4134 ISP_FC_OPMAP(0x00, 0x00), /* 0x79: */
4135 ISP_FC_OPMAP(0x00, 0x00), /* 0x7a: */
4136 ISP_FC_OPMAP(0x00, 0x00), /* 0x7b: */
4137 ISP_FC_OPMAP_HALF(0x03, 0x4f, 0x00, 0x07), /* 0x7c: Get ID List */
4138 ISP_FC_OPMAP(0xcf, 0x01), /* 0x7d: SEND LFA */
4139 ISP_FC_OPMAP(0x0f, 0x01) /* 0x7e: LUN RESET */
4141 #define MAX_FC_OPCODE 0x7e
4152 "NO-OP", /* 00h */
4251 "GET FC-AL POSITION MAP",
4282 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
4288 opcode = mbp->param[0];
4290 mbp->param[0] = MBOX_INVALID_COMMAND;
4291 isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
4301 isp_prt(isp, ISP_LOGDEBUG3, "Mailbox Command '%s'", cname);
4306 ibits |= mbp->ibits;
4307 obits |= mbp->obits;
4312 ibits &= mbp->ibitm;
4313 obits &= mbp->obitm;
4316 if (ibits == 0 && obits == 0) {
4317 mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
4318 isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
4322 for (box = 0; box < ISP_NMBOX(isp); box++) {
4324 isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box,
4325 mbp->param[box]);
4326 ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
4328 isp->isp_mboxtmp[box] = mbp->param[box] = 0;
4331 isp->isp_obits = obits;
4332 isp->isp_mboxbsy = 1;
4337 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
4342 to = (mbp->timeout == 0) ? MBCMD_DEFAULT_TIMEOUT : mbp->timeout;
4343 for (t = 0; t < to; t += 100) {
4344 if (!isp->isp_mboxbsy)
4346 ISP_RUN_ISR(isp);
4347 if (!isp->isp_mboxbsy)
4355 if (isp->isp_mboxbsy) {
4356 isp->isp_mboxbsy = 0;
4357 isp_prt(isp, ISP_LOGWARN, "Mailbox Command (0x%x) Timeout (%uus) (%s:%d)",
4358 opcode, to, mbp->func, mbp->lineno);
4359 mbp->param[0] = MBOX_TIMEOUT;
4366 for (box = 0; box < ISP_NMBOX(isp); box++) {
4368 mbp->param[box] = isp->isp_mboxtmp[box];
4369 isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box,
4370 mbp->param[box]);
4375 if (mbp->logval == 0 || mbp->param[0] == MBOX_COMMAND_COMPLETE)
4378 if ((mbp->param[0] & 0xbfe0) == 0 &&
4379 (mbp->logval & MBLOGMASK(mbp->param[0])) == 0)
4384 switch (mbp->param[0]) {
4396 ISP_SNPRINTF(mname, sizeof(mname), " subcode 0x%x",
4397 mbp->param[1]);
4434 ISP_SNPRINTF(mname, sizeof(mname), "error 0x%x", mbp->param[0]);
4439 isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s%s)",
4445 isp_fw_state(ispsoftc_t *isp, int chan)
4449 MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0);
4450 isp_mboxcmd(isp, &mbs);
4451 if (mbs.param[0] == MBOX_COMMAND_COMPLETE)
4457 isp_setdfltfcparm(ispsoftc_t *isp, int chan)
4459 fcparam *fcp = FCPARAM(isp, chan);
4464 fcp->role = DEFAULT_ROLE(isp, chan);
4465 fcp->isp_retry_delay = ICB_DFLT_RDELAY;
4466 fcp->isp_retry_count = ICB_DFLT_RCOUNT;
4467 fcp->isp_loopid = DEFAULT_LOOPID(isp, chan);
4468 fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
4469 fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
4470 fcp->isp_fwoptions = 0;
4471 fcp->isp_xfwoptions = 0;
4472 fcp->isp_zfwoptions = 0;
4473 fcp->isp_lasthdl = NIL_HANDLE;
4474 fcp->isp_login_hdl = NIL_HANDLE;
4476 fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS;
4477 fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS;
4478 if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
4479 fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
4480 fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
4481 fcp->isp_xfwoptions |= ICB2400_OPT2_LOOP_2_PTP;
4482 fcp->isp_zfwoptions |= ICB2400_OPT3_RATE_AUTO;
4488 if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
4489 int i, j = 0;
4493 for (i = 0; i < 2; i++) {
4494 j = isp_read_nvram(isp);
4495 if (j == 0) {
4500 isp->isp_confopts |= ISP_CFG_NONVRAM;
4504 fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan);
4505 fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan);
4506 isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s",
4507 chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn),
4508 (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn),
4509 isp_class3_roles[fcp->role]);
4513 * Re-initialize the ISP and complete all orphaned commands
4519 isp_reinit(ispsoftc_t *isp, int do_load_defaults)
4521 int i, res = 0;
4523 if (isp->isp_state > ISP_RESETSTATE)
4524 isp_stop(isp);
4525 if (isp->isp_state != ISP_RESETSTATE)
4526 isp_reset(isp, do_load_defaults);
4527 if (isp->isp_state != ISP_RESETSTATE) {
4529 isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
4533 isp_init(isp);
4534 if (isp->isp_state > ISP_RESETSTATE &&
4535 isp->isp_state != ISP_RUNSTATE) {
4537 isp_prt(isp, ISP_LOGERR, "%s: cannot init card", __func__);
4538 ISP_DISABLE_INTS(isp);
4542 isp_clear_commands(isp);
4543 for (i = 0; i < isp->isp_nchan; i++)
4544 isp_clear_portdb(isp, i);
4552 flash_data_addr(ispsoftc_t *isp, uint32_t faddr)
4554 fcparam *fcp = FCPARAM(isp, 0);
4556 return (fcp->flash_data_addr + faddr);
4560 isp_read_flash_dword(ispsoftc_t *isp, uint32_t addr, uint32_t *data)
4562 int loops = 0;
4564 ISP_WRITE(isp, BIU2400_FLASH_ADDR, addr & ~0x80000000);
4565 for (loops = 0; loops < 30000; loops++) {
4566 if (ISP_READ(isp, BIU2400_FLASH_ADDR & 0x80000000)) {
4567 *data = ISP_READ(isp, BIU2400_FLASH_DATA);
4572 isp_prt(isp, ISP_LOGERR,
4573 "Flash read dword at 0x%x timeout.", addr);
4574 *data = 0xffffffff;
4579 isp_read_flash_data(ispsoftc_t *isp, uint32_t *dwptr, uint32_t faddr, uint32_t dwords)
4581 int loops = 0;
4585 faddr = flash_data_addr(isp, faddr);
4586 for (loops = 0; loops < dwords; loops++, faddr++, dwptr++) {
4587 rval = isp_read_flash_dword(isp, faddr, dwptr);
4597 isp_rd_2xxx_flash(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
4599 fcparam *fcp = FCPARAM(isp, 0);
4600 int loops = 0;
4601 uint32_t base = fcp->flash_data_addr;
4603 ISP_WRITE(isp, BIU2400_FLASH_ADDR, (base + addr) & ~0x80000000);
4604 for (loops = 0; loops < 30000; loops++) {
4606 if (ISP_READ(isp, BIU2400_FLASH_ADDR & 0x80000000)) {
4607 *rp = ISP_READ(isp, BIU2400_FLASH_DATA);
4608 ISP_SWIZZLE_NVRAM_LONG(isp, rp);
4612 isp_prt(isp, ISP_LOGERR,
4613 "Flash read dword at 0x%x timeout.", (base + addr));
4614 *rp = 0xffffffff;
4618 isp_read_flthdr_2xxx(ispsoftc_t *isp)
4620 fcparam *fcp = FCPARAM(isp, 0);
4621 int retval = 0;
4626 addr = fcp->flt_region_flt;
4629 isp_prt(isp, ISP_LOGDEBUG0, "FLTL[DEF]: 0x%x", addr);
4630 for (lwrds = 0; lwrds < FLT_HEADER_SIZE >> 2; lwrds++) {
4631 isp_rd_2xxx_flash(isp, addr++, dptr++);
4634 for (csum = 0, lwrds = 0; lwrds < FLT_HEADER_SIZE >> 4; lwrds++) {
4636 ISP_IOXGET_16(isp, &dptr[lwrds], tmp);
4639 if (csum != 0) {
4640 retval = -1;
4643 isp_parse_flthdr_2xxx(isp, flthdr_data);
4649 isp_parse_flthdr_2xxx(ispsoftc_t *isp, uint8_t *flthdr_data)
4651 fcparam *fcp = FCPARAM(isp, 0);
4655 fcp->flt_length = le16toh((uint16_t) (ISP2XXX_FLT_LENGTH(flthdr_data)));
4658 if ((fcp->flt_length == 0) ||
4659 (fcp->flt_length > (FLT_HEADER_SIZE + FLT_REGIONS_SIZE))) {
4660 isp_prt(isp, ISP_LOGERR,
4661 "FLT[DEF]: Invalid length=0x%x(%d)",
4662 fcp->flt_length, fcp->flt_length);
4664 isp_prt(isp, ISP_LOGDEBUG0,
4665 "FLT[DEF]: version=0x%x length=0x%x(%d) checksum=0x%x",
4666 ver, fcp->flt_length, fcp->flt_length, csum);
4670 isp_read_flt_2xxx(ispsoftc_t *isp)
4672 fcparam *fcp = FCPARAM(isp, 0);
4673 int retval = 0;
4674 int len = fcp->flt_length - FLT_HEADER_SIZE;
4677 fcp->flt_region_entries = len / FLT_REGION_SIZE;
4679 addr = fcp->flt_region_flt + (FLT_HEADER_SIZE >> 2);
4681 isp_prt(isp, ISP_LOGDEBUG0, "FLT[DEF]: regions=%d",
4682 fcp->flt_region_entries);
4683 for (lwrds = 0; lwrds < len >> 2; lwrds++) {
4684 isp_rd_2xxx_flash(isp, addr++, dptr++);
4686 retval = isp_parse_flt_2xxx(isp, flt_data);
4691 isp_parse_flt_2xxx(ispsoftc_t *isp, uint8_t *flt_data)
4693 fcparam *fcp = FCPARAM(isp, 0);
4695 struct flt_region region[fcp->flt_region_entries];
4697 for (count = 0; count < fcp->flt_region_entries; count++) {
4711 isp_prt(isp, ISP_LOGDEBUG0,
4712 "FLT[0x%x]: start=0x%x end=0x%x size=0x%x attribute=0x%x",
4718 fcp->flt_region_fw = region[count].start;
4721 fcp->flt_region_boot = region[count].start;
4724 fcp->flt_region_vpd_nvram = region[count].start;
4725 if (isp->isp_port == 0)
4726 fcp->flt_region_vpd = region[count].start;
4729 if (isp->isp_port == 1)
4730 fcp->flt_region_vpd = region[count].start;
4733 if (!IS_27XX(isp))
4735 if (isp->isp_port == 2)
4736 fcp->flt_region_vpd = region[count].start;
4739 if (!IS_27XX(isp))
4741 if (isp->isp_port == 3)
4742 fcp->flt_region_vpd = region[count].start;
4745 if (isp->isp_port == 0)
4746 fcp->flt_region_nvram = region[count].start;
4749 if (isp->isp_port == 1)
4750 fcp->flt_region_nvram = region[count].start;
4753 if (!IS_27XX(isp))
4755 if (isp->isp_port == 2)
4756 fcp->flt_region_nvram = region[count].start;
4759 if (!IS_27XX(isp))
4761 if (isp->isp_port == 3)
4762 fcp->flt_region_nvram = region[count].start;
4765 fcp->flt_region_fdt = region[count].start;
4768 fcp->flt_region_flt = region[count].start;
4771 if (isp->isp_port == 0)
4772 fcp->flt_region_npiv_conf = region[count].start;
4775 if (isp->isp_port == 1)
4776 fcp->flt_region_npiv_conf = region[count].start;
4779 fcp->flt_region_gold_fw = region[count].start;
4782 if (isp->isp_port == 0)
4783 fcp->flt_region_fcp_prio = region[count].start;
4786 if (isp->isp_port == 1)
4787 fcp->flt_region_fcp_prio = region[count].start;
4790 if (IS_27XX(isp))
4791 fcp->flt_region_img_status_pri = region[count].start;
4794 if (IS_27XX(isp))
4795 fcp->flt_region_img_status_sec = region[count].start;
4798 if (IS_27XX(isp))
4799 fcp->flt_region_fw_sec = region[count].start;
4802 if (IS_27XX(isp))
4803 fcp->flt_region_boot_sec = region[count].start;
4806 if (IS_27XX(isp))
4807 fcp->flt_region_aux_img_status_pri = region[count].start;
4810 if (IS_27XX(isp))
4811 fcp->flt_region_aux_img_status_sec = region[count].start;
4814 if (IS_27XX(isp))
4815 if (isp->isp_port == 0)
4816 fcp->flt_region_nvram_sec = region[count].start;
4819 if (IS_27XX(isp))
4820 if (isp->isp_port == 1)
4821 fcp->flt_region_nvram_sec = region[count].start;
4824 if (IS_27XX(isp))
4825 if (isp->isp_port == 2)
4826 fcp->flt_region_nvram_sec = region[count].start;
4829 if (IS_27XX(isp))
4830 if (isp->isp_port == 3)
4831 fcp->flt_region_nvram_sec = region[count].start;
4835 if (IS_27XX(isp)) {
4836 fcp->flt_region_vpd_nvram_sec = region[count].start;
4837 if (isp->isp_port == 0)
4838 fcp->flt_region_vpd_sec = region[count].start;
4843 if (IS_27XX(isp))
4844 if (isp->isp_port == 1)
4845 fcp->flt_region_vpd_sec = region[count].start;
4849 if (IS_27XX(isp))
4850 if (isp->isp_port == 2)
4851 fcp->flt_region_vpd_sec = region[count].start;
4855 if (IS_27XX(isp))
4856 if (isp->isp_port == 3)
4857 fcp->flt_region_vpd_sec = region[count].start;
4861 isp_prt(isp, ISP_LOGCONFIG,
4862 "FLT[FLT]: boot=0x%x fw=0x%x vpd_nvram=0x%x vpd=0x%x nvram=0x%x "
4863 "fdt=0x%x flt=0x%x npiv=0x%x fcp_prif_cfg=0x%x",
4864 fcp->flt_region_boot, fcp->flt_region_fw, fcp->flt_region_vpd_nvram,
4865 fcp->flt_region_vpd, fcp->flt_region_nvram, fcp->flt_region_fdt,
4866 fcp->flt_region_flt, fcp->flt_region_npiv_conf,
4867 fcp->flt_region_fcp_prio);
4869 return (0);
4873 isp_print_image(ispsoftc_t *isp, char *name, struct isp_image_status *image_status)
4875 isp_prt(isp, ISP_LOGDEBUG0,
4876 "%s %s: mask=0x%02x gen=0x%04x ver=%u.%u map=0x%01x sum=0x%08x sig=0x%08x",
4878 image_status->image_status_mask,
4879 le16toh(image_status->generation),
4880 image_status->ver_major,
4881 image_status->ver_minor,
4882 image_status->bitmap,
4883 le32toh(image_status->checksum),
4884 le32toh(image_status->signature));
4890 unsigned long signature = le32toh(image_status->signature);
4898 unsigned long signature = le32toh(image_status->signature);
4909 uint32_t sum = 0;
4911 for ( ; n--; p++)
4920 return (aux->bitmap & bitmask ?
4927 active_regions->aux.board_config =
4930 active_regions->aux.vpd_nvram =
4933 active_regions->aux.npiv_config_0_1 =
4936 active_regions->aux.npiv_config_2_3 =
4939 active_regions->aux.nvme_params =
4944 isp_compare_image_generation(ispsoftc_t *isp,
4950 le16toh(pri_image_status->generation) -
4951 le16toh(sec_image_status->generation);
4953 isp_prt(isp, ISP_LOGDEBUG0, "generation delta = %d", delta);
4959 isp_get_aux_images(ispsoftc_t *isp, struct active_regions *active_regions)
4961 fcparam *fcp = FCPARAM(isp, 0);
4966 if (!fcp->flt_region_aux_img_status_pri) {
4967 isp_prt(isp, ISP_LOGWARN,
4972 isp_read_flash_data(isp, (uint32_t *)&pri_aux_image_status,
4973 fcp->flt_region_aux_img_status_pri,
4975 isp_print_image(isp, "Primary aux image", &pri_aux_image_status);
4978 isp_prt(isp, ISP_LOGERR,
4979 "Primary aux image signature (0x%x) not valid",
4985 isp_prt(isp, ISP_LOGERR,
4993 isp_prt(isp, ISP_LOGCONFIG,
4999 if (!fcp->flt_region_aux_img_status_sec) {
5000 isp_prt(isp, ISP_LOGWARN,
5005 isp_read_flash_data(isp, (uint32_t *)&sec_aux_image_status,
5006 fcp->flt_region_aux_img_status_sec,
5008 isp_print_image(isp, "Secondary aux image", &sec_aux_image_status);
5011 isp_prt(isp, ISP_LOGERR,
5012 "Secondary aux image signature (0x%x) not valid",
5018 isp_prt(isp, ISP_LOGERR,
5026 isp_prt(isp, ISP_LOGCONFIG,
5034 if (isp_compare_image_generation(isp, &pri_aux_image_status,
5035 &sec_aux_image_status) >= 0) {
5048 isp_prt(isp, ISP_LOGDEBUG0,
5050 active_regions->aux.board_config,
5051 active_regions->aux.vpd_nvram,
5052 active_regions->aux.npiv_config_0_1,
5053 active_regions->aux.npiv_config_2_3,
5054 active_regions->aux.nvme_params);
5058 isp_get_active_image(ispsoftc_t *isp, struct active_regions * active_regions)
5060 fcparam *fcp = FCPARAM(isp, 0);
5065 if (!fcp->flt_region_img_status_pri) {
5066 isp_prt(isp, ISP_LOGWARN,
5071 if (isp_read_flash_data(isp, (uint32_t *) &pri_image_status,
5072 fcp->flt_region_img_status_pri, sizeof(pri_image_status) >> 2) !=
5076 isp_print_image(isp, "Primary image", &pri_image_status);
5079 isp_prt(isp, ISP_LOGERR,
5080 "Primary image signature (0x%x) not valid",
5086 isp_prt(isp, ISP_LOGERR,
5094 isp_prt(isp, ISP_LOGCONFIG,
5100 if (!fcp->flt_region_img_status_sec) {
5101 isp_prt(isp, ISP_LOGWARN,
5106 if (isp_read_flash_data(isp, (uint32_t *) &sec_image_status,
5107 fcp->flt_region_img_status_sec, sizeof(sec_image_status) >> 2) !=
5111 isp_print_image(isp, "Secondary image", &sec_image_status);
5114 isp_prt(isp, ISP_LOGERR,
5115 "Secondary image signature (0x%x) not valid",
5120 isp_prt(isp, ISP_LOGERR,
5128 isp_prt(isp, ISP_LOGCONFIG,
5135 active_regions->global = ISP27XX_PRIMARY_IMAGE;
5138 if (!active_regions->global ||
5139 isp_compare_image_generation(isp,
5140 &pri_image_status, &sec_image_status) < 0) {
5141 active_regions->global = ISP27XX_SECONDARY_IMAGE;
5145 isp_prt(isp, ISP_LOGDEBUG0, "active image %s (%u)",
5146 active_regions->global == ISP27XX_DEFAULT_IMAGE ?
5148 active_regions->global == ISP27XX_PRIMARY_IMAGE ?
5150 active_regions->global == ISP27XX_SECONDARY_IMAGE ?
5152 active_regions->global);
5155 static bool isp_risc_firmware_invalid(ispsoftc_t *isp, uint32_t *dword)
5157 return ((dword[4] | dword[5] | dword[6] | dword[7]) == 0 ||
5158 (~dword[4] | ~dword[5] | ~dword[6] | ~dword[7]) == 0);
5162 isp_load_ram(ispsoftc_t *isp, uint32_t *data, uint32_t risc_addr,
5168 MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1);
5169 MBSINIT(&mbs, MBOX_LOAD_RISC_RAM, MBLOGALL, 0);
5171 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
5172 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
5175 mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
5176 mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
5178 isp_prt(isp, ISP_LOGDEBUG0,
5179 "LOAD RISC RAM %u (0x%x) words at load address 0x%x",
5181 isp_mboxcmd(isp, &mbs);
5182 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
5183 isp_prt(isp, ISP_LOGERR, "F/W download failed");
5191 isp_load_risc_flash(ispsoftc_t *isp, uint32_t *srisc_addr, uint32_t faddr)
5193 fcparam *fcp = FCPARAM(isp, 0);
5200 uint32_t risc_addr, risc_size = 0;
5202 isp_prt(isp, ISP_LOGDEBUG0,
5203 "Accessing flash firmware at 0x%x.", faddr);
5205 dcode = isp->isp_rquest;
5206 isp_read_flash_data(isp, dcode, faddr, 8);
5207 if (isp_risc_firmware_invalid(isp, dcode)) {
5208 snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
5210 isp_prt(isp, ISP_LOGERR,
5212 isp_prt(isp, ISP_LOGERR,
5213 "Firmware data: 0x%08x 0x%08x 0x%08x 0x%08x.",
5214 dcode[0], dcode[1], dcode[2], dcode[3]);
5217 for (i = 0; i < 4; i++)
5218 fcp->fw_flashrev[i] = be32toh(dcode[4 + i]);
5219 snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
5220 "%u.%u.%u", fcp->fw_flashrev[0], fcp->fw_flashrev[1],
5221 fcp->fw_flashrev[2]);
5222 isp_prt(isp, ISP_LOGCONFIG,
5224 fcp->fw_flashrev[0], fcp->fw_flashrev[1],
5225 fcp->fw_flashrev[2], fcp->fw_flashrev[3]);
5228 if (isp->isp_osinfo.ispfw != NULL) {
5229 int ispfw_newer = 0;
5231 if (ISP_FW_NEWER_THANX(fcp->fw_ispfwrev, fcp->fw_flashrev)) {
5235 if (isp->isp_confopts & ISP_CFG_FWLOAD_FORCE) {
5236 isp_prt(isp, ISP_LOGCONFIG,
5238 (ispfw_newer == 0) ? "older" : "newer",
5242 if (ispfw_newer != 0) {
5243 isp_prt(isp, ISP_LOGCONFIG,
5247 isp_prt(isp, ISP_LOGCONFIG,
5252 dcode = isp->isp_rquest;
5254 for (j = 0; j < segments; j++) {
5255 isp_prt(isp, ISP_LOGDEBUG0, "Loading segment %u", j);
5256 isp_read_flash_data(isp, dcode, faddr, 10);
5260 dlen = min(risc_size, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) / 4);
5261 for (fragment = 0; risc_size; fragment++) {
5265 isp_prt(isp, ISP_LOGDEBUG0,
5266 "Loading fragment %u: 0x%x <- 0x%x (0x%lx dwords)",
5268 isp_read_flash_data(isp, dcode, faddr, dlen);
5269 for (i = 0; i < dlen; i++) {
5273 rval = isp_load_ram(isp, dcode, risc_addr, dlen);
5275 isp_prt(isp, ISP_LOGERR,
5283 risc_size -= dlen;
5291 isp_load_risc(ispsoftc_t *isp, uint32_t *srisc_addr)
5293 fcparam *fcp = FCPARAM(isp, 0);
5301 if (!IS_27XX(isp))
5304 isp_get_active_image(isp, &active_regions);
5309 isp_prt(isp, ISP_LOGCONFIG,
5311 rval = isp_load_risc_flash(isp, srisc_addr, fcp->flt_region_fw_sec);
5315 isp_prt(isp, ISP_LOGCONFIG,
5317 rval = isp_load_risc_flash(isp, srisc_addr, fcp->flt_region_fw);
5322 isp_read_nvram(ispsoftc_t *isp)
5324 fcparam *fcp = FCPARAM(isp, 0);
5325 int retval = 0;
5330 if (IS_27XX(isp))
5331 isp_get_aux_images(isp, &active_regions);
5333 addr = fcp->flt_region_nvram;
5335 if (IS_28XX(isp)) {
5337 addr = fcp->flt_region_nvram_sec;
5339 isp_prt(isp, ISP_LOGCONFIG, "Loading %s NVRAM image",
5345 for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
5346 isp_rd_2xxx_flash(isp, addr++, dptr++);
5348 if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
5350 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
5351 nvram_data[0], nvram_data[1], nvram_data[2]);
5352 retval = -1;
5356 for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
5358 ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
5361 if (csum != 0) {
5362 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
5363 retval = -1;
5366 isp_parse_nvram_2400(isp, nvram_data);
5372 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
5374 fcparam *fcp = FCPARAM(isp, 0);
5377 isp_prt(isp, ISP_LOGDEBUG0,
5378 "NVRAM 0x%08x%08x 0x%08x%08x maxframelen %d",
5384 isp_prt(isp, ISP_LOGDEBUG0,
5385 "NVRAM loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
5392 fcp->isp_wwpn_nvram = wwn;
5397 wwn = 0;
5400 if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
5401 wwn = fcp->isp_wwpn_nvram;
5402 wwn &= ~((uint64_t) 0xfff << 48);
5404 fcp->isp_wwnn_nvram = wwn;
5406 if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
5407 DEFAULT_FRAMESIZE(isp) =
5410 if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
5411 fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
5413 fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
5414 fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
5415 fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);