diff options
author | mjacob <mjacob@cvs.openbsd.org> | 2000-02-20 21:22:42 +0000 |
---|---|---|
committer | mjacob <mjacob@cvs.openbsd.org> | 2000-02-20 21:22:42 +0000 |
commit | 843be39a687253a9894847550ed56ea58510c179 (patch) | |
tree | 5ba8385712451adffcce024f1c84487e320e5d2d /sys/dev/ic/isp.c | |
parent | 507037610dbda92ebe936b00eda0be017503a7d8 (diff) |
Add 12160 (Ultra3) support. Add files and changes for target mode support.
Do some SNS fabric suppor tchanges. Roll revision levels. Tested on
GENERIC i386 && sparc.
Diffstat (limited to 'sys/dev/ic/isp.c')
-rw-r--r-- | sys/dev/ic/isp.c | 1184 |
1 files changed, 735 insertions, 449 deletions
diff --git a/sys/dev/ic/isp.c b/sys/dev/ic/isp.c index e5eaeb54805..c7303a59778 100644 --- a/sys/dev/ic/isp.c +++ b/sys/dev/ic/isp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isp.c,v 1.12 2000/01/09 22:44:27 mjacob Exp $ */ +/* $OpenBSD: isp.c,v 1.13 2000/02/20 21:22:40 mjacob Exp $ */ /* * Machine and OS Independent (well, as best as possible) * code for the Qlogic ISP SCSI adapters. @@ -95,6 +95,11 @@ static void isp_update_bus __P((struct ispsoftc *, int)); static void isp_setdfltparm __P((struct ispsoftc *, int)); static int isp_read_nvram __P((struct ispsoftc *)); static void isp_rdnvram_word __P((struct ispsoftc *, int, u_int16_t *)); +static void isp_parse_nvram_1020 __P((struct ispsoftc *, u_int8_t *)); +static void isp_parse_nvram_1080 __P((struct ispsoftc *, int, u_int8_t *)); +static void isp_parse_nvram_12160 __P((struct ispsoftc *, int, u_int8_t *)); +static void isp_parse_nvram_2100 __P((struct ispsoftc *, u_int8_t *)); + /* * Reset Hardware. @@ -188,7 +193,15 @@ isp_reset(isp) isp->isp_clock = 100; - revname = "1080"; + if (IS_1280(isp)) + revname = "1280"; + else if (IS_1080(isp)) + revname = "1080"; + else if (IS_12160(isp)) + revname = "12160"; + else + revname = "<UNKLVD>"; + l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK; switch (l) { case ISP1080_LVD_MODE: @@ -209,9 +222,8 @@ isp_reset(isp) break; } - if (IS_1280(isp)) { + if (IS_DUALBUS(isp)) { sdp++; - revname[1] = '2'; l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT); l &= ISP1080_MODE_MASK; switch(l) { @@ -793,22 +805,16 @@ isp_scsi_init(isp) * * Ultra2 F/W always has had fast posting (and LVD transitions) * - * Ultra and older (i.e., SBus) cards may not. Assume SBus cards - * do not, and only guess that 4.55.0 <= x < 5.0.0 (initiator - * only) and x >= 7.55 (initiator/target) has fast posting. + * Ultra and older (i.e., SBus) cards may not. It's just safer + * to assume not for them. */ mbs.param[0] = MBOX_SET_FW_FEATURES; mbs.param[1] = 0; if (IS_ULTRA2(isp)) mbs.param[1] |= FW_FEATURE_LVD_NOTIFY; -#ifndef ISP_NO_FASTPOST_SCSI - if ((ISP_FW_REVX(isp->isp_fwrev) >= ISP_FW_REV(4, 55, 0) && - (ISP_FW_REVX(isp->isp_fwrev) < ISP_FW_REV(5, 0, 0))) || - (ISP_FW_REVX(isp->isp_fwrev) >= ISP_FW_REV(7, 55, 0))) { + if (IS_ULTRA2(isp) || IS_1240(isp)) mbs.param[1] |= FW_FEATURE_FAST_POST; - } -#endif if (mbs.param[1] != 0) { u_int16_t sfeat = mbs.param[1]; isp_mboxcmd(isp, &mbs); @@ -1007,7 +1013,6 @@ isp_fibre_init(isp) #else fcp->isp_fwoptions = 0; #endif - fcp->isp_fwoptions |= ICBOPT_FAIRNESS; /* * If this is a 2100 < revision 5, we have to turn off FAIRNESS. @@ -1059,7 +1064,19 @@ isp_fibre_init(isp) icbp->icb_retry_delay = fcp->isp_retry_delay; icbp->icb_retry_count = fcp->isp_retry_count; icbp->icb_hardaddr = loopid; - icbp->icb_logintime = 30; /* 30 second login timeout */ +#ifdef PRET_A_PORTE + if (IS_2200(isp)) { + icbp->icb_fwoptions |= ICBOPT_EXTENDED; + /* + * Prefer or force Point-To-Point instead Loop? + */ + if (isp->isp_confopts & ISP_CFG_NPORT) + icbp->icb_xfwoptions = ICBXOPT_PTP_2_LOOP; + else + icbp->icb_xfwoptions = ICBXOPT_LOOP_2_PTP; + } +#endif + icbp->icb_logintime = 60; /* 60 second login timeout */ if (fcp->isp_nodewwn) { u_int64_t pn; @@ -1238,7 +1255,6 @@ isp_fclink_test(isp, waitdelay) "N-Port to N-Port", "F Port" }; - char *tname; mbreg_t mbs; int count, topo = -1; u_int8_t lwfs; @@ -1283,19 +1299,13 @@ isp_fclink_test(isp, waitdelay) return (-1); } fcp->isp_loopid = mbs.param[1]; - if (isp->isp_type == ISP_HA_FC_2200) { - if (ISP_FW_REVX(isp->isp_fwrev) >= ISP_FW_REV(2, 0, 14)) { - topo = (int) mbs.param[6]; - } - } else if (isp->isp_type == ISP_HA_FC_2100) { - if (ISP_FW_REVX(isp->isp_fwrev) >= ISP_FW_REV(1, 17, 26)) { - topo = (int) mbs.param[6]; - } + if (IS_2200(isp)) { + topo = (int) mbs.param[6]; + if (topo < 0 || topo > 3) + topo = 0; + } else { + topo = 0; } - if (topo < 0 || topo > 3) - tname = "unknown"; - else - tname = toponames[topo]; /* * If we're not on a fabric, the low 8 bits will be our AL_PA. @@ -1305,11 +1315,16 @@ isp_fclink_test(isp, waitdelay) #if defined(ISP2100_FABRIC) fcp->isp_onfabric = 0; if (isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) { + + if (IS_2100(isp)) + topo = 1; + fcp->isp_portid = mbs.param[2] | (((int)mbs.param[3]) << 16); fcp->isp_onfabric = 1; CFGPRINTF("%s: Loop ID %d, AL_PA 0x%x, Port ID 0x%x Loop State " - "0x%x topology %s\n", isp->isp_name, fcp->isp_loopid, - fcp->isp_alpa, fcp->isp_portid, fcp->isp_loopstate, tname); + "0x%x topology '%s'\n", isp->isp_name, fcp->isp_loopid, + fcp->isp_alpa, fcp->isp_portid, fcp->isp_loopstate, + toponames[topo]); /* * Make sure we're logged out of all fabric devices. @@ -1329,10 +1344,9 @@ isp_fclink_test(isp, waitdelay) } } else #endif - CFGPRINTF("%s: Loop ID %d, ALPA 0x%x Loop State 0x%x topology %s\n", + CFGPRINTF("%s: Loop ID %d, ALPA 0x%x Loop State 0x%x topology '%s'\n", isp->isp_name, fcp->isp_loopid, fcp->isp_alpa, fcp->isp_loopstate, - tname); - fcp->loop_seen_once = 1; + toponames[topo]); return (0); } @@ -1394,6 +1408,7 @@ isp_pdb_sync(isp, target) * FL_PORT_ID times). */ tport = fcp->tport; + /* * make sure the temp port database is clean... */ @@ -1466,7 +1481,7 @@ isp_pdb_sync(isp, target) * use) and then compare it to our saved database which * never shifts. */ - if (isp_same_lportdb(lp, &fcp->portdb[target])) { + if (target >= 0 && isp_same_lportdb(lp, &fcp->portdb[target])) { lp->valid = 1; } } @@ -1635,8 +1650,9 @@ isp_pdb_sync(isp, target) /* * Now log in any fabric devices */ - for (lp = &fcp->portdb[FC_SNS_ID+1]; + for (lim = FC_SNS_ID+1, lp = &fcp->portdb[FC_SNS_ID+1]; lp < &fcp->portdb[MAX_FC_TARG]; lp++) { + u_int32_t portid; mbreg_t mbs; /* @@ -1644,67 +1660,77 @@ isp_pdb_sync(isp, target) */ if (lp->port_wwn == 0) continue; + /* * Don't try to log into yourself. */ - if (lp->portid == fcp->isp_portid) + if ((portid = lp->portid) == fcp->isp_portid) continue; /* - * Force a logout. + * Force a logout if we were logged in. */ - lp->loopid = loopid = lp - fcp->portdb; - mbs.param[0] = MBOX_FABRIC_LOGOUT; - mbs.param[1] = lp->loopid << 8; - mbs.param[2] = 0; - mbs.param[3] = 0; - isp_mboxcmd(isp, &mbs); + if (lp->valid) { + mbs.param[0] = MBOX_FABRIC_LOGOUT; + mbs.param[1] = lp->loopid << 8; + mbs.param[2] = 0; + mbs.param[3] = 0; + isp_mboxcmd(isp, &mbs); + lp->valid = 0; + } /* * And log in.... */ - mbs.param[0] = MBOX_FABRIC_LOGIN; - mbs.param[1] = lp->loopid << 8; - mbs.param[2] = lp->portid >> 16; - mbs.param[3] = lp->portid & 0xffff; - isp_mboxcmd(isp, &mbs); - switch (mbs.param[0]) { - case MBOX_COMMAND_COMPLETE: - break; - case MBOX_COMMAND_ERROR: - switch (mbs.param[1]) { - case 1: - PRINTF("%s: no loop\n", isp->isp_name); - break; - case 2: - PRINTF("%s: IOCB buffer could not be alloced\n", - isp->isp_name); - break; - case 3: - PRINTF("%s: could not alloc xchange resource\n", - isp->isp_name); - break; - case 4: - PRINTF("%s: ELS timeout\n", isp->isp_name); - break; - case 5: - PRINTF("%s: no fabric port\n", isp->isp_name); + loopid = lp - fcp->portdb; + lp->loopid = 0; + lim = 0; + do { + mbs.param[0] = MBOX_FABRIC_LOGIN; + mbs.param[1] = loopid << 8; + if (IS_2200(isp)) { + /* only issue a PLOGI if not logged in */ + mbs.param[1] |= 0x1; + } + mbs.param[2] = portid >> 16; + mbs.param[3] = portid & 0xffff; + isp_mboxcmd(isp, &mbs); + switch (mbs.param[0]) { + case MBOX_LOOP_ID_USED: + /* + * Try the next available loop id. + */ + loopid++; break; - case 6: - PRINTF("%s: remote device cannot be a target\n", - isp->isp_name); + case MBOX_PORT_ID_USED: + /* + * This port is already logged in. + * Snaffle the loop id it's using. + */ + if ((loopid = mbs.param[1]) == 0) { + lim = -1; + } + /* FALLTHROUGH */ + case MBOX_COMMAND_COMPLETE: + lp->loopid = loopid; + lim = 1; break; + case MBOX_COMMAND_ERROR: + PRINTF("%s: command error in PLOGI (0x%x)\n", + isp->isp_name, mbs.param[1]); + /* FALLTHROUGH */ + case MBOX_ALL_IDS_USED: /* We're outta IDs */ default: + lim = -1; break; } + } while (lim == 0 && loopid < MAX_FC_TARG); + if (lim < 0) continue; - default: - continue; - } lp->valid = 1; lp->fabdev = 1; - if (isp_getpdb(isp, loopid, &pdb) != 0) { + if (isp_getpdb(isp, lp->loopid, &pdb) != 0) { /* * Be kind... */ @@ -1722,7 +1748,6 @@ isp_pdb_sync(isp, target) lp->roles = (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT; lp->portid = BITS2WORD(pdb.pdb_portid_bits); - lp->loopid = loopid; lp->node_wwn = (((u_int64_t)pdb.pdb_nodename[0]) << 56) | (((u_int64_t)pdb.pdb_nodename[1]) << 48) | @@ -1745,6 +1770,7 @@ isp_pdb_sync(isp, target) * Check to make sure this all makes sense. */ if (lp->node_wwn && lp->port_wwn) { + loopid = lp - fcp->portdb; (void) isp_async(isp, ISPASYNC_PDB_CHANGED, &loopid); continue; } @@ -1758,6 +1784,12 @@ isp_pdb_sync(isp, target) isp_mboxcmd(isp, &mbs); } #endif + /* + * If we get here, we've for sure seen not only a valid loop + * but know what is or isn't on it, so mark this for usage + * in ispscsicmd. + */ + fcp->loop_seen_once = 1; return (0); } @@ -1798,6 +1830,8 @@ isp_scan_fabric(isp) MemoryBarrier(); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + IDPRINTF(1, ("%s: SNS failed (0x%x)\n", isp->isp_name, + mbs.param[0])); return (-1); } ISP_UNSWIZZLE_SNS_RSP(isp, resp, SNS_GAN_RESP_SIZE >> 1); @@ -1849,13 +1883,15 @@ ispscsicmd(xs) } /* - * We *could* do the different sequence type that has close - * to the whole Queue Entry for the command... + * Check command CDB length, etc.. We really are limited to 16 bytes + * for Fibre Channel, but can do up to 44 bytes in parallel SCSI, + * but probably only if we're running fairly new firmware (we'll + * let the old f/w choke on an extended command queue entry). */ - if (XS_CDBLEN(xs) > (IS_FC(isp) ? 16 : 12) || XS_CDBLEN(xs) == 0) { + if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) { PRINTF("%s: unsupported cdb length (%d, CDB[0]=0x%x)\n", - isp->isp_name, XS_CDBLEN(xs), XS_CDBP(xs)[0]); + isp->isp_name, XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff); XS_SETERR(xs, HBA_BOTCH); return (CMD_COMPLETE); } @@ -1908,11 +1944,17 @@ ispscsicmd(xs) * If our loop state is such that we haven't yet received * a "Port Database Changed" notification (after a LIP or * a Loop Reset or firmware initialization), then defer - * sending commands for a little while. + * sending commands for a little while, but only if we've + * seen a valid loop at one point (otherwise we can get + * stuck at initialization time). */ if (fcp->isp_loopstate < LOOP_PDB_RCVD) { XS_SETERR(xs, HBA_SELTIMEOUT); - return (CMD_RQLATER); + if (fcp->loop_seen_once) { + return (CMD_RQLATER); + } else { + return (CMD_COMPLETE); + } } /* @@ -1999,7 +2041,10 @@ ispscsicmd(xs) if (IS_FC(isp)) { reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS; } else { - reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST; + if (XS_CDBLEN(xs) > 12) + reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY; + else + reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST; } reqp->req_header.rqs_flags = 0; reqp->req_header.rqs_seqno = 0; @@ -2112,16 +2157,17 @@ isp_control(isp, ctl, arg) * Issue a bus reset. */ mbs.param[0] = MBOX_BUS_RESET; + mbs.param[2] = 0; if (IS_SCSI(isp)) { mbs.param[1] = ((sdparam *) isp->isp_param)->isp_bus_reset_delay; if (mbs.param[1] < 2) mbs.param[1] = 2; bus = *((int *) arg); - mbs.param[2] = bus; + if (IS_DUALBUS(isp)) + mbs.param[2] = bus; } else { mbs.param[1] = 10; - mbs.param[2] = 0; bus = 0; } isp->isp_sendmarker = 1 << bus; @@ -2174,8 +2220,8 @@ isp_control(isp, ctl, arg) mbs.param[1] = (bus << 15) | (XS_TGT(xs) << 8) | XS_LUN(xs); } - mbs.param[2] = handle >> 16; - mbs.param[3] = handle & 0xffff; + mbs.param[3] = handle >> 16; + mbs.param[2] = handle & 0xffff; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { PRINTF("%s: isp_control MBOX_ABORT failure (code %x)\n", @@ -2192,12 +2238,25 @@ isp_control(isp, ctl, arg) case ISPCTL_FCLINK_TEST: return (isp_fclink_test(isp, FC_FW_READY_DELAY)); -#ifdef ISP_TARGET_MODE - case ISPCTL_ENABLE_LUN: - return (isp_modify_lun, 1, arg)); - case ISPCTL_MODIFY_LUN: - return (isp_modify_lun, 0, arg)); + case ISPCTL_PDB_SYNC: + return (isp_pdb_sync(isp, -1)); + +#ifdef ISP_TARGET_MODE + case ISPCTL_TOGGLE_TMODE: + if (IS_SCSI(isp)) { + int ena = *(int *)arg; + mbs.param[0] = MBOX_ENABLE_TARGET_MODE; + mbs.param[1] = (ena)? ENABLE_TARGET_FLAG : 0; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + PRINTF("%s: cannot %sable target mode (0x%x)\n", + isp->isp_name, ena? "en" : "dis", + mbs.param[0]); + break; + } + } + return (0); #endif } return (-1); @@ -2289,12 +2348,12 @@ isp_intr(arg) MemoryBarrier(); /* * Do any appropriate unswizzling of what the Qlogic f/w has - * written into memory so it makes sense to us. + * written into memory so it makes sense to us. This is a + * per-platform thing. */ ISP_UNSWIZZLE_RESPONSE(isp, sp); if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) { if (isp_handle_other_response(isp, sp, &optr) == 0) { - ISP_WRITE(isp, INMAILBOX5, optr); continue; } /* @@ -2303,7 +2362,6 @@ isp_intr(arg) * not, something bad has happened. */ if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) { - ISP_WRITE(isp, INMAILBOX5, optr); PRINTF("%s: not RESPONSE in RESPONSE Queue " "(type 0x%x) @ idx %d (next %d)\n", isp->isp_name, @@ -2384,11 +2442,14 @@ isp_intr(arg) isp->isp_update |= (1 << XS_CHANNEL(xs)); } } else { - if (XS_STS(xs) == SCSI_CHECK) { + if (sp->req_scsi_status & RQCS_SV) { + int amt = min(XS_SNSLEN(xs), sp->req_sense_len); + MEMCPY(XS_SNSP(xs), sp->req_sense_data, amt); XS_SNS_IS_VALID(xs); - MEMCPY(XS_SNSP(xs), sp->req_sense_data, - XS_SNSLEN(xs)); sp->req_state_flags |= RQSF_GOT_SENSE; + } else if (XS_STS(xs) == SCSI_CHECK) { + IDPRINTF(1, ("%s: check condition with no sense" + " data\n", isp->isp_name)); } } if (XS_NOERR(xs) && XS_STS(xs) == SCSI_BUSY) { @@ -2431,6 +2492,10 @@ isp_intr(arg) ISP_DMAFREE(isp, xs, sp->req_handle); } /* + * Let the platforms cope. + */ +#if 0 + /* * XXX: If we have a check condition, but no Sense Data, * XXX: mark it as an error (ARQ failed). We need to * XXX: to do a more distinct job because there may @@ -2443,6 +2508,7 @@ isp_intr(arg) XS_SETERR(xs, HBA_ARQFAIL); } } +#endif if ((isp->isp_dblev >= 5) || (isp->isp_dblev > 2 && !XS_NOERR(xs))) { PRINTF("%s(%d.%d): FIN dl%d resid%d STS %x", @@ -2506,7 +2572,7 @@ isp_parse_async(isp, mbox) case ASYNC_BUS_RESET: isp->isp_sendmarker = (1 << bus); #ifdef ISP_TARGET_MODE - isp_target_async(isp, bus, ASYNC_BUS_RESET); + isp_target_async(isp, bus, mbox); #endif isp_async(isp, ISPASYNC_BUS_RESET, &bus); break; @@ -2540,7 +2606,7 @@ isp_parse_async(isp, mbox) isp->isp_name, bus); isp->isp_sendmarker = (1 << bus); #ifdef ISP_TARGET_MODE - isp_target_async(isp, bus, ASYNC_TIMEOUT_RESET); + isp_target_async(isp, bus, mbox); #endif break; @@ -2548,7 +2614,7 @@ isp_parse_async(isp, mbox) PRINTF("%s: device reset on bus %d\n", isp->isp_name, bus); isp->isp_sendmarker = 1 << bus; #ifdef ISP_TARGET_MODE - isp_target_async(isp, bus, ASYNC_DEVICE_RESET); + isp_target_async(isp, bus, mbox); #endif break; @@ -2626,6 +2692,9 @@ isp_parse_async(isp, mbox) isp->isp_sendmarker = 1; isp_mark_getpdb_all(isp); IDPRINTF(1, ("%s: LIP occurred\n", isp->isp_name)); +#ifdef ISP_TARGET_MODE + isp_target_async(isp, bus, mbox); +#endif break; case ASYNC_LOOP_UP: @@ -2634,6 +2703,9 @@ isp_parse_async(isp, mbox) ((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD; isp_mark_getpdb_all(isp); isp_async(isp, ISPASYNC_LOOP_UP, NULL); +#ifdef ISP_TARGET_MODE + isp_target_async(isp, bus, mbox); +#endif break; case ASYNC_LOOP_DOWN: @@ -2642,6 +2714,9 @@ isp_parse_async(isp, mbox) ((fcparam *) isp->isp_param)->isp_loopstate = LOOP_NIL; isp_mark_getpdb_all(isp); isp_async(isp, ISPASYNC_LOOP_DOWN, NULL); +#ifdef ISP_TARGET_MODE + isp_target_async(isp, bus, mbox); +#endif break; case ASYNC_LOOP_RESET: @@ -2651,7 +2726,7 @@ isp_parse_async(isp, mbox) isp_mark_getpdb_all(isp); PRINTF("%s: Loop RESET\n", isp->isp_name); #ifdef ISP_TARGET_MODE - isp_target_async(isp, bus, ASYNC_LOOP_RESET); + isp_target_async(isp, bus, mbox); #endif break; @@ -2671,6 +2746,37 @@ isp_parse_async(isp, mbox) isp_async(isp, ISPASYNC_CHANGE_NOTIFY, NULL); break; + case ASYNC_PTPMODE: + PRINTF("%s: Point-to-Point mode\n", isp->isp_name); + break; + + case ASYNC_CONNMODE: + mbox = ISP_READ(isp, OUTMAILBOX1); + switch (mbox) { + case ISP_CONN_LOOP: + PRINTF("%s: Point-to-Point -> Loop mode\n", + isp->isp_name); + break; + case ISP_CONN_PTP: + PRINTF("%s: Loop -> Point-to-Point mode\n", + isp->isp_name); + break; + case ISP_CONN_BADLIP: + PRINTF("%s: Point-to-Point -> Loop mode (1)\n", + isp->isp_name); + break; + case ISP_CONN_FATAL: + PRINTF("%s: FATAL CONNECTION ERROR\n", isp->isp_name); + isp_restart(isp); + /* no point continuing after this */ + return (-1); + + case ISP_CONN_LOOPBACK: + PRINTF("%s: Looped Back in Point-to-Point mode\n", + isp->isp_name); + } + break; + default: PRINTF("%s: unknown async code 0x%x\n", isp->isp_name, mbox); break; @@ -2692,7 +2798,7 @@ isp_handle_other_response(isp, sp, optrp) { switch (sp->req_header.rqs_entry_type) { case RQSTYPE_ATIO: - case RQSTYPE_CTIO0: + case RQSTYPE_CTIO: case RQSTYPE_ENABLE_LUN: case RQSTYPE_MODIFY_LUN: case RQSTYPE_NOTIFY: @@ -2702,7 +2808,7 @@ isp_handle_other_response(isp, sp, optrp) case RQSTYPE_CTIO2: case RQSTYPE_CTIO3: #ifdef ISP_TARGET_MODE - return (isp_target_entry(isp, sp)); + return (isp_target_notify(isp, sp, optrp)); #else /* FALLTHROUGH */ #endif @@ -3094,7 +3200,7 @@ static u_int8_t mbpcnt[] = { MAKNIB(0, 0), /* 0x52: */ MAKNIB(0, 0), /* 0x53: */ MAKNIB(8, 0), /* 0x54: MBOX_EXEC_COMMAND_IOCB_A64 */ - MAKNIB(0, 0), /* 0x55: */ + MAKNIB(2, 1), /* 0x55: MBOX_ENABLE_TARGET_MODE */ MAKNIB(0, 0), /* 0x56: */ MAKNIB(0, 0), /* 0x57: */ MAKNIB(0, 0), /* 0x58: */ @@ -3403,6 +3509,12 @@ command_known: } } + if (IS_2200(isp)) { + if (opcode == MBOX_GET_LOOP_ID) { + mbp->param[6] = ISP_READ(isp, OUTMAILBOX6); + } + } + switch (outparam) { case 8: mbp->param[7] = ISP_READ(isp, OUTMAILBOX7); case 7: mbp->param[6] = ISP_READ(isp, OUTMAILBOX6); @@ -3459,6 +3571,12 @@ command_known: } break; + case MBOX_LOOP_ID_USED: + case MBOX_PORT_ID_USED: + case MBOX_ALL_IDS_USED: + break; + + /* * Be silent about these... */ @@ -3826,7 +3944,14 @@ isp_setdfltparm(isp, channel) sdp->isp_devparam[tgt].cur_period = 0; sdp->isp_devparam[tgt].dev_flags = DPARM_DEFAULT; sdp->isp_devparam[tgt].cur_dflags = 0; - if (isp->isp_type < ISP_HA_SCSI_1040 || + /* + * We default to Wide/Fast for versions less than a 1040 + * (unless it's SBus). + */ + if ((isp->isp_bustype == ISP_BT_SBUS && + isp->isp_type < ISP_HA_SCSI_1020A) || + (isp->isp_bustype == ISP_BT_PCI && + isp->isp_type < ISP_HA_SCSI_1040) || (isp->isp_clock && isp->isp_clock < 60)) { sdp->isp_devparam[tgt].sync_offset = ISP_10M_SYNCPARMS >> 8; @@ -3891,7 +4016,7 @@ isp_setdfltparm(isp, channel) IDPRINTF(3, ("%s: bus %d tgt %d flags %x offset %x period %x\n", isp->isp_name, channel, tgt, sdp->isp_devparam[tgt].dev_flags, - sdp->isp_devparam[tgt].sync_period, + sdp->isp_devparam[tgt].sync_offset, sdp->isp_devparam[tgt].sync_period)); } @@ -3971,13 +4096,10 @@ isp_restart(isp) /* * NVRAM Routines */ - static int isp_read_nvram(isp) struct ispsoftc *isp; { - static char *tru = "true"; - static char *not = "false"; int i, amt; u_int8_t csum, minversion; union { @@ -4030,349 +4152,23 @@ isp_read_nvram(isp) return (-1); } - if (IS_ULTRA2(isp)) { - int bus; - sdparam *sdp = (sdparam *) isp->isp_param; - for (bus = 0; bus < (IS_DUALBUS(isp)? 2 : 1); bus++, sdp++) { - sdp->isp_fifo_threshold = - ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data); - - sdp->isp_initiator_id = - ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus); - - sdp->isp_bus_reset_delay = - ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus); - - sdp->isp_retry_count = - ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus); - - sdp->isp_retry_delay = - ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus); - - sdp->isp_async_data_setup = - ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, - bus); - - sdp->isp_req_ack_active_neg = - ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, - bus); - - sdp->isp_data_line_active_neg = - ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, - bus); - - sdp->isp_data_dma_burst_enabl = - ISP1080_NVRAM_BURST_ENABLE(nvram_data); - - sdp->isp_cmd_dma_burst_enable = - ISP1080_NVRAM_BURST_ENABLE(nvram_data); - - sdp->isp_selection_timeout = - ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus); - - sdp->isp_max_queue_depth = - ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus); - - if (isp->isp_dblev >= 3) { - PRINTF("%s: ISP1080 bus %d NVRAM values:\n", - isp->isp_name, bus); - PRINTF(" Initiator ID = %d\n", - sdp->isp_initiator_id); - PRINTF(" Fifo Threshold = 0x%x\n", - sdp->isp_fifo_threshold); - PRINTF(" Bus Reset Delay = %d\n", - sdp->isp_bus_reset_delay); - PRINTF(" Retry Count = %d\n", - sdp->isp_retry_count); - PRINTF(" Retry Delay = %d\n", - sdp->isp_retry_delay); - PRINTF(" Tag Age Limit = %d\n", - sdp->isp_tag_aging); - PRINTF(" Selection Timeout = %d\n", - sdp->isp_selection_timeout); - PRINTF(" Max Queue Depth = %d\n", - sdp->isp_max_queue_depth); - PRINTF(" Async Data Setup = 0x%x\n", - sdp->isp_async_data_setup); - PRINTF(" REQ/ACK Active Negation = %s\n", - sdp->isp_req_ack_active_neg? tru : not); - PRINTF(" Data Line Active Negation = %s\n", - sdp->isp_data_line_active_neg? tru : not); - PRINTF(" Cmd DMA Burst Enable = %s\n", - sdp->isp_cmd_dma_burst_enable? tru : not); - } - for (i = 0; i < MAX_TARGETS; i++) { - sdp->isp_devparam[i].dev_enable = - ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i, bus); - sdp->isp_devparam[i].exc_throttle = - ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, i, bus); - sdp->isp_devparam[i].sync_offset = - ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, i, bus); - sdp->isp_devparam[i].sync_period = - ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, i, bus); - sdp->isp_devparam[i].dev_flags = 0; - if (ISP1080_NVRAM_TGT_RENEG(nvram_data, i, bus)) - sdp->isp_devparam[i].dev_flags |= DPARM_RENEG; - if (ISP1080_NVRAM_TGT_QFRZ(nvram_data, i, bus)) { - PRINTF("%s: not supporting QFRZ option " - "for target %d bus %d\n", - isp->isp_name, i, bus); - } - sdp->isp_devparam[i].dev_flags |= DPARM_ARQ; - if (ISP1080_NVRAM_TGT_ARQ(nvram_data, i, bus) == 0) { - PRINTF("%s: not disabling ARQ option " - "for target %d bus %d\n", - isp->isp_name, i, bus); - } - if (ISP1080_NVRAM_TGT_TQING(nvram_data, i, bus)) - sdp->isp_devparam[i].dev_flags |= DPARM_TQING; - if (ISP1080_NVRAM_TGT_SYNC(nvram_data, i, bus)) - sdp->isp_devparam[i].dev_flags |= DPARM_SYNC; - if (ISP1080_NVRAM_TGT_WIDE(nvram_data, i, bus)) - sdp->isp_devparam[i].dev_flags |= DPARM_WIDE; - if (ISP1080_NVRAM_TGT_PARITY(nvram_data, i, bus)) - sdp->isp_devparam[i].dev_flags |= DPARM_PARITY; - if (ISP1080_NVRAM_TGT_DISC(nvram_data, i, bus)) - sdp->isp_devparam[i].dev_flags |= DPARM_DISC; - sdp->isp_devparam[i].cur_dflags = 0; - if (isp->isp_dblev >= 3) { - PRINTF(" Target %d: Ena %d Throttle " - "%d Offset %d Period %d Flags " - "0x%x\n", i, - sdp->isp_devparam[i].dev_enable, - sdp->isp_devparam[i].exc_throttle, - sdp->isp_devparam[i].sync_offset, - sdp->isp_devparam[i].sync_period, - sdp->isp_devparam[i].dev_flags); - } - } - } + if (IS_ULTRA3(isp)) { + isp_parse_nvram_12160(isp, 0, nvram_data); + isp_parse_nvram_12160(isp, 1, nvram_data); + } else if (IS_1080(isp)) { + isp_parse_nvram_1080(isp, 0, nvram_data); + } else if (IS_1280(isp) || IS_1240(isp)) { + isp_parse_nvram_1080(isp, 0, nvram_data); + isp_parse_nvram_1080(isp, 1, nvram_data); } else if (IS_SCSI(isp)) { - sdparam *sdp = (sdparam *) isp->isp_param; - - sdp->isp_fifo_threshold = - ISP_NVRAM_FIFO_THRESHOLD(nvram_data) | - (ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2); - - sdp->isp_initiator_id = - ISP_NVRAM_INITIATOR_ID(nvram_data); - - sdp->isp_bus_reset_delay = - ISP_NVRAM_BUS_RESET_DELAY(nvram_data); - - sdp->isp_retry_count = - ISP_NVRAM_BUS_RETRY_COUNT(nvram_data); - - sdp->isp_retry_delay = - ISP_NVRAM_BUS_RETRY_DELAY(nvram_data); - - sdp->isp_async_data_setup = - ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data); - - if (isp->isp_type >= ISP_HA_SCSI_1040) { - if (sdp->isp_async_data_setup < 9) { - sdp->isp_async_data_setup = 9; - } - } else { - if (sdp->isp_async_data_setup != 6) { - sdp->isp_async_data_setup = 6; - } - } - - sdp->isp_req_ack_active_neg = - ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data); - - sdp->isp_data_line_active_neg = - ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data); - - sdp->isp_data_dma_burst_enabl = - ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data); - - sdp->isp_cmd_dma_burst_enable = - ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data); - - sdp->isp_tag_aging = - ISP_NVRAM_TAG_AGE_LIMIT(nvram_data); - - sdp->isp_selection_timeout = - ISP_NVRAM_SELECTION_TIMEOUT(nvram_data); - - sdp->isp_max_queue_depth = - ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data); - - isp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data); - if (isp->isp_dblev > 2) { - PRINTF("%s: NVRAM values:\n", isp->isp_name); - PRINTF(" Fifo Threshold = 0x%x\n", - sdp->isp_fifo_threshold); - PRINTF(" Bus Reset Delay = %d\n", - sdp->isp_bus_reset_delay); - PRINTF(" Retry Count = %d\n", - sdp->isp_retry_count); - PRINTF(" Retry Delay = %d\n", - sdp->isp_retry_delay); - PRINTF(" Tag Age Limit = %d\n", - sdp->isp_tag_aging); - PRINTF(" Selection Timeout = %d\n", - sdp->isp_selection_timeout); - PRINTF(" Max Queue Depth = %d\n", - sdp->isp_max_queue_depth); - PRINTF(" Async Data Setup = 0x%x\n", - sdp->isp_async_data_setup); - PRINTF(" REQ/ACK Active Negation = %s\n", - sdp->isp_req_ack_active_neg? tru : not); - PRINTF(" Data Line Active Negation = %s\n", - sdp->isp_data_line_active_neg? tru : not); - PRINTF(" Data DMA Burst Enable = %s\n", - sdp->isp_data_dma_burst_enabl? tru : not); - PRINTF(" Cmd DMA Burst Enable = %s\n", - sdp->isp_cmd_dma_burst_enable? tru : not); - PRINTF(" Fast MTTR = %s\n", - isp->isp_fast_mttr? tru : not); - } - for (i = 0; i < MAX_TARGETS; i++) { - sdp->isp_devparam[i].dev_enable = - ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i); - sdp->isp_devparam[i].exc_throttle = - ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, i); - sdp->isp_devparam[i].sync_offset = - ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, i); - sdp->isp_devparam[i].sync_period = - ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, i); - - if (isp->isp_type < ISP_HA_SCSI_1040) { - /* - * If we're not ultra, we can't possibly - * be a shorter period than this. - */ - if (sdp->isp_devparam[i].sync_period < 0x19) { - sdp->isp_devparam[i].sync_period = - 0x19; - } - if (sdp->isp_devparam[i].sync_offset > 0xc) { - sdp->isp_devparam[i].sync_offset = - 0x0c; - } - } else { - if (sdp->isp_devparam[i].sync_offset > 0x8) { - sdp->isp_devparam[i].sync_offset = 0x8; - } - } - sdp->isp_devparam[i].dev_flags = 0; - if (ISP_NVRAM_TGT_RENEG(nvram_data, i)) - sdp->isp_devparam[i].dev_flags |= DPARM_RENEG; - if (ISP_NVRAM_TGT_QFRZ(nvram_data, i)) { - PRINTF("%s: not supporting QFRZ option for " - "target %d\n", isp->isp_name, i); - } - sdp->isp_devparam[i].dev_flags |= DPARM_ARQ; - if (ISP_NVRAM_TGT_ARQ(nvram_data, i) == 0) { - PRINTF("%s: not disabling ARQ option for " - "target %d\n", isp->isp_name, i); - } - if (ISP_NVRAM_TGT_TQING(nvram_data, i)) - sdp->isp_devparam[i].dev_flags |= DPARM_TQING; - if (ISP_NVRAM_TGT_SYNC(nvram_data, i)) - sdp->isp_devparam[i].dev_flags |= DPARM_SYNC; - if (ISP_NVRAM_TGT_WIDE(nvram_data, i)) - sdp->isp_devparam[i].dev_flags |= DPARM_WIDE; - if (ISP_NVRAM_TGT_PARITY(nvram_data, i)) - sdp->isp_devparam[i].dev_flags |= DPARM_PARITY; - if (ISP_NVRAM_TGT_DISC(nvram_data, i)) - sdp->isp_devparam[i].dev_flags |= DPARM_DISC; - sdp->isp_devparam[i].cur_dflags = 0; /* we don't know */ - if (isp->isp_dblev > 2) { - PRINTF(" Target %d: Enabled %d Throttle %d " - "Offset %d Period %d Flags 0x%x\n", i, - sdp->isp_devparam[i].dev_enable, - sdp->isp_devparam[i].exc_throttle, - sdp->isp_devparam[i].sync_offset, - sdp->isp_devparam[i].sync_period, - sdp->isp_devparam[i].dev_flags); - } - } + isp_parse_nvram_1020(isp, nvram_data); } else { - fcparam *fcp = (fcparam *) isp->isp_param; - union { - struct { -#if BYTE_ORDER == BIG_ENDIAN - u_int32_t hi32; - u_int32_t lo32; -#else - u_int32_t lo32; - u_int32_t hi32; -#endif - } wd; - u_int64_t full64; - } wwnstore; - - wwnstore.full64 = ISP2100_NVRAM_NODE_NAME(nvram_data); - /* - * Broken PTI cards with nothing in the top nibble. Pah. - */ - if ((wwnstore.wd.hi32 >> 28) == 0) { - wwnstore.wd.hi32 |= (2 << 28); - CFGPRINTF("%s: (corrected) Adapter WWN 0x%08x%08x\n", - isp->isp_name, wwnstore.wd.hi32, wwnstore.wd.lo32); - } else { - CFGPRINTF("%s: Adapter WWN 0x%08x%08x\n", isp->isp_name, - wwnstore.wd.hi32, wwnstore.wd.lo32); - } - fcp->isp_nodewwn = wwnstore.full64; - - /* - * If the Node WWN has 2 in the top nibble, we can - * authoritatively construct a Port WWN by adding - * our unit number (plus one to make it nonzero) and - * putting it into bits 59..56. If the top nibble isn't - * 2, then we just set them identically. - */ - if ((fcp->isp_nodewwn >> 60) == 2) { - fcp->isp_portwwn = fcp->isp_nodewwn | - (((u_int64_t)(isp->isp_unit+1)) << 56); - } else { - fcp->isp_portwwn = fcp->isp_nodewwn; - } - wwnstore.full64 = ISP2100_NVRAM_BOOT_NODE_NAME(nvram_data); - if (wwnstore.full64 != 0) { - PRINTF("%s: BOOT DEVICE WWN 0x%08x%08x\n", - isp->isp_name, wwnstore.wd.hi32, wwnstore.wd.lo32); - } - fcp->isp_maxalloc = - ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data); - fcp->isp_maxfrmlen = - ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data); - fcp->isp_retry_delay = - ISP2100_NVRAM_RETRY_DELAY(nvram_data); - fcp->isp_retry_count = - ISP2100_NVRAM_RETRY_COUNT(nvram_data); - fcp->isp_loopid = - ISP2100_NVRAM_HARDLOOPID(nvram_data); - fcp->isp_execthrottle = - ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data); - fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data); - if (isp->isp_dblev > 2) { - PRINTF("%s: NVRAM values:\n", isp->isp_name); - PRINTF(" Max IOCB Allocation = %d\n", - fcp->isp_maxalloc); - PRINTF(" Max Frame Length = %d\n", - fcp->isp_maxfrmlen); - PRINTF(" Execution Throttle = %d\n", - fcp->isp_execthrottle); - PRINTF(" Retry Count = %d\n", - fcp->isp_retry_count); - PRINTF(" Retry Delay = %d\n", - fcp->isp_retry_delay); - PRINTF(" Hard Loop ID = %d\n", - fcp->isp_loopid); - PRINTF(" Options = 0x%x\n", - fcp->isp_fwoptions); - PRINTF(" HBA Options = 0x%x\n", - ISP2100_NVRAM_HBA_OPTIONS(nvram_data)); - } + isp_parse_nvram_2100(isp, nvram_data); } IDPRINTF(3, ("%s: NVRAM is valid\n", isp->isp_name)); return (0); +#undef nvram_data +#undef nvram_words } static void @@ -4442,3 +4238,493 @@ isp_rdnvram_word(isp, wo, rp) *rp = ((*rp >> 8) | ((*rp & 0xff) << 8)); #endif } + +static void +isp_parse_nvram_1020(isp, nvram_data) + struct ispsoftc *isp; + u_int8_t *nvram_data; +{ + int i; + static char *tru = "true"; + static char *not = "false"; + sdparam *sdp = (sdparam *) isp->isp_param; + + sdp->isp_fifo_threshold = + ISP_NVRAM_FIFO_THRESHOLD(nvram_data) | + (ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2); + + sdp->isp_initiator_id = + ISP_NVRAM_INITIATOR_ID(nvram_data); + + sdp->isp_bus_reset_delay = + ISP_NVRAM_BUS_RESET_DELAY(nvram_data); + + sdp->isp_retry_count = + ISP_NVRAM_BUS_RETRY_COUNT(nvram_data); + + sdp->isp_retry_delay = + ISP_NVRAM_BUS_RETRY_DELAY(nvram_data); + + sdp->isp_async_data_setup = + ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data); + + if (isp->isp_type >= ISP_HA_SCSI_1040) { + if (sdp->isp_async_data_setup < 9) { + sdp->isp_async_data_setup = 9; + } + } else { + if (sdp->isp_async_data_setup != 6) { + sdp->isp_async_data_setup = 6; + } + } + + sdp->isp_req_ack_active_neg = + ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data); + + sdp->isp_data_line_active_neg = + ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data); + + sdp->isp_data_dma_burst_enabl = + ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data); + + sdp->isp_cmd_dma_burst_enable = + ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data); + + sdp->isp_tag_aging = + ISP_NVRAM_TAG_AGE_LIMIT(nvram_data); + + sdp->isp_selection_timeout = + ISP_NVRAM_SELECTION_TIMEOUT(nvram_data); + + sdp->isp_max_queue_depth = + ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data); + + isp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data); + if (isp->isp_dblev > 2) { + PRINTF("%s: NVRAM values:\n", isp->isp_name); + PRINTF(" Fifo Threshold = 0x%x\n", + sdp->isp_fifo_threshold); + PRINTF(" Bus Reset Delay = %d\n", + sdp->isp_bus_reset_delay); + PRINTF(" Retry Count = %d\n", + sdp->isp_retry_count); + PRINTF(" Retry Delay = %d\n", + sdp->isp_retry_delay); + PRINTF(" Tag Age Limit = %d\n", + sdp->isp_tag_aging); + PRINTF(" Selection Timeout = %d\n", + sdp->isp_selection_timeout); + PRINTF(" Max Queue Depth = %d\n", + sdp->isp_max_queue_depth); + PRINTF(" Async Data Setup = 0x%x\n", + sdp->isp_async_data_setup); + PRINTF(" REQ/ACK Active Negation = %s\n", + sdp->isp_req_ack_active_neg? tru : not); + PRINTF(" Data Line Active Negation = %s\n", + sdp->isp_data_line_active_neg? tru : not); + PRINTF(" Data DMA Burst Enable = %s\n", + sdp->isp_data_dma_burst_enabl? tru : not); + PRINTF(" Cmd DMA Burst Enable = %s\n", + sdp->isp_cmd_dma_burst_enable? tru : not); + PRINTF(" Fast MTTR = %s\n", + isp->isp_fast_mttr? tru : not); + } + for (i = 0; i < MAX_TARGETS; i++) { + sdp->isp_devparam[i].dev_enable = + ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i); + sdp->isp_devparam[i].exc_throttle = + ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, i); + sdp->isp_devparam[i].sync_offset = + ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, i); + sdp->isp_devparam[i].sync_period = + ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, i); + + if (isp->isp_type < ISP_HA_SCSI_1040) { + /* + * If we're not ultra, we can't possibly + * be a shorter period than this. + */ + if (sdp->isp_devparam[i].sync_period < 0x19) { + sdp->isp_devparam[i].sync_period = + 0x19; + } + if (sdp->isp_devparam[i].sync_offset > 0xc) { + sdp->isp_devparam[i].sync_offset = + 0x0c; + } + } else { + if (sdp->isp_devparam[i].sync_offset > 0x8) { + sdp->isp_devparam[i].sync_offset = 0x8; + } + } + sdp->isp_devparam[i].dev_flags = 0; + if (ISP_NVRAM_TGT_RENEG(nvram_data, i)) + sdp->isp_devparam[i].dev_flags |= DPARM_RENEG; + if (ISP_NVRAM_TGT_QFRZ(nvram_data, i)) { + PRINTF("%s: not supporting QFRZ option for " + "target %d\n", isp->isp_name, i); + } + sdp->isp_devparam[i].dev_flags |= DPARM_ARQ; + if (ISP_NVRAM_TGT_ARQ(nvram_data, i) == 0) { + PRINTF("%s: not disabling ARQ option for " + "target %d\n", isp->isp_name, i); + } + if (ISP_NVRAM_TGT_TQING(nvram_data, i)) + sdp->isp_devparam[i].dev_flags |= DPARM_TQING; + if (ISP_NVRAM_TGT_SYNC(nvram_data, i)) + sdp->isp_devparam[i].dev_flags |= DPARM_SYNC; + if (ISP_NVRAM_TGT_WIDE(nvram_data, i)) + sdp->isp_devparam[i].dev_flags |= DPARM_WIDE; + if (ISP_NVRAM_TGT_PARITY(nvram_data, i)) + sdp->isp_devparam[i].dev_flags |= DPARM_PARITY; + if (ISP_NVRAM_TGT_DISC(nvram_data, i)) + sdp->isp_devparam[i].dev_flags |= DPARM_DISC; + sdp->isp_devparam[i].cur_dflags = 0; /* we don't know */ + if (isp->isp_dblev > 2) { + PRINTF(" Target %d: Enabled %d Throttle %d " + "Offset %d Period %d Flags 0x%x\n", i, + sdp->isp_devparam[i].dev_enable, + sdp->isp_devparam[i].exc_throttle, + sdp->isp_devparam[i].sync_offset, + sdp->isp_devparam[i].sync_period, + sdp->isp_devparam[i].dev_flags); + } + } +} + +static void +isp_parse_nvram_1080(isp, bus, nvram_data) + struct ispsoftc *isp; + int bus; + u_int8_t *nvram_data; +{ + static char *tru = "true"; + static char *not = "false"; + int i; + sdparam *sdp = (sdparam *) isp->isp_param; + sdp += bus; + + sdp->isp_fifo_threshold = + ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data); + + sdp->isp_initiator_id = + ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus); + + sdp->isp_bus_reset_delay = + ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus); + + sdp->isp_retry_count = + ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus); + + sdp->isp_retry_delay = + ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus); + + sdp->isp_async_data_setup = + ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, + bus); + + sdp->isp_req_ack_active_neg = + ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, + bus); + + sdp->isp_data_line_active_neg = + ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, + bus); + + sdp->isp_data_dma_burst_enabl = + ISP1080_NVRAM_BURST_ENABLE(nvram_data); + + sdp->isp_cmd_dma_burst_enable = + ISP1080_NVRAM_BURST_ENABLE(nvram_data); + + sdp->isp_selection_timeout = + ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus); + + sdp->isp_max_queue_depth = + ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus); + + if (isp->isp_dblev >= 3) { + PRINTF("%s: ISP1080 bus %d NVRAM values:\n", + isp->isp_name, bus); + PRINTF(" Initiator ID = %d\n", + sdp->isp_initiator_id); + PRINTF(" Fifo Threshold = 0x%x\n", + sdp->isp_fifo_threshold); + PRINTF(" Bus Reset Delay = %d\n", + sdp->isp_bus_reset_delay); + PRINTF(" Retry Count = %d\n", + sdp->isp_retry_count); + PRINTF(" Retry Delay = %d\n", + sdp->isp_retry_delay); + PRINTF(" Tag Age Limit = %d\n", + sdp->isp_tag_aging); + PRINTF(" Selection Timeout = %d\n", + sdp->isp_selection_timeout); + PRINTF(" Max Queue Depth = %d\n", + sdp->isp_max_queue_depth); + PRINTF(" Async Data Setup = 0x%x\n", + sdp->isp_async_data_setup); + PRINTF(" REQ/ACK Active Negation = %s\n", + sdp->isp_req_ack_active_neg? tru : not); + PRINTF(" Data Line Active Negation = %s\n", + sdp->isp_data_line_active_neg? tru : not); + PRINTF(" Cmd DMA Burst Enable = %s\n", + sdp->isp_cmd_dma_burst_enable? tru : not); + } + for (i = 0; i < MAX_TARGETS; i++) { + sdp->isp_devparam[i].dev_enable = + ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i, bus); + sdp->isp_devparam[i].exc_throttle = + ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, i, bus); + sdp->isp_devparam[i].sync_offset = + ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, i, bus); + sdp->isp_devparam[i].sync_period = + ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, i, bus); + sdp->isp_devparam[i].dev_flags = 0; + if (ISP1080_NVRAM_TGT_RENEG(nvram_data, i, bus)) + sdp->isp_devparam[i].dev_flags |= DPARM_RENEG; + if (ISP1080_NVRAM_TGT_QFRZ(nvram_data, i, bus)) { + PRINTF("%s: not supporting QFRZ option " + "for target %d bus %d\n", + isp->isp_name, i, bus); + } + sdp->isp_devparam[i].dev_flags |= DPARM_ARQ; + if (ISP1080_NVRAM_TGT_ARQ(nvram_data, i, bus) == 0) { + PRINTF("%s: not disabling ARQ option " + "for target %d bus %d\n", + isp->isp_name, i, bus); + } + if (ISP1080_NVRAM_TGT_TQING(nvram_data, i, bus)) + sdp->isp_devparam[i].dev_flags |= DPARM_TQING; + if (ISP1080_NVRAM_TGT_SYNC(nvram_data, i, bus)) + sdp->isp_devparam[i].dev_flags |= DPARM_SYNC; + if (ISP1080_NVRAM_TGT_WIDE(nvram_data, i, bus)) + sdp->isp_devparam[i].dev_flags |= DPARM_WIDE; + if (ISP1080_NVRAM_TGT_PARITY(nvram_data, i, bus)) + sdp->isp_devparam[i].dev_flags |= DPARM_PARITY; + if (ISP1080_NVRAM_TGT_DISC(nvram_data, i, bus)) + sdp->isp_devparam[i].dev_flags |= DPARM_DISC; + sdp->isp_devparam[i].cur_dflags = 0; + if (isp->isp_dblev >= 3) { + PRINTF(" Target %d: Ena %d Throttle " + "%d Offset %d Period %d Flags " + "0x%x\n", i, + sdp->isp_devparam[i].dev_enable, + sdp->isp_devparam[i].exc_throttle, + sdp->isp_devparam[i].sync_offset, + sdp->isp_devparam[i].sync_period, + sdp->isp_devparam[i].dev_flags); + } + } +} + +static void +isp_parse_nvram_12160(isp, bus, nvram_data) + struct ispsoftc *isp; + int bus; + u_int8_t *nvram_data; +{ + static char *tru = "true"; + static char *not = "false"; + sdparam *sdp = (sdparam *) isp->isp_param; + int i; + + sdp += bus; + + sdp->isp_fifo_threshold = + ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data); + + sdp->isp_initiator_id = + ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus); + + sdp->isp_bus_reset_delay = + ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus); + + sdp->isp_retry_count = + ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus); + + sdp->isp_retry_delay = + ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus); + + sdp->isp_async_data_setup = + ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, + bus); + + sdp->isp_req_ack_active_neg = + ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, + bus); + + sdp->isp_data_line_active_neg = + ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, + bus); + + sdp->isp_data_dma_burst_enabl = + ISP12160_NVRAM_BURST_ENABLE(nvram_data); + + sdp->isp_cmd_dma_burst_enable = + ISP12160_NVRAM_BURST_ENABLE(nvram_data); + + sdp->isp_selection_timeout = + ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus); + + sdp->isp_max_queue_depth = + ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus); + + if (isp->isp_dblev >= 3) { + PRINTF("%s: ISP12160 bus %d NVRAM values:\n", + isp->isp_name, bus); + PRINTF(" Initiator ID = %d\n", + sdp->isp_initiator_id); + PRINTF(" Fifo Threshold = 0x%x\n", + sdp->isp_fifo_threshold); + PRINTF(" Bus Reset Delay = %d\n", + sdp->isp_bus_reset_delay); + PRINTF(" Retry Count = %d\n", + sdp->isp_retry_count); + PRINTF(" Retry Delay = %d\n", + sdp->isp_retry_delay); + PRINTF(" Tag Age Limit = %d\n", + sdp->isp_tag_aging); + PRINTF(" Selection Timeout = %d\n", + sdp->isp_selection_timeout); + PRINTF(" Max Queue Depth = %d\n", + sdp->isp_max_queue_depth); + PRINTF(" Async Data Setup = 0x%x\n", + sdp->isp_async_data_setup); + PRINTF(" REQ/ACK Active Negation = %s\n", + sdp->isp_req_ack_active_neg? tru : not); + PRINTF(" Data Line Active Negation = %s\n", + sdp->isp_data_line_active_neg? tru : not); + PRINTF(" Cmd DMA Burst Enable = %s\n", + sdp->isp_cmd_dma_burst_enable? tru : not); + } + + for (i = 0; i < MAX_TARGETS; i++) { + sdp->isp_devparam[i].dev_enable = + ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i, bus); + sdp->isp_devparam[i].exc_throttle = + ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, i, bus); + sdp->isp_devparam[i].sync_offset = + ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, i, bus); + sdp->isp_devparam[i].sync_period = + ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, i, bus); + sdp->isp_devparam[i].dev_flags = 0; + if (ISP12160_NVRAM_TGT_RENEG(nvram_data, i, bus)) + sdp->isp_devparam[i].dev_flags |= DPARM_RENEG; + if (ISP12160_NVRAM_TGT_QFRZ(nvram_data, i, bus)) { + PRINTF("%s: not supporting QFRZ option " + "for target %d bus %d\n", isp->isp_name, i, bus); + } + sdp->isp_devparam[i].dev_flags |= DPARM_ARQ; + if (ISP12160_NVRAM_TGT_ARQ(nvram_data, i, bus) == 0) { + PRINTF("%s: not disabling ARQ option " + "for target %d bus %d\n", isp->isp_name, i, bus); + } + if (ISP12160_NVRAM_TGT_TQING(nvram_data, i, bus)) + sdp->isp_devparam[i].dev_flags |= DPARM_TQING; + if (ISP12160_NVRAM_TGT_SYNC(nvram_data, i, bus)) + sdp->isp_devparam[i].dev_flags |= DPARM_SYNC; + if (ISP12160_NVRAM_TGT_WIDE(nvram_data, i, bus)) + sdp->isp_devparam[i].dev_flags |= DPARM_WIDE; + if (ISP12160_NVRAM_TGT_PARITY(nvram_data, i, bus)) + sdp->isp_devparam[i].dev_flags |= DPARM_PARITY; + if (ISP12160_NVRAM_TGT_DISC(nvram_data, i, bus)) + sdp->isp_devparam[i].dev_flags |= DPARM_DISC; + sdp->isp_devparam[i].cur_dflags = 0; + if (isp->isp_dblev >= 3) { + PRINTF(" Target %d: Ena %d Throttle %d Offset %d " + "Period %d Flags 0x%x\n", i, + sdp->isp_devparam[i].dev_enable, + sdp->isp_devparam[i].exc_throttle, + sdp->isp_devparam[i].sync_offset, + sdp->isp_devparam[i].sync_period, + sdp->isp_devparam[i].dev_flags); + } + } +} + +static void +isp_parse_nvram_2100(isp, nvram_data) + struct ispsoftc *isp; + u_int8_t *nvram_data; +{ + fcparam *fcp = (fcparam *) isp->isp_param; + union { + struct { +#if BYTE_ORDER == BIG_ENDIAN + u_int32_t hi32; + u_int32_t lo32; +#else + u_int32_t lo32; + u_int32_t hi32; +#endif + } wd; + u_int64_t full64; + } wwnstore; + + wwnstore.full64 = ISP2100_NVRAM_NODE_NAME(nvram_data); + + /* + * Broken PTI cards with nothing in the top nibble. Pah. + */ + if ((wwnstore.wd.hi32 >> 28) == 0) { + wwnstore.wd.hi32 |= (2 << 28); + CFGPRINTF("%s: (corrected) Adapter WWN 0x%08x%08x\n", + isp->isp_name, wwnstore.wd.hi32, wwnstore.wd.lo32); + } else { + CFGPRINTF("%s: Adapter WWN 0x%08x%08x\n", isp->isp_name, + wwnstore.wd.hi32, wwnstore.wd.lo32); + } + fcp->isp_nodewwn = wwnstore.full64; + + /* + * If the Node WWN has 2 in the top nibble, we can + * authoritatively construct a Port WWN by adding + * our unit number (plus one to make it nonzero) and + * putting it into bits 59..56. If the top nibble isn't + * 2, then we just set them identically. + */ + if ((fcp->isp_nodewwn >> 60) == 2) { + fcp->isp_portwwn = fcp->isp_nodewwn | + (((u_int64_t)(isp->isp_unit+1)) << 56); + } else { + fcp->isp_portwwn = fcp->isp_nodewwn; + } + wwnstore.full64 = ISP2100_NVRAM_BOOT_NODE_NAME(nvram_data); + if (wwnstore.full64 != 0) { + PRINTF("%s: BOOT DEVICE WWN 0x%08x%08x\n", + isp->isp_name, wwnstore.wd.hi32, wwnstore.wd.lo32); + } + fcp->isp_maxalloc = + ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data); + fcp->isp_maxfrmlen = + ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data); + fcp->isp_retry_delay = + ISP2100_NVRAM_RETRY_DELAY(nvram_data); + fcp->isp_retry_count = + ISP2100_NVRAM_RETRY_COUNT(nvram_data); + fcp->isp_loopid = + ISP2100_NVRAM_HARDLOOPID(nvram_data); + fcp->isp_execthrottle = + ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data); + fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data); + if (isp->isp_dblev > 2) { + PRINTF("%s: NVRAM values:\n", isp->isp_name); + PRINTF(" Max IOCB Allocation = %d\n", + fcp->isp_maxalloc); + PRINTF(" Max Frame Length = %d\n", + fcp->isp_maxfrmlen); + PRINTF(" Execution Throttle = %d\n", + fcp->isp_execthrottle); + PRINTF(" Retry Count = %d\n", + fcp->isp_retry_count); + PRINTF(" Retry Delay = %d\n", + fcp->isp_retry_delay); + PRINTF(" Hard Loop ID = %d\n", + fcp->isp_loopid); + PRINTF(" Options = 0x%x\n", + fcp->isp_fwoptions); + PRINTF(" HBA Options = 0x%x\n", + ISP2100_NVRAM_HBA_OPTIONS(nvram_data)); + } +} |