Fix target mode with fabric for pre-24xx chips.
For those chips we are not receiving login events, adding initiators based on ATIO requests. But there is no port ID in that structure, so in fabric mode we have to explicitly fetch it from firmware to be able to do normal scan after that.
This commit is contained in:
parent
070d1d2f21
commit
4187a96543
@ -2320,7 +2320,8 @@ isp_mark_portdb(ispsoftc_t *isp, int chan)
|
||||
lp = &fcp->portdb[i];
|
||||
if (lp->state == FC_PORTDB_STATE_NIL)
|
||||
continue;
|
||||
if ((lp->portid & 0xfffc00) == 0xfffc00)
|
||||
if (lp->portid >= DOMAIN_CONTROLLER_BASE &&
|
||||
lp->portid <= DOMAIN_CONTROLLER_END)
|
||||
continue;
|
||||
fcp->portdb[i].probational = 1;
|
||||
}
|
||||
@ -2787,9 +2788,6 @@ isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
|
||||
|
||||
fcp = FCPARAM(isp, chan);
|
||||
|
||||
/* Mark port database entries probational for following scan. */
|
||||
isp_mark_portdb(isp, chan);
|
||||
|
||||
if (fcp->isp_loopstate >= LOOP_LTEST_DONE)
|
||||
return (0);
|
||||
|
||||
@ -3078,6 +3076,48 @@ isp_pdb_add_update(ispsoftc_t *isp, int chan, isp_pdb_t *pdb)
|
||||
chan, pdb->portid, pdb->handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix port IDs for logged-in initiators on pre-2400 chips.
|
||||
* For those chips we are not receiving login events, adding initiators
|
||||
* based on ATIO requests, but there is no port ID in that structure.
|
||||
*/
|
||||
static void
|
||||
isp_fix_portids(ispsoftc_t *isp, int chan)
|
||||
{
|
||||
fcparam *fcp = FCPARAM(isp, chan);
|
||||
isp_pdb_t pdb;
|
||||
uint64_t wwpn;
|
||||
int i, r;
|
||||
|
||||
for (i = 0; i < MAX_FC_TARG; i++) {
|
||||
fcportdb_t *lp = &fcp->portdb[i];
|
||||
|
||||
if (lp->state == FC_PORTDB_STATE_NIL ||
|
||||
lp->state == FC_PORTDB_STATE_ZOMBIE)
|
||||
continue;
|
||||
if (VALID_PORT(lp->portid))
|
||||
continue;
|
||||
|
||||
r = isp_getpdb(isp, chan, lp->handle, &pdb, 1);
|
||||
if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
|
||||
return;
|
||||
if (r != 0) {
|
||||
isp_prt(isp, ISP_LOGDEBUG1,
|
||||
"Chan %d FC Scan Loop handle %d returned %x",
|
||||
chan, lp->handle, r);
|
||||
continue;
|
||||
}
|
||||
|
||||
MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
|
||||
if (lp->port_wwn != wwpn)
|
||||
continue;
|
||||
lp->portid = lp->new_portid = pdb.portid;
|
||||
isp_prt(isp, ISP_LOG_SANCFG,
|
||||
"Chan %d Port 0x%06x@0x%04x is fixed",
|
||||
chan, pdb.portid, pdb.handle);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan local loop for devices.
|
||||
*/
|
||||
@ -3097,13 +3137,18 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
return (0);
|
||||
}
|
||||
isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan", chan);
|
||||
fcp->isp_loopstate = LOOP_SCANNING_LOOP;
|
||||
if (TOPO_IS_FABRIC(fcp->isp_topo)) {
|
||||
if (!IS_24XX(isp)) {
|
||||
isp_fix_portids(isp, chan);
|
||||
if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
|
||||
goto abort;
|
||||
}
|
||||
isp_prt(isp, ISP_LOG_SANCFG,
|
||||
"Chan %d FC loop scan done (no loop)", chan);
|
||||
fcp->isp_loopstate = LOOP_LSCAN_DONE;
|
||||
return (0);
|
||||
}
|
||||
fcp->isp_loopstate = LOOP_SCANNING_LOOP;
|
||||
|
||||
lim = LOCAL_LOOP_LIM;
|
||||
r = isp_gethandles(isp, chan, handles, &lim, 1, 1);
|
||||
@ -3121,6 +3166,7 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
/*
|
||||
* Run through the list and get the port database info for each one.
|
||||
*/
|
||||
isp_mark_portdb(isp, chan);
|
||||
for (idx = 0; idx < lim; idx++) {
|
||||
handle = handles[idx];
|
||||
|
||||
@ -3162,8 +3208,6 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
isp_prt(isp, ISP_LOGDEBUG1,
|
||||
"Chan %d FC Scan Loop handle %d returned %x",
|
||||
chan, handle, r);
|
||||
if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
|
||||
goto abort;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -3363,13 +3407,13 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
return (0);
|
||||
}
|
||||
isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan", chan);
|
||||
fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
|
||||
if (!TOPO_IS_FABRIC(fcp->isp_topo)) {
|
||||
fcp->isp_loopstate = LOOP_FSCAN_DONE;
|
||||
isp_prt(isp, ISP_LOG_SANCFG,
|
||||
"Chan %d FC fabric scan done (no fabric)", chan);
|
||||
return (0);
|
||||
}
|
||||
fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
|
||||
|
||||
if (FC_SCRATCH_ACQUIRE(isp, chan)) {
|
||||
isp_prt(isp, ISP_LOGERR, sacq);
|
||||
@ -3493,7 +3537,7 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
* than one entry that has the same PortID or the same
|
||||
* WWNN/WWPN duple, we enter the device into our database.
|
||||
*/
|
||||
|
||||
isp_mark_portdb(isp, chan);
|
||||
for (portidx = 0; portidx < portlim; portidx++) {
|
||||
portid = ((rs1->snscb_ports[portidx].portid[0]) << 16) |
|
||||
((rs1->snscb_ports[portidx].portid[1]) << 8) |
|
||||
@ -3502,13 +3546,13 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
"Chan %d Checking fabric port 0x%06x", chan, portid);
|
||||
if (portid == 0) {
|
||||
isp_prt(isp, ISP_LOG_SANCFG,
|
||||
"Chan %d Skipping null PortID at idx %d",
|
||||
"Chan %d Port at idx %d is zero",
|
||||
chan, portidx);
|
||||
continue;
|
||||
}
|
||||
if (portid == fcp->isp_portid) {
|
||||
isp_prt(isp, ISP_LOG_SANCFG,
|
||||
"Chan %d Skipping our PortID 0x%06x", chan, portid);
|
||||
"Chan %d Port 0x%06x is our", chan, portid);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -3555,8 +3599,11 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
}
|
||||
|
||||
relogin:
|
||||
if ((fcp->role & ISP_ROLE_INITIATOR) == 0)
|
||||
if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
|
||||
isp_prt(isp, ISP_LOG_SANCFG,
|
||||
"Chan %d Port 0x%06x is not logged in", chan, portid);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isp_login_device(isp, chan, portid, &pdb,
|
||||
&FCPARAM(isp, 0)->isp_lasthdl)) {
|
||||
@ -5850,11 +5897,14 @@ isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *opt
|
||||
if (fcp->role == ISP_ROLE_NONE)
|
||||
continue;
|
||||
c = (chan == 0) ? 127 : (chan - 1);
|
||||
if (rid.ridacq_map[c / 16] & (1 << (c % 16)))
|
||||
if (rid.ridacq_map[c / 16] & (1 << (c % 16))) {
|
||||
fcp->isp_loopstate = LOOP_NIL;
|
||||
isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
|
||||
chan, ISPASYNC_CHANGE_OTHER);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FCPARAM(isp, rid.ridacq_vp_index)->isp_loopstate = LOOP_NIL;
|
||||
isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
|
||||
rid.ridacq_vp_index, ISPASYNC_CHANGE_OTHER);
|
||||
}
|
||||
|
@ -2342,7 +2342,7 @@ isp_handle_platform_atio(ispsoftc_t *isp, at_entry_t *aep)
|
||||
atp->bytes_xfered = 0;
|
||||
atp->lun = aep->at_lun;
|
||||
atp->nphdl = aep->at_iid;
|
||||
atp->portid = PORT_NONE;
|
||||
atp->portid = PORT_ANY;
|
||||
atp->oxid = 0;
|
||||
atp->cdb0 = atiop->cdb_io.cdb_bytes[0];
|
||||
atp->tattr = aep->at_tag_type;
|
||||
|
@ -2580,12 +2580,12 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t wwpn, uint64_t wwnn,
|
||||
* so log them verbosely and dump the whole port database.
|
||||
*/
|
||||
if ((VALID_INI(wwpn) && isp_find_pdb_by_wwpn(isp, chan, wwpn, &lp)) ||
|
||||
(s_id != PORT_NONE && isp_find_pdb_by_portid(isp, chan, s_id, &lp))) {
|
||||
(VALID_PORT(s_id) && isp_find_pdb_by_portid(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) {
|
||||
if (VALID_PORT(s_id) && lp->portid != s_id) {
|
||||
if (!VALID_PORT(lp->portid)) {
|
||||
isp_prt(isp, ISP_LOGTINFO,
|
||||
"Chan %d WWPN 0x%016llx handle 0x%x "
|
||||
"gets PortID 0x%06x",
|
||||
@ -2804,13 +2804,13 @@ isp_del_wwn_entries(ispsoftc_t *isp, isp_notify_t *mp)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (mp->nt_wwn != INI_ANY) {
|
||||
if (VALID_INI(mp->nt_wwn)) {
|
||||
if (isp_find_pdb_by_wwpn(isp, mp->nt_channel, mp->nt_wwn, &lp)) {
|
||||
isp_del_wwn_entry(isp, mp->nt_channel, lp->port_wwn, lp->handle, lp->portid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (mp->nt_sid != PORT_ANY && mp->nt_sid != PORT_NONE) {
|
||||
if (VALID_PORT(mp->nt_sid)) {
|
||||
if (isp_find_pdb_by_portid(isp, mp->nt_channel, mp->nt_sid, &lp)) {
|
||||
isp_del_wwn_entry(isp, mp->nt_channel, lp->port_wwn, lp->handle, lp->portid);
|
||||
return;
|
||||
|
@ -282,6 +282,7 @@ typedef struct {
|
||||
#define FABRIC_PORT_ID 0xFFFFFE
|
||||
#define PORT_ANY 0xFFFFFF
|
||||
#define PORT_NONE 0
|
||||
#define VALID_PORT(port) (port != PORT_NONE && port != PORT_ANY)
|
||||
#define DOMAIN_CONTROLLER_BASE 0xFFFC00
|
||||
#define DOMAIN_CONTROLLER_END 0xFFFCFF
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user