Another round of port scanner rewrite.

This change simplifies and unifies port adding/updating for loop and
fabric scanners.  It also fixes problems with scanning restarts due to
concurrent port databases changes.  It also fixes many cosmetic issues.
This commit is contained in:
Alexander Motin 2015-11-19 17:43:47 +00:00
parent 828b0885d9
commit eea52482f9
6 changed files with 295 additions and 635 deletions

File diff suppressed because it is too large Load Diff

View File

@ -2589,7 +2589,7 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
/*
* Find the PDB entry for this initiator
*/
if (isp_find_pdb_by_sid(isp, chan, sid, &lp) == 0) {
if (isp_find_pdb_by_portid(isp, chan, sid, &lp) == 0) {
/*
* If we're not in the port database terminate the exchange.
*/
@ -3322,7 +3322,7 @@ isp_handle_platform_target_notify_ack(ispsoftc_t *isp, isp_notify_t *mp)
uint16_t nphdl;
sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2];
if (isp_find_pdb_by_sid(isp, mp->nt_channel, sid, &lp)) {
if (isp_find_pdb_by_portid(isp, mp->nt_channel, sid, &lp)) {
nphdl = lp->handle;
} else {
nphdl = NIL_HANDLE;
@ -3446,7 +3446,7 @@ isp_handle_platform_target_tmf(ispsoftc_t *isp, isp_notify_t *notify)
goto bad;
}
if (isp_find_pdb_by_sid(isp, notify->nt_channel, notify->nt_sid, &lp) == 0 &&
if (isp_find_pdb_by_portid(isp, notify->nt_channel, notify->nt_sid, &lp) == 0 &&
isp_find_pdb_by_handle(isp, notify->nt_channel, notify->nt_nphdl, &lp) == 0) {
inot->initiator_id = CAM_TARGET_WILDCARD;
} else {
@ -4966,15 +4966,17 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
case ISPASYNC_CHANGE_NOTIFY:
{
char *msg;
int evt, nphdl, nlstate, reason;
int evt, nphdl, nlstate, portid, reason;
va_start(ap, cmd);
bus = va_arg(ap, int);
evt = va_arg(ap, int);
if (IS_24XX(isp) && evt == ISPASYNC_CHANGE_PDB) {
if (evt == ISPASYNC_CHANGE_PDB) {
nphdl = va_arg(ap, int);
nlstate = va_arg(ap, int);
reason = va_arg(ap, int);
} else if (evt == ISPASYNC_CHANGE_SNS) {
portid = va_arg(ap, int);
} else {
nphdl = NIL_HANDLE;
nlstate = reason = 0;
@ -4984,10 +4986,16 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
if (evt == ISPASYNC_CHANGE_PDB) {
msg = "Port Database Changed";
isp_prt(isp, ISP_LOGINFO,
"Chan %d %s (nphdl 0x%x state 0x%x reason 0x%x)",
bus, msg, nphdl, nlstate, reason);
} else if (evt == ISPASYNC_CHANGE_SNS) {
msg = "Name Server Database Changed";
isp_prt(isp, ISP_LOGINFO, "Chan %d %s (PortID 0x%06x)",
bus, msg, portid);
} else {
msg = "Other Change Notify";
isp_prt(isp, ISP_LOGINFO, "Chan %d %s", bus, msg);
}
/*
@ -4997,7 +5005,6 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Stopping Loop Down Timer @ %lu", (unsigned long) time_uptime);
callout_stop(&fc->ldt);
}
isp_prt(isp, ISP_LOGINFO, "Chan %d %s", bus, msg);
if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) {
isp_freeze_loopdown(isp, bus, msg);
}

View File

@ -565,11 +565,11 @@ isp_fc_toponame(fcparam *fcp)
return "Unavailable";
}
switch (fcp->isp_topo) {
case TOPO_NL_PORT: return "Private Loop";
case TOPO_FL_PORT: return "FL Port";
case TOPO_N_PORT: return "N-Port to N-Port";
case TOPO_F_PORT: return "F Port";
case TOPO_PTP_STUB: return "F Port (no FLOGI_ACC response)";
case TOPO_NL_PORT: return "Private Loop (NL_Port)";
case TOPO_FL_PORT: return "Public Loop (FL_Port)";
case TOPO_N_PORT: return "Point-to-Point (N_Port)";
case TOPO_F_PORT: return "Fabric (F_Port)";
case TOPO_PTP_STUB: return "Point-to-Point (no response)";
default: return "?????";
}
}
@ -2459,20 +2459,15 @@ isp_destroy_tgt_handle(ispsoftc_t *isp, uint32_t handle)
* Find port database entries
*/
int
isp_find_pdb_by_wwn(ispsoftc_t *isp, int chan, uint64_t wwn, fcportdb_t **lptr)
isp_find_pdb_empty(ispsoftc_t *isp, int chan, fcportdb_t **lptr)
{
fcparam *fcp;
fcparam *fcp = FCPARAM(isp, chan);
int i;
if (chan >= isp->isp_nchan)
return (0);
fcp = FCPARAM(isp, chan);
for (i = 0; i < MAX_FC_TARG; i++) {
fcportdb_t *lp = &fcp->portdb[i];
if (lp->state == FC_PORTDB_STATE_NIL)
continue;
if (lp->port_wwn == wwn) {
if (lp->state == FC_PORTDB_STATE_NIL) {
*lptr = lp;
return (1);
}
@ -2480,17 +2475,32 @@ 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_handle(ispsoftc_t *isp, int chan, uint16_t handle, fcportdb_t **lptr)
isp_find_pdb_by_wwpn(ispsoftc_t *isp, int chan, uint64_t wwpn, fcportdb_t **lptr)
{
fcparam *fcp;
fcparam *fcp = FCPARAM(isp, chan);
int i;
for (i = 0; i < MAX_FC_TARG; i++) {
fcportdb_t *lp = &fcp->portdb[i];
if (lp->state == FC_PORTDB_STATE_NIL)
continue;
if (lp->port_wwn == wwpn) {
*lptr = lp;
return (1);
}
}
return (0);
}
int
isp_find_pdb_by_handle(ispsoftc_t *isp, int chan, uint16_t handle,
fcportdb_t **lptr)
{
fcparam *fcp = FCPARAM(isp, chan);
int i;
if (chan >= isp->isp_nchan)
return (0);
fcp = FCPARAM(isp, chan);
for (i = 0; i < MAX_FC_TARG; i++) {
fcportdb_t *lp = &fcp->portdb[i];
@ -2505,20 +2515,18 @@ isp_find_pdb_by_handle(ispsoftc_t *isp, int chan, uint16_t handle, fcportdb_t **
}
int
isp_find_pdb_by_sid(ispsoftc_t *isp, int chan, uint32_t sid, fcportdb_t **lptr)
isp_find_pdb_by_portid(ispsoftc_t *isp, int chan, uint32_t portid,
fcportdb_t **lptr)
{
fcparam *fcp;
fcparam *fcp = FCPARAM(isp, chan);
int i;
if (chan >= isp->isp_nchan)
return (0);
fcp = FCPARAM(isp, chan);
for (i = 0; i < MAX_FC_TARG; i++) {
fcportdb_t *lp = &fcp->portdb[i];
if (lp->state == FC_PORTDB_STATE_NIL)
continue;
if (lp->portid == sid) {
if (lp->portid == portid) {
*lptr = lp;
return (1);
}
@ -2526,6 +2534,7 @@ isp_find_pdb_by_sid(ispsoftc_t *isp, int chan, uint32_t sid, fcportdb_t **lptr)
return (0);
}
#ifdef ISP_TARGET_MODE
void
isp_find_chan_by_did(ispsoftc_t *isp, uint32_t did, uint16_t *cp)
{
@ -2570,8 +2579,8 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t wwpn, uint64_t wwnn,
* with new parameters. Some cases of update can be suspicious,
* so log them verbosely and dump the whole port database.
*/
if ((VALID_INI(wwpn) && isp_find_pdb_by_wwn(isp, chan, wwpn, &lp)) ||
(s_id != PORT_NONE && isp_find_pdb_by_sid(isp, chan, s_id, &lp))) {
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))) {
change = 0;
lp->new_portid = lp->portid;
lp->new_prli_word3 = lp->prli_word3;
@ -2656,8 +2665,6 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t wwpn, uint64_t wwnn,
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 "
@ -2798,13 +2805,13 @@ isp_del_wwn_entries(ispsoftc_t *isp, isp_notify_t *mp)
}
}
if (mp->nt_wwn != INI_ANY) {
if (isp_find_pdb_by_wwn(isp, mp->nt_channel, mp->nt_wwn, &lp)) {
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 (isp_find_pdb_by_sid(isp, mp->nt_channel, mp->nt_sid, &lp)) {
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;
}

View File

@ -171,10 +171,11 @@ void *isp_find_xs_tgt(ispsoftc_t *, uint32_t);
uint32_t isp_find_tgt_handle(ispsoftc_t *, void *);
void isp_destroy_tgt_handle(ispsoftc_t *, uint32_t);
#endif
int isp_find_pdb_by_wwn(ispsoftc_t *, int, uint64_t, fcportdb_t **);
#ifdef ISP_TARGET_MODE
int isp_find_pdb_empty(ispsoftc_t *, int, fcportdb_t **);
int isp_find_pdb_by_wwpn(ispsoftc_t *, int, uint64_t, fcportdb_t **);
int isp_find_pdb_by_handle(ispsoftc_t *, int, uint16_t, fcportdb_t **);
int isp_find_pdb_by_sid(ispsoftc_t *, int, uint32_t, fcportdb_t **);
int isp_find_pdb_by_portid(ispsoftc_t *, int, uint32_t, fcportdb_t **);
#ifdef ISP_TARGET_MODE
void isp_find_chan_by_did(ispsoftc_t *, uint32_t, uint16_t *);
void isp_add_wwn_entry(ispsoftc_t *, int, uint64_t, uint64_t, uint16_t, uint32_t, uint16_t);
void isp_del_wwn_entry(ispsoftc_t *, int, uint64_t, uint16_t, uint32_t);

View File

@ -167,12 +167,13 @@
#define MBGSD_GET_RATE 0
#define MBGSD_SET_RATE 1
#define MBGSD_SET_RATE_NOW 2 /* 24XX only */
#define MBGSD_ONEGB 0
#define MBGSD_TWOGB 1
#define MBGSD_AUTO 2
#define MBGSD_FOURGB 3 /* 24XX only */
#define MBGSD_EIGHTGB 4 /* 25XX only */
#define MBGSD_1GB 0x00
#define MBGSD_2GB 0x01
#define MBGSD_AUTO 0x02
#define MBGSD_4GB 0x03 /* 24XX only */
#define MBGSD_8GB 0x04 /* 25XX only */
#define MBGSD_16GB 0x05 /* 26XX only */
#define MBGSD_10GB 0x13 /* 26XX only */
#define ISP2100_SET_PCI_PARAM 0x00ff

View File

@ -399,8 +399,9 @@ typedef struct {
*/
uint16_t prli_word3; /* PRLI parameters */
uint16_t new_prli_word3; /* Incoming new PRLI parameters */
uint16_t : 12,
uint16_t : 11,
autologin : 1, /* F/W does PLOGI/PLOGO */
probational : 1,
state : 3;
uint32_t : 6,
is_target : 1,
@ -414,14 +415,12 @@ typedef struct {
uint32_t gone_timer;
} fcportdb_t;
#define FC_PORTDB_STATE_NIL 0
#define FC_PORTDB_STATE_PROBATIONAL 1
#define FC_PORTDB_STATE_DEAD 2
#define FC_PORTDB_STATE_CHANGED 3
#define FC_PORTDB_STATE_NEW 4
#define FC_PORTDB_STATE_PENDING_VALID 5
#define FC_PORTDB_STATE_ZOMBIE 6
#define FC_PORTDB_STATE_VALID 7
#define FC_PORTDB_STATE_NIL 0 /* Empty DB slot */
#define FC_PORTDB_STATE_DEAD 1 /* Was valid, but no more. */
#define FC_PORTDB_STATE_CHANGED 2 /* Was valid, but changed. */
#define FC_PORTDB_STATE_NEW 3 /* Logged in, not announced. */
#define FC_PORTDB_STATE_ZOMBIE 4 /* Invalid, but announced. */
#define FC_PORTDB_STATE_VALID 5 /* Valid */
#define FC_PORTDB_TGT(isp, bus, pdb) (int)(lp - FCPARAM(isp, bus)->portdb)
@ -506,6 +505,8 @@ typedef struct {
#define TOPO_F_PORT 3
#define TOPO_PTP_STUB 4
#define TOPO_IS_FABRIC(x) ((x) == TOPO_FL_PORT || (x) == TOPO_F_PORT)
/*
* Soft Structure per host adapter
*/