summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp/isp_library.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/isp/isp_library.c')
-rw-r--r--sys/dev/isp/isp_library.c270
1 files changed, 106 insertions, 164 deletions
diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c
index 2f7dc4e..f7ee7bb 100644
--- a/sys/dev/isp/isp_library.c
+++ b/sys/dev/isp/isp_library.c
@@ -411,10 +411,6 @@ isp_fc_runstate(ispsoftc_t *isp, int chan, int tval)
}
}
- if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
- return (0);
- }
-
if (isp_control(isp, ISPCTL_SCAN_LOOP, chan) != 0) {
isp_prt(isp, ISP_LOG_SANCFG, "isp_fc_runstate: scan loop fails on channel %d", chan);
return (LOOP_PDB_RCVD);
@@ -444,7 +440,7 @@ isp_dump_portdb(ispsoftc_t *isp, int chan)
int i;
for (i = 0; i < MAX_FC_TARG; i++) {
- char mb[4], buf1[64], buf2[64];
+ char buf1[64], buf2[64];
const char *dbs[8] = {
"NIL ",
"PROB",
@@ -457,18 +453,13 @@ isp_dump_portdb(ispsoftc_t *isp, int chan)
};
fcportdb_t *lp = &fcp->portdb[i];
- if (lp->state == FC_PORTDB_STATE_NIL && lp->target_mode == 0) {
+ if (lp->state == FC_PORTDB_STATE_NIL) {
continue;
}
- if (lp->dev_map_idx) {
- ISP_SNPRINTF(mb, sizeof (mb), "%3d", ((int) lp->dev_map_idx) - 1);
- } else {
- ISP_SNPRINTF(mb, sizeof (mb), "---");
- }
isp_gen_role_str(buf1, sizeof (buf1), lp->prli_word3);
isp_gen_role_str(buf2, sizeof (buf2), lp->new_prli_word3);
- isp_prt(isp, ISP_LOGALL, "Chan %d [%d]: hdl 0x%x %s al%d tgt %s %s 0x%06x =>%s 0x%06x; WWNN 0x%08x%08x WWPN 0x%08x%08x",
- chan, i, lp->handle, dbs[lp->state], lp->autologin, mb, buf1, lp->portid, buf2, lp->new_portid,
+ isp_prt(isp, ISP_LOGALL, "Chan %d [%d]: hdl 0x%x %s al%d %s 0x%06x =>%s 0x%06x; WWNN 0x%08x%08x WWPN 0x%08x%08x",
+ chan, i, lp->handle, dbs[lp->state], lp->autologin, buf1, lp->portid, buf2, lp->new_portid,
(uint32_t) (lp->node_wwn >> 32), (uint32_t) (lp->node_wwn), (uint32_t) (lp->port_wwn >> 32), (uint32_t) (lp->port_wwn));
}
}
@@ -603,20 +594,8 @@ isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role)
return (ENXIO);
}
if (chan == 0) {
- isp_clear_commands(isp);
- isp_reset(isp, 0);
- if (isp->isp_state != ISP_RESETSTATE) {
- isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
- return (EIO);
- }
fcp->role = new_role;
- isp_init(isp);
- if (isp->isp_state != ISP_INITSTATE) {
- isp_prt(isp, ISP_LOGERR, "%s: cannot init card", __func__);
- return (EIO);
- }
- isp->isp_state = ISP_RUNSTATE;
- return (0);
+ return (isp_reinit(isp, 0));
} else if (ISP_CAP_MULTI_ID(isp)) {
mbreg_t mbs;
vp_modify_t *vp;
@@ -2347,8 +2326,10 @@ isp_destroy_tgt_handle(ispsoftc_t *isp, uint32_t handle)
}
}
+#endif
+
/*
- * Find target mode entries
+ * Find port database entries
*/
int
isp_find_pdb_by_wwn(ispsoftc_t *isp, int chan, uint64_t wwn, fcportdb_t **lptr)
@@ -2359,10 +2340,10 @@ isp_find_pdb_by_wwn(ispsoftc_t *isp, int chan, uint64_t wwn, fcportdb_t **lptr)
if (chan >= isp->isp_nchan)
return (0);
fcp = FCPARAM(isp, chan);
- for (i = MAX_FC_TARG - 1; i >= 0; i--) {
+ for (i = 0; i < MAX_FC_TARG; i++) {
fcportdb_t *lp = &fcp->portdb[i];
- if (lp->target_mode == 0)
+ if (lp->state == FC_PORTDB_STATE_NIL)
continue;
if (lp->port_wwn == wwn) {
*lptr = lp;
@@ -2372,8 +2353,10 @@ isp_find_pdb_by_wwn(ispsoftc_t *isp, int chan, uint64_t wwn, fcportdb_t **lptr)
return (0);
}
+#ifdef ISP_TARGET_MODE
+
int
-isp_find_pdb_by_loopid(ispsoftc_t *isp, int chan, uint32_t loopid, fcportdb_t **lptr)
+isp_find_pdb_by_handle(ispsoftc_t *isp, int chan, uint32_t handle, fcportdb_t **lptr)
{
fcparam *fcp;
int i;
@@ -2381,9 +2364,15 @@ isp_find_pdb_by_loopid(ispsoftc_t *isp, int chan, uint32_t loopid, fcportdb_t **
if (chan >= isp->isp_nchan)
return (0);
fcp = FCPARAM(isp, chan);
- if ((i = fcp->isp_tgt_map[loopid]) > 0) {
- *lptr = &fcp->portdb[i - 1];
- return (1);
+ for (i = 0; i < MAX_FC_TARG; i++) {
+ fcportdb_t *lp = &fcp->portdb[i];
+
+ if (lp->state == FC_PORTDB_STATE_NIL)
+ continue;
+ if (lp->handle == handle) {
+ *lptr = lp;
+ return (1);
+ }
}
return (0);
}
@@ -2397,10 +2386,10 @@ isp_find_pdb_by_sid(ispsoftc_t *isp, int chan, uint32_t sid, fcportdb_t **lptr)
if (chan >= isp->isp_nchan)
return (0);
fcp = FCPARAM(isp, chan);
- for (i = MAX_FC_TARG - 1; i >= 0; i--) {
+ for (i = 0; i < MAX_FC_TARG; i++) {
fcportdb_t *lp = &fcp->portdb[i];
- if (lp->target_mode == 0)
+ if (lp->state == FC_PORTDB_STATE_NIL)
continue;
if (lp->portid == sid) {
*lptr = lp;
@@ -2437,14 +2426,13 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3
char buf[64];
fcparam *fcp;
fcportdb_t *lp;
- isp_notify_t nt;
- int i, something, take, taken;
+ int i, change;
fcp = FCPARAM(isp, chan);
if (nphdl >= MAX_NPORT_HANDLE) {
- isp_prt(isp, ISP_LOGWARN, "Chan %d IID 0x%016llx "
- "N-Port handle 0x%04x Port ID 0x%06x -- bad handle",
- chan, (unsigned long long) ini, nphdl, s_id);
+ isp_prt(isp, ISP_LOGTINFO|ISP_LOGWARN, "Chan %d WWPN 0x%016llx "
+ "PortID 0x%06x handle 0x%x -- bad handle",
+ chan, (unsigned long long) ini, s_id, nphdl);
return;
}
@@ -2453,146 +2441,118 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3
* with new parameters. Some cases of update can be suspicious,
* so log them verbosely and dump the whole port database.
*/
- if ((i = fcp->isp_tgt_map[nphdl]) > 0) {
- take = taken = i - 1;
- lp = &fcp->portdb[taken];
- something = 0;
+ if ((VALID_INI(ini) && isp_find_pdb_by_wwn(isp, chan, ini, &lp)) ||
+ (s_id != PORT_NONE && isp_find_pdb_by_sid(isp, chan, s_id, &lp))) {
+ change = 0;
+ lp->new_portid = lp->portid;
+ lp->new_prli_word3 = lp->prli_word3;
if (s_id != PORT_NONE && lp->portid != s_id) {
if (lp->portid == PORT_NONE) {
isp_prt(isp, ISP_LOGTINFO,
- "Chan %d IID 0x%016llx N-port handle 0x%04x "
- "gets Port ID 0x%06x",
+ "Chan %d WWPN 0x%016llx handle 0x%x "
+ "gets PortID 0x%06x",
chan, (unsigned long long) lp->port_wwn,
nphdl, s_id);
} else {
isp_prt(isp, ISP_LOGTINFO|ISP_LOGWARN,
- "Chan %d IID 0x%016llx N-port handle 0x%04x "
- "changes Port ID 0x%06x to 0x%06x",
+ "Chan %d WWPN 0x%016llx handle 0x%x "
+ "changes PortID 0x%06x to 0x%06x",
chan, (unsigned long long) lp->port_wwn,
nphdl, lp->portid, s_id);
if (isp->isp_dblev & (ISP_LOGTINFO|ISP_LOGWARN))
isp_dump_portdb(isp, chan);
}
- lp->portid = s_id;
- something++;
+ lp->new_portid = s_id;
+ change++;
}
if (VALID_INI(ini) && lp->port_wwn != ini) {
if (!VALID_INI(lp->port_wwn)) {
isp_prt(isp, ISP_LOGTINFO,
- "Chan %d N-port handle 0x%04x Port ID "
- "0x%06x gets WWN 0x%016llxx",
- chan, nphdl, lp->portid,
+ "Chan %d PortID 0x%06x handle 0x%x "
+ "gets WWN 0x%016llxx",
+ chan, lp->portid, nphdl,
(unsigned long long) ini);
} else if (lp->port_wwn != ini) {
isp_prt(isp, ISP_LOGTINFO|ISP_LOGWARN,
- "Chan %d N-port handle 0x%04x Port ID "
- "0x%06x changes WWN 0x%016llx to 0x%016llx",
- chan, nphdl, lp->portid,
+ "Chan %d PortID 0x%06x handle 0x%x "
+ "changes WWN 0x%016llx to 0x%016llx",
+ chan, lp->portid, nphdl,
(unsigned long long) lp->port_wwn,
(unsigned long long) ini);
if (isp->isp_dblev & (ISP_LOGTINFO|ISP_LOGWARN))
isp_dump_portdb(isp, chan);
}
lp->port_wwn = ini;
- something++;
+ change++;
}
- if (lp->prli_word3 != prli_params) {
- lp->prli_word3 = prli_params;
- isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
+ if (prli_params != 0 && lp->prli_word3 != prli_params) {
+ isp_gen_role_str(buf, sizeof (buf), prli_params);
isp_prt(isp, ISP_LOGTINFO|ISP_LOGCONFIG,
- "Chan %d IID 0x%016llx N-Port Handle 0x%04x "
- "Port ID 0x%06x changes PRLI Word 3 %s",
+ "Chan %d WWPN 0x%016llx PortID 0x%06x "
+ "handle 0x%x changes PRLI Word 3 %s",
chan, (unsigned long long) lp->port_wwn,
- lp->handle, lp->portid, buf);
- something++;
+ lp->portid, lp->handle, buf);
+ lp->new_prli_word3 = prli_params;
+ change++;
}
- if (!something) {
- isp_prt(isp, ISP_LOGTINFO,
- "Chan %d IID 0x%016llx N-Port Handle 0x%04x "
- "Port ID 0x%06x reentered",
+ if (lp->handle != nphdl) {
+ isp_prt(isp, ISP_LOGTINFO|ISP_LOGCONFIG,
+ "Chan %d WWPN 0x%016llx PortID 0x%06x "
+ "changes handle 0x%x to 0x%x",
chan, (unsigned long long) lp->port_wwn,
- lp->handle, lp->portid);
- }
- } else
- take = taken = -1;
-
- /*
- * Search for records colliding on handler, Port ID or WWN.
- * Remove any found collisions, logging suspicious cases of
- * still valid records.
- */
- for (i = 0; i < MAX_FC_TARG; i++) {
- lp = &fcp->portdb[i];
- if (lp->target_mode == 0 || i == take)
- continue;
- if (lp->handle != nphdl && lp->portid != s_id &&
- lp->port_wwn != ini)
- continue;
- if (lp->state == FC_PORTDB_STATE_VALID) {
- isp_prt(isp, ISP_LOGTINFO|ISP_LOGWARN,
- "Chan %d IID 0x%016llx N-Port Handle 0x%04x "
- "Port ID 0x%06x is conflicting",
+ lp->portid, lp->handle, nphdl);
+ lp->handle = nphdl;
+ change++;
+ }
+ lp->state = FC_PORTDB_STATE_VALID;
+ if (change) {
+ isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
+ lp->portid = lp->new_portid;
+ lp->prli_word3 = lp->new_prli_word3;
+ lp->new_prli_word3 = 0;
+ lp->new_portid = 0;
+ } else {
+ isp_prt(isp, ISP_LOGTINFO,
+ "Chan %d WWPN 0x%016llx PortID 0x%06x "
+ "handle 0x%x reentered",
chan, (unsigned long long) lp->port_wwn,
- lp->handle, lp->portid);
- if (isp->isp_dblev & (ISP_LOGTINFO|ISP_LOGWARN))
- isp_dump_portdb(isp, chan);
- isp_del_wwn_entry(isp, chan,
- lp->port_wwn, lp->handle, lp->portid);
+ lp->portid, lp->handle);
+ isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
}
- ISP_MEMZERO(lp, sizeof (fcportdb_t));
- take = i;
- }
-
- /* If valid record already exists -- we are done. */
- if (taken >= 0)
return;
+ }
/* Search for room to insert new record. */
- if (take < 0) {
- for (i = MAX_FC_TARG - 1; i >= 0; i--) {
- if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL) {
- take = i;
- break;
- }
- }
+ for (i = 0; i < MAX_FC_TARG; i++) {
+ if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL)
+ break;
}
- if (take < 0) {
+ if (i >= MAX_FC_TARG) {
isp_prt(isp, ISP_LOGTINFO|ISP_LOGWARN,
- "Chan %d IID 0x%016llx N-Port Handle 0x%04x Port ID 0x%06x "
+ "Chan %d WWPN 0x%016llx PortID 0x%06x handle 0x%x "
"-- no room in port database",
- chan, (unsigned long long) ini, nphdl, s_id);
+ chan, (unsigned long long) ini, s_id, nphdl);
if (isp->isp_dblev & (ISP_LOGTINFO|ISP_LOGWARN))
isp_dump_portdb(isp, chan);
return;
}
/* Insert new record and mark it valid. */
- lp = &fcp->portdb[take];
+ lp = &fcp->portdb[i];
ISP_MEMZERO(lp, sizeof (fcportdb_t));
- lp->target_mode = 1;
lp->handle = nphdl;
lp->portid = s_id;
lp->port_wwn = ini;
- lp->prli_word3 = prli_params;
+ lp->prli_word3 = (prli_params != 0) ? prli_params : PRLI_WD3_INITIATOR_FUNCTION;
lp->state = FC_PORTDB_STATE_VALID;
- fcp->isp_tgt_map[nphdl] = take + 1;
isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
- isp_prt(isp, ISP_LOGTINFO, "Chan %d IID 0x%016llx N-Port Handle 0x%04x"
- " Port ID 0x%06x vtgt %d %s added", chan,
- (unsigned long long) ini, nphdl, s_id, take, buf);
-
- /* Notify above levels about new initiator arrival. */
- ISP_MEMZERO(&nt, sizeof (nt));
- nt.nt_hba = isp;
- nt.nt_wwn = ini;
- nt.nt_tgt = FCPARAM(isp, chan)->isp_wwpn;
- nt.nt_sid = s_id;
- nt.nt_did = FCPARAM(isp, chan)->isp_portid;
- nt.nt_nphdl = nphdl;
- nt.nt_channel = chan;
- nt.nt_ncode = NT_ARRIVED;
- isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
+ isp_prt(isp, ISP_LOGTINFO, "Chan %d WWPN 0x%016llx "
+ "PortID 0x%06x handle 0x%x vtgt %d %s added", chan,
+ (unsigned long long) ini, s_id, nphdl, i, buf);
+
+ /* Notify above levels about new port arrival. */
+ isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
}
/*
@@ -2602,45 +2562,27 @@ void
isp_del_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint32_t s_id)
{
fcparam *fcp;
- isp_notify_t nt;
fcportdb_t *lp;
if (nphdl >= MAX_NPORT_HANDLE) {
- isp_prt(isp, ISP_LOGWARN, "Chan %d IID 0x%016llx bad N-Port handle 0x%04x Port ID 0x%06x",
- chan, (unsigned long long) ini, nphdl, s_id);
+ isp_prt(isp, ISP_LOGWARN, "Chan %d WWPN 0x%016llx PortID 0x%06x bad handle 0x%x",
+ chan, (unsigned long long) ini, s_id, nphdl);
return;
}
fcp = FCPARAM(isp, chan);
- if (fcp->isp_tgt_map[nphdl] == 0) {
- lp = NULL;
- } else {
- lp = &fcp->portdb[fcp->isp_tgt_map[nphdl] - 1];
- if (lp->target_mode == 0) {
- lp = NULL;
- }
- }
- if (lp == NULL) {
- isp_prt(isp, ISP_LOGWARN, "Chan %d IID 0x%016llx N-Port Handle 0x%04x Port ID 0x%06x cannot be found to be deleted",
- chan, (unsigned long long) ini, nphdl, s_id);
+ if (isp_find_pdb_by_handle(isp, chan, nphdl, &lp) == 0) {
+ isp_prt(isp, ISP_LOGWARN, "Chan %d WWPN 0x%016llx PortID 0x%06x handle 0x%x cannot be found to be deleted",
+ chan, (unsigned long long) ini, s_id, nphdl);
isp_dump_portdb(isp, chan);
return;
}
- isp_prt(isp, ISP_LOGTINFO, "Chan %d IID 0x%016llx N-Port Handle 0x%04x Port ID 0x%06x vtgt %d deleted",
- chan, (unsigned long long) lp->port_wwn, nphdl, lp->portid, fcp->isp_tgt_map[nphdl] - 1);
- fcp->isp_tgt_map[nphdl] = 0;
- lp->state = FC_PORTDB_STATE_DEAD;
+ isp_prt(isp, ISP_LOGTINFO, "Chan %d WWPN 0x%016llx PortID 0x%06x handle 0x%x vtgt %d deleted",
+ chan, (unsigned long long) lp->port_wwn, lp->portid, nphdl, FC_PORTDB_TGT(isp, chan, lp));
+ lp->state = FC_PORTDB_STATE_NIL;
- ISP_MEMZERO(&nt, sizeof (nt));
- nt.nt_hba = isp;
- nt.nt_wwn = lp->port_wwn;
- nt.nt_tgt = FCPARAM(isp, chan)->isp_wwpn;
- nt.nt_sid = lp->portid;
- nt.nt_did = FCPARAM(isp, chan)->isp_portid;
- nt.nt_nphdl = nphdl;
- nt.nt_channel = chan;
- nt.nt_ncode = NT_DEPARTED;
- isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
+ /* Notify above levels about gone port. */
+ isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
}
void
@@ -2671,11 +2613,11 @@ isp_del_all_wwn_entries(ispsoftc_t *isp, int chan)
if (fcp == NULL) {
return;
}
- for (i = 0; i < MAX_NPORT_HANDLE; i++) {
- if (fcp->isp_tgt_map[i]) {
- fcportdb_t *lp = &fcp->portdb[fcp->isp_tgt_map[i] - 1];
+ for (i = 0; i < MAX_FC_TARG; i++) {
+ fcportdb_t *lp = &fcp->portdb[i];
+
+ if (lp->state != FC_PORTDB_STATE_NIL)
isp_del_wwn_entry(isp, chan, lp->port_wwn, lp->handle, lp->portid);
- }
}
}
@@ -2702,7 +2644,7 @@ isp_del_wwn_entries(ispsoftc_t *isp, isp_notify_t *mp)
* We need to find the actual entry so we can delete it.
*/
if (mp->nt_nphdl != NIL_HANDLE) {
- if (isp_find_pdb_by_loopid(isp, mp->nt_channel, mp->nt_nphdl, &lp)) {
+ if (isp_find_pdb_by_handle(isp, mp->nt_channel, mp->nt_nphdl, &lp)) {
isp_del_wwn_entry(isp, mp->nt_channel, lp->port_wwn, lp->handle, lp->portid);
return;
}
@@ -2719,8 +2661,8 @@ isp_del_wwn_entries(ispsoftc_t *isp, isp_notify_t *mp)
return;
}
}
- isp_prt(isp, ISP_LOGWARN, "Chan %d unable to find entry to delete N-port handle 0x%04x initiator WWN 0x%016llx Port ID 0x%06x",
- mp->nt_channel, mp->nt_nphdl, (unsigned long long) mp->nt_wwn, mp->nt_sid);
+ isp_prt(isp, ISP_LOGWARN, "Chan %d unable to find entry to delete WWPN 0x%016jx PortID 0x%06x handle 0x%x",
+ mp->nt_channel, mp->nt_wwn, mp->nt_sid, mp->nt_nphdl);
}
void
OpenPOWER on IntegriCloud